How to Configuring Awall on Alpine Linux latest Guide

Introduction:

Configuring Awall on Alpine Linux has been my preferred Linux distribution for more workloads as of late. I’m particularly impressed by its simplicity, size, and speed—but above all else. I required additional information about firewall server security, especially making the firewall operate well with Docker, as I began moving these workloads to Alpine-based platforms.

The configuration of an Alpine Linux firewall, known as awall, which is a straightforward interface for Linux iptables, will be covered in detail in this post.

Awall Background:

Configuring Awall on Alpine Linux, Awall is a firewall program that creates iptables. It makes use of some JSON configuration files, which your firewall converts to iptables. The /etc/awall directory contains the awall configuration files.

It is customary to keep all of your user-generated firewall rules in either /etc/awall/private or /etc/awall/optional.You can also refer to a set of pre-defined defaults that Awall ships with. You can find these under /usr/share/awall/mandatory.

{"http": { "proto": "tcp", "port": 80 },
  "http-alt": { "proto": "tcp", "port": 8080 },
  "https": { "proto": "tcp", "port": 443 },
  "ping": [
    { "proto": "icmp", "type": 8, "reply-type": 0 },
    { "proto": "icmpv6", "type": 128, "reply-type": 129 }
  ],
  "ssh": { "proto": "tcp", "port": 22 }
}

We will use these definitions in our firewall rules and can even create our own shortcuts if needed.

Default deny all:

We will add only SSH and Ping access at first, starting with a firewall that permits nothing. This will let us become accustomed to using a wall before permitting increased outside traffic.

To do this, two files will be created. To begin, make the file /etc/awall/optional/default.json, which will set up a basic deny rule and define our network interfaces. Run ip link show to find out what interfaces you have, as you will need to know that information. The host in this instance only has one interface, eth0.

{"description": "default deny all",
  "zone": {
    "WAN": { "iface": ["eth0"] }
  },
  "policy": [{ "in": "WAN", "action": "drop" }, { "action": "reject" }]
}

We define a zone in this rule that other rules can make reference to. We include one interface and specify our WAN zone. It should be noted that the syntax eth+, where + denotes any integer from 0 forward, is another option. If you have more than one interface, like eth1 and eth2, this is useful. When necessary, the array-based interface property can take more than one interface.

We then define a policy to drop all incoming traffic on WAN. We also have a blanket reject policy for all other traffic.

Allow ssh:

The next step is to enable SSH access; else, our server connection will be lost. Let’s make a new file called ssh.json under /etc/awall/optional. We enable SSH in this file and make use of the built-in SSH service from the previously examined built-in Awall services. We permit traffic to enter the WAN interfaces and exit the firewall’s built-in zone, _fw.

//file:/etc/awall/optional/ssh.json{
  "description": "allow ssh",
  "filter": [
    {
      "in": "WAN",
      "out": "_fw",
      "service": "ssh",
      "action": "accept"
    }
  ]
}

Allow ping:

Another useful tool for debugging is the ability to ping so lets go ahead and add that as well.

//file:/etc/awall/optional/ping.json
{
  "description": "allow ping",
  "filter": [
    {
      "in": "WAN",
      "service": "ping",
      "action": "accept"
    }
  ]
}

Enable the firewall:

We now have a reasonable firewall configuration, so let’s activate the policies and give them a try.

Run awall list in order to list the policies created above. You should be able to read the policies from this.

awall list

default   disabled  default deny all
ping      disabled  allow ping
ssh       disabled  allow ssh

As you can see they are all disabled so lets go ahead and enable them one-by-one.

awall enable default
awall enable ssh
awall enable ping

After turning on our rules, we must instruct Awall to create the IPtables and then apply them. A wall has the excellent feature of requiring two confirmations. Awalls enforce rules immediately upon activation; however, they are rolled back after a brief amount of time if you fail to confirm, saving you from potentially dangerous errors.

Go ahead and activate the rules with awall activate.

Checking ping:

You ought to be able to ping your server at its IP address if your rules are appropriately applied. Try experimenting with turning on and off the ping policy at this point.

Start a persistent ping from your computer to your server, and then on the server, run awall deactivate ping && awall activate. When the policy is disabled, you ought to be able to observe in real time that the ping stops functioning.

Inbound and outbound:

Our firewall is currently rather restrictive, which renders our server essentially worthless. Let’s enable incoming http and https connections to liven things up a bit. Additionally, we’ll allow outgoing connections for several common protocols.

//file:/etc/awall/optional/inbound.json
{
  "description": "allow inbound http/https",
  "filter": [
    {
      "in": "WAN",
      "out": "_fw",
      "service": ["http", "https"],
      "action": "accept"
    }
  ]
}

