docs: sync reference doc with ipset-optional and ExecStartPre fixes

This commit is contained in:
datadunia
2026-04-30 21:01:23 +07:00
parent 93b781b17c
commit 1268c8a4a2
+39 -6
View File
@@ -153,8 +153,13 @@ validate_cidr() {
# IPSET MANAGEMENT # IPSET MANAGEMENT
# ============================================================ # ============================================================
has_ipset() {
command -v ipset &>/dev/null
}
ensure_ipset() { ensure_ipset() {
local name="$1" family="$2" local name="$1" family="$2"
has_ipset || return 0
if ! ipset list "$name" &>/dev/null; then if ! ipset list "$name" &>/dev/null; then
ipset create "$name" hash:net family "$family" hashsize 1024 maxelem 65536 timeout 0 ipset create "$name" hash:net family "$family" hashsize 1024 maxelem 65536 timeout 0
log_info "Created ipset: $name (family=$family)" log_info "Created ipset: $name (family=$family)"
@@ -163,6 +168,7 @@ ensure_ipset() {
flush_ipset() { flush_ipset() {
local name="$1" local name="$1"
has_ipset || return 0
if ipset list "$name" &>/dev/null; then if ipset list "$name" &>/dev/null; then
ipset flush "$name" ipset flush "$name"
fi fi
@@ -170,6 +176,7 @@ flush_ipset() {
destroy_ipset() { destroy_ipset() {
local name="$1" local name="$1"
has_ipset || return 0
if ipset list "$name" &>/dev/null; then if ipset list "$name" &>/dev/null; then
ipset destroy "$name" ipset destroy "$name"
fi fi
@@ -640,6 +647,9 @@ main() {
log_info "Chain $CHAIN created and linked to FORWARD" log_info "Chain $CHAIN created and linked to FORWARD"
# === POPULATE IPSET (for large-scale whitelist) === # === POPULATE IPSET (for large-scale whitelist) ===
local use_ipset=false
if has_ipset; then
use_ipset=true
log_info "Populating ipsets..." log_info "Populating ipsets..."
ensure_ipset "$IPSET_V4" "inet" ensure_ipset "$IPSET_V4" "inet"
@@ -663,7 +673,6 @@ main() {
' "$POLICY_FILE" 2>/dev/null | while read -r client_ip target; do ' "$POLICY_FILE" 2>/dev/null | while read -r client_ip target; do
[[ -z "$client_ip" || -z "$target" ]] && continue [[ -z "$client_ip" || -z "$target" ]] && continue
# Determine if v4 or v6
if [[ "$target" == *":"* ]]; then if [[ "$target" == *":"* ]]; then
if [[ "$use_ipv6" == true ]]; then if [[ "$use_ipv6" == true ]]; then
ipset add "$IPSET_V6" "$target" 2>/dev/null || \ ipset add "$IPSET_V6" "$target" 2>/dev/null || \
@@ -679,12 +688,19 @@ main() {
v4_count=$(ipset list "$IPSET_V4" 2>/dev/null | grep -c '^[0-9]' || echo 0) 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) 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" 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 === # === RULE 1: ESTABLISHED,RELATED — allow return traffic ===
iptables -A "$CHAIN" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A "$CHAIN" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# === RULE 2: WHITELIST via ipset (per-client source) === # === RULE 2: WHITELIST (per-client source) ===
# For each client with access rules, allow only from that client's IP to ipset targets if [[ "$use_ipset" == true ]]; then
jq -r ' jq -r '
.clients // {} | to_entries[] | .clients // {} | to_entries[] |
select(.value.access != null and (.value.access | length > 0)) | select(.value.access != null and (.value.access | length > 0)) |
@@ -693,15 +709,32 @@ main() {
[[ -z "$client_ip" ]] && continue [[ -z "$client_ip" ]] && continue
if [[ "$client_ip" == *":"* ]]; then if [[ "$client_ip" == *":"* ]]; then
# IPv6 client
if [[ "$use_ipv6" == true ]]; 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 ip6tables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V6" dst -j ACCEPT 2>/dev/null || true
fi fi
else else
# IPv4 client
iptables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V4" dst -j ACCEPT iptables -A "$CHAIN" -s "$client_ip" -m set --match-set "$IPSET_V4" dst -j ACCEPT
fi 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 === # === RULE 3: ISOLATION — drop NEW connections between WG clients ===
if [[ -n "$WG_SUBNET" ]]; then if [[ -n "$WG_SUBNET" ]]; then
@@ -932,7 +965,7 @@ StartLimitBurst=5
[Service] [Service]
Type=simple Type=simple
ExecStartPre=/usr/local/bin/wg-policy-engine.sh --health-check ExecStartPre=/usr/local/bin/wg-sync-policy.sh
ExecStart=/usr/local/bin/wg-sync-watch.sh ExecStart=/usr/local/bin/wg-sync-watch.sh
ExecStopPost=/usr/local/bin/wg-policy-cleanup.sh ExecStopPost=/usr/local/bin/wg-policy-cleanup.sh
Restart=always Restart=always