# SSH Multi-factor authentication for admins only



## Khaine (Jun 12, 2017)

Hi,

I want to allow an automated task to synchronise directories between servers using net/unison which uses ssh to synchronise remote directories.  To do this in a secure manner I was planning on creating a user to run the task.

However, I have configured ssh to require multi-factor authentication using pam-google-authenticator, and ssh keys.  I there a way I can exclude this user from the multi-factor auth requirements?

I have configured ssh_config as follows:


```
PasswordAuthentication yes
PermitEmptyPasswords no
PubkeyAuthentication yes

PermitRootLogin no
AllowUser khaine_admin

Match User khaine_admin
    AuthenticationMethods publickey,keyboard-interactive
```

And I have configure /etc/pam.d/sshd as follows:


```
auth            required        pam_unix.so             no_warn try_first_pass
auth            required        /usr/local/lib/pam_google_authenticator.so
```


----------



## ShelLuser (Jun 12, 2017)

You basically provided the answer yourself already. As shown you can override SSH settings on either a per-group or per user basis. Just use that. Set up a regular (though I'd probably go for public key) authentication and assign that to the user account which will be performing the synchronization.

By the way... You realize that Google also allows people to use their PC as means for authentication? Basically resulting in 1 device (PC) being used to authenticate in 2 ways? Don't know about you, but I don't see any security advances in that scenario. If a PC is taken over an attacker has full control anyway, no matter what.


----------



## Khaine (Jun 13, 2017)

I thought that because pam is used for the google-authenticator that the /etc/pam.d/sshd would require the second factor for the authentication to proceed as all authentication is offloaded to pam.

I will set up a user tonight and give it a go


----------



## Eric A. Borisch (Jun 13, 2017)

You want security/pam_per_user.

As long as you don't have too many "exceptions to the rule" it's fairly straightforward. I've used it for a very similar case (2-factor for admins only.)


----------



## Khaine (Jun 13, 2017)

Thanks.

I've installed security/pam_per_user and configured /etc/pam_per_user.map as follows:


```
unison : sshd-unison
* : sshd
```

And then created /etc/pam.d/sshd-unison with the default freebsd configuration


```
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            required        pam_unix.so             no_warn try_first_pass
```

I've also set up the associated user and ssh keys and edited /etc/ssh/sshd_config to add the user to AllowedUsers directive, however whenever I try and log in I get the following error:


```
<auth.err> Nas sshd[42238]: error: PAM: authentication error for illegal user unison from unison.local
```

What am I doing wrong?


----------



## Eric A. Borisch (Jun 14, 2017)

As I recall, you need to /etc/pam.d/sshd out of the way (to sshd-default, for example) and add then configure sshd auth, etc to go to pam_per_user. Note you can add an argument (config file path) to pam_per_user.so.1 such that you can have different services have different mappings.

Something like this:
/usr/local/etc/pam.d/sshd
`# May not need all four?
auth required /usr/local/lib/security/pam_per_user.so.1 /usr/local/etc/ppu.sshd
account required /usr/local/lib/security/pam_per_user.so.1 /usr/local/etc/ppu.sshd
password required /usr/local/lib/security/pam_per_user.so.1 /usr/local/etc/ppu.sshd
session required /usr/local/lib/security/pam_per_user.so.1 /usr/local/etc/ppu.sshd`

/usr/local/etc/ppu.sshd
`root : sshd-google
* : sshd-default`

`~# ls /etc/pam.d/sshd* /usr/local/etc/pam.d/sshd*
/etc/pam.d/sshd-default 
/usr/local/etc/pam.d/sshd
/usr/local/etc/pam.d/sshd-google`

NB /etc/pam.d/sshd needs to move otherwise it is preferred over /usr/local/etc/pam.d/sshd. The route pam follows is:


```
Key: [service] resolves to -> destination

[sshd] /usr/local/etc/pam.d/sshd -> pam_per_user

[pam_per_user] (library) --+---(root)--> sshd-google
                           +--(!root)--> sshd-default

[sshd-google] /usr/local/etc/pam.d/sshd-google [end]
[sshd-default] /etc/pam.d/sshd-default [end]
```

NOTE: if your only connection method is SSH (no physical access) be sure you test, and test again, before you log out of your active session when adjusting these files. Also be sure to double check on any upgrades to PAM-related things...

Please TEST FIRST; this isn't my actual config, but is based on it...


----------



## tokred (Jun 14, 2017)

Just a suggestion: Maybe using the "nullok" parameter of pam_google_authenticator.so would fit your requirement more easily. It basically skips 2-Factor for accounts which do not have set up Google Authenticator.

Best regards


----------



## Khaine (Jun 14, 2017)

I had actually tried to use the nullok parameter before but it wouldn't work which is what drove me down this rabbit hole. However, through attempting to get pam_per_user working I've discovered why it didn't work.

In my /etc/ssh/sshd_config I had set:


```
AllowUsers unison khaine_admin
AllowGroups wheel
DenyUsers khaine
```

However the usage of _AllowGroups wheel_ was preventing the unison user from logging in.  I'm not sure why this is the case.  My understanding is that the order of operation for ssh was DenyUsers,AllowUsers,DenyGroups,AllowGroups meaning that the user should have been allowed access as AllowUsers is given precedence to AllowGroups.

Anyway granting access to the user to allow automated syncing is currently working with nullok.  I think I will try setting up pam_per_user in the near future as that feels like a better solution as it forces all other users to have multi-factor authentication.


----------



## Eric A. Borisch (Jun 14, 2017)

tokred said:


> Just a suggestion: Maybe using the "nullok" parameter of pam_google_authenticator.so would fit your requirement more easily. It basically skips 2-Factor for accounts which do not have set up Google Authenticator.
> 
> Best regards



Excellent point. My actual use case (looking back now) was to support forcing ("required") most users to authenticate via pam_krb5, a few with google auth, and some via neither. I was already doing pam_per_user for the Kerberos differences, so I used it for both. Also prevents the user from being able to disable two-factor (intentionally or not) by deleting their google auth config. (Granted, there are other ways to achieve that, too.)

Hopefully someone finds the description useful.


----------

