2

My SSH server is configured to use certificate authentication, so it will trust anyone who presents a certificate issued by the user CA when they connect.

For reasons related with audit logs, I don't want my server admins to access the server with root. Which would be the standard way to have user accounts created in the server, so admins can log in using their own accounts?

I'm thinking of a flow like this:

  1. Alice, server administrator, wants to access server1.
  2. She uses her SSH certificate signed by the user CA to connect to server1 issuing the command ssh alice@server1 (the certificate is stored in her local SSH agent).
  3. server1 checks Alice's certificate signature and confirms it was issued by the user CA using the public key specified by the TrustedUserCAKeys key in the sshd_config file).
  4. server1 sends its host certificate to Alice, which gets validated by the ssh client using the host CA's public key in the known_hosts file.
  5. The server creates the alice user locally, along with its home directory and group bindings. Here's where I need your magic.
  6. Alice gets a shell with user alice in server1 and does her admin stuff.

1 Answer 1

0

Following an idea of this response, you can use libnss_shim to allow authenticated users not present in the /etc/passwd.

It is also useful to use pam_mkhomedir to create the homedirs (for ssh should be added to /etc/pam.d/sshd):

session    required    pam_mkhomedir.so skel=/etc/skel/ umask=0022

The libnss_shim could be something like:

{
  "databases": {
    "passwd": {
      "functions": {
        "get_entry_by_uid": {
          "command": "/usr/local/bin/passwd_get_all_entries.sh -u <$uid>"
        },
        "get_entry_by_name": {
          "command": "/usr/local/bin/passwd_get_all_entries.sh -n <$name>"
        }
      }
    },
    "shadow": {
      "functions": {
        "get_entry_by_name": {
          "command": "/bin/bash -c \"echo $name:*:19156:0:99999:7:::\""
        }
      }
    }
  }
}

And the passwd_get_all_entries.sh script:

#!/bin/bash
if [ $# -eq 0 ]; then
    exit 0
fi

while getopts "u:n:" opt; do
    case $opt in
        u)
            uid=$OPTARG
            name=$(find /home -maxdepth 1 -type d -uid $uid | head -1 | cut -d "/" -f 3)
            echo "$name:x:$uid:1::/home/$name:/bin/bash"
            ;;
        n)
            name=$OPTARG
            uid=$(stat -c %u /home/$name 2>/dev/null)
            if [[ -z $uid ]]; then
              uid=$(stat -c %u /home/* | sort | tail -1 | awk '{print $1+1;}')
            fi
            sudo_gid=27
            echo "$name:x:$uid:$sudo_gid::/home/$name:/bin/bash"
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done

This will allow any user authenticated by the signed ssh certificate to login and it will have a home dir and unique uid.

The bash script does not handle possible duplicated UIDs and probably other cases, but shows the idea.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .