Key topics within the post:
When I think about it, in all my years of working with servers, I can’t count how many instances of improperly secured SSH access I’ve come across. Yeesss, we all know you need to login first, but metaphorically that’s a mighty thin paper wall we’re left with. Add that John might like cats so his password is kitty01 which is just a brute force happy moment there. Why not go Great Wall/Firewall of China scale when it’s so easy to do? Multi-layered security! Yea baby!
The passwords at the top of a brute force dictionary attack include:
You may leave your front door unlocked when you leave, but the majority of servers have irreplaceable data on them and are much more prone to attack than your front door. So lets go over a few really simple ways to secure SSH access to your Linux server.
This has to be one of the simplest and most effective way to restrict access to SSH. If an attacker can’t find it within 10 secs they might just well move onto the nexxt server on their list. Security through obscurity – remember it. The default SSH port is 22. Everyone knows this, so make it something they don’t know. There are only two catches: 1) don’t forget what the new port is and 2) don’t use another port already taken or popularly used.
Now I’m a vim fan these days but I’m going to use nano as the default editor around here for people who haven’t grasped vim yet. If you’re a vim user then by all means use it, we know its better.
$ nano -w /etc/ssh/sshd_config Port 1234
It may be set to something by default to #Port 22 or similar. The # comments it out and therefore disables that line (it will use the default). Your new setting won’t work unless you uncomment the line. So after entering your new port, write it down on paper and save your changes. You need to restart SSHD afterwards to come into effect.
$ service sshd restart
OR$ /etc/init.d/sshd restart
Do NOT just logout to test it works because if it doesn’t, you’re locked out of your server. Open a new terminal window, put in your IP and change the port from 22 to the new port (1234) and login. How easy was that?
Holy shit its not working! Relax, you likely have a firewall setup. Adjust your firewall remove the old and add the new port, and try again.
Raise your hand if you hate remembering passwords. Then don’t use them, use something better. Lets talk about keys people.
Keys are very neat to say the least. There are two keys, a public and private key. The public key you give out to the public, it is installed on the remote server. The private key is just that, yours, never share it with anyone. It sits locally and you use it to connect to the remote server.
If you’re using a Windows machine and PuTTY, then look for PuTTYgen. If not download PuTTYgen here. Follow instructions to make your key, making sure you name it properly and use a passphrase. A passphrase is basically a password to use the key – I know we’re getting rid of passwords but any password is better than none.
If you use a Mac or another Linux box then check out ssh-keygen.
$ ssh-keygen -t rsa -C "sysadminspot.com" Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: cd:8f:e6:10:9c:b7:98:0b:d6:05:30:bc:f1:00:5c:e6 brendan home
And look at that! Now I have some extra files:
$ ls ~/.ssh id_rsa id_rsa.pub
Your new files are:
- id_rsa – Is your private key. Look after this and don’t share it with anyone. Don’t sent it unsecured across any networks. Use scp if you must relocate it.
- id_rsa.pub – Is your public key. This is what you give to people to grant you access to their server. They install it as described below.
The public key is generated from the private key, so you can always get it again if you lose it but avoid that. Here’s what they look like:
$ cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvHsdNSZFxK7gJ+mtCObQdv4ANLVM3LgDGkW1pg4+opWRPsQeYBNnV5eDArrbw9nEiN6ugIuxn4TyvGdUwLFI4ZGwY93SOSsk6r5LKen/No2ZqsEHtQ4R0D6LlInXVByVgquUHh3g9QouXtT2TsH3/RPuTrkncjvzphoeu02+EDs= brendan home $ cat .ssh/id_rsa -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,F2CE94BC19FB32A7 itQ6WqVkOfd0Xo2GmiUrlSf+ABfc3WvOQyX3j43TQ6kDfz9rRUNr0SOGwa7E7XaP fXtiLDnialehrozcYvpJMB9es7CKypcPf9UFD5/JFUJeJWV0ZDNg0UpcCvCamTsh 0i41uNKm+OYJrEsxhMiEEisvTpyEpOWi1xzTqVZ87UnKwGIVFQLjNQKRxzaw74QC /kW3qQYVDDMRuo+S25f+6ObYfPRrU1TuY0g4yGvVgkxwZNbnyY91vcEoyYRFs2o1 uY/BLueuyGOgSfEZ8iGaQKzZHM/MH12lI3EIk8f6rQAeOC4bS7Coxiq5yHA/gBBc H9KmSo9QvI4aWGqd8jZwc2OOmZGJy/n8hLP9qalUjM84ahoBHr1HxheIHUPeet0A aWcVKvkepvxbs7sm259yb04K7VUSkop9y/A6h07jO7egMyYUH2PgvDCW2kgiXjyn d+gKNDaVj6PLgZEth2UPoZ3uR85VuiBydVl2ngqiWqlZnH2g5KT21XbZ0zQ+nOei GUhsEMc1/orrooll2FvPYjSnPhLJ5KBTx/MXlvGnyfUGQlLv6fNt4KXU4KlesC07 Lf/icEedQZLhXo/4Wye7eb5TKnF5nkJpz34g9LOZzUx4uRD5huM2ICIL8KsrnJhQ mZRDu/73pve1anT4vg+RAKrpSFhnFOfnQkNSvzsQmgLDTbUQr50nZO7Q4SEhpAFu l/CaBPC68tvjJDJYVabiz/ljoq3W2Ck73DDgNLxXTDc2wpXsivdz0NOfE5vas43u jkwvXoqT4gPer3mAxAmKaen7sFv8VXP8kGLQkcMMdDA= -----END RSA PRIVATE KEY-----
Oh no! I just gave out my new private key!! The key must now be decommissioned since it is no longer secure. If someone else has your key and passphrase they have your clearance and access.
Now login to your remote server through normal means and grab a copy of your public key. This is my favourite way of deploying it:
$ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvHsdNSZFxK7gJ+mtCObQdv4ANLVM3LgDGkW1pg4+opWRPsQeYBNnV5eDArrbw9nEiN6ugIuxn4TyvGdUwLFI4ZGwY93SOSsk6r5LKen/No2ZqsEHtQ4R0D6LlInXVByVgquUHh3g9QouXtT2TsH3/RPuTrkncjvzphoeu02+EDs= brendan home" >> ~/.ssh/authorized_keys
Use the >> as to not overwrite any other keys there. You could also use your preferred text editor (nano, vim, etc):
nano -w ~/.ssh/authorized_keys
Now, back on your local workstation… If using PuTTY, use the normal settings however go to SSH > Connection > Auth and select your private key. I very strongly recommend you then save these settings under a profile for later use. You don’t want to have to keep selecting the key every time you connect.
If on a Linux or Mac box you can connect with something like this:
$ ssh -p <port> -i <path to pri-key> <user>@<host> $ ssh -p 1234 -i ~/.ssh/id_rsa email@example.com Enter passphrase for key '/root/.ssh/id_rsa': Last login: Fri Sep 4 13:45:38 2009 from 192.168.1.10
Cycle your SSH keys annually at least. Also keep your authorized_keys file neat and commented well so you know who owns what key.
Now we’re gonna look at ways to harden your SSH configuration. Read each carefully because they should only be applied if applicable. So open your sshd_config file and lets have a look around:
$ nano -w /etc/ssh/sshd_config
Below are the recommended options. Note if the line is commented out remove the # from the start of the line to bring it into effect. Also test all your changes before logging out of the server. If you’ve broken SSH you’ll need someone to fix it from the console which is to be avoided!
- Protocol 2 – Enforce use of this protocol only. If it says 1,2 then remove “1,” from it. Version 1 allows you to SSH using insecure methods. There is no excuse to permit this type of authentication any more.
- PermitRootLogin without-password – If you’ve just setup keys for your root user, disable the use of password authentication for root. If you’re the only one that accesses root and you have the key setup, why use password authentication to allow others to access?
- AllowUsers brendan,ben,lisa – Limit the users that can connect to SSH in the actual SSH configuration. There are many ways of doing this, but why not double up? Perhaps users need SFTP access but not SSH?
- PasswordAuthentication no – Once again if there are limited persons accessing the box and they all have keys, why leave the option to authenticate with a password on? If people are still authenticating with passwords, encourage a migration to SSH keys. Only use this option if your keys are setup, tested and working perfectly.
- PermitEmptyPasswords no – If there is no password set on a user then they can’t login to SSH. Simple as that.
After you’ve made some changes you need to restart SSHD:
$ service sshd restart
OR$ /etc/init.d/sshd restart
As mentioned several times previously, test your new settings work before completely locking yourself out. Open a new window and attempt to login again.
One of the big rules in security is unless you need access to do your job, you don’t get access. Typically there are only a limited number of users who need access to SSH. So give me one good reason why you should expose your SSH port to the world? Restrict access to your SSH port (which ever it is, whether 22 or a custom described above) to only authorised IP addresses or networks.
If you work in an office, you might only want to allow access to internal IP addresses. To access outside the office, connect to a VPN to access the office network. The other option is to permit your common IP addresses access (NY Office, Sydney Office, London Office, Home, etc).
Oh! And if your answer to the above was “because my ISP gives me a dynamic IP address or one that changes all the time” – this is still not a valid excuse! Here is what the decision comes down to:
- Give billions of networks around the world access to SSH or just your ISP…. billions or thousands… which is the better?
Whois your current IP address, find the block range, convert it to CIDR form and permit it. See the below example:
$ whois 188.8.131.52 [Querying whois.arin.net] [whois.arin.net] OrgName: Apple Computer, Inc. OrgID: APPLEC-3 ... NetRange: 184.108.40.206 - 220.127.116.11 CIDR: 18.104.22.168/8 ...
Whois your current public IP address – I picked a random IP address and ran a whois on it above. Note the NetRange and CIDR references. That CIDR reference you can use to permit the whole NetRange they’re likely assigned. Sometimes there are multiple ranges assigned, so you might have to do this a few times as your IP address changes to a new range. However however, ISPs do not have an infinite number of these so keep going until you get them all. Perhaps even phone your ISP and ask for their allocated dymanic IP ranges.
If your whois result only returns a range, and not CIDR block, you can use this great IP range into CIDR calculator. Just enter the first IP address (usually ending in .0) and the end address (usually ending in .255).
Anyway, moving on – there are two key types of firewalls to consider: hardware and software firewalls.
Hardware firewalls could include firewall boxes, routers (CISCO, Netgear, Dlink, etc) with firewall options, dedicated boxes running software (like IPCop). Sometimes these are share or distributed between a number of hosts.
Software firewalls are scripts like APF, CSF and KISS firewalls which sit on the server they’re protecting. These particular scripts integrate with iptables, which in turn talks to the netfilter framework in the Linux kernel. Windows servers do a similar thing.
There are advantages, disadvantages and specifics for each which I’m not going into this time. Whichever firewall you use, restrict it to employees’ known ISPs, VPN gateways, internal IPs, etc. Importantly if the requirement for access ceases, then access should be revoked.
- Allow, Deny and Remove with Advanced Policy Firewall (APF)
- Moving From No Control Panel Servers to a cPanel Server
- Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (13)
- Linux Software Firewalls
- Modifying cPanel Mailbox Quota Errors “invalid maildirsize file”
- apf: command not found
- Installing WordPress via SSH Command Line
- Find What IP Address cPanel Site Is Using via Command Line