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:

  1. 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)
  2. Disable root login
  3. Enable public key authentication
  4. Disable password authentication
  5. Restrict the setting MaxAuthTries to 3
  6. 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)
  7. 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:

  1. Don’t allow anonymous use unless you’re storing files for anyone to grab (like linux distro’s that store their iso files)
  2. Disable anonymous upload if you do allow for anonymous access
  3. Always set a unique user with the nologin shell for ftp access
  4. If you’re using standard FTP, enable FTPS and force clients to use it
  5. 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