From 30ca6a506eafac1d6a75efbc58472733c48b7670 Mon Sep 17 00:00:00 2001 From: Adar Nimrod <nimrod@shore.co.il> Date: Tue, 5 Jul 2016 23:49:47 +0300 Subject: [PATCH] - New entry on SSH security. --- content/ssh_security.rst | 105 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 content/ssh_security.rst diff --git a/content/ssh_security.rst b/content/ssh_security.rst new file mode 100644 index 0000000..2b779e2 --- /dev/null +++ b/content/ssh_security.rst @@ -0,0 +1,105 @@ +SSH security +############ + +:date: 2016-07-05 +:summary: My best practices regarding SSH security + +Over the years I'd heard many people share their best practices regarding +securing SSH access and have been asked by friends and colleagues how to secure +their servers. So here are my opinions and practices regarding SSH security. The +main point I try to get across is balance. Balance between security and +functionality. + +Practices I avoid +----------------- + +First of all, changing the listening port. The upside is that a high random port +is scanned less often and the various script kiddies sometimes fails to notice +it, thus reducing the noise in the logs. This however is no real security +measure as any capable attacker will quickly spot the daemon listening on a +different and all benefits will be lost. The downside is that by not using the +default port you need to configure all clients accordingly. So, no substantial +wins and minor loss. I pass on this idea. + +The second most common is allowing access only from the office IP or a few +select IP addresses. The security benefit is high but the risk is also high. I +view SSH access to servers as critical and limiting access puts you in risk of +locking yourself out in case of trouble/ emergency. Not having management access +to your servers is more dangerous to your business than allowing whomever to +try (not succeed) to access your servers. Therefore I prefer to limit the access +in different ways. + +Practices I employ +------------------ + +Most importantly, allow only key-based authentication. This works without +relying on 3rd party services and is extremely secure when done properly. The +most important issue keeping your private key private. Personally I keep my home +directory on a separate partition that is encrypted with LUKS so the keys are +encrypted when in rest. If you don't have encrypted storage for your keys, +password encrypt the keys (consult the ssh-keygen manual for instructions). + +Another measure of security is limiting the number of authentication attempts +any single IP can perform in a given time. This is achieved by 2 actions. By +ensuring that :code:`MaxAuthTries` in your sshd config is not set too high (the +default is 6 which is damn reasonable) and by limiting the number of TCP +connections to port 22 any IP can initiate. With UFW on Linux this is done by +running :code:`ufw limit ssh` and for OpenBSD or FreeBSD I'd refer you to Peter +Hansteen's `great PF tutorial +<https://home.nuug.no/~peter/pf/en/bruteforce.html>`_. + +These 2 steps will create a barrier to entry that no brute-force attack will be +able to overcome in anyone's lifetime. This is what I do on all of my servers +and it has served me well. However, although the commonly used OpenSSH is +extensively used, researched and tested, bugs still happen. Keeping current +with updates is vital. + +Also, some other good practices are disabling root login, SSH protocol version 1 +is deprecated, insecure and must be turned off (is off by default, but I felt +it's worth mentioning). To further simplify things, here is a short Ansible +playbook that covers the actions mentioned above for Debian based systems. + +.. code:: yaml + + --- + - hosts: all + handlers: + - name: Restart SSH + service: + name: ssh + state: restarted + + tasks: + - name: APT install and update + with_items: + - openssh-server + - ufw + apt: + name: '{{ item }}' + state: latest + update_cache: yes + cache_valid_time: 3600 + + - name: Configure SSHd + with_dict: + MaxAuthTries: 10 + PasswordAuthentication: no + PermitRootLogin: no + Protocol: 2 + lineinfile: + dest: /etc/ssh/sshd_config + regexp: '{{ item.key }}' + line: '{{ item.key }} {{ item.value }}' + state: present + notify: + - Restart SSH + + - name: Enable UFW + ufw: + state: enabled + + - name: Rate limit SSH + ufw: + rule: limit + port: ssh + protocol: tcp -- GitLab