Back from the Cybercamp 2016, about which I will talk you about in future post, I have decided to finish this little guide about basic hardening that I apply to my Debian installations.
Probably you won’t need to apply everything I recommend or maybe some options doesn’t adjust to what you need. This is not a dogma to follow blindly, I recommend that you stop to check what each option does and instead of just doing copy/paste, adapt it to what you need.
In the title I specify Debian but any distro based on it should be compatible with this guide.
You are gonna need root permissions to do this changes so you will need to be logged as root or at least an user with sudo.
Before we start I recommend you to update your system to be sure you have the latest security patches.
apt-get update; apt-get upgrade; apt-get dist-upgrade
Let’s start with a classic: iptables.
To begin with we are gonna start installing the packet iptables-persistent:
apt-get install iptables-persistent
This packet will make our iptables rules load on boot and give us an easy way to keep them updated.
In the installation process you may have been asked to save your current rules, depending of what you did you may already have the file /etc/iptables/rules.v4, if you don’t, create it manually.
We are gonna edit the above mentioned file /etc/iptables/rules.v4 so it looks like this:
*nat :PREROUTING ACCEPT [48:11060] :INPUT ACCEPT [2:104] :OUTPUT ACCEPT [5:270] COMMIT *filter :INPUT DROP [27:7448] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [325:462098] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT COMMIT
What this rules do is cut any remote connection attempt to the machine except those that already exist, this way, if you are connected over SSH you will not be kicked out of the machine.
If you want to open a port at boot time simply add a line like this one before the last COMMIT:
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
Or if you want to just open it till the next reboot:
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
And to close it:
iptables -D INPUT -p tcp -m tcp --dport 22 -j ACCEPT
To save your current rules you can run this command:
iptables-save > /etc/iptables/rules.v4
And to restore them:
iptables-restore < /etc/iptables/rules.v4
Iptables is a world on itself so, I will recommend you take a look at it in depth and add the rules you may need.
The next thing we are gonna do is to apply a little bit of hardening to the kernel, to do this we are gonna edit the file /etc/sysctl.conf and add the following lines at the end:
net.ipv4.icmp_echo_ignore_all=1 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.default.disable_ipv6=1 net.ipv6.conf.lo.disable_ipv6=1 net.ipv6.conf.eth0.disable_ipv6=1 kernel.core_uses_pid=1 kernel.ctrl-alt-del=0 kernel.kptr_restrict=2 kernel.sysrq=0 net.ipv4.conf.all.accept_redirects=0 net.ipv4.conf.all.log_martians=1 net.ipv4.conf.all.rp_filter=1 net.ipv4.conf.all.send_redirects=0 net.ipv4.conf.default.accept_redirects=0 net.ipv4.conf.default.accept_source_route=0 net.ipv4.conf.default.log_martians=1 net.ipv4.tcp_timestamps=0 net.ipv6.conf.all.accept_redirects=0 net.ipv6.conf.all.accept_source_route=0 net.ipv6.conf.default.accept_redirects=0 net.ipv4.conf.all.forwarding=0
As you can see the lines are not properly sorted, this is my preference, if you look closely the first block of net rules disable ping and ipv6, the other block are more specific rules; in any case, the order doesn’t really matter.
As in the iptables case I recommend you to check and see what you need and you dont; for example, probably some of you may want to forward traffic between interfaces so you should remove the last rule.
Once we have the file edited we will launch the next command to apply the changes, or you can always reboot, is your uptime not mine:
sysctl -p
The next step will be to change the SSH configuration a little bit to make it more robust. To do that we should edit the file /etc/ssh/sshd_config and modify/add the following options so they look like this:
UsePrivilegeSeparation SANDBOX LogLevel VERBOSE PermitRootLogin no X11Forwarding no TCPKeepAlive no AllowTcpForwarding no ClientAliveCountMax 2 Compression no MaxAuthTries 3 MaxSessions 2
You may have notice that I didn’t change the port, this is recommended, as if you leave SSH listening a simple nmap will reveal the service, but I will leave it to your decision.
Restar the SSH service to apply the changes:
/etc/init.d/ssh restart
Last but not least we will apply a password security policy.
Install the PAM module pam_passwdqc:
apt-get install libpam-passwdqc
And modify the file /etc/login.defs so it looks like this:
PASS_MAX_DAYS 90 PASS_MIN_DAYS 1 PASS_WARN_AGE 7
I should say again that this is a simple recommendation, adjust the values as you need.
Another personal recommendation would be to disable all those services that you don’t need, specially those that list in some ports. Even with iptables already blocking them it never hurst. For example, for the CUPS service:
/etc/init.d/cups stop; systemctl disable cups
What the previous command does is, first stop the service and later on disable the autostart on boot time. This doesn’t prevent that other applications may start the service, this only tells the system that, if nobody asks for it, don’t start it.
If you want to have a general idea of the hardening status of your machine I recommend you try the application Lynis. It’s already on the Debian repos but I like to use their own to have the latest version, to do this run the following commands:
echo "deb https://packages.cisofy.com/community/lynis/deb/ jessie main" > /etc/apt/sources.list.d/cisofy-lynis.list apt-get install apt-transport-https apt-get update; apt-get install lynis
Now we simply run Lynis like this:
lynis audit system
What Lynis is gonna do is run several check in our machine and at the end will provide a series of recommendations and a grade, in my case I like that my machine’s grade are at least at 85.
And that’s it, you may have noticed that I only touched SSH as an application, that’s because as this is a basic guide I thought it was already long enough without getting into apps that some people doesn’t even have. If you want any specific guide for an app just let me know.
Hope you enjoyed this post, and as always; thanks for your visit, and don’t be shy, leave a comment!
Hi,
i strongly discourage you to use these password guidlelines:
PASS_MAX_DAYS 90
PASS_MIN_DAYS 1
PASS_WARN_AGE 7
These are the standard recommendations and best practices from IT Auditors. It works when you only have to memorize a single password for your mainframe. It stops working when you have to memorize passwords for multiple users on multiple Systems and leads to reuse passwords and patterns.
In bigger environments Users tend to reuse their passwords whenever possible on as many logons as possible. If this does not work, they write it down and put it under their Keyboard.
The way to go is password-less whenever possible with pub-keys.
AuthorizedKeysFile %h/.ssh/authorized_keys
PasswordAuthentication no
Even PuTTy on windows can use this with ease.
First thanks a lot for your comment 🙂 and yeah, using only pub-keys is one of the best options, but as with the changing of the SSH port this is a basic guide not intended for something like a production server but more for an user computer or a home server.
The problem I have faced with key-only access is when you can’t have an usb stick or something where you carry them around all the time. If you don’t have them you don’t have another way in, or if the device where you store them is compromised access is compromised. I think the best option is to use a combination of both.
In my case I use both, depending of the user to avoid that kind of situation, with fail2ban and some other measures like ip whitelists from where the users can login.
But as I said, this is just a basic guide with some recommendations not dogmas.
In any case, I was thinking in writting a whole post just in the different types of options we can use to make SSH more robust like the public keys you mentioned or two-factor auth and other options.
Thanks again for your comment 🙂
Pingback: Debian basic hardening guide | 0ddn1x: tricks with *nix