手順2:基本的な ルータ機能の 構築
第一部にて、
インターフェースの 準備
最初に、
- ブリッジ
( br0
)の作成
[NetDev]Name=br0Kind=bridge# wan0からMACアドレス(ランダム化済み)を継承MACAddress=none
[Match]OriginalName=br0
[Link]# wan0からMACアドレス(ランダム化済み)を継承MACAddressPolicy=none
- VLAN用サブインターフェース
( home
、hgw
)の作成
[NetDev]Name=homeKind=vlan
[VLAN]Id=10
[NetDev]Name=hgwKind=vlan# 一応 home とは別のMACアドレスにしておくMACAddress=de:ad:be:ef:00:03
[VLAN]Id=100
- サブインターフェースと
物理インターフェース ( lan0
)の紐づけ
[Match]Name=lan0
[Network]VLAN=homeVLAN=hgwLinkLocalAddressing=noLLMNR=no
br0
のメンバーに wan0
を追加 ( hgw
はあとで 追加する)
[Match]Name=wan0
[Network]Bridge=br0
フレッツ網への 接続
IPv6 IPoE
DHCPv6クライアントを
受け取った
(
[Match]Name=br0
[Link]RequiredForOnline=yes
[Network]DHCP=ipv6# 起動ごとにリンクローカルアドレスを変えるIPv6LinkLocalAddressGenerationMode=randomIPv6Forwarding=yesIPv6AcceptRA=yes# 一時アドレスを割り当てるIPv6PrivacyExtensions=yesDHCPPrefixDelegation=yesTunnel=mape0
[Route]Gateway=_ipv6ra# TCPの初期ウィンドウサイズを大きくするInitialCongestionWindow=30InitialAdvertisedReceiveWindow=30
[DHCPv6]DUIDType=link-layerIAID=0# DHCPv6リクエストに余分な情報を含めないようにするSendHostname=noUseCaptivePortal=noUseDNR=no
[DHCPPrefixDelegation]UplinkInterface=:selfSubnetId=0Announce=no# CEアドレスの後半64bit(= インターフェースID)を指定Token=::ce
CEアドレスはNetwork.Address=
でもDHCPPrefixDelegation.Token=
を
その
IPv4 over IPv6
トンネルデバイスmape0
)を
[NetDev]Name=mape0Kind=ip6tnl
[Tunnel]Mode=ipip6# CEアドレスLocal=3fff:0:0:ab00::ce# BRアドレスRemote=2001:db8::1DiscoverPathMTU=yesEncapsulationLimit=none
[Match]Name=mape0
[Link]RequiredForOnline=yes
[Network]BindCarrier=br0IPv4Forwarding=yesLinkLocalAddressing=noLLMNR=no# DefaultRouteOnDevice=yes
[Route]Gateway=0.0.0.0InitialCongestionWindow=30InitialAdvertisedReceiveWindow=30
な[Route]
セクションのNetwork.DefaultRouteOnDevice=yes
を
MAP-E関連の 設定
前回紹介したtc
を
MSSの
#!/usr/sbin/nft -f
destroy table ip mape
table ip mape { chain mape-filter { type filter hook postrouting priority filter; policy accept; # TCP MSSの調整 iif "mape0" tcp flags syn tcp option maxseg size set rt mtu oif "mape0" tcp flags syn tcp option maxseg size set rt mtu # fwmarkの付与 oif "mape0" meta l4proto tcp meta mark set 0x54 counter oif "mape0" meta l4proto udp meta mark set 0x55 counter }
chain mape-snat { type nat hook postrouting priority srcnat; policy accept; # ソースNAT(IPv4アドレスは前回計算したものを使う) oif "mape0" meta l4proto {tcp, udp, icmp} counter snat to 192.0.2.1:32784-33023 }}
起動時にtc
コマンドも、
#!/usr/bin/env bash
TUNNEL=mape0 # トンネルデバイスの名前PSID=ab # ポートセットID(16進)
# Outtc qdisc replace dev $TUNNEL root handle 1: htb
tc filter add dev $TUNNEL parent 1: handle 0x55 fw action csum ip4h udp continuetc filter add dev $TUNNEL parent 1: handle 0x54 fw action csum ip4h tcp continuetc filter add dev $TUNNEL parent 1: handle 0x54/0xfffffffe fw action pedit pedit munge ip sport set "0x0${PSID}0" retain 0x0ff0 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x54 0xfffffffe match ip sport 0x0010 0x0010 action pedit pedit munge ip sport set 0x1000 retain 0x1000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x54 0xfffffffe match ip sport 0x0020 0x0020 action pedit pedit munge ip sport set 0x2000 retain 0x2000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x54 0xfffffffe match ip sport 0x0040 0x0040 action pedit pedit munge ip sport set 0x4000 retain 0x4000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x54 0xfffffffe match ip sport 0x0000 0x0080 action pedit pedit munge ip sport set 0x0000 retain 0x8000 continue
# ICMP echo replytc filter add dev $TUNNEL parent 1: u32 match mark 0x59 0xffffffff action pedit pedit munge offset 24 u16 set "0x0${PSID}0" retain 0x0ff0 pipe action csum ip4h icmp continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x59 0xffffffff match u16 0x0010 0x0010 at 24 action pedit pedit munge offset 24 u16 set 0x1000 retain 0x1000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x59 0xffffffff match u16 0x0020 0x0020 at 24 action pedit pedit munge offset 24 u16 set 0x2000 retain 0x2000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x59 0xffffffff match u16 0x0040 0x0040 at 24 action pedit pedit munge offset 24 u16 set 0x4000 retain 0x4000 continuetc filter add dev $TUNNEL parent 1: u32 match mark 0x59 0xffffffff match u16 0x0000 0x0080 at 24 action pedit pedit munge offset 24 u16 set 0x0000 retain 0x8000 continuetc filter add dev $TUNNEL parent 1: u32 match ip protocol 1 0xff match ip icmp_type 8 0xff match ip ihl 0x5 0xf match u16 0 1fff at 6 action skbedit mark 0x59 continue
# Intc qdisc add dev $TUNNEL ingress handle ffff:
tc filter add dev $TUNNEL parent ffff: handle 0x65 fw action csum ip4h udp continuetc filter add dev $TUNNEL parent ffff: handle 0x64 fw action csum ip4h tcp continuetc filter add dev $TUNNEL parent ffff: handle 0x64/0xfffffffe fw action pedit pedit munge ip dport set 0x8000 retain 0xf000 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x64 0xfffffffe match ip dport 0x8000 0x8000 action pedit pedit munge ip dport set 0x0080 retain 0x0080 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x64 0xfffffffe match ip dport 0x4000 0x4000 action pedit pedit munge ip dport set 0x0040 retain 0x0040 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x64 0xfffffffe match ip dport 0x2000 0x2000 action pedit pedit munge ip dport set 0x0020 retain 0x0020 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x64 0xfffffffe match ip dport 0x1000 0x1000 action pedit pedit munge ip dport set 0x0010 retain 0x0010 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x64 0xfffffffe action pedit pedit munge ip dport set 0 retain 0x0ff0 continuetc filter add dev $TUNNEL parent ffff: u32 match ip protocol 17 0xff match u16 0 1fff at 6 match ip dport "0x0${PSID}0" 0x0ff0 action skbedit mark 0x65 continuetc filter add dev $TUNNEL parent ffff: u32 match ip protocol 6 0xff match u16 0 1fff at 6 match ip dport "0x0${PSID}0" 0x0ff0 action skbedit mark 0x64 continue
# ICMP echo requesttc filter add dev $TUNNEL parent ffff: handle 0x69 fw action pedit pedit munge offset 24 u16 set 0x8000 retain 0xf000 pipe action csum ip4h icmp continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x69 0xffffffff match u16 0x8000 0x8000 at 24 action pedit pedit munge offset 24 u16 set 0x0080 retain 0x0080 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x69 0xffffffff match u16 0x4000 0x4000 at 24 action pedit pedit munge offset 24 u16 set 0x0040 retain 0x0040 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x69 0xffffffff match u16 0x2000 0x2000 at 24 action pedit pedit munge offset 24 u16 set 0x0020 retain 0x0020 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x69 0xffffffff match u16 0x1000 0x1000 at 24 action pedit pedit munge offset 24 u16 set 0x0010 retain 0x0010 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x69 0xffffffff action pedit pedit munge offset 24 u16 set 0 retain 0x0ff0 continuetc filter add dev $TUNNEL parent ffff: u32 match ip protocol 1 0xff match ip icmp_type 0 0xff match ip ihl 0x5 0xf match u16 0 1fff at 6 match u16 "0x0${PSID}0" 0x0ff0 at 24 action skbedit mark 0x69 continue
# port unreachabletc filter add dev $TUNNEL parent ffff: handle 0x79 fw action pedit pedit munge offset 48 u16 set 0x8000 retain 0xf000 pipe action csum ip4h and icmp continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x79 0xffffffff match ip dport 0x8000 0x8000 at 48 action pedit pedit munge offset 48 u16 set 0x0080 retain 0x0080 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x79 0xffffffff match ip dport 0x4000 0x4000 at 48 action pedit pedit munge offset 48 u16 set 0x0040 retain 0x0040 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x79 0xffffffff match ip dport 0x2000 0x2000 at 48 action pedit pedit munge offset 48 u16 set 0x0020 retain 0x0020 continuetc filter add dev $TUNNEL parent ffff: u32 match mark 0x79 0xffffffff match ip dport 0x1000 0x1000 at 48 action pedit pedit munge offset 48 u16 set 0x0010 retain 0x0010 continuetc filter add dev $TUNNEL parent ffff: handle 0x79 fw action pedit pedit munge offset 48 u16 set 0 retain 0x0ff0 continuetc filter add dev $TUNNEL parent ffff: u32 match ip protocol 1 0xff match ip icmp_type 3 0xff match ip ihl 0x5 0xf match ip ihl 0x5 0xf at 28 match u16 0 1fff at 6 match ip sport "0x0${PSID}0" 0x0ff0 at 48 action skbedit mark 0x79 continue
起動後、mape0
デバイスの
[Unit]Description=Apply nftables filter rules for mape0# 下のように書くと、このサービスはmape0デバイスの設定完了後に実行されるAfter=sys-subsystem-net-devices-mape0.device nftables.serviceBindsTo=sys-subsystem-net-devices-mape0.deviceRequires=nftables.service
[Service]Type=oneshotExecStart=/usr/sbin/nft -f /etc/nftables.d/lazy/mape0.nftRemainAfterExit=true
[Install]WantedBy=multi-user.target
[Unit]Description=Apply custom tc rulesWants=network-online.targetAfter=network-online.target sys-subsystem-net-devices-mape0.deviceBindsTo=sys-subsystem-net-devices-mape0.device
[Service]Type=oneshotRemainAfterExit=yesExecStart=/usr/local/sbin/tc-mape0.shExecStop=/usr/sbin/tc filter del dev mape0 && /usr/sbin/tc filter del dev mape0 parent ffff:
[Install]WantedBy=multi-user.target
systemctl enable nftables-mape0systemctl enable tc-mape0reboot
天地の
> ping -c3 2606:4700:4700::1001PING 2606:4700:4700::1001 (2606:4700:4700::1001) 56 data bytes64 bytes from 2606:4700:4700::1001: icmp_seq=1 ttl=54 time=7.45 ms64 bytes from 2606:4700:4700::1001: icmp_seq=2 ttl=54 time=7.19 ms64 bytes from 2606:4700:4700::1001: icmp_seq=3 ttl=54 time=7.12 ms
--- 2606:4700:4700::1001 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2003msrtt min/avg/max/mdev = 7.123/7.254/7.451/0.141 ms> ping -c3 1.0.0.1PING 1.0.0.1 (1.0.0.1) 56(84) bytes of data.64 bytes from 1.0.0.1: icmp_seq=1 ttl=58 time=7.36 ms64 bytes from 1.0.0.1: icmp_seq=2 ttl=58 time=7.17 ms64 bytes from 1.0.0.1: icmp_seq=3 ttl=58 time=7.84 ms
--- 1.0.0.1 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2003msrtt min/avg/max/mdev = 7.172/7.458/7.839/0.280 ms
宅内機器側インターフェースの 設定
続いてhome
)を
[Match]Name=home
[Network]IPv6StableSecretAddress=xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxxIPv6Forwarding=yesIPv6AcceptRA=noIPv6SendRA=yesDHCPPrefixDelegation=yes
Address=10.0.0.1/24DHCPServer=yesMulticastDNS=yes
[DHCPPrefixDelegation]# このセグメントに/64のサブネット(3fff:0:0:ab01::/64)を割り当てるSubnetId=1# ただしインターフェース自体にはアドレスを割り振らないAssign=no
# 割り当てたサブネットとDNSサーバをRAで配布する[IPv6SendRA]DNS=_link_localRouterLifetimeSec=9000DNSLifetimeSec=14400
[DHCPServer]DNS=_server_addressPoolOffset=32PoolSize=208DefaultLeaseTimeSec=24hMaxLeaseTimeSec=48h
# IPv4の固定もお手のもの[DHCPServerStaticLease]MACAddress=de:ad:be:ef:00:04Address=10.0.0.2
先ほどbr0
)に
DNS=_link_local
やDNS=_server_address
と
networkctl reload
設定を
な
ファイアウォール設定
インターネット側から
#!/usr/bin/nft -f
destroy table inet filter
table inet filter { set LANv4 { type ipv4_addr; flags interval; elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } }
set LANv6 { type ipv6_addr; flags interval; elements = { fd00::/8, fe80::/10 } }
chain lan_input { meta l4proto { tcp, udp } th dport { 22, 53 } accept comment "allow LAN services" }
chain input { type filter hook input priority filter; policy drop;
ct state invalid drop comment "early drop of invalid connections" ct state { established, related } accept comment "allow tracked connections" iif lo accept comment "allow from loopback" ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply } limit rate 5/second burst 10 packets accept ip6 nexthdr icmpv6 ip6 saddr fe80::/10 icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, 148, 149 } iifname "br0" accept ip6 nexthdr icmpv6 icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report, 148, 149, 151, 152, 153 } iifname "home" accept ip protocol icmp accept comment "allow icmp" udp dport bootps ip saddr 0.0.0.0 ip daddr 255.255.255.255 iifname "home" accept comment "allow dhcpv4" udp dport dhcpv6-server ip6 saddr fe80::/10 ip6 daddr ff02::1:2 iifname "home" accept comment "allow dhcpv6" udp dport dhcpv6-client iifname "br0" accept ip saddr @LANv4 jump lan_input comment "allow private services" ip6 saddr @LANv6 iifname "home" jump lan_input comment "allow private services"
counter }
chain forward { type filter hook forward priority filter; policy drop;
iifname "home" ip protocol tcp tcp flags != syn / fin,syn,rst,ack ct state new counter reject with tcp reset meta protocol ip6 iifname "home" tcp flags != syn / fin,syn,rst,ack ct state new counter accept ct state invalid drop ct state { established, related } accept ip protocol icmp icmp type { destination-unreachable, time-exceeded, parameter-problem } accept ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply } accept
meta l4proto { tcp, udp } th dport { 135, 137-139, 445 } oifname { "br0", "mape0" } counter drop iifname "home" oifname { "br0", "mape0" } accept
counter }}
include "/etc/nftables.d/*.nft"
systemctl enable --now nftables
以上で、