Introduction
If you encounter such error, it means that the CONFIG_NETFILTER module was not complied in your kernel. All VPS (virtual private server) that I owned from DigitalOcean, AWS, Google Cloud and other lesser-known host providers have it by default when I choose Ubuntu or Debian. However, I owned an OpenVZ (Open Virtuozzo) from a particular provider and it was absent from Debian 9.
Error 1 – iptables: No chain/target/match by that name
If the module is not loaded, using iptables with -m conntrack –ctstate ESTABLISHED,RELATED will cause this error. Note that CONFIG_PACKET is not needed for iptables to work. You can read more about Linux Packet Filtering and iptables at linuxtopia.org
user@server:~$ sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables: No chain/target/match by that name.
user@server:~$ sudo iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables: No chain/target/match by that name.
Error 2 – apt-get update Cannot initiate the connection to and Temporary failure resolving repository
If the option -m conntrack –ctstate is not available on the server, you will have to omit them from the iptables command. While the firewall rules will now be accepted without error but by simply removing them will cause two problems when running apt-get. They are fail to resolve e.g. ftp.us..debian.org and connection timed out trying to connect to repository.
user@server:~$ sudo apt-get update
Err:1 http://ftp.us..debian.org/debian oldstable InRelease
Could not resolve 'ftp.us..debian.org'
user@server:~$ sudo apt-get update
Err:1 https://packages.sury.org/php stretch InRelease
Failed to connect to packages.sury.org port 443: Connection timed out
0% [Connecting to prod.debian.map.fastly.net (151.101.24.204)] [Connecting to security.debian.org (151.101.0.204)]
Solution
The solution is to add six additional firewall rules (Step 1) associated to Port 53 (DNS), 80 (HTTP) and 443 (HTTPS) to replace the absence of these two rules rejected on servers without netfilter (CONFIG_PACKET) complied.
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
Step 1 – Firewall Rules for Servers without Netfilter Module
Don’t be in a hurry to enter these rules yet! This command iptables -P INPUT DROP will drop you out of your current SSH session and you will require serial console to gain access to update the rule back to iptables -P INPUT ACCEPT before you can reconnect via SSH again.
# Flush all existing rules
iptables -F
# Set 'close all ports' chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# apt-get to resolve (53) and initiate connections (80, 443) to fetch updates from repo
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# Accept all incoming SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
# Accept all incoming HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# Accept all incoming HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT
# Enable SMTPS for e.g. Postfix
iptables -A INPUT -p tcp --sport 465 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 465 -j ACCEPT
# Accept incoming PING
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
# Accept loopback access
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Step 2 – Using iptables-restore to Import Rules
Create a file e.g. fw-rules and use iptables-restore < fw-rules to import the rules below which only allow incoming SSH connections via Port 22, web services Port 80/ 443, SMTPS (Simple Mail Transfer Protocol Secure) Port 465 and ICMP ping. The rest of the network packets will be dropped.
*filter
:INPUT DROP
:FORWARD DROP
:OUTPUT DROP
# For apt-get to resolve (53) and initiate connections (80, 443)
# to fetch updates from repository
-A INPUT -p udp --sport 53 -j ACCEPT
-A OUTPUT -p udp --dport 53 -j ACCEPT
-A INPUT -p tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --sport 443 -j ACCEPT
-A OUTPUT -p tcp --dport 443 -j ACCEPT
# Accept SSH, HTTP, HTTPS, SMTPS and ICMP ping
-A INPUT -p tcp --dport 22 -j ACCEPT
-A OUTPUT -p tcp --sport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A OUTPUT -p tcp --sport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A OUTPUT -p tcp --sport 443 -j ACCEPT
-A INPUT -p tcp --sport 465 -j ACCEPT
-A OUTPUT -p tcp --dport 465 -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
COMMIT
You can list your rules for your first firewall with iptables -L
user@server:~$ sudo iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp spt:domain
ACCEPT tcp -- anywhere anywhere tcp spt:http
ACCEPT tcp -- anywhere anywhere tcp spt:https
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere tcp spt:ssh
ACCEPT tcp -- anywhere anywhere tcp spt:http
ACCEPT tcp -- anywhere anywhere tcp spt:https
ACCEPT icmp -- anywhere anywhere icmp echo-reply
ACCEPT all -- anywhere anywhere
Step 3 – (optional) How to Check CONFIG_NETFILTER is Compiled into Kernel
On a KVM (Kernel-based Virtual Machine) with Debian 10 that I owned which returns that the CONFIG_NETFILTER was complied.
user@server:~$ grep CONFIG_NETFILTER= /boot/*config*
/boot/config-4.19.0-5-amd64:CONFIG_NETFILTER=y
/boot/config-4.19.0-8-amd64:CONFIG_NETFILTER=y
On OpenVZ (Open Virtuozzo) with Debian 9 that I owned which returns no such file or directory. This can be due to OpenVZ shares a single kernel which is always maintained by the host provider which end-users have no access to. In any case, option –ctstate is not available on this server for me.
user@server:~$ grep CONFIG_NETFILTER= /boot/*config*
grep: /boot/*config*: No such file or directory
Conclusion
I had actually spent hours debugging how to get apt-get to work for this particular server of mine without netfilter module. I had tried to add all suggested firewall rules from the Internet even for Port 21 (FTP) but none worked for me. They are all but just a fraction of the bigger solution required which I conclude is to add those six firewall rules for Port 53, 80 and 443. Last but not least, rules stored in iptables are not persistent, they will be deleted (flushed) on next server reboot. Install iptables-persistent package to save the existing rules to a file and load it on every startup.