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