adds 2fa ssh post
This commit is contained in:
parent
bfea28c2a7
commit
cdb0e0c10e
@ -4,7 +4,7 @@ if [[ -z "$@" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
title="$@"
|
title="$@"
|
||||||
filename="$(echo $@ | tr ' ' '_' | tr '[:upper:]' '[:lower:]')"
|
filename="content/$(echo $@ | tr ' ' '_' | tr '[:upper:]' '[:lower:]')"
|
||||||
if [[ -e $filename.md ]]; then
|
if [[ -e $filename.md ]]; then
|
||||||
echo "$filename.md already exists"
|
echo "$filename.md already exists"
|
||||||
exit 1
|
exit 1
|
132
content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md
Normal file
132
content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
Title: 2fa SSH on Linux, and deploying it via Puppet
|
||||||
|
Date: 2017-11-24T13:11+01:00
|
||||||
|
Author: Wxcafé
|
||||||
|
Category:
|
||||||
|
Slug: 2fa_ssh_on_linux,and_deploying_it_via_puppet
|
||||||
|
|
||||||
|
So, I recently (on Monday, 11/20/17) started at a new job! Aside from all the new
|
||||||
|
stuff that implies, and that is much more important overall, I received
|
||||||
|
a Yubikey Neo key to be used for two-factor authentication on various internal
|
||||||
|
services. I found this pretty cool, started using it, and thought no more of it.
|
||||||
|
|
||||||
|
Then the next day, I tried to SSH to my server for some reason and found out
|
||||||
|
that I could obviously not log in since I didn't have my key. So I thought for
|
||||||
|
a minute, didn't find any way to enter my infrastructure when I don't have my
|
||||||
|
key, and took note to do whatever I was planning that evening.
|
||||||
|
|
||||||
|
After a bit of time I put two and two together and thought I could probably try
|
||||||
|
to add 2fa (TOTP, Time-based One Time Password + username) as an alternative
|
||||||
|
authentication method to RSA public key. So I looked a bit and ended up setting
|
||||||
|
that up. Here's how it works.
|
||||||
|
|
||||||
|
So as you might know, authentication on Linux is handled by PAM (Pluggable
|
||||||
|
Authentication Modules). As the name implies, it's made of modules that you can
|
||||||
|
simply plug onto the existing authentication mechanism. And thankfully, someone
|
||||||
|
developped a TOTP module for PAM, which is named `libpam_google_authenticator`
|
||||||
|
(which is not a very good name, but I'm not gonna complain if I can get it
|
||||||
|
working). So the plan is to install that module (pretty easy, since it's
|
||||||
|
packaged by most linux distros), then configure ssh to use it to auth users.
|
||||||
|
*That's* done by editing the `/etc/pam.d/sshd` file, and setting it up like so:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# PAM configuration for the Secure Shell service
|
||||||
|
|
||||||
|
### This is the important part. It adds the module and marks it as a required
|
||||||
|
### authentication method.
|
||||||
|
##
|
||||||
|
auth required pam_google_authenticator.so
|
||||||
|
##
|
||||||
|
|
||||||
|
@include common-auth
|
||||||
|
|
||||||
|
# Disallow non-root logins when /etc/nologin exists.
|
||||||
|
account required pam_nologin.so
|
||||||
|
|
||||||
|
# Uncomment and edit /etc/security/access.conf if you need to set complex
|
||||||
|
# access limits that are hard to express in sshd_config.
|
||||||
|
# account required pam_access.so
|
||||||
|
|
||||||
|
# Standard Un*x authorization.
|
||||||
|
@include common-account
|
||||||
|
|
||||||
|
# SELinux needs to be the first session rule. This ensures that any
|
||||||
|
# lingering context has been cleared. Without this it is possible that a
|
||||||
|
# module could execute code in the wrong domain.
|
||||||
|
session [success=ok ignore=ignore module_unknown=ignore default=bad]
|
||||||
|
pam_selinux.so close
|
||||||
|
|
||||||
|
# ... nothing else interesting until end of file
|
||||||
|
```
|
||||||
|
|
||||||
|
Now that this is done, we need to change sshd's config, to allow it to present
|
||||||
|
the prompt for the TOTP code and tell it to fallback to keyboard-interactive if
|
||||||
|
publickey auth doesn't work. To do that, we add these lines to
|
||||||
|
`/etc/ssh/sshd_config`:
|
||||||
|
|
||||||
|
```sshd
|
||||||
|
UsePam yes
|
||||||
|
ChallengeResponseAuthentication yes
|
||||||
|
AuthenticationMethods publickey keyboard-interactive:pam
|
||||||
|
```
|
||||||
|
|
||||||
|
**Be careful, this will allow users to login with TOTP+pass even if **
|
||||||
|
`PasswordAuthentication` **is set to** `no`
|
||||||
|
|
||||||
|
|
||||||
|
Once this is done, we need to generate a secret for the TOTP generator.
|
||||||
|
`libpam_google_authenticator` has a tool for this named ...
|
||||||
|
`google-authenticator`. Once you run it, it'll ask a few questions, display
|
||||||
|
a QR-code on the screen, give you a private key and a few recovery codes, and
|
||||||
|
write all this into a file named `~/.google_authenticator`. Scan the QR code or
|
||||||
|
add the private key into your TOTP client (an app on your phone, a linux CLI
|
||||||
|
client, whatever. I use OTP Auth on iOS.)
|
||||||
|
|
||||||
|
Once that's done, you can try to use that authentication by running `ssh -o
|
||||||
|
PubkeyAuthentication=no whatever.space`. It should ask you for your
|
||||||
|
"Verification Code", which is the TOTP, and then your password, and then let you
|
||||||
|
log in. Done, you have 2fa on SSH now 😄
|
||||||
|
|
||||||
|
Now for the puppet setup:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
package {'libpam-google-authenticator':
|
||||||
|
ensure => present,
|
||||||
|
}
|
||||||
|
|
||||||
|
file {'/etc/pam.d/sshd':
|
||||||
|
ensure => present,
|
||||||
|
content => file('base/pam/sshd'),
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
}
|
||||||
|
|
||||||
|
file {'/home/wxcafe/.google_authenticator':
|
||||||
|
ensure => present,
|
||||||
|
content => file(modules/base/google_authenticator,
|
||||||
|
owner => 'wxcafe',
|
||||||
|
group => 'wxcafe',
|
||||||
|
mode => '0600',
|
||||||
|
}
|
||||||
|
|
||||||
|
file {'/etc/ssh/sshd_config':
|
||||||
|
ensure => present,
|
||||||
|
content => file('base/ssh/sshd_config'),
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Yeah, I know, this is pretty generic. It was a bit harder for me because I use
|
||||||
|
a git repo for my dotfiles, and as such I have a `git` block and an `exec` block
|
||||||
|
to chmod 600 the .google_authenticator file, and I had a bit of trouble trying
|
||||||
|
to use a `file` block inside another `file` block (setting the mode of the file
|
||||||
|
inside dotfiles git repo) (if you're wondering, puppet simply ignores the
|
||||||
|
least-specific block here... I spent a while wondering why my files wouldn't
|
||||||
|
copy...)
|
||||||
|
|
||||||
|
Either way it should work alright. You might also notice that I just deploy the
|
||||||
|
.google_authenticator file on every machine, and think that's not a very good
|
||||||
|
security practice. I think it's alright, a TOTP is basically identical
|
||||||
|
security-wise to 10 TOTPs, as long as the key doesn't leak, and the increased
|
||||||
|
usability of not having to keep tens of TOTP codes on my phone is clearly worth
|
||||||
|
it.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user