feat: migrate policy firewall from iptables/ipset to nftables

- Rewrite wg-policy-lib.sh: replace ipset functions with nft helpers, add backup_nftables()
- Rewrite wg-policy-engine.sh: generate nft ruleset file, atomic load via nft -f, rollback support
- Simplify wg-policy-cleanup.sh: single nft delete table inet wg_policy
- Update wg-policy-ctl: nft commands for rules/ipset/stats/backup
- Rebuild install.sh: nftables dependency, WireGuard pre-check, PostUp/PostDown auto-integration
- Update build.sh/build.bat: match install.sh changes
- Update README.md: nftables prerequisites and references
This commit is contained in:
datadunia
2026-06-21 15:02:48 +07:00
parent eb525879f1
commit b5c9b180dc
8 changed files with 705 additions and 821 deletions
+16 -29
View File
@@ -13,11 +13,11 @@ Usage: $(basename "$0") <command>
Commands:
status Show full health check report
policy Display current policy.json formatted
rules Show current iptables rules in WG_POLICY chain
ipset Show ipset contents
rules Show current nftables rules
ipset Show nftables set contents
log Tail WG_DROP logs (last 50 lines)
reload Force re-sync and re-apply policy
backup Manual backup of policy + iptables
backup Manual backup of policy + nftables
stats Show connection and rule statistics
validate Validate policy.json without applying
help Show this help
@@ -43,27 +43,18 @@ cmd_policy() {
}
cmd_rules() {
echo "=== IPv4 Chain: $CHAIN ==="
if iptables -L "$CHAIN" -n -v --line-numbers 2>/dev/null; then
echo "=== Table: $NFT_TABLE_FULL ==="
if nft list table "$NFT_TABLE_FULL" 2>/dev/null; then
echo ""
else
echo "(chain not found)"
fi
echo "=== FORWARD references ==="
iptables -L FORWARD -n -v --line-numbers 2>/dev/null | grep -i "$CHAIN" || echo "(none)"
if command -v ip6tables &>/dev/null; then
echo ""
echo "=== IPv6 Chain: $CHAIN ==="
ip6tables -L "$CHAIN" -n -v --line-numbers 2>/dev/null || echo "(chain not found)"
echo "(table not found)"
fi
}
cmd_ipset() {
for set_name in "$IPSET_V4" "$IPSET_V6"; do
echo "=== ipset: $set_name ==="
if ipset list "$set_name" 2>/dev/null; then
for set_name in "$NFT_SET_V4" "$NFT_SET_V6"; do
echo "=== nft set: $set_name ==="
if nft list set "$NFT_TABLE_FULL" "$set_name" 2>/dev/null; then
echo ""
else
echo "(not found)"
@@ -94,7 +85,7 @@ cmd_reload() {
cmd_backup() {
backup_policy
backup_iptables
backup_nftables
log_info "Manual backup complete. Files in: $BACKUP_DIR"
}
@@ -111,18 +102,14 @@ cmd_stats() {
jq -r '.clients // {} | to_entries[] | select(.value.access | length == 0) | .key' "$POLICY_FILE" 2>/dev/null || echo "N/A"
echo ""
echo "=== Active iptables rules ==="
iptables -L "$CHAIN" -n 2>/dev/null | tail -n +3 | wc -l || echo "N/A"
echo "=== Active nftables rules ==="
nft list chain "$NFT_TABLE_FULL" forward 2>/dev/null | grep -c '#' || echo "N/A"
echo ""
echo "=== Drop count (since boot) ==="
iptables -L "$CHAIN" -n -v 2>/dev/null | grep "DROP" | awk '{sum += $1} END {print sum+0, "packets dropped"}'
echo ""
echo "=== ipset entries ==="
for set_name in "$IPSET_V4" "$IPSET_V6"; do
echo "=== nft set entries ==="
for set_name in "$NFT_SET_V4" "$NFT_SET_V6"; do
local count
count=$(ipset list "$set_name" 2>/dev/null | grep -c '^[0-9a-f:]' || echo 0)
count=$(nft list set "$NFT_TABLE_FULL" "$set_name" 2>/dev/null | grep -c -E '^\s+[0-9a-f]' || echo 0)
echo " $set_name: $count entries"
done
}
@@ -183,4 +170,4 @@ case "${1:-help}" in
stats) cmd_stats ;;
validate) cmd_validate ;;
help|*) usage ;;
esac
esac