Configure firewall#

When not using Docker#

The firewall.sh script closes most ports by default. Its behavior is controlled by variables in the firewall-settings.local file.

Most variables are set by state files:

SSH_IPV4 and SSH_IPV6

IPs from which to allow SSH collections. Set by the firewall state using Pillar data. See Connect to a server (SSH).

PUBLIC_HTTP

Opens port 80. Set by the apache state.

PUBLIC_HTTPS

Opens port 443. Set by the apache state.

PUBLIC_POSTGRESQL

Opens port 5432. Set by the postgres state, if postgres.public_access is True in Pillar.

PRIVATE_POSTGRESQL

Opens port 5432 to the replica servers. Set by the postgres state, if postgres.public_access isn’t True in Pillar.

REPLICA_IPV4 and REPLICA_IPV6

The IPs of replica servers. Set by the postgres state using Pillar data, if postgres.public_access isn’t True in Pillar.

PUBLIC_ELASTICSEARCH

Opens port 9200. Set by the elasticsearch state.

PUBLIC_TINYPROXY

Opens port 8888. Set by the tinyproxy state.

PRIVATE_PROMETHEUS_CLIENT

Opens port 7231 to the Prometheus server. Set by the prometheus.node_exporter state.

PROMETHEUS_IPV4 and PROMETHEUS_IPV6

The IPs of the Prometheus server. Set by the prometheus.node_exporter state using Pillar data.

Other variables are:

PUBLIC_SSH

Opens port 22. Supersedes port knocking.

Open a port#

If no variable corresponds to the port you need to open, update the firewall.sh script and firewall-settings.local template.

You might need to set variables if you’re working in a development environment. To set a variable, use the set_firewall macro, for example:

{{ set_firewall("PUBLIC_SSH") }}

This sets PUBLIC_SSH="yes" in the firewall-settings.local file.

Close a port#

Use the unset_firewall macro if a set_firewall call is removed from a service’s state, whether directly (by deleting a set_firewall call) or indirectly (by un-including a state file with set_firewall calls).

Troubleshoot#

When making changes to firewall settings or port assignments, you might want to:

  • Check if a port is open:

    telnet host port
    
  • List active connections:

    ss -tupln # netstat -tupln
    

When using Docker#

The firewall.sh script rewrites all iptables rules. However, Docker needs to add rules to route traffic to and from containers. To address this incompatibility, the firewall.sh script exits if the docker command exists. To implement firewall rules on Docker servers, we implement an external firewall.

Hetzner (hardware servers)#

Hetzner provide a free stateless firewall for each dedicated server. “Stateless” means that the firewall does not store information about connections over time, which is required for HTTP sessions and port knocking, for example.

You can configure a Hetzner firewall as follows:

  1. Connect to the server, to reset the server-side firewall after configuring the external firewall

  2. Log into Hetzner

  3. Select your server and go to the Firewall tab

  4. Set Status to active

  5. Enable Hetzner Services

  6. Select “SSH” from the Firewall template: dropdown and click Apply to fill in:

    Name

    Protocol

    Destination port

    TCP flags

    Action

    icmp

    icmp

    0-65535

    accept

    ssh

    tcp

    22

    accept

    tcp established

    tcp

    32768-65535

    ack

    accept

    Or, select “Webserver” from the Firewall template: dropdown and click Apply to also fill in:

    Name

    Protocol

    Destination port

    TCP flags

    Action

    http

    tcp

    80,443

    accept

    Note

    Destination IP and Source port are never set.

  7. Add additional firewall rules. The recommended minimum is to also add:

      • Name

      • Protocol

      • Source IP

      • Destination port

      • TCP flags

      • Action

      • prometheus

      • tcp

      • 139.162.253.17/32

      • 7231

      • accept

  8. Click Save and wait for the configuration to be applied.

  9. Reset the server-side firewall:

    /home/sysadmin-tools/bin/firewall_reset.sh
    
  10. Restart the Docker service, if running:

    systemctl restart docker
    

Linode (VPS servers)#

Linode provide a stateful Cloud Firewall. Stateful firewalls can store information about connections over time, which is required for HTTP sessions and port knocking, for example.

You can configure a Linode Cloud Firewall as follows:

  1. Connect to the server, to reset the server-side firewall after configuring the external firewall

  2. Log into Linode

  3. Open the Firewalls list

  4. Click Create Firewall

    1. Set Label to the server name

    2. Set Linodes to the server

    3. Click Create Firewall

  5. Click on the label for the new firewall

    1. Set Default inbound policy to Drop

    2. Add an inbound rule. The recommended minimum is:

      Label

      Protocol

      Ports

      Sources

      Action

      Allow-SSH

      TCP

      SSH (22)

      All IPv4, All IPv6

      Accept

      Allow-ICMP

      ICMP

      All IPv4, All IPv6

      Accept

      Allow-Prometheus

      TCP

      7231

      139.162.253.17/32, 2a01:7e00::f03c:93ff:fe13:a12c/128

      Accept

      Most servers will also have:

      Label

      Protocol

      Ports

      Sources

      Action

      Allow-HTTP

      TCP

      HTTP (80), HTTPS (443)

      All IPv4, All IPv6

      Accept

    3. Click Save Changes

  6. Reset the server-side firewall:

    /home/sysadmin-tools/bin/firewall_reset.sh
    
  7. Restart the Docker service, if running:

    systemctl restart docker