Requirements for which I will offer solutions, as bullet points:
- Passwordless root console login
- Passwordless root remote login from pre-authorised users
- Passwordless remote login for specified accounts from pre-authorised users
- Passwordless remote login for any account from pre-authorised users
The following examples are based on Debian, since that's what I've got here for testing. However, I see no reason why the principles cannot be applied to any distribution (or indeed any PAM-based *ix derivative).
Passwordless root console login
I think the way I would approach this would be to leverage PAM and the /etc/securetty
configuration file.
As a pre-requisite, a "sufficiently secure" root password must be set. This is not required for console login but exists to make brute force cracking attempts unrealistic. The account is otherwise a perfectly normal root account.
In /etc/pam.d/login
I have the following standard set of lines for authentication (those beginning with keyword auth
):
auth optional pam_faildelay.so delay=3000000
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so
auth requisite pam_nologin.so
@include common-auth
auth optional pam_group.so
The referenced common-auth
include file contains the following relevant lines:
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth requisite pam_deny.so
auth required pam_permit.so
auth optional pam_cap.so
The common-auth
file instructs PAM to skip one rule (the deny) if a "UNIX login" succeeds. Typically this means a match in /etc/shadow
.
The auth ... pam_securetty.so
line is configured to prevent root logins except on tty devices specified in /etc/securetty
. (This file already includes all the console devices.)
By modifying this auth
line slightly it is possible to define a rule that permits a root login without a password from a tty device specified in /etc/securetty
. The success=ok
parameter needs to be amended so that the ok
is replaced by the number of auth
lines to be skipped in the event of a successful match. In the situation shown here, that number is 3
, which jumps down to the auth ... pam_permit.so
line:
auth [success=3 new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so
Passwordless root remote login from pre-authorised users
This is a straightforward inclusion of ssh keys for those authorised users being added to the root authorized_keys
file.
Passwordless remote login for specified accounts from pre-authorised users
This is also a straightforward inclusion of ssh keys for authorised users being added to the appropriate and corresponding user's .ssh/authorized_keys
file. (The typical remote user chris wants passwordless login to local user chris scenario.)
Note that accounts can remain in the default locked state after creation (i.e. with just !
in the password field for /etc/shadow
) but permit SSH key based login. This requires root to place the key in the new user's .ssh/authorized_keys
file. What is not so obvious is that this approach is only available when UsePAM Yes
is set in /etc/ssh/sshd_config
. PAM differentiates !
as "account locked for password but other access methods may be permitted" and !...
"account locked. Period." (If UsePAM No
is set, then OpenSSH considers any presence of !
starting the password field to represent a locked account.)
Passwordless remote login for any account from pre-authorised users
It wasn't entirely clear to me whether you wanted this facility or not. Namely, certain authorised users would be able to ssh login without a password to any any every local account.
I cannot test this scenario but I believe this can be achieved with OpenSSH 5.9 or newer, which permits multiple authorized_keys
files to be defined in /etc/ssh/sshd_config
. Edit the configuration file to include a second file called /etc/ssh/authorized_keys
. Add your selected authorised users' public keys to this file, ensuring permissions are such that it is owned by root and has write access only by root (0644).
Best Answer
You could add a directive to the
authorized_keys
entry for a key to add a value to the environment for sessions where that key was used. This is from the sshd documentation:So the authorized_keys entry might look like this:
When the user's .bashrc runs, the presence or absence of the SSHKEY variable would indicate whether that particular key was used to authenticate or not.
This is obviously not a general-purpose solution. You'd have to annotate every key entry in every authorized_keys file with this directive. And the user could subvert the check if he had access to alter his
.bashrc
,authorized_keys
, or.ssh/rc
files.