This episode builds an Alpine firewall using nftables and iptables-nft. You'll learn setup-firewall, write nft rules for the input, forward, and output chains, and set up NAT masquerade and IP forwarding so Alpine can act as a router or gateway.

A firewall is the first line of defense for any network-connected server. Episode 10 builds an Alpine firewall using nftables — the modern firewall framework that backs iptables-nft — and turns Alpine into a small router with NAT and IP forwarding.
Alpine has been known as a router and firewall platform since birth, so this episode's material is some of the most "Alpine" in the whole series. You'll write nft rules directly while also using the setup-firewall helper tool, which simplifies a lot of the work.
Since kernel 3.13, the Linux firewall framework has been nftables. The iptables commands you know are a frontend translated into nftables. On Alpine:
nftables package provides the nft command for writing rules directly.iptables-nft package provides iptables commands that use the nftables backend.Check the available firewall tools:
apk add nftables iptables-nft
nft --version
iptables-nft --versionThe nft --version output shows the nftables framework version. For new configuration, nft is the recommended choice because its syntax is a single language for all protocol families.
Alpine provides setup-firewall, which creates basic rules interactively. When the firewall package is installed, this command runs automatically. To reload the configuration:
setup-firewall
rc-service firewall start
rc-update add firewall defaultThe configuration is generated from your wizard answers and saved to /etc/nftables.nft (or /etc/iptables for iptables). The generated basic rules open SSH and drop everything else on the input chain.
For full control, write your own nft rules. Here's a basic configuration example at /etc/nftables.nft:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
tcp dport 80 accept
tcp dport 443 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}Load the configuration and verify:
nft -f /etc/nftables.nft
nft list rulesetnft -f /etc/nftables.nft loads the rules file, and nft list ruleset shows the entire active ruleset. The policy drop on the input chain means all incoming connections are rejected unless explicitly allowed.
To make Alpine act as a gateway for a local network, enable IP forwarding and add a masquerade rule to the nat table:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -pAdd NAT to the nftables file:
table inet nat {
chain postrouting {
type nat hook postrouting priority 100;
oif eth0 masquerade
}
}oif eth0 masquerade replaces the source address of packets leaving via eth0 — the standard technique for sharing an internet connection with the LAN. Verify the complete ruleset:
nft list ruleset
sysctl net.ipv4.ip_forwardThe sysctl net.ipv4.ip_forward output must be 1 for forwarding to be active.
From a client machine on the LAN, test outgoing connectivity:
ping -c 4 8.8.8.8If it works, make the rules persistent by running rc-service firewall start and registering it in the default runlevel — or make sure nft -f /etc/nftables.nft is called by the firewall init script.
Warning
Rules with a drop policy will lock you out if you mistype the SSH port. Always test the rules from another SSH session, or have physical console access ready as a safety net.
Episode 10 built an Alpine firewall from scratch: understanding iptables-nft and nftables, using setup-firewall for basic rules, writing nft rules with input, forward, and output chains, and enabling NAT masquerade and IP forwarding for the router role.
Key takeaways:
In the next episode, episode 11, we'll cover web servers and the LEMP stack — installing nginx with OpenRC, adding PHP-FPM, connecting to MariaDB or PostgreSQL, and wiring it all into a complete web application stack.