There are a lot of articles on that topic out there. Also, there is more than one opinion on that as well. Don’t take my opinion as the one and only way to do this, but this is how I am doing it. Well, this actually can apply to other *nix-like systems out there to some extent.
Change port of SSH
Well, this actually doesn’t increase the security per se, but it keeps your audit.log clean. On my last server it took about 15 minutes until the first automatic scan tried some broadly used username and password combinations. Of course, these aren’t successful, but you can’t easily differentiate between a targetet attack and an automatic scan if your logs are full of login failures.
To change the default port, just edit /etc/ssh/sshd_config and change the port to something else. Preferrable are 5-digit numbers as they normally don’t collide with other services.
Port 12345
After that, just reload the SSH configuration.
service sshd reload
Now try to connect to your machine with the new configured using another session to verify it’s working.
You can also update your local .ssh/config file to use the new configured port by default.
Host newhost.example.org Hostname newhost.example.org Port 12345
Disable root login
Users root and toor are very common usernames. Also, I don’t want to have root privileges by default when I log in to my machine. You can always use su or sudo to get root privileges. Using the VNC-console of your hosting provider, root login will still work. This only disabled the access by SSH.
Edit /etc/ssh/sshd_config again enable the following line.
PermitRootLogin no
After that, reload the SSH configuration.
service sshd reload
Public key authentication
I don’t like typing in my password for every login. I prefer using my private key on my machine. Using ssh-agent helps that you only have to enter the password of your key once per workstation session.
FreeBSD 10.1’s OpenSSH even supports ED25519 keys as well as ECDSA. Of course, you can still use RSA keys if your client can’t handle these elliptic curve cryptography yet.
For example, to create an ECDSA key, you can use the following command.
ssh-keygen -t ecdsa
For RSA, I suggest a keysize of 4096.
ssh-keygen -t rsa -b 4096
Your public keys will by default end up in $HOME/.ssh/id_ecdsa.pub respectively $HOME/.ssh/id_rsa.pub. I would prefer an ED25519 key over an ECDSA key and likewise an ECDSA key over an RSA key – and I wouldn’t use an DSA key anymore.
On a modern system, you have ssh-copy-id to copy the just created key to your server.
ssh-copy-id funzi@newhost.example.org
If you don’t have this tool, or your don’t like to use it, just append your created public key to .ssh/authorized_keys on your server. Make sure the permission of .ssh are 0700 and the permission of authorized_keys is 0600 – or SSH will refuse to authenticate against public keys.
Test that your login succeeds without entering your password, then edit /etc/ssh/sshd_config again and change the configuration to the following.
PubkeyAuthentication yes PasswordAuthentication no
Then restart SSHD for the last time.
service sshd restart
Use Denyhosts to block failed login attempts
Installing Denyhosts comes with a catch. An attacker knowing your IP address could spoof an attack to lock you out from your server. Keep that in mind if you install Denyhosts. I am using it to keep my logs clean. With password authentication disabled, only unauthorized requests will try passwords.
Denyhosts is a ready package in FreeBSD 10. So you can install it using ports or packages. To install the package, just run
pkg install denyhosts
and follow the instructions. You have to create an empty file /etc/hosts.deniedssh and refer to it in /etc/hosts.deny. Make sure you go over the settings in /usr/local/etc/denyhosts.conf. It’s a quite short configuration file, so there is not excuse for not reading it.
Enable denyhosts by adding the line
denyhosts_enable="YES"
to /etc/rc.conf and then start the service.
service denyhosts start
Enable FreeBSD’s packet filter
FreeBSD’s packet filter is very easy to configure. Only enable the services you want to access from the outside. Disable the rest. This very simple rule will save you a lot of trouble. A good basic setting in /etc/pf.conf which only enables SSH (on the non-standard port) looks like this.
scrub in all set skip on lo0 block in on vtnet0 pass in on vtnet0 proto icmp pass in on vtnet0 proto icmp6 pass in on vtnet0 proto tcp from any to any port 12345
This will allow any communication on lo0 which is okay as well as allows ICMP. If your network device isn’t called vtnet0, you have to change it accordingly. Make sure you consult the FreeBSD Firewall Handbook for more information.
Check that your config doesn’t have any syntax problems by running
pfctl -nf /etc/pf.conf
Enable pf by adding the line
pf_enable="YES"
to /etc/rc.conf and then start the service.
service pf start
As an alternative, you can use service pf onestart without enabling it in rc.conf. This way you can just reboot your machine (using your hoster’s control panel) without locking yourself out forever.
Summary
This should provide you an overview what you can do to enable a minimal security on your hosted machine. Of course this is not everything you have to do, but it raises the barrier.