Securing the Network

Firewall With UFW (Uncomplicated Firewall)

Call me paranoid, and you don’t have to agree, but I want to deny all traffic in and out of my server except what I explicitly allow. Why would my server be sending traffic out that I don’t know about? And why would external traffic be trying to access my server if I don’t know who or what it is? When it comes to good security, my opinion is to reject/deny by default, and allow by exception.

Of course, if you disagree, that is totally fine and can configure UFW to suit your needs.

Either way, ensuring that only traffic we explicitly allow is the job of a firewall.

How It Works

The Linux kernel provides capabilities to monitor and control network traffic. These capabilities are exposed to the end-user through firewall utilities. On Linux, the most common firewall is iptables. However, iptables is rather complicated and confusing (IMHO). This is where UFW comes in. Think of UFW as a front-end to iptables. It simplifies the process of managing the iptables rules that tell the Linux kernel what to do with network traffic.

UFW works by letting you configure rules that:

  • allow or deny
  • input or output traffic
  • to or from ports

You can create rules by explicitly specifying the ports or with application configurations that specify the ports.

Goals

  • all network traffic, input and output, blocked except those we explicitly allow

Notes

  • As you install other programs, you’ll need to enable the necessary ports/applications.

Steps

  1. Install ufw.

    On Debian based systems:

     sudo apt install ufw
    
  2. Deny all outgoing traffic:

     sudo ufw default deny outgoing comment 'deny all outgoing traffic'
    
    Default outgoing policy changed to 'deny'
    (be sure to update your rules accordingly)
    

    If you are not as paranoid as me, and don’t want to deny all outgoing traffic, you can allow it instead:

     sudo ufw default allow outgoing comment 'allow all outgoing traffic'
    
  3. Deny all incoming traffic:

     sudo ufw default deny incoming comment 'deny all incoming traffic'
    
  4. Obviously we want SSH connections in:

     sudo ufw limit in ssh comment 'allow SSH connections in'
    
    Rules updated
    Rules updated (v6)
    
  5. Allow additional traffic as per your needs. Some common use-cases:

     # allow traffic out on port 53 -- DNS
     sudo ufw allow out 53 comment 'allow DNS calls out'
    	
     # allow traffic out on port 123 -- NTP
     sudo ufw allow out 123 comment 'allow NTP out'
    
     # allow traffic out for HTTP, HTTPS, or FTP
     # apt might needs these depending on which sources you're using
     sudo ufw allow out http comment 'allow HTTP traffic out'
     sudo ufw allow out https comment 'allow HTTPS traffic out'
     sudo ufw allow out ftp comment 'allow FTP traffic out'
    
     # allow whois
     sudo ufw allow out whois comment 'allow whois'
    
     # allow traffic out on port 68 -- the DHCP client
     # you only need this if you're using DHCP
     sudo ufw allow out 67 comment 'allow the DHCP client to update'
     sudo ufw allow out 68 comment 'allow the DHCP client to update'
    

    Note: You’ll need to allow HTTP/HTTPS for installing packages and many other things.

  6. Start ufw:

     sudo ufw enable
    
    Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
    Firewall is active and enabled on system startup
    
  7. If you want to see a status:

     sudo ufw status
    
    Status: active
    
    To                         Action      From
    --                         ------      ----
    22/tcp                     LIMIT       Anywhere                   # allow SSH connections in
    22/tcp (v6)                LIMIT       Anywhere (v6)              # allow SSH connections in
    
    53                         ALLOW OUT   Anywhere                   # allow DNS calls out
    123                        ALLOW OUT   Anywhere                   # allow NTP out
    80/tcp                     ALLOW OUT   Anywhere                   # allow HTTP traffic out
    443/tcp                    ALLOW OUT   Anywhere                   # allow HTTPS traffic out
    21/tcp                     ALLOW OUT   Anywhere                   # allow FTP traffic out
    Mail submission            ALLOW OUT   Anywhere                   # allow mail out
    43/tcp                     ALLOW OUT   Anywhere                   # allow whois
    53 (v6)                    ALLOW OUT   Anywhere (v6)              # allow DNS calls out
    123 (v6)                   ALLOW OUT   Anywhere (v6)              # allow NTP out
    80/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow HTTP traffic out
    443/tcp (v6)               ALLOW OUT   Anywhere (v6)              # allow HTTPS traffic out
    21/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow FTP traffic out
    Mail submission (v6)       ALLOW OUT   Anywhere (v6)              # allow mail out
    43/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow whois
    

    or

     sudo ufw status verbose
    
    Status: active
    Logging: on (low)
    Default: deny (incoming), deny (outgoing), disabled (routed)
    New profiles: skip
    
    To                         Action      From
    --                         ------      ----
    22/tcp                     LIMIT IN    Anywhere                   # allow SSH connections in
    22/tcp (v6)                LIMIT IN    Anywhere (v6)              # allow SSH connections in
    
    53                         ALLOW OUT   Anywhere                   # allow DNS calls out
    123                        ALLOW OUT   Anywhere                   # allow NTP out
    80/tcp                     ALLOW OUT   Anywhere                   # allow HTTP traffic out
    443/tcp                    ALLOW OUT   Anywhere                   # allow HTTPS traffic out
    21/tcp                     ALLOW OUT   Anywhere                   # allow FTP traffic out
    587/tcp (Mail submission)  ALLOW OUT   Anywhere                   # allow mail out
    43/tcp                     ALLOW OUT   Anywhere                   # allow whois
    53 (v6)                    ALLOW OUT   Anywhere (v6)              # allow DNS calls out
    123 (v6)                   ALLOW OUT   Anywhere (v6)              # allow NTP out
    80/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow HTTP traffic out
    443/tcp (v6)               ALLOW OUT   Anywhere (v6)              # allow HTTPS traffic out
    21/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow FTP traffic out
    587/tcp (Mail submission (v6)) ALLOW OUT   Anywhere (v6)              # allow mail out
    43/tcp (v6)                ALLOW OUT   Anywhere (v6)              # allow whois
    

