Category: Linux
Created: 2019-11-28
Updated: 2020-08-31
This document describes some “best practices” for improving security on a Linux server.
When installing a new server, you can improve the security of the server if you keep a few things in mind when partitioning:
Set up (at least) one separate partition for all user-writable directories. This is to prevent users from “filling up” the storage space (intentionally or unintentionally) and thus causing the server to fail.
At least /var/www
should be on its own partition. The mount option nodev
and, if possible, noexec
should be activated on this, and group quota should be enabled.
Create a separate partition for /tmp
and enable the mount options nodev
and nosetuid
.
Optionally set the option noexec
for the /tmp
directory. This can reduce the risk of exploits a little.
On Debian/Ubuntu based systems you should create a file /etc/apt/apt.conf.d/10noexec
which contains the following lines:
DPkg::Pre-Invoke { "mount -o remount,exec /tmp"; };
DPkg::Post-Invoke { "mount -o remount /tmp"; };
limit access to MySQL/MariaDB
The default installation of MySQL and MariaDB provides a database called test
and allows anonymous access to that. Additionally, no initial password for the database admin account (root
) is set.
To fix this, run the script mysql_secure_installation
:
root@srv:~# mysql_secure_installation
You will be asked several questions and will be prompted for a root password. You can usually answer all questions with its default value (yes).
disable portmapper service
Often the portmapper service is installed and enabled by default. When this service is available from outside, this is a security risk (the portmapper might be used by attackers for DDoS attacks).
You can check if the portmapper is active with the tool rpcinfo
:
root@srv:~# rpcinfo
program version netid address service owner
100000 4 tcp6 ::.0.111 portmapper superuser
100000 3 tcp6 ::.0.111 portmapper superuser
100000 4 udp6 ::.0.111 portmapper superuser
100000 3 udp6 ::.0.111 portmapper superuser
100000 4 tcp 0.0.0.0.0.111 portmapper superuser
100000 3 tcp 0.0.0.0.0.111 portmapper superuser
100000 2 tcp 0.0.0.0.0.111 portmapper superuser
100000 4 udp 0.0.0.0.0.111 portmapper superuser
100000 3 udp 0.0.0.0.0.111 portmapper superuser
100000 2 udp 0.0.0.0.0.111 portmapper superuser
100000 4 local /var/run/rpcbind.sock portmapper superuser
100000 3 local /var/run/rpcbind.sock portmapper superuser
In most cases you can not uninstall the portmapper service, because things like the quota subsystem depend on it. So just disable that service permanently:
root@srv:~# systemctl stop rpcbind
Warning: Stopping rpcbind.service, but it can still be activated by:
rpcbind.socket
root@srv:~# systemctl stop rpcbind.socket
root@srv:~# systemctl disable rpcbind
Removed symlink /etc/systemd/system/multi-user.target.wants/rpcbind.service.
restrict access to su
command
Hosting users should never have access to the su
command. We recommend to only allow members of the group adm
to use the su
command.
add your admin users (non-root) to the adm
group, e.g.:
root@srv:~# usermod -aG adm admin-user
add the following line to /etc/pam.d/su
:
auth required pam_wheel.so group=adm
test if executing su
is now still possible for your admin user
test whether “normal” users can’t run su
any more
restrict access to process list (ps
)
Normal users shouldn’t see which processes are running on the server (except of their own ones, of course). Restrict the access to the process list by adding hidepid=2
to the /proc
entry in /etc/fstab
:
proc /proc proc defaults,hidepid=2 0 0
Then remount the /proc
filesystem:
root@srv:~# mount /proc -o remount
All non-root users should now only see their own processes when running ps aux
.
restrict SSH access
Access via SSH should also be restricted. Edit /etc/ssh/sshd_config
and set these values:
PermitRootLogin no
(or: PermitRootLogin without-password
) to prevent brute-force password attacks on your root account (be sure to have created a normal admin account first, preferably with Public Key authentication!)AllowTcpForwarding no
and X11Forwarding no
to not use your server as TCP tunnel into the internetDebianBanner no
(Debian/Ubuntu only) to not show your Debian/Ubuntu version before logging in (though the OpenSSH version is still displayed, which can hardly be suppressed)After that, restart the SSH daemon (service sshd restart
).
Many tutorials recommend to change the default port of SSH (port 22) to some random other port. Sorry, but this doesn’t help anything - in fact that’s even a security risk. Only applications with root privileges may bind to ports <1024. So if you decide to run SSH for example on port 12345, any user could easily run a program trying to bind to port 12345 by itself. On the next SSH restart this could be successful, and so a normal (unprivileged) user has hijacked your SSH access - which is at least a DoS. Either bind SSH to any port <1024, or better leave it at its default port.
The following tuning settings are based on the Kernel sysctl configuration file for Linux from Michiel Klaver.
Edit/create the file /etc/sysctl.d/security.conf
(or download):
# Controls the System Request debugging functionality of the kernel
# Default: 438
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
# Default: 0
kernel.core_uses_pid = 1
# Allow for more PIDs
# Default: 32768
kernel.pid_max = 65535
# Controls the maximum size of a message, in bytes
# Default: 16384
kernel.msgmnb = 65535
# Controls the default maxmimum size of a mesage queue
# Default: 8192
kernel.msgmax = 65535
# Hide exposed kernel pointers
# Default: 0
kernel.kptr_restrict = 1
Edit/create the file /etc/sysctl.d/network-security.conf
(or download):
# Prevent SYN attack, enable SYNcookies (they will kick-in when the max_syn_backlog reached)
# Default: tcp_syncookies=1, tcp_syn_retries=6, tcp_synack_retries=5, tcp_max_syn_backlog=1024
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_syn_backlog = 4096
# Disables IP source routing
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Enable Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Enable a fix for RFC1337 - time-wait assassination hazards in TCP
net.ipv4.tcp_rfc1337 = 1
To apply your new settings, run the following command:
sysctl --system
This list is not exhaustive. If you have additional tips or comments, please contact us.