DS-Lite(transix)のポリシールーティング(PBR)にちょっと苦労したので

Yamahaルータの代わりにubuntuをルータにしようとしています。
だいたい参考URLのとおりですが、参考URLの3番目のrp_filter=0に気づくのに苦労しました。

**参考URL：
https://mxnl.com/ds-lite/
https://qiita.com/knok/items/f6a4c2cf3f6293acb01d
https://qiita.com/kanejun/items/4f7a5fe7c811a77c0b7b**


#ポリシールーティングの設定
port80、443が来たらDS-Liteで、それ以外はFlet's直となるようにしたい。
振り分けはufw(iptables)のマーク付けで。

```
+-----+           +---------------------------+               +--------+
| PC  |-----(eth1)| デフォルト   ⇒ flets (100) |(eth2)-----(gw)| Flet's |
+-----+           | port80,443 ⇒ dslite(101) |               +--------+
                  +---------------------------+      192.168.100.254
        192.168.1.254/24                 192.168.100.1/24
```
LAN側がeth1(192.168.1.1/24)。WAN側がeth2(192.168.100.1/24)。
ポリシールーティング用テーブルは、Flet's直通(100)、DS-Lite向け(101)。
テーブルはDS-Lite向けだけでもいいけど対称性とこまい制御ができるように。

#DS-Liteトンネルの設定
##事前確認(IPv6アドレス)
WAN側のIPv6のグローバルアドレスを確認★

```bash:WAN側のIPv6アドレス確認
	# ip a
		:
		3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
		    link/ether 52:54:**:**:**:** brd ff:ff:ff:ff:ff:ff
		    altname enp6s0
	☆	    inet 192.168.1.254/24 brd 192.168.1.255 scope global eth1
		       valid_lft forever preferred_lft forever
		    inet6 fe80::**:**:**:**/64 scope link 
		       valid_lft forever preferred_lft forever
		:
		4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
		    link/ether 52:54:**:**:**:** brd ff:ff:ff:ff:ff:ff
		    altname enp7s0
	☆	    inet 192.168.100.1/24 brd 192.168.100.255 scope global eth2
		       valid_lft forever preferred_lft forever
	★	    inet6 2409:**:**:**:**:**:**:**/64 scope global dynamic mngtmpaddr noprefixroute 
		       valid_lft 2591983sec preferred_lft 604783sec
		    inet6 fe80::**:**:**:**/64 scope link 
		       valid_lft forever preferred_lft forever
		:
```
##ポリシールーティング用テーブル

```bash:ポリシールーティング用テーブル
	# vi /etc/iproute2/rt_tables.d/inet.conf 
		100     flets
		101     dslite
```
ufw(iptables)のマーク付けでポリシー定義したいので、
IF(eth2)アップ時にルールが有効になるようにする。

```bash:ポリシールール設定
	# vi /etc/networkd-dispatcher/routable.d/50-ifup-hooks
		#! /bin/bash
		if [ "$IFACE" == "eth2" ]; then
			ip rule add fwmark 100 table flets
			ip rule add fwmark 101 table dslite
		fi
```

##DS-Liteトンネルの設定
netplanでDSLiteのトンネルを設定。
localには事前確認にしたglobalのIPv6アドレス★を。

```bash:
	# vi /etc/netplan/00-installer-config.yaml
		network:
		  version: 2
		  ethernets:
		    lan:
		      match:
		        macaddress: 52:54:**:**:**:**
		      set-name:  eth1
		      dhcp4:     false
		      addresses: ['192.168.1.254/24']
		      nameservers:
		        addresses: [192.168.100.254]
		    wan:
		      match:
		        macaddress: 52:54:**:**:**:**
		      set-name:  eth2
		      dhcp4:     false
		      addresses: ['192.168.100.1/24']
		      gateway4:    192.168.100.254
		#flets直通のポリシールーティング用のテーブル定義(なくても良い)
		      routes:
		        - to:      0.0.0.0/0
		          via:     192.168.100.254
		          on-link: true
		          table:   100
		  tunnels:
		    dslite:
		      mode:   ipip6
		#NTT 東日本の場合
		      remote: 2404:8e00::feed:100
		#NTT 西日本の場合
		#     remote: 2404:8e01::feed:100
		#上記どちらかを記述
	★	      local:  2409:**:**:**:**:**:**:**
		#dslite用のポリシールーティング用のテーブル定義
		      routes:
		        - to:    0.0.0.0/0
		          scope: link
		          table:  101
```
設定して再起動すると、dsliteというトンネルができます。ip6tn0は勝手にできる。

