(前置き経緯)
自宅のネット環境がPPPoE接続で、通常利用でそれほど支障はなかったのですが、macOS更新ダウンロードで3時間以上は絶えられなくなり、IPv6接続に切り替えました。
市販のコンパクトな4千円程度の小さなWifiルータを試しましたが、ルーターの起動も遅い、動作も遅い、なにか固まるような動き、小型アンテナで電波は強くとも距離が飛びません。
Raspberry Pi 2Bで構築のルータ(PPPoE接続)+長いアンテナのついたWifiルータ のほうが快適でした。そこで、IPv4 over IPv6環境も自前でブロードバンドルーターを構築するに至りました。
(環境) Raspberry Pi 2B 用 OpenWrt 19.07.4 をインストール構築。
イメージの場所 https://openwrt.org/toh/raspberry_pi_foundation/raspberry_pi
あちこち参考にさせていただきましたが、結果として自前でルータ構築できたことに感謝です。
OpenWrt標準では、完全ではないので、追加修正が必要です。
MAP-E技術、OpenWrtのmapeセットアップに関しては、多くの先人たちの説明に譲ります。
(参考) https://qiita.com/s_ponta/items/5652a7be49198288ae61
(参考) https://ktaka.blog.ccmp.jp/2020/05/linuxipv6-ipoe.html
(参考) https://blog.mamemaki.com/entry/2019/12/15/171104
パケットmark付けのiptablesについて自分なりに補います。
(OpenWrt) Firewall - Custom Rules 用
先人たちのコードを修正して、ルール用のテーブルのテキストを吐き出すように次を作成しました。
次の実行結果テキストをカスタムルールに貼り付け適用するものです。
#!/bin/sh
createMAPE()
{
if [ "$1" = "OCNV" ] ; then
divNum=64
startPort=1024
fi
if [ "$1" = "V6P" ] ; then
divNum=16
startPort=4096
fi
rule=1
startMark=9
Every=`expr $divNum - 1`
while [ $rule -lt $divNum ] ; do
mark=`expr $rule + $startMark`
pn=`expr $rule - 1`
portl=`expr $rule \* $startPort + $PSID \* 16`
portr=`expr $portl + 15`
echo "iptables -t nat -A prerouting_lan_rule -m statistic --mode nth --every $Every --packet $pn -j MARK --set-mark $mark"
echo "iptables -t nat -A OUTPUT -o map-tnl -m statistic --mode nth --every $Every --packet $pn -j MARK --set-mark $mark" #output_wan_ruleだとバグな感じで適用されませんので、「OUTPUT -o map-tnl」とします。
done
}
# あなたの環境に書き換えてください。
BR='xxxx:xxx:xxxx::x'
CE='xxxx:xxxx:xxxx:xxxx:xx:xxxx:xxx:xxx' # xで適当に隠します。
IP4='xxx.xx.xx.xx'
PSID='x'
createMAPE OCNV
#createMAPE V6P
BR CE IPV4 PSID の求め方は「MAP-E計算」で検索かけて、1ページ目を一通りチェックします。
私の環境が、今はOCNバーチャルコネクトなので、ここでは createMAPE OCNV を走らせます。
markの番号は 10進数の10からはじめています。0以上ならよさそうです。paketは0からのようです。
paket分散は計算でキリの良い64したくなりますが、0〜62 の 63個です。間違うとロスするタイミングがときどきありそうです。常に --every 63 になるように $Every を当てています。
##OpenWrt カスタムルール用の考慮
-A PREROUTING や -A OUTPUT の チェイン指定でも動作はするようですが、全部インターフェースの出入りに適用されてしまいますので、いくらか動きが遅いです。次のチェインを指定します。
REROUTING | OUTPUT | |
---|---|---|
適用先 | LAN の入り | WAN の出 |
チェイン | prerouting_lan_rule | output_wan_rule が適用され ないので OUTPUT -o map-tnl |
(重要)OpenWrt 19.07.4において、output_wan_ruleは、バグのようで適用されませんので、OUTPUT -o map-tnl を直接指定する必要がありました。
(参考)インターフェースの名称は lan wan tnl を使っています。これに連動してチェイン名も変わるかもしれません。
config interface 'lan'
~省略
config interface 'wan'
~省略
config interface 'tnl'
~省略
チェイン名をiptables-saveで内容確認、探してください。
たとえば、prerouting_xxxx_ruleで、xxxxがインターフェース名になっていると予想します。
root@OpenWrt:~# iptables-save
#以上を踏まえ、カスタムルールに追加するiptablesが得ました
出力されたこれらをコピーしてOpenWrtの Network -> Firewall -> Custom Rules に貼り付け適用します。
iptables -t nat -A prerouting_lan_rule -m statistic --mode nth --every 63 --packet 0 -j MARK --set-mark 10
iptables -t nat -A OUTPUT -o map-tnl -m statistic --mode nth --every 63 --packet 0 -j MARK --set-mark 10
.
.
.
iptables -t nat -A prerouting_lan_rule -m statistic --mode nth --every 63 --packet 62 -j MARK --set-mark 72
iptables -t nat -A OUTPUT -o map-tnl -m statistic --mode nth --every 63 --packet 62 -j MARK --set-mark 72
POSTROUTING についても mark 追加対応
POSTROUTINGは /lib/netifd/proto/map.shで作られています。ipv4 over ipv6トンネルに抜けていくPOSTROUTINGも分散させるために、次のようにmarkをつけます。同じ値の範囲:0x0a(10)〜0x48(72)になるようにします。
###修正箇所
130行目あたり
json_add_array firewall
if [ -z "$(eval "echo \$RULE_${k}_PORTSETS")" ]; then
json_add_object ""
json_add_string type nat
json_add_string target SNAT
json_add_string family inet
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_close_object
else
local mark=17 # ■■ 追加 ■■
for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
for proto in icmp tcp udp; do
json_add_object ""
json_add_string type nat
json_add_string target SNAT
json_add_string family inet
json_add_string proto "$proto"
json_add_string mark "$mark" # ■■ 追加 ■■
# ■■ コメントアウト ■■ json_add_boolean connlimit_ports 1
json_add_string connlimit_ports "1" # ■■ 追加 ■■
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
json_add_string snat_port "$portset"
json_close_object
done
mark=`expr $mark + 1` # ■■ 追加 ■■
done
fi
再起動すれば完了です。
iptables-save で確認すれば、POSTROUTINGで「-m mark --mark 0xa」〜「-m mark --mark 0x48」の範囲で追加されています。
-A POSTROUTING -o map-tnl -p tcp -m mark --mark 0xa -m connlimit --connlimit-upto 16 --connlimit-mask 32 --connlimit-daddr -m comment --comment "!fw3: ubus:tnl[map] nat 0" -j SNAT --to-source xxx.xx.xx.xx:1056-1071
.
.
.
-A POSTROUTING -o map-tnl -p tcp -m mark --mark 0x48 -m connlimit --connlimit-upto 16 --connlimit-mask 32 --connlimit-daddr -m comment --comment "!fw3: ubus:tnl[map] nat 187" -j SNAT --to-source xxx.xx.xx.xx:64544-64559
これで通信が途切れたり、繋がらないようなことは少し減ると思います。