Basic hardening guide for Debian

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:

:INPUT DROP [27:7448]
:OUTPUT ACCEPT [325:462098]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT

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:


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
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:


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 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!


This entry was posted in hardening, tools, tutorial. Bookmark the permalink.

3 Responses to Basic hardening guide for Debian

  1. cave says:


    i strongly discourage you to use these password guidlelines:


    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.

    • KALRONG says:

      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 🙂

  2. Pingback: Debian basic hardening guide | 0ddn1x: tricks with *nix

Leave a Reply to KALRONG Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.