Get rid of NAT64 setup
ci/woodpecker/push/flux-reconcile-source Pipeline was successful
ci/woodpecker/push/coredns-build Pipeline was successful

This commit is contained in:
2026-06-16 00:29:18 +02:00
parent b993115b41
commit 679ebb3465
13 changed files with 316 additions and 419 deletions
@@ -6,9 +6,6 @@
- address: 172.20.0.1/24
interface: containers
network: 172.20.0.0
- address: 192.168.239.1/30
interface: nat64
network: 192.168.239.0
- address: 192.168.4.1/24
interface: lo
network: 192.168.4.0
@@ -40,10 +37,6 @@
community.routeros.api_modify:
path: ipv6 address
data:
- address: fc64::1/126
advertise: false
comment: nat64 loopback
interface: nat64
- address: 2001:470:70:dd::2/64
advertise: false
interface: sit1
+10 -42
View File
@@ -6,7 +6,6 @@
- name: bridge1
vlan-filtering: true
- name: containers
- name: nat64
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -69,9 +68,6 @@
- bridge: containers
interface: veth-coredns
comment: CoreDNS container interface
- bridge: nat64
interface: veth-tayga
comment: Tayga NAT64 container interface
- bridge: bridge1
interface: ether1
pvid: 2
@@ -180,7 +176,8 @@
values:
allow-remote-requests: true
cache-size: 20480
# CoreDNS container provides DNS64; it forwards upstream to 1.1.1.1/8.8.8.8.
# CoreDNS container: plain forwarder with selective AAAA suppression.
# Forwards upstream to 1.1.1.1/8.8.8.8.
servers: 172.20.0.3
- name: Configure DNS static entries
@@ -195,9 +192,9 @@
# Do NOT add a lumpiasty.xyz FWD entry here. RouterOS FWD entries return
# NOERROR with an empty answer instead of relaying NXDOMAIN, which breaks
# getaddrinfo search-domain processing (ENOTFOUND for valid names in k8s
# pods). The DNS64 bypass for our own zone lives in the CoreDNS Corefile
# (mikrotik/coredns/Corefile, lumpiasty.xyz server block) which relays
# rcodes correctly. See docs/coredns-nat64.md pitfall #4.
# pods). Our own zone is handled in the CoreDNS Corefile (lumpiasty.xyz
# server block, AAAA kept) which relays rcodes correctly.
# See docs/coredns.md.
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -243,24 +240,6 @@
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
# Option 108 (IPv6-only preferred, RFC 8925). Without force=yes RouterOS only
# includes the option for clients that request code 108 in their Parameter
# Request List — i.e. RFC 8925-capable clients. Clients that receive it drop
# IPv4 and rely on CLAT/NAT64, which REQUIRES pref64 in RA (see ND tasks below).
- name: Configure DHCP server options (IPv6-only preferred, RFC 8925)
community.routeros.api_modify:
path: ip dhcp-server option
data:
# 32-bit seconds timer (V6ONLY_WAIT) — how long the client suppresses
# IPv4. Refreshed on every renewal; acts as automatic fallback if the
# DHCP server disappears. 0x00015180 = 86400 s (1 day).
# Quoted to prevent YAML from parsing the hex literal as integer 86400.
- name: v6only-preferred
code: 108
value: "0x00015180"
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
- name: Configure DHCP networks
community.routeros.api_modify:
path: ip dhcp-server network
@@ -268,14 +247,12 @@
- address: 192.168.0.0/24
dns-server: 192.168.0.1
gateway: 192.168.0.1
dhcp-option: v6only-preferred
- address: 192.168.255.0/24
dns-none: true
gateway: 192.168.255.10
- address: 192.168.5.0/24
dns-server: 192.168.5.1
gateway: 192.168.5.1
dhcp-option: v6only-preferred
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -288,18 +265,11 @@
values:
advertise-dns: true
# Per-interface ND entries must be CREATED — only the interface=all default
# exists out of the box. The previous api_find_and_modify approach silently
# matched zero entries and never applied pref64.
#
# pref64: NAT64 prefix discovery (RFC 8781) — required by clients honouring
# DHCP option 108 to activate CLAT. Without it they go IPv6-only with no
# working translation and appear stuck while "obtaining IP address".
#
# dns: RDNSS (RFC 8106) — IPv6-only clients ignore DHCPv4 entirely, including
# its dns-server. They need an IPv6 DNS address from RA. We advertise the
# router's own per-VLAN IPv6 address; RouterOS DNS forwards to CoreDNS.
- name: Configure IPv6 ND per-interface (pref64 + RDNSS)
# RDNSS (RFC 8106): advertise an IPv6 DNS server in RAs so dual-stack clients
# have an IPv6 resolver. Points at the router's per-VLAN IPv6 address; RouterOS
# DNS forwards to CoreDNS. No pref64 — NAT64 has been removed (see docs/coredns.md);
# AAAA suppression now happens in CoreDNS, no client-side translation needed.
- name: Configure IPv6 ND per-interface (RDNSS)
community.routeros.api_modify:
path: ipv6 nd
data:
@@ -308,9 +278,7 @@
# entirely even when a static dns= list is configured.
- interface: vlan2
advertise-dns: true
pref64: 64:ff9b::/96
dns: 2001:470:61a3:9:ffff:ffff:ffff:ffff
- interface: vlan5
advertise-dns: true
pref64: 64:ff9b::/96
dns: 2001:470:61a3:a:ffff:ffff:ffff:ffff
@@ -43,13 +43,5 @@
remote-image: gitea.lumpiasty.xyz/lumpiasty/coredns-mikrotik:latest
root-dir: coredns/root
start-on-boot: true
# Tayga auto-configures from the veth addresses and routes — no env vars needed.
- interface: veth-tayga
logging: true
name: tayga
remote-image: ghcr.io/apalrd/tayga-nat64
root-dir: tayga/root
start-on-boot: true
workdir: /app
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
-56
View File
@@ -67,20 +67,6 @@
chain: forward
comment: Allow from containers to everywhere
in-interface: containers
- action: accept
chain: forward
comment: Allow Tayga NAT64 pool to internet
out-interface: pppoe-gpon
src-address: 192.168.240.0/20
# IPv6-only clients reaching internal services published on the public IP
# (e.g. authentik.lumpiasty.xyz -> 139.28.40.212 -> dst-nat -> 10.44.0.0/16)
# arrive from the Tayga pool after NAT64 translation. Without this rule
# they fall through to the final reject (hairpin via NAT64).
- action: accept
chain: forward
comment: Allow Tayga NAT64 pool to LoadBalancer (hairpin port forwards)
dst-address: 10.44.0.0/16
src-address: 192.168.240.0/20
- action: jump
chain: forward
comment: Allow port forwards
@@ -268,11 +254,6 @@
chain: srcnat
comment: GPON ONT management
dst-address: 192.168.100.1
- action: masquerade
chain: srcnat
comment: Tayga NAT64 dynamic pool to internet
out-interface: pppoe-gpon
src-address: 192.168.240.0/20
- action: dst-nat
chain: dstnat
comment: TS3
@@ -394,30 +375,6 @@
dst-address: 2001:470:71:dd::/64
out-interface-list: wan
reject-with: icmp-no-route
# Block NAT64-mapped RFC1918 destinations before any broad accept rules.
# Without these, NAT64 (64:ff9b::/96) could be used to reach private IPv4
# ranges by encoding them in the prefix — bypassing IPv4 forward policy.
# 64:ff9b::a00:0/104 = 10.0.0.0/8
# 64:ff9b::ac10:0/108 = 172.16.0.0/12
# 64:ff9b::c0a8:0/112 = 192.168.0.0/16
- action: reject
chain: forward
comment: Block NAT64 to RFC1918 (10/8)
dst-address: 64:ff9b::a00:0/104
out-interface: nat64
reject-with: icmp-no-route
- action: reject
chain: forward
comment: Block NAT64 to RFC1918 (172.16/12)
dst-address: 64:ff9b::ac10:0/108
out-interface: nat64
reject-with: icmp-no-route
- action: reject
chain: forward
comment: Block NAT64 to RFC1918 (192.168/16)
dst-address: 64:ff9b::c0a8:0/112
out-interface: nat64
reject-with: icmp-no-route
- action: accept
chain: forward
comment: Allow from LAN to everywhere
@@ -455,16 +412,6 @@
comment: Allow from IOT to internet only
in-interface: vlan5
out-interface-list: wan
- action: accept
chain: forward
comment: Allow from SRV to internet via NAT64
in-interface: vlan4
out-interface: nat64
- action: accept
chain: forward
comment: Allow from IOT to internet via NAT64
in-interface: vlan5
out-interface: nat64
- action: accept
chain: forward
comment: Allow from OPENWRT UPLINK to internet only
@@ -480,9 +427,6 @@
dst-address: 2001:470:61a3:500::/64
in-interface-list: wan
out-interface: containers
# NAT64 to Tayga is now covered by the broad per-VLAN accept rules above.
# RFC1918-mapped destinations are blocked at the top of the chain before
# those broad accepts, so no separate per-source NAT64 rules are needed.
- action: accept
chain: forward
comment: Allow tcp transmission port to LAN
-16
View File
@@ -21,15 +21,6 @@
suppress-hw-offload: false
target-scope: 10
vrf-interface: pppoe-gpon
- comment: Tayga NAT64 dynamic pool
disabled: false
distance: 1
dst-address: 192.168.240.0/20
gateway: 192.168.239.2
routing-table: main
scope: 30
suppress-hw-offload: false
target-scope: 10
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -50,13 +41,6 @@
pref-src: ""
routing-table: main
suppress-hw-offload: false
- comment: NAT64 prefix via Tayga
disabled: false
distance: 1
dst-address: 64:ff9b::/96
gateway: fc64::2%nat64
routing-table: main
suppress-hw-offload: false
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
-6
View File
@@ -43,11 +43,5 @@
gateway: 172.20.0.1
name: veth-coredns
comment: CoreDNS container
- address: 192.168.239.2/30,fc64::2/126
dhcp: false
gateway: 192.168.239.1
gateway6: fc64::1
name: veth-tayga
comment: Tayga NAT64 container
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible