6

I would like to configure OpenSSH 6.2p2 for a service account (we'll call it "serviceacct") with an empty password which does the following:

  1. First try public key authentication; if it succeeds then run the forced command specified in the authorized_keys file.
  2. Fall back to empty password authentication and run the forced command specified somewhere else.

Essentially this would give one behavior for known users and another behavior for anonymous users.

In an ideal world, these settings in sshd_config would do what I want:

PubkeyAuthentication yes
PasswordAuthentication yes
Match User serviceacct
  PermitEmptyPasswords yes
  ForceCommand /my/program

But I'm running into a couple of problems:

  1. ForceCommand /my/program overrides the forced command that is set in the authorized_keys file.
  2. Using an empty password seems to take precedence over public key authentication.

Is there any way around these two problems, short of modifying the OpenSSH server? One obvious workaround that I can think of is to just use two service accounts - one for known users that only uses public key authentication, and another for anonymous users that only uses empty password authentication. I'm trying to avoid having two user accounts if possible.

Edit - Why I'd like this behavior

I'm building a service which hosts various types of version control system repositories (Subversion, Git, and Mercurial). Think GitHub or Bitbucket, but locally hosted (this is the key, since some of our work cannot leave our site). Arguably, the simplest access method which is common to each of these version control systems is SSH.

Each repository has configurable access rules for known and anonymous users. I'd like to be able to support both known and anonymous users using the same URL for any of the version control systems. Since the user that hosts the repository is part of the URL (e.g. ssh://user@host/path), having two different users - one for known users and one for anonymous users - would require two different URLs.

There is one technicality that I should clarify: I'm actually using the AuthorizedKeysCommand directive in sshd_config, which instructs sshd use the output of an external program instead of reading the ~/.ssh/authorized_keys file.

  • 3
    I'm struggling to find a reason why you would possibly want to do this. Can you explain your actual use case (i.e. tell us something more than "I want this behavior" - like why: What practical problem are you trying to solve by doing this)? – voretaq7 Oct 3 '13 at 18:50
  • Did you ever figure this out? I'm hoping to do the same thing. – Mike Boers May 26 '16 at 21:46
  • This is an excellent question, one that I am struggling to find an answer to. I can see why it may seem crazy (allowing a user to override a centrally-defined force command in their own authorized_keys file) however, for a service account concept it makes total sense. I want to allow new users connect without a password where a registration script would fire and demand their public key. It's a 3-year old question with no answers - I fear the answer is that it cannot be done. – starfry Jul 21 '16 at 14:15
  • It's been some time but just to brain storm an idea: Maybe you could set sshd to be publickey only and when an empty password situation happens, detect it on-the-fly, modify sshd_config accordingly, do your stuff and in the end reset your sshd_config to it's original state. Never looked into this kind of detection but I'm assuming you could somehow use your logs to do this. Although I think probably the user would have to initiate another connection then. – Can Sürmeli Nov 20 '18 at 13:36
2

IIUC you want to use same use account for people who either login via ssh key or without any password, and you want to distinguish between these two authentication methods.

IMO this is doable like this, first server part:

$ sshd --help 2>&1 | sed -n '2p'
OpenSSH_7.9, LibreSSL 2.8.2
$ grep ^Expose /etc/ssh/sshd_config                                                                               
ExposeAuthInfo yes

$ man sshd_config | col -b | sed -n '/ExposeAuthInfo/,/^$/p'
     ExposeAuthInfo
             Writes a temporary file containing a list of authentication
             methods and public credentials (e.g. keys) used to authenticate
             the user.  The location of the file is exposed to the user
             session through the SSH_USER_AUTH environment variable.  The
             default is no.

You would also need to tune sshd_config for your password-less logins. I would recommend to use something like this, keep PermitEmptyPasswords no in global part of the config file!

Match User specialuser
    PermitEmptyPasswords yes
    AuthenticationMethods publickey none
    ForceCommand /path/to/wrapper

And let's make a test wrapper (to make it easy I put it into ~/.ssh/authorized_keys for now)...

$ grep ^command $HOME/.ssh/authorized_keys
command="$HOME/test.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrJU7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ cat ~/test.sh
#!/bin/sh
set -x
printenv | egrep "^(SSH_ORIGINAL_COMMAND|SSH_USER_AUTH)"

if [[ -r ${SSH_USER_AUTH} ]]; then
    cat ${SSH_USER_AUTH}
    if grep -q ^publickey ${SSH_USER_AUTH} ; then
        echo "XXX I've logged with a public key!"
    else
        echo "XXX I've NOT logged with a public key!"
    fi
fi

if [[ -z "${SSH_ORIGINAL_COMMAND}" ]]; then
    exec ${SHELL}
else
    exec ${SHELL} -c "${SSH_ORIGINAL_COMMAND}"
fi

Let's try to ssh with a public key.

$ ssh -l specialuser remote_server
+ printenv
+ egrep ^(SSH_ORIGINAL_COMMAND|SSH_USER_AUTH)
SSH_USER_AUTH=/tmp/sshauth.UTmBQYIadWVem97
+ cat /tmp/sshauth.UTmBQYIadWVem97
publickey ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ grep -q ^publickey /tmp/sshauth.UTmBQYIadWVem97
+ echo XXX I've logged with a public key!
XXX I've logged with a public key!
+ exec /bin/ksh
$

I'm not going to test password-less login for you but I think we have all parts needed here ;)

  • I'm using OpenBSD here, I don't know how PAM fits into this topic. – Jiri B Jan 21 at 21:23
0

Isn't it the thing?

man /etc/ssh/sshd_config:

  • AuthenticationMethods
    • Specifies the authentication methods that must be successfully completed for a user to be granted access. This option must be followed by one or more comma-separated lists of authentication method names. Successful authentication requires completion of every method in at least one of these lists.
    • For example, an argument of publickey,password publickey,keyboard-interactive would require the user to complete public key authentication, followed by either password or keyboard interactive authentication. Only methods that are next in one or more lists are offered at each stage, so for this example, it would not be possible to attempt password or keyboard-interactive authentication before public key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.