mirror of
https://github.com/angristan/openvpn-install.git
synced 2025-12-15 16:37:03 +01:00
feat: add native nftables support (#1389)
- Add nftables as a third firewall backend option alongside firewalld and iptables - Detection priority: firewalld → nftables → iptables (legacy fallback) - Uses dedicated `openvpn` and `openvpn-nat` tables for clean isolation - Integrates with native `nftables.service` via include in `/etc/nftables.conf` Closes https://github.com/angristan/openvpn-install/issues/530
This commit is contained in:
@@ -7,32 +7,40 @@ FROM ${BASE_IMAGE}
|
||||
ARG BASE_IMAGE
|
||||
# Set to "y" to install and enable firewalld for testing
|
||||
ARG ENABLE_FIREWALLD=n
|
||||
# Set to "y" to install and enable nftables for testing
|
||||
ARG ENABLE_NFTABLES=n
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV ENABLE_FIREWALLD=${ENABLE_FIREWALLD}
|
||||
ENV ENABLE_NFTABLES=${ENABLE_NFTABLES}
|
||||
|
||||
# Install basic dependencies based on the OS
|
||||
# dnsutils/bind-utils provides dig for DNS testing with Unbound
|
||||
RUN if command -v apt-get >/dev/null; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
iproute2 iptables curl procps systemd systemd-sysv dnsutils \
|
||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then apt-get install -y --no-install-recommends nftables; fi \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
elif command -v dnf >/dev/null; then \
|
||||
dnf install -y --allowerasing \
|
||||
iproute iptables curl procps-ng systemd tar gzip bind-utils \
|
||||
&& if [ "$ENABLE_FIREWALLD" = "y" ]; then dnf install -y firewalld; fi \
|
||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then dnf install -y nftables; fi \
|
||||
&& dnf clean all; \
|
||||
elif command -v yum >/dev/null; then \
|
||||
yum install -y \
|
||||
iproute iptables curl procps-ng systemd tar gzip bind-utils \
|
||||
&& if [ "$ENABLE_FIREWALLD" = "y" ]; then yum install -y firewalld; fi \
|
||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then yum install -y nftables; fi \
|
||||
&& yum clean all; \
|
||||
elif command -v pacman >/dev/null; then \
|
||||
pacman -Syu --noconfirm \
|
||||
iproute2 iptables curl procps-ng bind \
|
||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then pacman -S --noconfirm nftables; fi \
|
||||
&& pacman -Scc --noconfirm; \
|
||||
elif command -v zypper >/dev/null; then \
|
||||
zypper install -y \
|
||||
iproute2 iptables curl procps systemd tar gzip bind-utils gawk \
|
||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then zypper install -y nftables; fi \
|
||||
&& zypper clean -a; \
|
||||
fi
|
||||
|
||||
@@ -41,6 +49,14 @@ RUN if [ "$ENABLE_FIREWALLD" = "y" ] && command -v firewall-cmd >/dev/null; then
|
||||
systemctl enable firewalld; \
|
||||
fi
|
||||
|
||||
# Enable nftables if requested (must be done after systemd is available)
|
||||
# Use empty nftables.conf - do NOT flush ruleset as it removes Docker's networking rules
|
||||
RUN if [ "$ENABLE_NFTABLES" = "y" ] && command -v nft >/dev/null; then \
|
||||
systemctl enable nftables; \
|
||||
mkdir -p /etc/nftables; \
|
||||
echo '#!/usr/sbin/nft -f' > /etc/nftables.conf; \
|
||||
fi
|
||||
|
||||
# Create TUN device (will be mounted at runtime)
|
||||
RUN mkdir -p /dev/net
|
||||
|
||||
|
||||
@@ -87,9 +87,11 @@ REQUIRED_FILES=(
|
||||
/etc/openvpn/server/easy-rsa/pki/ca.crt
|
||||
/root/testclient.ovpn
|
||||
)
|
||||
# Only check for iptables script if firewalld is not active
|
||||
if ! systemctl is-active --quiet firewalld; then
|
||||
# Only check for iptables script if firewalld and nftables are not active
|
||||
if ! systemctl is-active --quiet firewalld && ! systemctl is-active --quiet nftables; then
|
||||
REQUIRED_FILES+=(/etc/iptables/add-openvpn-rules.sh)
|
||||
elif systemctl is-active --quiet nftables; then
|
||||
REQUIRED_FILES+=(/etc/nftables/openvpn.nft)
|
||||
fi
|
||||
|
||||
for f in "${REQUIRED_FILES[@]}"; do
|
||||
@@ -422,6 +424,46 @@ if systemctl is-active --quiet firewalld; then
|
||||
firewall-cmd --list-rich-rules
|
||||
exit 1
|
||||
fi
|
||||
elif systemctl is-active --quiet nftables; then
|
||||
# nftables mode - verify OpenVPN tables exist
|
||||
echo "nftables detected, checking OpenVPN tables..."
|
||||
for _ in $(seq 1 10); do
|
||||
if nft list table inet openvpn >/dev/null 2>&1; then
|
||||
echo "PASS: nftables 'inet openvpn' table exists"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if ! nft list table inet openvpn >/dev/null 2>&1; then
|
||||
echo "FAIL: nftables 'inet openvpn' table not found"
|
||||
echo "Current nftables ruleset:"
|
||||
nft list ruleset 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
# Verify NAT table exists
|
||||
if nft list table ip openvpn-nat >/dev/null 2>&1; then
|
||||
echo "PASS: nftables 'ip openvpn-nat' table exists"
|
||||
else
|
||||
echo "FAIL: nftables 'ip openvpn-nat' table not found"
|
||||
nft list ruleset 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
# Verify masquerade rule exists
|
||||
if nft list table ip openvpn-nat | grep -q "masquerade"; then
|
||||
echo "PASS: nftables masquerade rule exists"
|
||||
else
|
||||
echo "FAIL: nftables masquerade rule not found"
|
||||
nft list table ip openvpn-nat 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
# Verify include in nftables.conf
|
||||
if grep -q 'include.*/etc/nftables/openvpn.nft' /etc/nftables.conf; then
|
||||
echo "PASS: OpenVPN rules included in nftables.conf"
|
||||
else
|
||||
echo "FAIL: OpenVPN rules not included in nftables.conf"
|
||||
cat /etc/nftables.conf 2>&1 || true
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# iptables mode - verify NAT rules
|
||||
echo "iptables mode, checking NAT rules..."
|
||||
|
||||
Reference in New Issue
Block a user