Ultimate Security Guide Part 3
Server Hardening
This last part of my security and privacy guide is focused on server infrastructure. In particular, I’ll be covering the securing of common services as well as various steps to take that will prevent intruders from easily gaining access. Some of the things mentioned in here can be applied to desktop machines as well.
Common Vulnerable Services
It’s often the case that people don’t do their basic diligence in fully securing system daemons that are network facing. Attackers often leverage the fact that many people don’t bother securing their services well. Thus, it’s imperative to verify that all system daemons have been adequately hardened against possible threats.
Useless Stuff
Do not enable services if you don’t need them; in particular, never enable insecure services like telnet, rsh, or rlogin. In general, run as few services
as necessary (you can use a tool like nmap
to scan for open ports on your system). Related to this, uninstall compilers and any ancillary system
packages that aren’t necessary for the purpose(s) of your server; additional software serves as more attack vectors for intruders.
SSH
This is the most critical of the services I’ll mention as nearly every server has an SSH daemon for secure remote access. There are several steps that all users must take to secure SSH. For the server side:
- Change the default port to an unused, obscure port not used by any other services (recommended that you choose a 4 digit number at a minimum)
- Disable root login
- Enable public key authentication
- Disable password authentication
- Restrict the setting
MaxAuthTries
to 3 - Set Maximum sessions to the amount of people you expect to be connecting to the server at any one time (for most people, that number is 1)
- If you don’t intend on using X11 forwarding, disable it
Client Considerations
For client side configuration, it’s imperative to make separate keys for each server or service (such as GitLab) that you have. It’s also wise to specify your key generation parameters:
- The
-t
flag specifies the algorithm used (i.e rsa, ed25519) - The
-b
flag specifies the size of the key in bits (i.e 4096 for rsa)
It’s also prudent of the user to change their private key password every so often. This can be done as follows:
ssh-keygen -f id_rsa_sample -p
FTP
It’s preferable to use SFTP (part of the OpenSSH tool suite) over FTP if possible. If you’re setting up a standard FTP server, vsftpd is a great choice of server. I tend to recommend lftp for Linux as a client and the stock clients for FreeBSD and OpenBSD. In server configuration, I recommend the following:
- Don’t allow anonymous use unless you’re storing files for anyone to grab (like linux distro’s that store their iso files)
- Disable anonymous upload if you do allow for anonymous access
- Always set a unique user with the nologin shell for ftp access
- If you’re using standard FTP, enable FTPS and force clients to use it
- If you’re uploading files to a public ftp server that are only intended to be accessed by some, encrypt them
Passwords
Particularly on multi-user systems, it’s crucial to have good passwords practices. At a minimum, server administrators should
- Enable password aging with the
chage
command - Enforce a strong password policy
- Disallow password reuse
I’ll show how to configure these last two items. For ensuring that passwords aren’t vulnerable, we install the pwquality library. This prevents the use of passwords that are more vulnerable to certain kinds of attacks like dictionary attacks. To enable it, edit /etc/pam.d/passwd to look like this:
password required pam_pwquality.so \
retry=3 difok=6 dcredit=-3 ucredit=-3 ocredit=-3 minlen=16
password required pam_unix.so \
sha512 shadow
This is a highly robust configuration that requires that a password be no shorter than 16 characters and have at least 6 different characters from the old password, at least 3 numbers, uppercase letters, and other special characters with 3 attempts given at making such a password. To disallow password reuse, append remember=15 or some other high number to the line
password required pam_unix.so try_first_pass nullok sha512 shadow remember=15
in /etc/pam.d/system-auth.
Audit
In part 1, I mentioned a tool called Lynis, which is a system audit tool for Unix like systems. While I showcased its use on desktop, it is best used on server platforms as it scans for a number of settings that are only really relevant for servers. It is wise to adopt all of the recommendations it makes that are feasible to change.
Mandatory Access Control
Mandatory Access Control frameworks (MACs) restrict users from being able to alter certain attributes about an object in a file system. There are several notable implementations, most of which are Linux specific:
- Security Enhanced Linux (SELinux)
- AppArmor
- TOMOYO Linux
- FreeBSD’s built in MAC
Most of these have different levels of enforcement than range from permissive to full enforcement of configured policies. On Linux, the most extensively
used software is SELinux, which ships with CentOS/Red Hat. Make sure it’s set to enforcing mode at /etc/sysconfig/selinux
. To check the available labels
for all files and directories, run (with sudo or elevated as root)
semanage fcontext -l
For ports, it is
semanage port -l
The chcon
and restorecon
utilities are used to temporarily change and revert contexts respectively. To add a context permanently to an object, we use
we use the -a
and -t
flags to add and indicate context type respectively. To remove, we use -d
in place of -a
. A generic example of enforcing on
an arbitrary file would look like this:
semanage fcontext -a -t some_type /path/to/file
To view contexts in a file listing (ls), process listing (ps), id listing (id), etc, the -Z
flag is used.
AppArmor is in contrast somewhat easier to manage. To check the set of profiles and their statuses, we run aa-status
with sudo. New profiles can be
created with aa-genprof
. This creates a profile for a given application and initialize a profile on first run. Finally, aa-logprof
reads the audit
log of AppArmor for any behavior not consistent with what is specifically allowed in application profiles and then allows the user to address those
events. More information on AppArmor can be read at the official wiki page.
FreeBSD’s MAC is described in thorough detail in the FreeBSD handbook.
Firewall
The recommendations remain largely the same from part 1. For nftables, a sane server config might look like this:
#!/usr/bin/nft -f
flush ruleset
table inet my_table {
chain my_input {
type filter hook input priority 0; policy drop;
iif lo accept comment "Accept any localhost traffic"
ct state invalid drop comment "Drop invalid connections"
ct state established,related accept comment "Accept traffic originated from us"
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 2/second accept;
ip protocol icmp icmp type echo-request limit rate 2/second accept comment "Prevent ping floods";
tcp dport ssh accept comment "Run SSH on port 22"
tcp dport { http, https, 8008, 8080 } accept comment "Accept all HTTP ports"
}
chain my_forward {
type filter hook forward priority 0; policy drop comment "Drop all forwarded traffic"
}
chain my_input {
type filter hook output priority 0; policy accept comment "Accept all outbound connections";
}
}
Intrusion Detection/Prevention
Network intrusion detection systems (NIDS) are applications that monitor networks for potentially malicious activities via a set of pre-configured policies. Some of these systems also double as Network Intrusion Prevention Systems (NIPS). These systems actively attempt to stop threats through a myriad of different methods depending on efficacy; this includes rewriting the firewall on the fly, using a honeypot, etc.
The NIDS I recommend using is Snort. It is highly configurable and has a lot of options, which are documented extensively here.
Sshguard
Sshguard is a daemon that prevents brute-force attacks; it specifically monitors sshd and vsftpd and logs failed login attempts to the system logger.
The configuration is very straight forward, and I recommend tightening some of the default settings; particularly lowering THRESHOLD
to 10, BLOCK_TIME
to at least 900, and DETECTION_TIME
to at least 7200.
Detect Rootkits
The utility rkhunter
reads definitions from a text file and tries to look for backdoors, rootkits, and any other potential local exploit. Install it
from your package manager and then run with sudo:
rkhunter --update # This updates the definitions
rkhunter --check # Performs a system scan