60 lines
2.5 KiB
Python
60 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Replace wg-easy iptables hooks with nftables equivalents.
|
|
|
|
wg-easy images ship iptables-legacy, which cannot initialize the `nat`/`filter`
|
|
tables inside a podman container netns on nftables-only kernels (fc42). Every
|
|
`wg-quick up wg0` then fails at the PostUp hook, so the wg0 interface is rolled
|
|
back and ALL client API calls 500 with "Unable to access interface: No such device".
|
|
|
|
The official wg-easy podman+nftables tutorial replaces the hooks with nft rules.
|
|
This script rewrites hooks_table in /opt/apps/wireguard/wg-easy.db when the hooks
|
|
still reference iptables. Run it with the wg-easy container stopped, then restart
|
|
the container so wg0.conf is regenerated. Idempotent.
|
|
"""
|
|
import sqlite3
|
|
import sys
|
|
|
|
DB = "/opt/apps/wireguard/wg-easy.db"
|
|
|
|
POSTUP = (
|
|
"nft add table inet wg_table;"
|
|
" nft add chain inet wg_table prerouting { type nat hook prerouting priority 100 \\; };"
|
|
" nft add chain inet wg_table postrouting { type nat hook postrouting priority 100 \\; };"
|
|
" nft add rule inet wg_table postrouting ip saddr {{ipv4Cidr}} oifname {{device}} masquerade;"
|
|
" nft add rule inet wg_table postrouting ip6 saddr {{ipv6Cidr}} oifname {{device}} masquerade;"
|
|
" nft add chain inet wg_table input { type filter hook input priority 0 \\; policy accept \\; };"
|
|
" nft add rule inet wg_table input udp dport {{port}} accept;"
|
|
" nft add rule inet wg_table input tcp dport {{uiPort}} accept;"
|
|
" nft add chain inet wg_table forward { type filter hook forward priority 0 \\; policy accept \\; };"
|
|
' nft add rule inet wg_table forward iifname "wg0" accept;'
|
|
' nft add rule inet wg_table forward oifname "wg0" accept;'
|
|
)
|
|
POSTDOWN = "nft delete table inet wg_table"
|
|
|
|
|
|
def main() -> int:
|
|
con = sqlite3.connect(DB)
|
|
try:
|
|
rows = con.execute("SELECT id, post_up, post_down FROM hooks_table").fetchall()
|
|
changed = 0
|
|
for name, post_up, post_down in rows:
|
|
post_up = post_up or ""
|
|
post_down = post_down or ""
|
|
if "iptables" in post_up or "iptables" in post_down:
|
|
con.execute(
|
|
"UPDATE hooks_table SET post_up=?, post_down=?, updated_at=CURRENT_TIMESTAMP WHERE id=?",
|
|
(POSTUP, POSTDOWN, name),
|
|
)
|
|
print(f"patched hooks for {name!r}")
|
|
changed += 1
|
|
else:
|
|
print(f"hooks ok for {name!r}")
|
|
con.commit()
|
|
finally:
|
|
con.close()
|
|
print(f"changed={changed}")
|
|
return 0 if changed >= 0 else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |