スキップしてメイン コンテンツに移動

フレッツ光クロス:MAP-E ROUTER by Debian Box (iptables)

フレッツ光クロスがようやく開通したので、Debianにてrouterを構成し接続してみました。なお、プロバイダーを選ぶにあたっては、IPoE方式がそれぞれ異なるため検討したところ、IPoEでは、MAP-Eでもv6plusとocnバーチャルコネクトがあり、前者がポート数240なのに対し、後者は約4倍のポート数が使えるようなネットの情報をみて、OCNバーチャルコネクトを選択しました。(プロバイダーとしてはぷららです。なおDS-LiteはCE側でのNATではないので今回は見送りました。)そこで、OCN バーチャルコネクトをDebian(iptables)で実現するとどうなるかと思い、ネットの情報を頼りにしつつ、設定した次第です。
実際に試した結果、とりあえず通信できていますが、MAP-Eは本来マッピングルールをマップサーバから取得するはずなので、今回のやり方が正解とはいえませんし、仕様変更されると通信できなくなる可能性があります。あくまでも参考程度ですが、本稿をUPしてみました。
2023/03/16追記:こちらにゲームコンソールNAT越え(Nintendo Switch ナットタイプ A判定)対応版を投稿しました。
2023/03/28追記:※1の記述および3行無効化によりNAT越え(Nintendo Switch ナットタイプ B判定)できるようになりました。
構成は以下の通りです。
ルーターがDebianで回線がOCNバーチャルコネクトであること以外はなにも特別なところはない構成です。
さて、いきなり設定ですが、まず、割り当てられたプレフィックスを確認します。
確認は、
dhclient -6 -d -P enp2s0
とします。出力の中に
前略
RCV:  | | X-- IAPREFIX 2400:4050:5c71:af00::/56
後略
このようにプレフィックスが表示されるので、その確認したプレフィックスを書き留めておきます。これをこちらで入力します。すると、
CE: 2400:4050:5c71:af00:99:f171:c600:2f00
IPv4 アドレス: 153.241.113.198

ポート番号:(1776-1791 2800-2815 3824-3839)
4848-4863 5872-5887 6896-6911
7920-7935 8944-8959 9968-9983
10992-11007 12016-12031 13040-13055
14064-14079 15088-15103 16112-16127
17136-17151 18160-18175 19184-19199
20208-20223 21232-21247 22256-22271
23280-23295 24304-24319 25328-25343
26352-26367 27376-27391 28400-28415
29424-29439 30448-30463 31472-31487
32496-32511 33520-33535 34544-34559
35568-35583 36592-36607 37616-37631
38640-38655 39664-39679 40688-40703
41712-41727 42736-42751 43760-43775
44784-44799 45808-45823 46832-46847
47856-47871 48880-48895 49904-49919
50928-50943 51952-51967 52976-52991
54000-54015 55024-55039 56048-56063
57072-57087 58096-58111 59120-59135
60144-60159 61168-61183 62192-62207
63216-63231 64240-64255 65264-65279
PSID: 47

注: 本当の値とは違う場合があります。

option peeraddr 2001:380:a120::9
(以下略)
というように、計算してくれます。さらにこれを、こちらこちらを参考に作ったシェルスクリプトに代入してやります。(貴重な情報を感謝します。)シェルスクリプトは以下のようにしました。(実際に動かす場合は、先頭の!/bin/sh以外の#と、iptablesのまえのechoを外してください。(##はそのままです。)そのほか、環境に合わせて適宜修正してください。)
追記 2023/03/25:CEアドレスをLANDEVではなくWANDEVに割り当てる様にスクリプトの一部を修正しました。
#!/bin/bash

## 2023/03/21: PFXをPrefixとPLENに分割
PLEN=56
PFX=2400:4050:5c71:af00::
## 2023/03/21: Gateway addr(suffix)を追加
GWS=1

BR='2001:380:a120::9'
CE='2400:4050:5c71:af00:99:f171:c600:2f00'
IP4='153.241.113.198'
PSID='47'
LANDEV='enp1s0'
WANDEV='enp2s0'
TUNDEV='tun0'

## TYPE: [ OCN | V6P ]
TYPE='OCN'

if [ "$TYPE" = "OCN" ]; then \
  lp=63
  skip=0
  lp=`expr $lp - $skip`
  if [ $PSID -ge 64 ] && [ $PSID -le 127 ]; then lp=$(($lp - 1));fi
  if [ $PSID -ge 128 ] && [ $PSID -le 191 ]; then lp=$(($lp - 2));fi
  if [ $PSID -ge 192 ] && [ $PSID -le 255 ]; then lp=$(($lp - 3));fi
  nxps=1024 # next port set

elif [ "$TYPE" = "V6P" ]; then \
  lp=15
  skip=0
  lp=`expr $lp - $skip`
  nxps=4096 # next port set

else
  echo Unknown TYPE: $TYPE
  exit 1
fi


##2023/03/23: CEをWANDEVに割り当てるようにしました
#ip -6 addr add $CE dev $WANDEV

##2023/03/21: GW addressを $PFX$GWS/$PLENにしました
#ip -6 addr add $PFX$GWS/$PLEN dev $LANDEV

#ip -6 tunnel add $TUNDEV mode ip4ip6 remote $BR local $CE dev $WANDEV encaplimit none
#ip link set dev $TUNDEV mtu 1460
#ip link set dev $TUNDEV up

#ip route delete default
#ip route add default dev $TUNDEV

#iptables -t nat -F
#iptables -t mangle -F

## 2023/03/27: 以下一行を追加(※1)
echo iptables -t mangle -o $TUNDEV -A POSTROUTING -j HMARK --hmark-tuple sport --hmark-mod $lp --hmark-offset 0 --hmark-rnd 0

rule=1

while [ $rule -le $lp  ] ; do
  mark=$rule
  pn=`expr $rule - 1`
  portl=`expr \( $rule + $skip \) \* $nxps + $PSID \* 16`
  portr=`expr $portl + 15`

## 2023/03/27: ※1 追加により、以下3行を無効化
## iptables -t nat -A PREROUTING -m statistic --mode nth --every $(( $lp -1)) --packet $pn -j MARK --set-mark $mark
## iptables -t nat -A OUTPUT -m statistic --mode nth --every $(( $lp -1)) --packet $pn -j MARK --set-mark $mark
## iptables -t mangle -A POSTROUTING -o $TUNDEV -m statistic --mode nth --every $lp --packet $pn -j MARK --set-mark $mark

echo  iptables -t nat -A POSTROUTING -p icmp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
echo  iptables -t nat -A POSTROUTING -p tcp  -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
echo  iptables -t nat -A POSTROUTING -p udp  -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
echo  iptables -t nat -A POSTROUTING -p sctp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
echo  iptables -t nat -A POSTROUTING -p dccp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr

echo
  rule=`expr $rule + 1`
done

#iptables -t mangle -o $TUNDEV --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu

## local messy setups below.

## and so on ...
なおBRは、(前述の計算サイトでBR(peeraddr)を表示してくれるとはいうものの)正しくは、レンタルルータのログで、IP encap(protocol number 4)を通信している所があるはずだということですが、ない場合はルータを工場出荷時にした直後に、例えば
ssh 153.241.113.198 -p 4848
のように、割り当てられたIPと割り当てられたポートのいずれかを指定してsshやcurl/wgetで通信すると"セキュリティログ(IPv6)"に表示されるので、レンタルルータは結果的に使用しなくても確認用途・緊急用途で必要だと思います。なお、当方の環境の場合、前出の計算サイトで表示されたpeeraddr(BR)はレンタルルータのログと同じaddressでした。
   67. 2019-01-01 14:35:58 SRC=2001:380:a120::9/- DST=2400:4050:5c71:af00:99:f171:c600:2f00/- 4 table=filter
さて、上述のシェルを起動すると、以下のようになります。(一部抜粋)
# 2003/04/16修正
iptables -t mangle -o tun0 -A POSTROUTING -j HMARK --hmark-tuple sport --hmark-mod 63 --hmark-offset 0 --hmark-rnd 0
iptables -t nat -A POSTROUTING -p icmp -o tun0 -m mark --mark 1 -j SNAT --to 153.241.113.198:1776-1791
iptables -t nat -A POSTROUTING -p tcp -o tun0 -m mark --mark 1 -j SNAT --to 153.241.113.198:1776-1791
iptables -t nat -A POSTROUTING -p udp -o tun0 -m mark --mark 1 -j SNAT --to 153.241.113.198:1776-1791
iptables -t nat -A POSTROUTING -p sctp -o tun0 -m mark --mark 1 -j SNAT --to 153.241.113.198:1776-1791
iptables -t nat -A POSTROUTING -p dccp -o tun0 -m mark --mark 1 -j SNAT --to 153.241.113.198:1776-1791

iptables -t nat -A POSTROUTING -p icmp -o tun0 -m mark --mark 2 -j SNAT --to 153.241.113.198:2800-2815
iptables -t nat -A POSTROUTING -p tcp -o tun0 -m mark --mark 2 -j SNAT --to 153.241.113.198:2800-2815
iptables -t nat -A POSTROUTING -p udp -o tun0 -m mark --mark 2 -j SNAT --to 153.241.113.198:2800-2815
iptables -t nat -A POSTROUTING -p sctp -o tun0 -m mark --mark 2 -j SNAT --to 153.241.113.198:2800-2815
iptables -t nat -A POSTROUTING -p dccp -o tun0 -m mark --mark 2 -j SNAT --to 153.241.113.198:2800-2815
...(中略)
iptables -t nat -A POSTROUTING -p icmp -o tun0 -m mark --mark 63 -j SNAT --to 153.241.113.198:65264-65279
iptables -t nat -A POSTROUTING -p tcp -o tun0 -m mark --mark 63 -j SNAT --to 153.241.113.198:65264-65279
iptables -t nat -A POSTROUTING -p udp -o tun0 -m mark --mark 63 -j SNAT --to 153.241.113.198:65264-65279
iptables -t nat -A POSTROUTING -p sctp -o tun0 -m mark --mark 63 -j SNAT --to 153.241.113.198:65264-65279
iptables -t nat -A POSTROUTING -p dccp -o tun0 -m mark --mark 63 -j SNAT --to 153.241.113.198:65264-65279
シェルスクリプトとこのiptables設定をみてわかるように、map-eは、基本的には、"mode ip4ip6"のトンネル つまり、ipip6トンネルで、パブリックIPアドレスをポート指定付きでSNATする、というのがMAP-Eの基本のようです。
また、プレフィックスは、上の例でいうと、2400:4050:5c71:af00::という/56のプレフィックス長+末尾8bit 00 でない場合、たとえば2400:4050:5c71:af3c::とすると、「入力値とCEとで/64が異なる」とのメッセージがでます。フレッツ光クロスがIPoEでサービスを開始し、DHCPv6-PDをつかい、かつ、/56のプレフィックスを配布するというのもここで納得できたところです。(IP通信網サービスのインターフェースより)
閑話休題。今回の設定は、上述のシェルスクリプトを/etc/rc.localから呼び出して起動させています。また、外側デバイス $WANDEV (enp2s0)のインターフェース設定は、
## 2023/04/14修正
#/etc/network/interfaces.d/enp2s0
auto enp2s0
iface enp2s0 inet6 manual
で大丈夫でした。
なお、DHCPv6-PDにて自動で(/etc/dhcp/dhclient-exit-hooks.d/以下にスクリプトを配置し)サブネットの構成をする場合はこの限りではありません。また、内側のLANインターフェース(enp1s0)の設定やフォワード設定、ファイアウォール設定、ULA/GUA変換、radvd設定等々は本稿では触れません。あしからずご了承ください。
それと、回線側からのra(router advertisement)は2,3分ごとに広報され、広報されるまでデフォルトルートが設定されずに通信できません。追記2021/03/16:raが下りてきてもデフォルトルートが設定されない場合があるようです。ですので、一旦デフォルトルートが判明すれば、スクリプトの ##local messy...以下でipv6のデフォルトルートを設定してやると早く確実に通信開始できます。なお対向のルータ(デフォルトルート)は、前述のdhclient -6 -d -P enp2s0でもわかります。
前略
RCV: Reply message on enp1s0 from fe80::wwww:xxxx:yyyy:zzzz.
後略
追記 2021/03/16:radvdumpでも対向ルータのアドレスがわかります。
前略
#
# radvd configuration generated by radvdump 2.18
# based on Router Advertisement from fe80::a653:XXXX:YYYY:ZZZZ
# received by interface enp1s0f1
#
後略

ところで、今回の設定をやってわかったことは、フレッツ光クロス/ぷらら/OCNバーチャルコネクトではrtt/latencyが非常によい、という点でした。
PS C:\WINDOWS\system32> ping -6 www.google.co.jp

www.google.co.jp [2404:6800:400a:80b::2003]に ping を送信しています 32 バイトのデータ:
2404:6800:400a:80b::2003 からの応答: 時間 =3ms
2404:6800:400a:80b::2003 からの応答: 時間 =3ms
2404:6800:400a:80b::2003 からの応答: 時間 =3ms
2404:6800:400a:80b::2003 からの応答: 時間 =2ms

2404:6800:400a:80b::2003 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 2ms、最大 = 3ms、平均 = 2ms
PS C:\WINDOWS\system32>
今回は以上です。それでは。

追記1:プライベートアドレスのパケット漏れとパケット分散に偏りがあった(Debian 10/Buster)のですが、/etc/sysctl.confにてエフェメラルポートの範囲をRFC6056と同じく1024から65535に設定すると、パケットがほぼ均等に分散がなされ、かつ、パケット漏れがほぼ収まりましたので、追記しておきます。
net.ipv4.ip_local_port_range = 1024 65535

2023/04/16追記:当方の環境だけかもしれませんが、Debian 12/Bookworm(2023/04/16現在はTest版)にバージョンアップしてから、起動後しばらくするとIPv6が切断され、結果としてIPv4も接続できなくなる症状が発生しました。/etc/sysctl.conf(.autoconf=0)の記述なども試してみたのですが、効果なしでした。そこで、interfacesを以下のようにしてみたのですが、今度はdhclientが起動されません。
#/etc/network/interfaces.d/enp2s0
auto enp2s0
iface enp2s0 inet6 dhcp
  accept_ra 2
  request_prefix 1
仕方ないので手動で以下のように dhclient(prefix delegation)を起動したところ
dhclient -6 -v -pf /run/dhclient6.enp2s0.pid -lf /var/lib/dhcp/dhclient6.enp2s0.leases \
-I -P -N -df /var/lib/dhcp/dhclient.enp2s0.leases enp2s0
接続断されなくなりましたので、この記述を/etc/rc.localの先頭(map-eスクリプトの前)に持ってくることで対処しています。

コメント

このブログの人気の投稿

Hyper-V Server2019にワークグループ環境下でWindows10(1809)から接続

Hyper-V server 2019に、ワークグループ環境にてWindows10(1809)から接続してみました。Windows10にHyper-V管理ツールがインストールされていることと、Hyper-V Serverをインストール済であることが前提です。以下、Hyper-V serverは名前がHyperVSV、アドレスは192.168.1.110としています。 まず、Hyper-V server上で、powershellを起動し、以下のコマンドを入力します。 Enable-WSManCredSSP -Role Server -Force 続いて、クライアントのWindows10のpowershell で以下のコマンドを入力します。 winrm quickconfig -Force Enable-WSManCredSSP -Role Client -DelegateComputer * -Force さらに、クライアントマシンで、gpedit(グループポリシーエディタ)を起動し、以下の要領でポリシーを設定します。 a. [コンピューターの構成]->[管理テンプレート]->[システム]->[資格情報の委任]->[NTLMのみのサーバー認証で新しい資格情報の委任を許可する] を有効にし、サーバを一覧に追加[表示...]ボタンをクリックして、「WSMAN/*」を追加 b. [コンピューターの構成]->[管理テンプレート]->[システム]->[資格情報の委任]->[NTLM のみのサーバー認証で保存された資格情報の委任を許可する] を有効にし、サーバを一覧に追加[表示...]ボタンをクリックして、「*」を追加 また、名前解決できるように、(notepadを管理者権限で実行し)C:\Windows\System32\Drivers\etc\hostsにサーバ名とIPアドレスの対を追加。 192.168.1.110 HyperVSV 最後に、Hyper-Vマネージャーを起動し、Windows10からHyper-V サーバに接続します。手順は以下の通りです。 「サーバーに接続」->コンピュータの選択->別のコンピューターに[HyperVSV]と入力し、[別のユーザーとして接続する

wsdd を使ってSamba サーバをネットワークに表示

Windows 10のアップデートで、セキュリティー対応のため、smbv1がデフォルトではインストールされなくなり、Samba serverがエクスプローラーのネットワークに表示されなくなってしまいました。そこで、いくつか方法を調べたのですが、linuxでwsdの実装がないか探したところ、 https://github.com/christgau/wsdd が、見つかりましたので、さっそくインストールしてみました。まだパッケージにはないようですが、インストール自身は簡単です。wsdd自体は以下のように取得し、linkを張っておきます。 cd /usr/local/bin/ sudo wget https://raw.githubusercontent.com/christgau/wsdd/master/src/wsdd.py sudo chmod 755 wsdd.py sudo ln -sf wsdd.py wsdd こちらのsambaサーバはDebianなので、/etc/systemd/system/wsdd.serviceは以下のようにしました。 [Unit] Description=Web Services Dynamic Discovery host daemon Requires=network-online.target After=network.target network-online.target multi-user.target [Service] Type=simple ExecStart=/usr/local/bin/wsdd -d MYDOMAIN [Install] WantedBy=multi-user.target wsdd -d MYDOMAINのところを、環境にあわせて書き換えてください。 次に、systemdに登録・起動テストを行います。 systemctl enable wsdd systemctl start wsdd 起動に成功すると、エクスプローラーのネットワークに表示されます。  なおこのwsddはpython3が必要です。一度試してみてください。SMBv1/CIFSを停止していても、大丈夫です。 cで書かれたほかのwsddの実装もあるようなので、いずれパッケージになるかもしれませ