If you are running any Linux server that is accessible over the Internet, then as an administrator of the server, you must be careful about the security of the server. A few things that could be helpful are as follow:
- Disable password-based authentication for SSH; only allow SSH key-based authentication.
- Move the SSH default port to some other port in higher ranges. For example, move port 22 to port 60000.
- Use firewall tools like UFW to block or allow safe IPs or CIDRs.
- Use a Paraphrase while creating the SSH key; this would act as a 2nd line of defense. For example, if unauthorized persons access your private key, they still have to crack the paraphrase.
- Enable a 2FA authentication.
This post shows the steps to set up 2FA/OTP for SSH, and the Sever we would be enforcing 2FA is running Ubuntu. My authentication is already set to SSH keys.
hostname | IP address | username | password |
---|---|---|---|
my-secure-server | 192.168.122.57 | technekey | technekey |
WARNING: Before performing the following steps, ensure the following:
- Backup up /etc/ssh/sshd_config file
- backup /etc/pam.d/sshd file
- Keep at least two SSH sessions open on the server at all times; the 2nd session can be beneficial in reverting any incorrect changes. This would ensure configuration can be restored all the time.
Step 0: Identify the IP Address that does not warrant 2FA
Add the List of IP address that does not require the 2FA. For example, your home Router IP address. E.g., If I want to exclude 2FA for the source IP 192.168.1.135, then add it here. Similarly, you can add multiple IP addresses or CIDR. Although this step is optional, in most real-world cases, the server administrator would add a set of CIDRS to disable 2FA for those source IPs.
vi /etc/security/access-local.conf
#localhost doesn't need two step verification
+ : ALL : 192.168.1.135
#All other hosts need two step verification
- : ALL : ALL
Step 1: Update and install the Google Authenticator PAM module on the server
sudo apt update
sudo apt install libpam-google-authenticator
Step 2: Configure PAM to use the google authenticator PAM module.
vi /etc/pam.d/sshd #file
# PAM configuration for the Secure Shell service
# Standard Un*x authentication.
#@include common-auth #Uncomment for enable default auth, I have NOT
auth [success=done default=ignore] pam_access.so accessfile=/etc/security/access-local.conf #THIS IS IMP
auth required pam_google_authenticator.so #THIS IS IMP
Step 3: Enable the SSH challenge response in /etc/ssh/sshd_config
Ensure that the following parameters are set in /etc/ssh/sshd_config
vi /etc/ssh/sshd_config #file
UsePAM yes
ChallengeResponseAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey,password publickey,keyboard-interactive
Step 4: Restart the sshd
sudo service sshd restart
Step 5: Configure the google authenticator application
technekey@my-secure-server:~$ google-authenticator
Do you want authentication tokens to be time-based (y/n) y
Scan this code in Google Authenticator mobile Application(This code is blurred out)
Enter the One-time password in the prompt below; save this recovery code if needed for recovery purposes. I have replaced all the real values with dummy values.
Your new secret key is: 12321431241412412DUMMY421QO12334453
Enter code from app (-1 to skip): 123456
Code confirmed
Your emergency scratch codes are:
123456789
123456789
123456789
123456789
123456789
Do you want me to update your "/home/technekey/.google_authenticator" file? (y/n) y
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y
Step 6: Test the configuration
In the below prompt, provide the OTP from the Google Authenticator application from the phone. You can also tweak more by uncommenting line#7 of step#1.
ssh [email protected]
[email protected]'s password:<ENTER-OTP-FROM-MOBILE>
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-56-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Wed Jan 11 20:44:08 CST 2023
System load: 0.00341796875 Processes: 115
Usage of /: 6.0% of 38.58GB Users logged in: 1
Memory usage: 25% IPv4 address for enp1s0: 192.168.122.57
Swap usage: 0%
* Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
just raised the bar for easy, resilient and secure K8s cluster deployment.
https://ubuntu.com/engage/secure-kubernetes-at-the-edge
0 updates can be applied immediately.
*** System restart required ***
Last login: Wed Jan 11 20:37:11 2023 from 192.168.122.1
technekey@my-secure-server:~$