Add NAT64, DNS64 to network
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
- 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
|
||||
@@ -37,19 +40,25 @@
|
||||
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
|
||||
- address: ::ffff:ffff:ffff:ffff/64
|
||||
from-pool: pool1
|
||||
# Static instead of from-pool: pool allocation is dynamic (first free /64,
|
||||
# e.g. ...:0::/64) which made the RDNSS address advertised in ND config
|
||||
# point at a nonexistent router address. HE prefix is static, so static
|
||||
# per-VLAN addressing is deterministic and matches docs/network.md.
|
||||
- address: 2001:470:61a3:9:ffff:ffff:ffff:ffff/64
|
||||
interface: vlan2
|
||||
- address: 2001:470:61a3:500:ffff:ffff:ffff:ffff/64
|
||||
interface: containers
|
||||
- address: 2001:470:61a3:100::1/64
|
||||
advertise: false
|
||||
interface: vlan4
|
||||
- address: ::ffff:ffff:ffff:ffff/64
|
||||
from-pool: pool1
|
||||
- address: 2001:470:61a3:a:ffff:ffff:ffff:ffff/64
|
||||
interface: vlan5
|
||||
- address: 2001:470:61a3:600::1/64
|
||||
advertise: false
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
- name: bridge1
|
||||
vlan-filtering: true
|
||||
- name: containers
|
||||
- name: nat64
|
||||
handle_absent_entries: remove
|
||||
handle_entries_content: remove_as_much_as_possible
|
||||
|
||||
@@ -65,6 +66,12 @@
|
||||
- bridge: containers
|
||||
interface: veth-tailscale
|
||||
comment: Tailscale container interface
|
||||
- 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
|
||||
@@ -152,24 +159,9 @@
|
||||
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
|
||||
data:
|
||||
- address: 192.168.0.0/24
|
||||
dns-server: 192.168.0.1
|
||||
gateway: 192.168.0.1
|
||||
- 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
|
||||
handle_absent_entries: remove
|
||||
handle_entries_content: remove_as_much_as_possible
|
||||
|
||||
# TODO: IPv6 pools are useful when we have dynamic prefix, but we don't
|
||||
# We can remove it now
|
||||
# Pool is no longer referenced — vlan2/vlan5 now use static addresses
|
||||
# (addressing.yml) so the RDNSS addresses in ND config are deterministic.
|
||||
# Kept defined for one run after migration; safe to delete afterwards.
|
||||
- name: Configure IPv6 pools
|
||||
community.routeros.api_modify:
|
||||
path: ipv6 pool
|
||||
@@ -188,7 +180,8 @@
|
||||
values:
|
||||
allow-remote-requests: true
|
||||
cache-size: 20480
|
||||
servers: 1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001
|
||||
# CoreDNS container provides DNS64; it forwards upstream to 1.1.1.1/8.8.8.8.
|
||||
servers: 172.20.0.3
|
||||
|
||||
- name: Configure DNS static entries
|
||||
community.routeros.api_modify:
|
||||
@@ -199,6 +192,11 @@
|
||||
forward-to: 100.100.100.100
|
||||
match-subdomain: true
|
||||
comment: Tailscale MagicDNS
|
||||
- name: lumpiasty.xyz
|
||||
type: FWD
|
||||
forward-to: 1.1.1.1
|
||||
match-subdomain: true
|
||||
comment: lumpiasty.xyz bypass nat64
|
||||
handle_absent_entries: remove
|
||||
handle_entries_content: remove_as_much_as_possible
|
||||
|
||||
@@ -244,6 +242,42 @@
|
||||
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
|
||||
data:
|
||||
- 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
|
||||
|
||||
- name: Configure IPv6 ND defaults
|
||||
community.routeros.api_find_and_modify:
|
||||
ignore_dynamic: false
|
||||
@@ -252,3 +286,30 @@
|
||||
default: true
|
||||
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)
|
||||
community.routeros.api_modify:
|
||||
path: ipv6 nd
|
||||
data:
|
||||
# advertise-dns must be explicitly enabled — RouterOS creates new ND
|
||||
# entries with advertise-dns=no, which suppresses the RDNSS option
|
||||
# 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
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
handle_absent_entries: remove
|
||||
handle_entries_content: remove_as_much_as_possible
|
||||
|
||||
- name: Configure tailscale container
|
||||
- name: Configure containers
|
||||
community.routeros.api_modify:
|
||||
path: container
|
||||
data:
|
||||
- dns: 172.17.0.1
|
||||
- dns: 172.20.0.1
|
||||
interface: veth-tailscale
|
||||
logging: true
|
||||
mountlists: tailscale_state
|
||||
@@ -36,5 +36,20 @@
|
||||
remote-image: gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale:stable
|
||||
root-dir: tailscale/root
|
||||
start-on-boot: true
|
||||
- dns: 172.20.0.1
|
||||
interface: veth-coredns
|
||||
logging: true
|
||||
name: coredns
|
||||
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
|
||||
|
||||
@@ -67,6 +67,11 @@
|
||||
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
|
||||
- action: jump
|
||||
chain: forward
|
||||
comment: Allow port forwards
|
||||
@@ -254,6 +259,11 @@
|
||||
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
|
||||
@@ -375,6 +385,30 @@
|
||||
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
|
||||
@@ -412,6 +446,11 @@
|
||||
comment: Allow from IOT to internet only
|
||||
in-interface: vlan5
|
||||
out-interface-list: wan
|
||||
- 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
|
||||
@@ -427,6 +466,9 @@
|
||||
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
|
||||
|
||||
@@ -21,6 +21,15 @@
|
||||
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
|
||||
|
||||
@@ -41,6 +50,13 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
keepalive-timeout: 2
|
||||
name: pppoe-gpon
|
||||
password: "{{ routeros_pppoe_password }}"
|
||||
use-peer-dns: true
|
||||
# Using CoreDNS container with DNS64
|
||||
use-peer-dns: false
|
||||
user: "{{ routeros_pppoe_username }}"
|
||||
handle_absent_entries: remove
|
||||
handle_entries_content: remove_as_much_as_possible
|
||||
@@ -37,5 +38,16 @@
|
||||
mac-address: 7E:7E:A1:B1:2A:7B
|
||||
name: veth-tailscale
|
||||
comment: Tailscale container
|
||||
- address: 172.20.0.3/24
|
||||
dhcp: false
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user