Default Applications

ufw ships with some default applications. You can see them with:

sudo ufw app list
Available applications:
  AIM
  Bonjour
  CIFS
  DNS
  Deluge
  IMAP
  IMAPS
  IPP
  KTorrent
  Kerberos Admin
  Kerberos Full
  Kerberos KDC
  Kerberos Password
  LDAP
  LDAPS
  LPD
  MSN
  MSN SSL
  Mail submission
  NFS
  OpenSSH
  POP3
  POP3S
  PeopleNearby
  SMTP
  SSH
  Socks
  Telnet
  Transmission
  Transparent Proxy
  VNC
  WWW
  WWW Cache
  WWW Full
  WWW Secure
  XMPP
  Yahoo
  qBittorrent
  svnserve

To get details about the app, like which ports it includes, type:

sudo ufw app info [app name]
sudo ufw app info DNS
Profile: DNS
Title: Internet Domain Name Server
Description: Internet Domain Name Server

Port:
  53

Custom Application

If you don’t want to create rules by explicitly providing the port number(s), you can create your own application configurations. To do this, create a file in /etc/ufw/applications.d.

For example, here is what you would use for Plex:

cat /etc/ufw/applications.d/plexmediaserver
[PlexMediaServer]
title=Plex Media Server
description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp

Then you can enable it like any other app:

sudo ufw allow plexmediaserver

iptables Intrusion Detection And Prevention with PSAD

Even if you have a firewall to guard your doors, it is possible to try brute-forcing your way in any of the guarded doors. We want to monitor all network activity to detect potential intrusion attempts, such has repeated attempts to get in, and block them.

How It Works

I can’t explain it any better than user FINESEC from https://serverfault.com/ did at: https://serverfault.com/a/447604/289829.

Fail2BAN scans log files of various applications such as apache, ssh or ftp and automatically bans IPs that show the malicious signs such as automated login attempts. PSAD on the other hand scans iptables and ip6tables log messages (typically /var/log/messages) to detect and optionally block scans and other types of suspect traffic such as DDoS or OS fingerprinting attempts. It’s ok to use both programs at the same time because they operate on different level.

And, since we’re already using UFW so we’ll follow the awesome instructions by netson at https://gist.github.com/netson/c45b2dc4e835761fbccc to make PSAD work with UFW.

Steps

  1. Install psad.

    On Debian based systems:

     sudo apt install psad
    
  2. Make a backup of psad’s configuration file /etc/psad/psad.conf:

     sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
    
  3. Review and update configuration options in /etc/psad/psad.conf. Pay special attention to these:

    Setting Set To
    EMAIL_ADDRESSES your email address(s)
    HOSTNAME your server’s hostname
    ENABLE_PSADWATCHD ENABLE_PSADWATCHD Y;
    ENABLE_AUTO_IDS ENABLE_AUTO_IDS Y;
    ENABLE_AUTO_IDS_EMAILS ENABLE_AUTO_IDS_EMAILS Y;
    EXPECT_TCP_OPTIONS EXPECT_TCP_OPTIONS Y;

    Check the configuration file psad’s documentation at http://www.cipherdyne.org/psad/docs/config.html for more details.

  4. Now we need to make some changes to ufw so it works with psad by telling ufw to log all traffic so psad can analyze it. Do this by editing two files and adding these lines at the end but before the COMMIT line.

    Make backups:

     sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
     sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
    

    Edit the files:

    • /etc/ufw/before.rules
    • /etc/ufw/before6.rules

    And add add this at the end but before the COMMIT line:

     # log all traffic so psad can analyze
     -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
     -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
    

    Note: We’re adding a log prefix to all the iptables logs. We’ll need this for seperating iptables logs to their own file.

    For example:

    ...
    
    # log all traffic so psad can analyze
    -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
    -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
    
    # don't delete the 'COMMIT' line or these rules won't be processed
    COMMIT
    
  5. Now we need to reload/restart ufw and psad for the changes to take effect:

     sudo ufw reload
    
     sudo psad -R
     sudo psad --sig-update
     sudo psad -H
    
  6. Analyze iptables rules for errors:

     sudo psad --fw-analyze
    
    [+] Parsing INPUT chain rules.
    [+] Parsing INPUT chain rules.
    [+] Firewall config looks good.
    [+] Completed check of firewall ruleset.
    [+] Results in /var/log/psad/fw_check
    [+] Exiting.
    

    Note: If there were any issues you will get an e-mail with the error.

  7. Check the status of psad:

     sudo psad --Status
    
    [-] psad: pid file /var/run/psad/psadwatchd.pid does not exist for psadwatchd on vm
    [+] psad_fw_read (pid: 3444)  %CPU: 0.0  %MEM: 2.2
        Running since: Sat Feb 16 01:03:09 2019
    
    [+] psad (pid: 3435)  %CPU: 0.2  %MEM: 2.7
        Running since: Sat Feb 16 01:03:09 2019
        Command line arguments: [none specified]
        Alert email address(es): [email protected]
    
    [+] Version: psad v2.4.3
    
    [+] Top 50 signature matches:
            [NONE]
    
    [+] Top 25 attackers:
            [NONE]
    
    [+] Top 20 scanned ports:
            [NONE]
    
    [+] iptables log prefix counters:
            [NONE]
    
        Total protocol packet counters:
    
    [+] IP Status Detail:
            [NONE]
    
        Total scan sources: 0
        Total scan destinations: 0
    
    [+] These results are available in: /var/log/psad/status.out
    