Our inbound policy will allow http and https. Again these shortcuts are defined for us by the default awall services and refer to port 80 and 443.

//file:/etc/awall/optional/outbound.json
{
  "description": "allow outbound dns, http/https, ssh, ntp, ssh and ping",

  "filter": [
    {
      "in": "_fw",
      "out": "WAN",
      "service": ["dns", "http", "https", "ssh", "ntp", "ping"],
      "action": "accept"
    }
  ]
}

Our outbound policy allows our server to send dns requests, http and https requests, as well as ssh, ntp, and ping requests.

Go ahead and enable the policies with awall enable inbound and awall enable outbound. Then run awall activate.

Docker:

Our server is now protected by a basic firewall that can handle any amount of internet workload. We will use Docker to run containers, which will make it easier to run our workloads.We can install Docker on our machine by running apk add docker, as it is a first-class citizen on Alpine.

Running rc-update add docker boot adds Docker to the startup configuration so that it can start automatically. We can use service docker start and service docker status to make sure the service is up and running now that it has registered as one.

At this moment, launching a container would start it, but it would not have any connectivity. It won’t be able to establish connections with other Docker-running containers or the internet. Let’s put that right!

We must include the interfaces that Docker handles back into our /etc/awall/optional/default.json file. Now let’s add a zone to each and every Docker interface.

{
  "description": "default deny all connections",
  "variable": { "awall_dedicated_chains": true },
  "zone": {
    "WAN": { "iface": "eth+" },
    "DOCKER": { "iface": ["docker+", "br-+"] }
  },
  "policy": [{ "in": "WAN", "action": "drop" }, { "action": "reject" }]
}

Our new DOCKER zone includes all numbered interface that start with docker. We also add all numbered interfaces that start with br-.

Whenever you create a docker network the dameon creates a new interface for that network to communicate on. This allows containers connected to the same docker network to talk to each other.

To test this out create a new docker network with docker network create my-network. Then run ip link show and you will see a new interface with the prefix br-. This is mapped to my-network.

Delete the network with docker network rm my-network and your br- interface will be gone.

So now a DOCKER zone exists but we need to allow traffic. Lets edit our inbound and outbound policies. You can place this in a separate policy in /etc/awall/optional/docker.json if you prefer to control this policy separately.

//file:/etc/awall/optional/inbound.json{
  "description": "allow inbound http/https",

  "filter": [
    {
      "in": "WAN",
      "out": "_fw",
      "service": ["http", "https"],
      "action": "accept"
    },
    {
      "in": "DOCKER",
      "action": "accept"
    }
  ]
}
//file:/etc/awall/optional/outbound.json
{
  "description": "allow outbound dns, http/https, ssh, ntp, ssh and ping",

  "filter": [
    {
      "in": "_fw",
      "out": "WAN",
      "service": ["dns", "http", "https", "ssh", "ntp", "ping"],
      "action": "accept"
    },
    {
      "out": "DOCKER",
      "action": "accept"
    }
  ]
}

These two rules allow your containers to talk to each other over any docker network created. It also allows the containers to have access to the internet.

Protecting unwanted container access:

Docker has a somewhat infamous history when it comes to Linux firewalls. Because Docker generates its own set of iptables, it does not work well with many common Linux firewalls, including firewalld or ufw. Tragically, this comes to pass because, despite users’ belief that their hosts are safe, Docker suddenly exposes workloads to the public internet.

Regretfully, this is not the default practice. One may assume that the inbound policy that was previously defined would prohibit external contact with containers on ports other than 22, 80, or 443.

Run a nginx container on a port other than those listed in the incoming policy and attempt to access it to show the issue. You may use docker run -it -p 88:80 nginx as an example of this. In actuality, you have to exercise caution when it comes to port exposure. For your web server, you might be accustomed to simply giving -p 80:8080 or -p 5432:5432; but, by default, using -p without a host IP exposes your workload on 0.0.0.0.

It’s probably best not to try that unless you are an expert with iptables, while there are a lot of possible techniques to create a firewall with iptables that work with the Docker rules.

Conclusion:

By turning on the firewall, you may fortify and improve your system’s security even further. This tutorial shows you how to turn Alpine Linux’s firewall on and off. Alpine comes without an installed awall iptables firewall, and it supports both IPv6 and IPv4 protocols.

Installing Awall is simple because it’s already part of the Alpine Linux repository. After installation, you may turn on the firewall by setting up the policies and turning them on. In a similar vein, you may also turn off the firewall by turning off every policy that has been set up.

Get more information about
How To Use Bash History Commands and Expansions on a Linux VPS

Leave a Reply

Your email address will not be published. Required fields are marked *