Setting up a Secure Linux Server
No server is ever completely secure. Whenever you expose services to the public, someone will eventually try to attack them, whether through privilege escalation or denial of service. What you can do is reduce the odds that an attack succeeds, or at least limit the damage it causes.

This article doesn’t cover advanced security techniques. It covers practical, common-sense measures that will stop most opportunistic attackers and automated bots. Let’s begin.
You might wonder why you need a configured firewall if your server runs only three services and those are the only ones listening on sockets.
The answer: a firewall is always necessary. A “deny everything, allow exceptions” policy makes any rogue service an attacker manages to plant through privilege escalation useless, since it can’t be reached from outside.
On RedHat/CentOS 6 systems, the firewall rules live in /etc/sysconfig/iptables. A typical restrictive configuration looks like this:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
This configuration accepts new TCP connections to ports 22 (SSH), 80 (HTTP) and 443 (HTTPS). It permits all outgoing traffic along with the replies to it, and allows ICMP (ping). Everything else is blocked.
/tmp is the best-known place on a Linux server where anyone can create files. In a default installation it’s just another directory on the root partition, which leads to problems such as:
- An attacker can create huge numbers of files in /tmp, filling the disk or, worse, exhausting the file system’s inodes.
- Attack scripts can be dropped into /tmp and executed, hoping to exploit a kernel bug or a flaw in a daemon running as root.
- If a scripting language isn’t powerful enough for the attack, the attacker may even bring a compiler and build a binary.
The fix is to give /tmp its own mount point and apply special mount options: noexec or, if that isn’t possible, nosuid. The first prevents anything from being executed in /tmp, even by the superuser. The second disables the “suid” bit on executables, blocking a class of privilege escalation techniques that rely on such scripts or binaries.
An example /etc/fstab entry:
/dev/xvdf2 /tmp xfs defaults,nosuid,noexec 1 2
User files may live in /home (a classic Linux setup) or somewhere under /var (typical for a web server). Either way, they should sit on a dedicated mount point, for several important reasons:
- Disk quotas can only be enforced per mount point, so a dedicated one makes setup simpler.
- Even without quotas, no user can cripple the server by filling the disk or using up all the inodes.
- Hard links to system files become impossible. Otherwise, a rogue user could keep a copy of a vulnerable suid binary for their own use, and the sysadmin would never know.
- Mount options such as noexec or nosuid can be applied to user files alone without affecting the rest of the system.
Password login is insecure: passwords are easier to steal and guess than private keys. On large installations with many nodes, remembering and typing passwords for every login is also impractical and tedious.
Disabling password authentication completely shuts out brute-force bots, which then have no theoretical chance of getting in.
This one arguably belongs at the top of the list. In production, there should be no direct root access, by password or by SSH key, without exception. All administrative work should be done through sudo from a dedicated, ordinary user account that is reachable only by SSH key.
In lower-level environments or fully private servers, this rule can safely be relaxed.
- Enable SYN cookies if they aren’t already on by default.
- Use a fail2ban-style tool.
- Consider using SELinux.
That’s all. I hope you found it useful!