Merge 'origin/fixing-order'

This commit is contained in:
RadekSabacky
2025-11-20 14:41:45 +01:00
+119 -31
View File
@@ -307,20 +307,20 @@ apply_iptables_rules() {
iptables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
iptables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || \
iptables -A FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
iptables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
iptables -C FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
iptables -A FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
# ipv6 nat and forwarding
ip6tables -t nat -C POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE 2>/dev/null || \
ip6tables -t nat -A POSTROUTING -o "$NETWORK_DEVICE" -j MASQUERADE
ip6tables -C FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null || \
ip6tables -A FORWARD -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
ip6tables -I FORWARD 1 -i "$interface" -o "$NETWORK_DEVICE" -j ACCEPT
ip6tables -C FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \
ip6tables -A FORWARD -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
save_iptables_rules
}
@@ -519,45 +519,40 @@ setup_nat_rules() {
fi
if ! iptables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null; then
iptables -A FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT
iptables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT
fi
if ! iptables -C FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
iptables -A FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
fi
if ! ip6tables -C FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT 2>/dev/null; then
ip6tables -A FORWARD -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT
ip6tables -I FORWARD 1 -i "$WG_INTERFACE" -o "$NETWORK_DEVICE" -j ACCEPT
fi
if ! ip6tables -C FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
ip6tables -A FORWARD -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -I FORWARD 2 -i "$NETWORK_DEVICE" -o "$WG_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
fi
}
configure_exit_dns_and_icmp() {
echo "ensuring dns and icmp are allowed inside nym exit chain"
if ! iptables -C "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT 2>/dev/null; then
iptables -A "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT
fi
if ! iptables -C "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT 2>/dev/null; then
iptables -A "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT
fi
if ! ip6tables -C "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT 2>/dev/null; then
ip6tables -A "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT
fi
if ! ip6tables -C "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT 2>/dev/null; then
ip6tables -A "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT
fi
# Remove any existing DNS/ICMP rules first to avoid duplicates
iptables -D "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT 2>/dev/null || true
iptables -D "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT 2>/dev/null || true
iptables -D "$NYM_CHAIN" -p icmp --icmp-type echo-request -j ACCEPT 2>/dev/null || true
iptables -D "$NYM_CHAIN" -p icmp --icmp-type echo-reply -j ACCEPT 2>/dev/null || true
ip6tables -D "$NYM_CHAIN" -p udp --dport 53 -j ACCEPT 2>/dev/null || true
ip6tables -D "$NYM_CHAIN" -p tcp --dport 53 -j ACCEPT 2>/dev/null || true
ip6tables -D "$NYM_CHAIN" -p ipv6-icmp -j ACCEPT 2>/dev/null || true
if ! iptables -C "$NYM_CHAIN" -p icmp --icmp-type echo-request -j ACCEPT 2>/dev/null; then
iptables -A "$NYM_CHAIN" -p icmp --icmp-type echo-request -j ACCEPT
fi
if ! iptables -C "$NYM_CHAIN" -p icmp --icmp-type echo-reply -j ACCEPT 2>/dev/null; then
iptables -A "$NYM_CHAIN" -p icmp --icmp-type echo-reply -j ACCEPT
fi
if ! ip6tables -C "$NYM_CHAIN" -p ipv6-icmp -j ACCEPT 2>/dev/null; then
ip6tables -A "$NYM_CHAIN" -p ipv6-icmp -j ACCEPT
fi
# Insert rules at the beginning in correct order: DNS first, then ICMP
iptables -I "$NYM_CHAIN" 1 -p udp --dport 53 -j ACCEPT
iptables -I "$NYM_CHAIN" 2 -p tcp --dport 53 -j ACCEPT
iptables -I "$NYM_CHAIN" 3 -p icmp --icmp-type echo-request -j ACCEPT
iptables -I "$NYM_CHAIN" 4 -p icmp --icmp-type echo-reply -j ACCEPT
ip6tables -I "$NYM_CHAIN" 1 -p udp --dport 53 -j ACCEPT
ip6tables -I "$NYM_CHAIN" 2 -p tcp --dport 53 -j ACCEPT
ip6tables -I "$NYM_CHAIN" 3 -p ipv6-icmp -j ACCEPT
}
apply_port_allowlist() {
@@ -817,8 +812,95 @@ test_exit_policy_connectivity() {
echo "connectivity tests finished"
}
###############################################################################
# part 3: exit policy verification tests
# part 3: check the firewall setup
###############################################################################
firewall_rule_line() {
local chain=$1
local rule_idx=$2
# this is because thefirst rule appears on line 3
iptables -L "$chain" -n --line-numbers | sed -n "$((rule_idx + 2))p"
}
check_forward_chain() {
local output
output=$(iptables -L FORWARD -n --line-numbers)
if ! echo "$output" | grep -q "^1[[:space:]]\+$NYM_CHAIN"; then
echo "FORWARD rule 1 is not ${NYM_CHAIN}; re-run network-tunnel-manager.sh exit_policy_install"
return 1
fi
if ! echo "$output" | grep -q "ACCEPT.*state RELATED,ESTABLISHED"; then
echo "FORWARD chain missing RELATED,ESTABLISHED accepts; re-run network-tunnel-manager.sh apply_iptables_rules_wg"
return 1
fi
echo "FORWARD chain ordering looks good"
return 0
}
check_nym_exit_chain() {
local errors=0
local patterns=("udp.*dpt:53" "tcp.*dpt:53" "icmp.*type 8" "icmp.*type 0")
for idx in "${!patterns[@]}"; do
local line
line=$(firewall_rule_line "$NYM_CHAIN" $((idx + 1)))
if [[ "$line" =~ ${patterns[$idx]} ]]; then
echo "${NYM_CHAIN} rule $((idx + 1)) ok (${patterns[$idx]})"
else
echo "${NYM_CHAIN} rule $((idx + 1)) is not ${patterns[$idx]}; re-run network-tunnel-manager.sh exit_policy_install"
errors=1
fi
done
local last_rule
last_rule=$(iptables -L "$NYM_CHAIN" -n --line-numbers | awk 'NR>2 {line=$0} END {print line}')
if [[ -z "${last_rule:-}" ]]; then
echo "${NYM_CHAIN} chain is empty; re-run network-tunnel-manager.sh exit_policy_install"
errors=1
elif [[ "$last_rule" =~ REJECT ]] && [[ "$last_rule" =~ 0\.0\.0\.0/0 ]]; then
echo "${NYM_CHAIN} ends with the catch-all REJECT"
else
echo "${NYM_CHAIN} final rule is not the catch-all REJECT (got: $last_rule)"
errors=1
fi
return $errors
}
check_firewall_setup() {
echo "checking ipv4 firewall ordering…"
local errors=0
check_forward_chain || errors=1
check_nym_exit_chain || errors=1
if command -v ip6tables >/dev/null 2>&1; then
echo "checking ipv6 firewall ordering…"
if ip6tables -L "$NYM_CHAIN" -n --line-numbers >/dev/null 2>&1; then
if ! ip6tables -L "$NYM_CHAIN" -n --line-numbers | sed -n '3p' | grep -q "udp.*dpt:53"; then
echo "ip6tables ${NYM_CHAIN} rule 1 is not UDP 53"
errors=1
fi
fi
fi
if [[ $errors -ne 0 ]]; then
echo "There may be some ordering issues, it is recommended to re-run network-tunnel-manager.sh exit_policy_install after configuring UFW."
return 1
fi
echo "It's looking good!"
return 0
}
###############################################################################
# part 4: full exit policy verification tests
###############################################################################
test_port_range_rules() {
@@ -971,7 +1053,7 @@ exit_policy_run_tests() {
}
###############################################################################
# part 4: high level workflows
# part 5: high level workflows
###############################################################################
full_tunnel_setup() {
@@ -1018,6 +1100,7 @@ complete_networking_configuration() {
full_tunnel_setup
exit_policy_install
check_firewall_setup || error "firewall order checks reported problems, please review output"
exit_policy_run_tests || error "exit policy tests reported problems, please review output"
ok "complete networking configuration finished"
@@ -1106,6 +1189,10 @@ case "$cmd" in
show_exit_policy_status
status=$?
;;
check_firewall_setup)
check_firewall_setup
status=$?
;;
exit_policy_test_connectivity)
test_exit_policy_connectivity
status=$?
@@ -1147,6 +1234,7 @@ tunnel and nat helpers:
exit policy manager:
exit_policy_install install exit policy (iptables rules and blocklist)
check_firewall_setup run ordering sanity check (dns/icmp + FORWARD jump)
exit_policy_status show status of exit policy and forwarding
exit_policy_test_connectivity test connectivity via ${WG_INTERFACE}
exit_policy_clear remove ${NYM_CHAIN} chains and hooks