fix: make ipset optional, fix ExecStartPre, add prerequisites to README
This commit is contained in:
+78
-52
@@ -115,68 +115,94 @@ main() {
|
||||
log_info "Chain $CHAIN created and linked to FORWARD"
|
||||
|
||||
# === POPULATE IPSET (for large-scale whitelist) ===
|
||||
log_info "Populating ipsets..."
|
||||
local use_ipset=false
|
||||
if has_ipset; then
|
||||
use_ipset=true
|
||||
log_info "Populating ipsets..."
|
||||
|
||||
ensure_ipset "$IPSET_V4" "inet"
|
||||
flush_ipset "$IPSET_V4"
|
||||
ensure_ipset "$IPSET_V4" "inet"
|
||||
flush_ipset "$IPSET_V4"
|
||||
|
||||
# Check if we need IPv6 ipset
|
||||
local use_ipv6=false
|
||||
if [[ -n "$WG_SUBNET_V6" ]] && command -v ip6tables &>/dev/null; then
|
||||
use_ipv6=true
|
||||
ensure_ipset "$IPSET_V6" "inet6"
|
||||
flush_ipset "$IPSET_V6"
|
||||
fi
|
||||
|
||||
# Read all access entries and populate ipset
|
||||
jq -r '
|
||||
.clients // {} | to_entries[] |
|
||||
select(.value.access != null and (.value.access | length > 0)) |
|
||||
.key as $ip |
|
||||
.value.access[] |
|
||||
"\($ip) \(.)"
|
||||
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip target; do
|
||||
[[ -z "$client_ip" || -z "$target" ]] && continue
|
||||
|
||||
# Determine if v4 or v6
|
||||
if [[ "$target" == *":"* ]]; then
|
||||
if [[ "$use_ipv6" == true ]]; then
|
||||
ipset add "$IPSET_V6" "$target" 2>/dev/null || \
|
||||
log_warn "Failed to add $target to ipset $IPSET_V6"
|
||||
fi
|
||||
else
|
||||
ipset add "$IPSET_V4" "$target" 2>/dev/null || \
|
||||
log_warn "Failed to add $target to ipset $IPSET_V4"
|
||||
# Check if we need IPv6 ipset
|
||||
local use_ipv6=false
|
||||
if [[ -n "$WG_SUBNET_V6" ]] && command -v ip6tables &>/dev/null; then
|
||||
use_ipv6=true
|
||||
ensure_ipset "$IPSET_V6" "inet6"
|
||||
flush_ipset "$IPSET_V6"
|
||||
fi
|
||||
done
|
||||
|
||||
local v4_count v6_count
|
||||
v4_count=$(ipset list "$IPSET_V4" 2>/dev/null | grep -c '^[0-9]' || echo 0)
|
||||
v6_count=$(ipset list "$IPSET_V6" 2>/dev/null | grep -c '^[0-9a-f:]' || echo 0)
|
||||
log_info "ipset $IPSET_V4: $v4_count entries, $IPSET_V6: $v6_count entries"
|
||||
# Read all access entries and populate ipset
|
||||
jq -r '
|
||||
.clients // {} | to_entries[] |
|
||||
select(.value.access != null and (.value.access | length > 0)) |
|
||||
.key as $ip |
|
||||
.value.access[] |
|
||||
"\($ip) \(.)"
|
||||
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip target; do
|
||||
[[ -z "$client_ip" || -z "$target" ]] && continue
|
||||
|
||||
if [[ "$target" == *":"* ]]; then
|
||||
if [[ "$use_ipv6" == true ]]; then
|
||||
ipset add "$IPSET_V6" "$target" 2>/dev/null || \
|
||||
log_warn "Failed to add $target to ipset $IPSET_V6"
|
||||
fi
|
||||
else
|
||||
ipset add "$IPSET_V4" "$target" 2>/dev/null || \
|
||||
log_warn "Failed to add $target to ipset $IPSET_V4"
|
||||
fi
|
||||
done
|
||||
|
||||
local v4_count v6_count
|
||||
v4_count=$(ipset list "$IPSET_V4" 2>/dev/null | grep -c '^[0-9]' || echo 0)
|
||||
v6_count=$(ipset list "$IPSET_V6" 2>/dev/null | grep -c '^[0-9a-f:]' || echo 0)
|
||||
log_info "ipset $IPSET_V4: $v4_count entries, $IPSET_V6: $v6_count entries"
|
||||
else
|
||||
log_warn "ipset not installed, falling back to per-rule iptables whitelist"
|
||||
local use_ipv6=false
|
||||
if [[ -n "$WG_SUBNET_V6" ]] && command -v ip6tables &>/dev/null; then
|
||||
use_ipv6=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# === RULE 1: ESTABLISHED,RELATED — allow return traffic ===
|
||||
iptables -A "$CHAIN" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# === RULE 2: WHITELIST via ipset (per-client source) ===
|
||||
# For each client with access rules, allow only from that client's IP to ipset targets
|
||||
jq -r '
|
||||
.clients // {} | to_entries[] |
|
||||
select(.value.access != null and (.value.access | length > 0)) |
|
||||
"\(.key)"
|
||||
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip; do
|
||||
[[ -z "$client_ip" ]] && continue
|
||||
# === RULE 2: WHITELIST (per-client source) ===
|
||||
if [[ "$use_ipset" == true ]]; then
|
||||
jq -r '
|
||||
.clients // {} | to_entries[] |
|
||||
select(.value.access != null and (.value.access | length > 0)) |
|
||||
"\(.key)"
|
||||
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip; do
|
||||
[[ -z "$client_ip" ]] && continue
|
||||
|
||||
if [[ "$client_ip" == *":"* ]]; then
|
||||
# IPv6 client
|
||||
if [[ "$use_ipv6" == true ]]; then
|
||||
ip6tables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V6" dst -j ACCEPT 2>/dev/null || true
|
||||
if [[ "$client_ip" == *":"* ]]; then
|
||||
if [[ "$use_ipv6" == true ]]; then
|
||||
ip6tables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V6" dst -j ACCEPT 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
iptables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V4" dst -j ACCEPT
|
||||
fi
|
||||
else
|
||||
# IPv4 client
|
||||
iptables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V4" dst -j ACCEPT
|
||||
fi
|
||||
done
|
||||
done
|
||||
else
|
||||
jq -r '
|
||||
.clients // {} | to_entries[] |
|
||||
select(.value.access != null and (.value.access | length > 0)) |
|
||||
.key as $ip |
|
||||
.value.access[] |
|
||||
"\($ip) \(.)"
|
||||
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip target; do
|
||||
[[ -z "$client_ip" || -z "$target" ]] && continue
|
||||
|
||||
if [[ "$client_ip" == *":"* ]]; then
|
||||
if [[ "$use_ipv6" == true ]]; then
|
||||
ip6tables -A "$CHAIN" -s "$client_ip" -d "$target" -j ACCEPT 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
iptables -A "$CHAIN" -s "$client_ip" -d "$target" -j ACCEPT
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# === RULE 3: ISOLATION — drop NEW connections between WG clients ===
|
||||
if [[ -n "$WG_SUBNET" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user