Monday, October 10, 2016

Setup Another Instance of sshd Support Google's Two-Factor Authentication in Raspberry Pi

For security reason, I want to enhance the sshd running in my Raspberry Pi to make use of Two-Factor Authentication (i.e. SSH Key plus Google Authenticator), if an user logins from WAN (from public network). However, if an user logins from LAN (local network), it just needs password or SSH Key for authentication.

To archive this, I need to setup a new instance of sshd with Two-Factor Authentication. The original sshd remains unchange for LAN users. Moreover, I also need to install google-authenticator related packages.

(Note: need to use root account to do below steps)

  1. install the google-authenticator
    apt-get install libpam-google-authenticator libqrencode3
  2. link sshd-second to sshd. The name of executable sshd-second will be used to load the corresponding PAM config.
    ln /usr/sbin/sshd /usr/sbin/sshd-second
  3. create sshd_config-second by copying from sshd_config
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config-second
  4. update the sshd_config-second: Change the "Port" to 9022 (you can use any available port you want); change "ChallengeResponseAuthentication" to "yes"; Set "PasswordAuthentication" to "no"; add "AuthenticationMethods publickey,keyboard-interactive:pam" and add "PidFile /var/run/sshd-second.pid". Here shows the diff between /etc/ssh/sshd_config and /etc/ssh/sshd_config-second after edited:
    # diff sshd_config sshd_config-second 
    5c5
    < Port 22
    ---
    > Port 9022
    49c49
    < ChallengeResponseAuthentication no
    ---
    > ChallengeResponseAuthentication yes
    52c52,54
    < #PasswordAuthentication yes
    ---
    > PasswordAuthentication no
    > 
    > AuthenticationMethods publickey,keyboard-interactive:pam
    89a92
    > PidFile /var/run/sshd-second.pid
  5. create /etc/pam.d/sshd-second by copying from /etc/pam.d/sshd
  6. cp /etc/pam.d/sshd /etc/pam.d/sshd-second
  7. updte the /etc/pam.d/sshd-second: comment out the line "@include common-auth" and add a line "auth required pam_google_authenticator.so" after "@include common-auth". Here shows the diff between /etc/pam.d/sshd-second and /etc/pam.d/sshd after edited:
    # diff sshd sshd-second 
    4c4,5
    < @include common-auth
    ---
    > #@include common-auth
    > auth required pam_google_authenticator.so
    
    (I comment out the "common-auth" here because I don't want it prompts for password during login.)
  8. create /lib/systemd/system/sshd-second.service by copying from /lib/systemd/system/sshd.service
    cp /lib/systemd/system/sshd.service /lib/systemd/system/sshd-second.service
  9. edit /lib/systemd/system/sshd-second.service: Update the "Description"; update the "ExecStart" to "/usr/sbin/sshd-second -f /etc/ssh/sshd_config-second -D $SSHD_OPTS"; update the "Alias" to "sshd-second.service". Here shows the diff between sshd-second.service and sshd.service after edited:
    # diff sshd.service sshd-second.service 
    2c2
    < Description=OpenBSD Secure Shell server
    ---
    > Description=OpenBSD Secure Shell server (2nd)
    8c8
    < ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
    ---
    > ExecStart=/usr/sbin/sshd-second -f /etc/ssh/sshd_config-second -D $SSHD_OPTS
    15c15
    < Alias=sshd.service
    ---
    > Alias=sshd-second.service
  10. enable and start the new sshd instance:
    systemctl enable sshd-second
    systemctl start sshd-second
    
    (To check the status of the new sshd, you can run "systemctl status sshd-second")
Up to now, the new sshd setup is done. Next, need to setup Google Authenticator for each users.
  1. Login as user and run "google-authenticator". Like below:
  2. On user's smart phone, open the Google Authenticator app. Then, add the account using the QRCode or input the secret key. (If the user's phone doesn't have the app, please follow this link to install).
  3. To test the login, use ssh command, e.g:
    ssh localhost -o Port=9022
    Then, it prompts for "Verification code". The user can get the code from the Google Authenticator App. As long as the user input the code correctly and with correct ssh-key, he/she can login.
Last but not least, need to update router/firewall setting, such that it blocks the original sshd (port 22) from public network and opens for the port (9022 in my case) of the new sshd instance to be access from public network.

[the demo environment is Raspbian GNU/Linux 8 (jessie)]

No comments: