I don’t really see the benefit of disabling root logon vs. allowing user login + sudo to root, if you only allow login via keypairs. This seems to me to be one of those cases where there might be some theoretical benefits, but those benefits don’t matter in practice.
Edit: I see several other people posted this while I was typing :)
I configured it so I can only sudo with my password. So even if someone gets hold of my private key, they'd have to guess my password for sudo access. Also, as someone pointed out you can restrict sudo commands, which is the sensible thing to do.
SSH to your account, add an alias to sudo in .bashrc (or equivalent for your shell) that records the password in a hidden file before passing it to the real sudo.
I'm not security pro, but I think the best way is to use a separate account that you'd login to directly (on the physical TTY or via SSH) just to run the root commands. Going through your regular account is always more dangerous if you assume it might be compromised.
By the way, this is why Microsoft invented the UAC prompt: rather than a password, which can be intercepted, it generates a window which (presumably) cannot, thanks to User Interface Privilege Isolation.
It's a little bit of a mix of security through obscurity and security in event of sshd having the vulnerability. It won't save you from a targeted attack but will save from blanket "scan 22 port and try root" attacks.
The same way moving ssh from 22 port to something else helps. If you see someone brute-forcing your root you can dismiss it since it's just someone found open 22 port, but if your actual username is being used in attack then you can detect the targeted attack.
Now having password-less sudo is almost the same as using root.
it's not more secure/less secure if you enable root over pubkey only. I mean if I can login with a user that has sudo rights (probably with no password, the default on most cloud providers) there is no real benefit in having a user called ubuntu or centos that can login and gain full sudo rights than using root directly.
I have never seen anyone implement such a policy for sysadmins that actually prevents an attacker from running arbitrary commands. As soon as you permit running e.g. vi on some file, you can just shell out from vi. Or if you can sudo apt-get install, you can downgrade a package to a vulnerable version and then exploit it. Or if you can sudo tcpdump, you can write a dump file to /etc/cron.d and send a valid cron command surrounded by newlines over the network. Or lots of other things.
sudo is useful for allowing generally non-root users to run specific commands or better yet specific scripts (that they can't write to) with elevated privileges - e.g., letting someone "sudo systemctl restart apache2" but nothing else. But it's not particularly useful for auditing people that you want to have mostly-full control over the machine. It can keep honest people honest, sure, but so can .bash_history.
10+ years ago I was setting up a new web server, Apache running on a Linux box.
I was not in the sysadmin team, I was in the web team, so I was not allowed root access, even though the box belonged to the web team.
I asked for root access (via sudo) so I could do stuff like restart Apache.
The manager of the sysadmin team said no way was I getting full access to root, but I could get sudo to run specific commands.
So one of the sysadmins wrote a helper script to do the things I needed, and I could use sudo to run that script (and that script alone) as root.
I told him, it wasn't secure, I could use his helper script to get full root access. He challenged me to prove it.
So I wrote a program which dropped a setuid root shell in my home directory. I used the CustomLog directive in Apache to pipe Apache's logs to that program. Then I used his helper script to restart Apache.
When Apache started, it ran my program as root. I then used the setuid binary it had dropped to become root, and created a file in the sysadmin's home directory to prove it.
When I showed this to the sysadmin, he decided to abandon the helper script. Instead, he just told me the root password.
Apache starts as root so it can bind ports 80 and 443, then switches to the apache user. But the logging subsystem starts before the setuid to apache, so a piped CustomLog binary runs as root.
More secure options would be to use CAP_NET_BIND_SERVICE instead of root, or to make Apache bind an unprivileged port and then use something like iptables (or an external load balancer) to redirect 80/443 to the privileged ports. But, for reasons I can't quite recall (it was 10+ years ago) we didn't take up any of those more secure options.
The setuid binary was created (indirectly) by the Apache CustomLog directive, which is able to spawn programs to use as log targets. So it matters which user Apache runs as, because that controls which user creates the setuid binary and thereby which privileges you can gain.
Rereading the comment it also seems more like Apache is starting something that can become root somehow, I really don't think it is implied Apache is running as root.
Apache usually starts up as root so it can do setup that requires root, and then drops privileges to a user/group specified in Apache configuration. Most commonly the required setup is just binding to privileged ports, but one of the supported setup steps is opening log pipes. See the security note here:
By default, only root can bind to ports 80 and 443. You can change this policy, but that's considered unsecure because then any program can bind to the so called "privileged ports."
You can be more specific than that and allow only a specific user/program to bind a specific privileged port. This is accomplished with a combination of SELinux and the capabilities API in 2.6.24 and newer.
Even if you do that, I think Apache still starts as root to do things like open SSL certificates and log files (and logging configuration is the thing exploited here). Is there a common config - e.g. an initscript / systemd unit on an SELinux distro - that starts Apache as a dedicated user?
I know Apache supports being started as an unprivileged user (I do this myself a lot when I need something a little more featureful than SimpleHTTPServer) but my impression was that that's not very common for production deployments.
On macOS an administrator (someone in the admin group) cannot create, delete, or move files in the system domain. That makes it harder to completely fuck up the computer, but as you say it won't really stop an attacker from running almost any arbitrary command.
Hopefully all admins does that. Never allow a user to run any command if you intend for them to run just one.
SSH public keys have the exact same feature however. Look at "command=" under "Authorized Keys File Format" in the man page. This is a good idea for batch jobs that uses SSH to execute on remote machines.
With SSH keys you even have the option of limiting keys not just to certain commands but to certain IP addresses. By limiting the SSH keys you also don't have to give your keys access to an unprivileged shell where you don't need it.
If the password used for the user, in the remote machine, is different from that of the machine he/she is connecting from, the attacker will not be able to gain root access, even if the account has permission to escalate priviledges.
I don't see how the authentication used for a user on a local machine has anything to do with the authentication of a user on a remote machine unless both are using the same domain authentication (RADIUS, Active Directory, etc). Even then, there can be cache involved.
My parent comment indicates that the password needs to be different. Your comment does not support that.
First, sudo should not be cached for this very reason.
Second, agent caching should never be enabled for this very reason.
Third, agent forwarding should never be enabled for this very reason.
Indeed, using key authentication to log in and then using a password to upgrade to sudo is, I think, very reasonable.
what's wrong with public key auth as root? The "alternative" would be making a sudo-enabled login account. Another indirection, and probably not fully transparent...
If you have more than one person logging in, it's far easier to identify who did something as root by looking at the username that logged in.
Also far better to encourage running sudo for every command, gives a nice simple audit log of what happened, right there in your syslog, so you can identify and undo mistakes, and also eliminate lines of enquiry.
Clearly you can cover your tracks with the old sudo vi / !bash and similar tricks, but the goal isn't to protect against hostile privileges users, its to know what happened so that when John is on holiday you can see what he did to fix the problem you had last week.
Failed at what? I want my sysadmins to have full access, I just want to know what they did. I'm not trying to defend against malicious staff members - I trust them, otherwise they wouldn't have sudo access.
If you can trust your administrators then you don't need to worry about shell escapes in editors.
The idea for sudoedit is that it allows you to allow non-root users to safely edit files, and if they shell out of their editor then they've not gained root rights - they edit a temporary file as a regular user and then sudo moves the file into place after it is edited.
Use of shared accounts eliminates individual accountability if humans are using them.
Unless you have an system with its own auth and audit capability connecting as root, shared accountability is bad. People do dumb shit, including illegal shit.
If you run any command it will run with the root privilege when you are root. It happened to me many times, where I ran a command and it asked for root then I investigated why the particular command needs root and figured that this is not what I want in the first place.
So, account with sudo capabilities is better than then one which is sudo by default.
In my personal opinion, there's nothing wrong with that, as long as key is not compromised, of course.
However, it's somewhat less secure than sudo-enabled account with password requirement. If your SSH key is somehow compromised (unpassworded keyfile or attacker had gained access to ssh-agent's socket, or you've ran a network-listening daemon from your account that had an exploitable RCE) you're a little bit more safe if attackers won't get root access. This only works well for noexec $HOME, of course, as attacker can't mess with your .*shrc and trick you into entering the password.
Clearly you'll only be accepting public key authentication too.