Application Intrusion Detection And Prevention With Fail2Ban

UFW tells your server what doors to board up so nobody can see them, and what doors to allow authorized users through. PSAD monitors network activity to detect and prevent potential intrusions – repeated attempts to get in.

But what about the applications/services your server is running, like SSH and Apache, where your firewall is configured to allow access in. Even though access may be allowed that doesn’t mean all access attempts are valid and harmless. What if someone tries to brute-force their way in to a web-app you’re running on your server? This is where Fail2ban comes in.

How It Works

Fail2ban monitors the logs of your applications (like SSH and Apache) to detect and prevent potential intrusions. It will monitor network traffic/logs and prevent intrusions by blocking suspicious activity (e.g. multiple successive failed connections in a short time-span).

Goals

  • network monitoring for suspicious activity with automatic banning of offending IPs

Notes

  • As of right now, the only thing running on this server is SSH so we’ll want Fail2ban to monitor SSH and ban as necessary.
  • As you install other programs, you’ll need to create/configure the appropriate jails and enable them.

Steps

  1. Install fail2ban.

    On Debian based systems:

     sudo apt install fail2ban
    
  2. We don’t want to edit /etc/fail2ban/fail2ban.conf or /etc/fail2ban/jail.conf because a future update may overwrite those so we’ll create a local copy instead. Create the file /etc/fail2ban/jail.local and add this to it after replacing [LAN SEGMENT] and [your email] with the appropriate values:

     [DEFAULT]
     # the IP address range we want to ignore
     ignoreip = 127.0.0.1/8 [LAN SEGMENT]
    
     # who to send e-mail to
     destemail = [your e-mail]
    
     # who is the email from
     sender = [your e-mail]
    
     # since we're using exim4 to send emails
     mta = mail
    
     # get email alerts
     action = %(action_mwl)s
    

    Note: Your server will need to be able to send e-mails so Fail2ban can let you know of suspicious activity and when it banned an IP.

  3. We need to create a jail for SSH that tells fail2ban to look at SSH logs and use ufw to ban/unban IPs as needed. Create a jail for SSH by creating the file /etc/fail2ban/jail.d/ssh.local and adding this to it:

     [sshd]
     enabled = true
     banaction = ufw
     port = ssh
     filter = sshd
     logpath = %(sshd_log)s
     maxretry = 5
    
     cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local
     [sshd]
     enabled = true
     banaction = ufw
     port = ssh
     filter = sshd
     logpath = %(sshd_log)s
     maxretry = 5
     EOF
    
  4. In the above we tell fail2ban to use the ufw as the banaction. Fail2ban ships with an action configuration file for ufw. You can see it in /etc/fail2ban/action.d/ufw.conf

  5. Enable fail2ban:

     sudo fail2ban-client start
     sudo fail2ban-client reload
     sudo fail2ban-client add sshd # This may fail on some systems if the sshd jail was added by default
    
  6. To check the status:

     sudo fail2ban-client status
    
    Status
    |- Number of jail:      1
    `- Jail list:   sshd
    
     sudo fail2ban-client status sshd
    
    Status for the jail: sshd
    |- Filter
    |  |- Currently failed: 0
    |  |- Total failed:     0
    |  `- File list:        /var/log/auth.log
    `- Actions
       |- Currently banned: 0
       |- Total banned:     0
       `- Banned IP list:
    

Unban an IP

To unban an IP use this command:

fail2ban-client set [jail] unbanip [IP]

[jail] is the name of the jail that has the banned IP and [IP] is the IP address you want to unban. For example, to unaban 192.168.1.100 from SSH you would do:

fail2ban-client set sshd unbanip 192.168.1.100

Licenses and Attributions


Speak Your Mind