mirror of
https://github.com/angristan/openvpn-install.git
synced 2026-08-11 09:08:13 +02:00
Fix firewall backend installation
This commit is contained in:
+31
-17
@@ -1854,8 +1854,9 @@ cmd_interactive() {
|
|||||||
if isOpenVPNInstalled; then
|
if isOpenVPNInstalled; then
|
||||||
manageMenu
|
manageMenu
|
||||||
else
|
else
|
||||||
installQuestions
|
# Reuse the install command so interactive installs receive the same
|
||||||
installOpenVPN
|
# validation and derived network configuration as non-interactive installs.
|
||||||
|
cmd_install --interactive
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2429,6 +2430,17 @@ function detect_server_ips() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Select the active firewall manager, with iptables as the fallback.
|
||||||
|
function detect_firewall_backend() {
|
||||||
|
if systemctl is-active --quiet firewalld; then
|
||||||
|
echo firewalld
|
||||||
|
elif systemctl is-active --quiet nftables; then
|
||||||
|
echo nftables
|
||||||
|
else
|
||||||
|
echo iptables
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Calculate derived network configuration values
|
# Calculate derived network configuration values
|
||||||
function prepare_network_config() {
|
function prepare_network_config() {
|
||||||
# Calculate IPv4 gateway (always needed for leak prevention)
|
# Calculate IPv4 gateway (always needed for leak prevention)
|
||||||
@@ -3047,6 +3059,10 @@ function installOpenVPN() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Select the firewall backend before installing dependencies so native
|
||||||
|
# firewalld and nftables systems do not need the iptables package.
|
||||||
|
FIREWALL_BACKEND=$(detect_firewall_backend)
|
||||||
|
|
||||||
# If OpenVPN isn't installed yet, install it. This script is more-or-less
|
# If OpenVPN isn't installed yet, install it. This script is more-or-less
|
||||||
# idempotent on multiple runs, but will only install OpenVPN from upstream
|
# idempotent on multiple runs, but will only install OpenVPN from upstream
|
||||||
# the first time.
|
# the first time.
|
||||||
@@ -3057,21 +3073,26 @@ function installOpenVPN() {
|
|||||||
installOpenVPNRepo
|
installOpenVPNRepo
|
||||||
|
|
||||||
log_info "Installing OpenVPN and dependencies..."
|
log_info "Installing OpenVPN and dependencies..."
|
||||||
# socat is used for communicating with the OpenVPN management interface (client disconnect on revoke)
|
# iptables is only required by the fallback backend. socat communicates
|
||||||
|
# with the OpenVPN management interface for client disconnect on revoke.
|
||||||
|
local -a firewall_packages=()
|
||||||
|
if [[ $FIREWALL_BACKEND == 'iptables' ]]; then
|
||||||
|
firewall_packages+=(iptables)
|
||||||
|
fi
|
||||||
if [[ $OS =~ (debian|ubuntu) ]]; then
|
if [[ $OS =~ (debian|ubuntu) ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" apt-get install -y openvpn iptables openssl curl ca-certificates tar dnsutils socat
|
run_cmd_fatal "Installing OpenVPN" apt-get install -y openvpn "${firewall_packages[@]}" openssl curl ca-certificates tar dnsutils socat
|
||||||
elif [[ $OS == 'centos' ]]; then
|
elif [[ $OS == 'centos' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" yum install -y openvpn iptables openssl ca-certificates curl tar bind-utils socat 'policycoreutils-python*'
|
run_cmd_fatal "Installing OpenVPN" yum install -y openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind-utils socat 'policycoreutils-python*'
|
||||||
elif [[ $OS == 'oracle' ]]; then
|
elif [[ $OS == 'oracle' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" yum install -y openvpn iptables openssl ca-certificates curl tar bind-utils socat policycoreutils-python-utils
|
run_cmd_fatal "Installing OpenVPN" yum install -y openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind-utils socat policycoreutils-python-utils
|
||||||
elif [[ $OS == 'amzn2023' ]]; then
|
elif [[ $OS == 'amzn2023' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" dnf install -y openvpn iptables openssl ca-certificates curl tar bind-utils socat
|
run_cmd_fatal "Installing OpenVPN" dnf install -y openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind-utils socat
|
||||||
elif [[ $OS == 'fedora' ]]; then
|
elif [[ $OS == 'fedora' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" dnf install -y openvpn iptables openssl ca-certificates curl tar bind-utils socat policycoreutils-python-utils
|
run_cmd_fatal "Installing OpenVPN" dnf install -y openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind-utils socat policycoreutils-python-utils
|
||||||
elif [[ $OS == 'opensuse' ]]; then
|
elif [[ $OS == 'opensuse' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" zypper install -y openvpn iptables openssl ca-certificates curl tar bind-utils socat
|
run_cmd_fatal "Installing OpenVPN" zypper install -y openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind-utils socat
|
||||||
elif [[ $OS == 'arch' ]]; then
|
elif [[ $OS == 'arch' ]]; then
|
||||||
run_cmd_fatal "Installing OpenVPN" pacman --needed --noconfirm -Syu openvpn iptables openssl ca-certificates curl tar bind socat
|
run_cmd_fatal "Installing OpenVPN" pacman --needed --noconfirm -Syu openvpn "${firewall_packages[@]}" openssl ca-certificates curl tar bind socat
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify ChaCha20-Poly1305 compatibility if selected
|
# Verify ChaCha20-Poly1305 compatibility if selected
|
||||||
@@ -3493,13 +3514,6 @@ verb 3"
|
|||||||
} >>/etc/openvpn/server/server.conf
|
} >>/etc/openvpn/server/server.conf
|
||||||
|
|
||||||
# Record installer-owned policy so firewall rules can be removed exactly.
|
# Record installer-owned policy so firewall rules can be removed exactly.
|
||||||
if systemctl is-active --quiet firewalld; then
|
|
||||||
FIREWALL_BACKEND=firewalld
|
|
||||||
elif systemctl is-active --quiet nftables; then
|
|
||||||
FIREWALL_BACKEND=nftables
|
|
||||||
else
|
|
||||||
FIREWALL_BACKEND=iptables
|
|
||||||
fi
|
|
||||||
{
|
{
|
||||||
echo "FIREWALL_BACKEND=$FIREWALL_BACKEND"
|
echo "FIREWALL_BACKEND=$FIREWALL_BACKEND"
|
||||||
echo "ROUTE_INTERNET=$ROUTE_INTERNET"
|
echo "ROUTE_INTERNET=$ROUTE_INTERNET"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ENV ENABLE_NFTABLES=${ENABLE_NFTABLES}
|
|||||||
# Note: socat is installed by openvpn-install.sh during OpenVPN installation
|
# Note: socat is installed by openvpn-install.sh during OpenVPN installation
|
||||||
RUN if command -v apt-get >/dev/null; then \
|
RUN if command -v apt-get >/dev/null; then \
|
||||||
apt-get update && apt-get install -y --no-install-recommends \
|
apt-get update && apt-get install -y --no-install-recommends \
|
||||||
iproute2 iptables curl procps systemd systemd-sysv dnsutils jq \
|
iproute2 curl procps systemd systemd-sysv dnsutils jq \
|
||||||
&& if [ "$ENABLE_NFTABLES" = "y" ]; then apt-get install -y --no-install-recommends nftables; fi \
|
&& if [ "$ENABLE_NFTABLES" = "y" ]; then apt-get install -y --no-install-recommends nftables; fi \
|
||||||
&& rm -rf /var/lib/apt/lists/*; \
|
&& rm -rf /var/lib/apt/lists/*; \
|
||||||
elif command -v dnf >/dev/null; then \
|
elif command -v dnf >/dev/null; then \
|
||||||
@@ -69,7 +69,8 @@ RUN chmod +x /opt/openvpn-install.sh
|
|||||||
COPY test/server-entrypoint.sh /entrypoint.sh
|
COPY test/server-entrypoint.sh /entrypoint.sh
|
||||||
COPY test/validate-output.sh /opt/test/validate-output.sh
|
COPY test/validate-output.sh /opt/test/validate-output.sh
|
||||||
COPY test/local-network-detection.sh /opt/test/local-network-detection.sh
|
COPY test/local-network-detection.sh /opt/test/local-network-detection.sh
|
||||||
RUN chmod +x /entrypoint.sh /opt/test/validate-output.sh /opt/test/local-network-detection.sh
|
COPY test/interactive-install-flow.sh /opt/test/interactive-install-flow.sh
|
||||||
|
RUN chmod +x /entrypoint.sh /opt/test/validate-output.sh /opt/test/local-network-detection.sh /opt/test/interactive-install-flow.sh
|
||||||
|
|
||||||
# Create systemd service for the test script
|
# Create systemd service for the test script
|
||||||
# PassEnvironment passes Docker env vars (-e) from PID 1 to the service
|
# PassEnvironment passes Docker env vars (-e) from PID 1 to the service
|
||||||
|
|||||||
Executable
+60
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# shellcheck disable=SC1091,SC2034
|
||||||
|
# SC1091: The installer path is provided by the test environment.
|
||||||
|
# SC2034: Configuration globals are consumed by sourced installer functions.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
INSTALLER=${1:-/opt/openvpn-install.sh}
|
||||||
|
export FORCE_COLOR=0 LOG_FILE="" NON_INTERACTIVE_INSTALL=n OUTPUT_FORMAT=table
|
||||||
|
# shellcheck source=../openvpn-install.sh
|
||||||
|
source "$INSTALLER"
|
||||||
|
|
||||||
|
questions_called=n
|
||||||
|
validation_called=n
|
||||||
|
install_called=n
|
||||||
|
|
||||||
|
isOpenVPNInstalled() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
requireNoOpenVPN() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
installQuestions() {
|
||||||
|
questions_called=y
|
||||||
|
VPN_SUBNET_IPV4=10.23.0.0
|
||||||
|
VPN_SUBNET_IPV6=fd42:23::
|
||||||
|
CLIENT_IPV6=n
|
||||||
|
ROUTE_INTERNET=y
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_configuration() {
|
||||||
|
validation_called=y
|
||||||
|
}
|
||||||
|
|
||||||
|
installOpenVPN() {
|
||||||
|
install_called=y
|
||||||
|
if [[ ${VPN_GATEWAY_IPV4:-} != "10.23.0.1" ]]; then
|
||||||
|
echo "FAIL: Interactive install did not prepare the IPv4 VPN gateway" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ${IPV6_SUPPORT:-} != "n" ]]; then
|
||||||
|
echo "FAIL: Interactive install did not prepare legacy IPv6 state" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_interactive
|
||||||
|
|
||||||
|
for state in \
|
||||||
|
"questions_called:$questions_called" \
|
||||||
|
"validation_called:$validation_called" \
|
||||||
|
"install_called:$install_called"; do
|
||||||
|
if [[ ${state#*:} != "y" ]]; then
|
||||||
|
echo "FAIL: Interactive install skipped ${state%%:*}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "PASS: Interactive install prepares derived network configuration"
|
||||||
@@ -4,6 +4,7 @@ set -e
|
|||||||
echo "=== OpenVPN Server Container ==="
|
echo "=== OpenVPN Server Container ==="
|
||||||
|
|
||||||
/opt/test/local-network-detection.sh /opt/openvpn-install.sh
|
/opt/test/local-network-detection.sh /opt/openvpn-install.sh
|
||||||
|
/opt/test/interactive-install-flow.sh /opt/openvpn-install.sh
|
||||||
|
|
||||||
# Create TUN device if it doesn't exist
|
# Create TUN device if it doesn't exist
|
||||||
if [ ! -c /dev/net/tun ]; then
|
if [ ! -c /dev/net/tun ]; then
|
||||||
@@ -185,6 +186,21 @@ if [ "$INSTALL_EXIT_CODE" -ne 0 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Native firewall backends must not require the iptables package. The fallback
|
||||||
|
# backend must install it because the test image does not include it.
|
||||||
|
if systemctl is-active --quiet firewalld || systemctl is-active --quiet nftables; then
|
||||||
|
if command -v dpkg-query >/dev/null && dpkg-query -W -f='${db:Status-Abbrev}' iptables 2>/dev/null | grep -q '^ii'; then
|
||||||
|
echo "FAIL: iptables was installed with a native firewall backend"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if ! command -v iptables >/dev/null; then
|
||||||
|
echo "FAIL: iptables fallback dependency was not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "PASS: Firewall dependencies match the selected backend"
|
||||||
|
|
||||||
# Verify all expected files were created
|
# Verify all expected files were created
|
||||||
echo "Verifying installation..."
|
echo "Verifying installation..."
|
||||||
MISSING_FILES=0
|
MISSING_FILES=0
|
||||||
|
|||||||
Reference in New Issue
Block a user