```bash:ネットワーク/ルーティングテーブルの確認
	# ip a
		4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
		    link/ether 52:54:**:**:**:** brd ff:ff:ff:ff:ff:ff
		    altname enp7s0
		    inet 192.168.100.1/24 brd 192.168.100.255 scope global eth2
		       valid_lft forever preferred_lft forever
		    inet6 2409:**:**:**:**:**:**:**/64 scope global dynamic mngtmpaddr noprefixroute 
		       valid_lft 2591983sec preferred_lft 604783sec
		    inet6 fe80::**:**:**:**/64 scope link 
		       valid_lft forever preferred_lft forever
		:
		5: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
		    link/tunnel6 :: brd :: permaddr ****:****:****::
		6: dslite@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1452 qdisc noqueue state UNKNOWN group default qlen 1000
		    link/tunnel6 2409:**:**:**:**:**:**:** peer 2404:8e00::feed:100 permaddr ****:****:****::
		    inet6 fe80::**:**:**:**/64 scope link 
		       valid_lft forever preferred_lft forever

	# route -n
		カーネルIP経路テーブル
		受信先サイト     ゲートウェイ       ネットマスク     フラグ  Metric Ref 使用数 インタフェース
		default        192.168.100.254  0.0.0.0         UG    0      0        0 eth2
		192.168.1.0    0.0.0.0          255.255.255.0   U     0      0        0 eth1
		192.168.100.0  0.0.0.0          255.255.255.0   U     0      0        0 eth2

	# ip route show table flets
		default via 192.168.100.254 dev eth2 proto static onlink 

	# ip route show table dslite
		default dev dslite proto static scope link 

	# ip rule show
		0:      from all lookup local
		32764:  from all fwmark 0x65 lookup dslite
		32765:  from all fwmark 0x64 lookup flets
		32766:  from all lookup main
		32767:  from all lookup default
```
まだ、ufw(NATとか)の設定をしていないのでルータとしては動きません。

#ufw(iptables)の初期設定

初期設定が面倒だったのでufwを使うこととしました。ルールはおいおい充実させたい。

```bash:FOWARD/自動起動/ログを有効にする
	# vi /etc/default/ufw
		:
		DEFAULT_FORWARD_POLICY="ACCEPT"
		:

	# vi /etc/ufw/ufw.conf 
		# /etc/ufw/ufw.conf
		:
		＃自動起動
		ENABLED=yes
		:
		＃うまく動くまではログは少し詳細に
		LOGLEVEL=medium
```
rp_filterを緩くしないと、パケットの戻りがうまく行かなかった。
参考URL通り戻りパケットがFORWARDされず内部で消える。

```bash:カーネルパラメータ
	# vi /etc/ufw/sysctl.conf
			:
		net/ipv4/ip_forward=1
		net/ipv6/conf/default/forwarding=1
		net/ipv6/conf/all/forwarding=1

		#	https://qiita.com/kanejun/items/4f7a5fe7c811a77c0b7b
		#	スプーフィング対策解除
		net/ipv4/conf/all/rp_filter=0
		net/ipv4/conf/default/rp_filter=0
```
```bash:ufw(iptables)の有効化
	# systemctl enable ufw.service
	# ufw enable
	# shutdown -r now
```

##ポリシールーティングの設定
ufwコマンドでの設定はわかりにくいのでbefore.rulesに。
とりあえず、最低限。

```bash:ufw(iptables)の設定
	# vi /etc/ufw/before.rules
		# Don't delete these required lines, otherwise there will be errors
		*filter
		:
		# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
		# is uncommented)
		-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
		:
		#######(filterのCOMMITの前に追加)
		#LAN側のパケットINPUTは許可
		-A ufw-before-input -i eth1 -j ACCEPT

		# don't delete the 'COMMIT' line or these rules won't be processed
		COMMIT

		#######(COMMITの後ろに追加：ここから)
		*mangle
		-F
		:PREROUTING ACCEPT [0:0]
		:OUTPUT     ACCEPT [0:0]
		#
		#eth1からのポート80/443のパケットにdslite向けのマーク(101)をつける
		-A PREROUTING -p tcp -m multiport --dports 80,443 -j MARK --set-mark 101
		#
		#内部からdsliteに向かう設定はOUTPUTで(外からくるのはPREROUTING)
		-A OUTPUT     -p tcp -m multiport --dports 80,443 -j MARK --set-mark 101
		#
		# radiko.jp(203.211.199.120)はDS-Lite経由だと地域判定がおかしくなるのでflets(100)へ
		-A PREROUTING -d 203.211.199.120 -j MARK --set-mark 100
		#
		# localアドレスはマークしない
		-A PREROUTING -d 127.0.0.1/8,192.168.1.0/24,192.168.100.0/24 -j MARK --set-mark 0
		#
		COMMIT
		#
		#######
		*nat
		-F
		:POSTROUTING ACCEPT [0:0]
		#
		# eth2へはNAT変換
		-A POSTROUTING -o eth2 -j MASQUERADE
		#
		COMMIT
```
```bash:ufw(iptables)設定の反映
	# ufw reload
```
#通信状況の確認
次のURLにアクセすると、接続先がFlet'sのプロバイダではなく、DS-Lite(transix)になっているはず。

**https://test-ipv6.com/index.html.ja_JP
⇒ご利用のインターネットサービスプロバイダ (ISP): MF-NATIVE6-E INTERNET MULTIFEED CO.
https://www.cman.jp/network/support/go_access.cgi
⇒あなたの利用しているIPアドレス( ...shared.user.transix.jp )**

あまり自信ないけど一旦これで。