From cdb0e0c10e89129206a9f8ec7e1940eb6297606f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wxcaf=C3=A9=20=28Cl=C3=A9ment=20Hertling=29?= Date: Fri, 24 Nov 2017 16:30:10 +0100 Subject: [PATCH] adds 2fa ssh post --- content/add.sh => add.sh | 2 +- ...h_on_linux,_and_deploying_it_via_puppet.md | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) rename content/add.sh => add.sh (85%) create mode 100644 content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md diff --git a/content/add.sh b/add.sh similarity index 85% rename from content/add.sh rename to add.sh index 4e331b2..2c1b637 100755 --- a/content/add.sh +++ b/add.sh @@ -4,7 +4,7 @@ if [[ -z "$@" ]]; then exit 1 fi title="$@" -filename="$(echo $@ | tr ' ' '_' | tr '[:upper:]' '[:lower:]')" +filename="content/$(echo $@ | tr ' ' '_' | tr '[:upper:]' '[:lower:]')" if [[ -e $filename.md ]]; then echo "$filename.md already exists" exit 1 diff --git a/content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md b/content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md new file mode 100644 index 0000000..d1bda42 --- /dev/null +++ b/content/2fa_ssh_on_linux,_and_deploying_it_via_puppet.md @@ -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. +