【Network】InterlinkのZOOT NATIVE IPv4固定IP1個をDebianから使う 
 現在この環境にはNuroや今まで通りのPPPoE接続やZOOT NATIVEによるDS-Lite接続など、複数のネットワークを利用しているのですが、固定IPのためのPPPoEセッションがまともに使えるような速度でなくなってきたため、ZOOT NATIVE IPv4固定IP1個というサービスが開始されたのでこちらのサービスに変更しようと思っていました。
 しかし、いまいち使っているトンネルなどの仕様がよくわからず、動作対象外のOSで接続するにはどうすればいいのかがはっきりしなかったため二の足を踏んでいたのですが、人柱になろうと覚悟を決めて契約してみました。

tr;dr


・トンネルとしてはipip6トンネルを利用している
・oepnwrt、pfsense、opensenseといったメジャーどころは現状トンネル形式がipip6に対応していないっぽい
→pfは行けました
・vyarttaは多分イケそうだけど検証してない
・トンネルを張る前にv6網内のWebサーバにcurlなどでクエリを飛ばす必要がある
・ip token set ::feed dev ens192など、Interface IDを指定する必要がある
・Debianだと/etc/network/interfacesの中で完結できないため、いくつかスクリプトをかませる必要があった
・IPv6の再配布やルーティングは今回は考慮していない
設定方法まとめまで飛ぶ

何故保証外のOSを使いたかったのか


 そもそも何故おとなしく動作検証済みの機器を使わなかったかというと、OpenWRTやpfsense/OpenSenseなど、仮想環境で動くOSを利用したかったのです。
 仮想環境で動くものについては、CPUやNICなどの物理HWで殴ればそれに応じてネットワークを速くできること、物理的なネットワーク機器より安価にある程度の性能は達成できること、ハードウェアに縛られないので様々な入れ替えが効くといったメリットが大きく、昔は色々物理ネットワーク機器が動いていましたが、今はすべて仮想環境に集約してしまいました。

 そのため、今は動いているネットワーク機器というとスイッチとAPくらいしかありません。頑張って物理を減らしたのにその逆行をしたくなかったのです。

契約してみた


 契約するとこのような情報がきます。



 さて、この情報だけだとなかなかどうしたらいいかわかりません。なんもわからんので色々調べてみます。

そもそもどうすればつながるのかを調べる


 Univerge IXシリーズの設定例を見ると、どうやら4-over-6というトンネル形式を使っているようなので、これをサポートしているか色々調べてみました。トンネルにIPv4を設定するのにデフォゲアドレスを設定せずにデバイスを指定するのがなんとも違和感がありましたが、そういうものみたいです。DS-Liteの場合は192.0.0.2がB4(ルーターのトンネル内v4IP)で192.0.0.1がAFTER(トンネル先のIP)アドレスとして振られるので何となく分かるのですが、これでいいのかちょっと不安でした。

 transixのページを見てみると、こちらにはIPIPトンネルを利用しているという記述があるので、これらのキーワードで色々調べてみます。

pfsenseの対応


 pfsenseにはgreやgifトンネルを張る機能があるので僅かな可能性ながら行けるかと思いましたが、どうやらできないようです。DS-Liteを使おうとしたときも同じだったのでうっすらわかっていましたが。。いつか対応してくれると嬉しいのですが。
 →pfsenseについては接続できたので訂正します。

OpenWrtの対応


 OpenWrtはDS-Liteのトンネルを張るのに一番かんたんなOSでしたが、それ以外にも色々対応しているので行けるだろうと思っていました。しかし、対応するプロトコルには4-over-6はありませんでした。 6to4(IPv6-in-IPv4Tunnel)はあるのですが、欲しいのは逆なんだよなあ…。。IPIPトンネルもあるのですが、これはv4アドレス同士のトンネルを張るためのプロトコルで、v6アドレスを設定することはできませんでした。
 調べてみるとDebianでのチュートリアルがあったのでip -6 tunで設定できるかと思いましたが、どうやら入っているのはiproute2ではなくiproute1(もしくはBusybox的な何か?)が入っているようで、ip -6 tun addネームスペースは実装されていませんでした。Linux自体は対応しているので、需要が増えてくれば対応してくれる気もしますが、現状どうやってもトンネルは作れませんでした。

Vyattaの対応


 対応しているトンネル方式一覧にはあるので、多分問題なく行ける気がします。しかし、コントリビューター以外がダウンロードできるのはdailyのバッチビルドのOSのみで、個人的な経験ですがdd-wrtやpfsenseなどでdailyビルドについてはあまりいい思い出がないので導入をためらってしまいました。

 どれも微妙な状況だったので、どうしようかなあと思いましたが、Debianでのチュートリアルがあるので、一旦素のDebianでまず接続ができるかどうかを試してみることにしました。iptablesはよく忘れるので、できればWebUI持ってるOSが良かったのですが。CentOS?なんで家でまで社畜しないといけないんですか…。

Debianで接続を試してみる


 チュートリアルにあるように、まずは割り振られたIPをそのまま使って接続を試してみます。

ip l add link ens224 name vlan1000 type vlan id 1000
ip -6 tun add sit1 mode ipip6 local <自動でもらったIPv6> remote 2404:8e00::feed:140 dev vlan1000
ip link set dev sit1 up
ip a add dev sit1 <割り振られたIPv4>
ip route add default dev sit1

 さて、これでping 1.1.1.1などを試してみますが、案の定通信できません。

いろいろ調べてみる


 調べてみると、先駆者の方がいたので色々参考にしました。
https://y2web.net/blog/inet/now-available-fixed-ipv4-service-in-interlink-8229/
 こちらの方が調べたように、特定のURLに対してクエリを飛ばす必要があるようです。試しにcurlで突っついてみます。ここでやっとユーザーとパスワードの出番が来ます。

curl "http://update.transix.jp/request?username=<もらったユーザーID>&password=<もらったパスワード>"

 しかし、RAだけだとDNSまでもらえないので、update.transix.jpが引けませんでした。DS-Lite で接続しているOpenWrtでは引けたので、そちらでDNSを引いて直接IPにして実行しました。IPは変わる可能性があるので直接指定はおすすめしませんが、まずは接続を確立したいので一旦直接指定で進めます。

curl "http://[2404:8e00::feed:400]request?username=<もらったユーザーID>&password=<もらったパスワード>"
→OK

 OKが帰ってきたので行けるだろうと思いましたが、まだ駄目でした。上記ブログにあるように、どうやらアドレスを::feedにしないといけないようです。インターフェースIDってそういうことか…なんでそういう事するの…

ip -6 add add <割り振られたPrefix>::feed/64 dev vlan1000
ip -6 add del <RAでもらったIPv6> dev vlan1000
curl "http://[2404:8e00::feed:400]request?username=<もらったユーザーID>&password=<もらったパスワード>"
→OK

 この状態でping 1.1.1.1などを実行すると、ようやく応答が帰ってきました。やったぜ。

再起動後にも自動接続をするようにしたい


 接続は確立できたので、今回手でやった部分をうまくOSの仕組みに組み込んでいきます。 まずはDNSが引けないところとIPv6を手打ち指定しているところがイケてないので、これらをどうにかします。シェルスクリプトで組んでしまえばなんとでもなりますが、できればそれを避けてOSの標準機構で処理させていきたいと思うので更にいろいろ調べます。

 DNSをもらうためにはDHCPを受ける必要がありますが、inet6 dhcpを指定するとSLAACではなくステートフルDHCPv6で受けようとしているのか、ifupのときに永遠に何かを待ち続けてしまうので、公式マニュアルを参考にSLAACを受けるために以下の設定が必要でした。

#---/etc/network/interfaces---
auto ens224.1000
iface ens224.1000 inet6 auto
dhcp 1
accept_ra 1

 この設定でifup時に/etc/resolv.conに必要な情報が更新されるようになったので多分合ってる気がするのですが、正直あっているのかいまいち自信がありません…。しかし、これだけではアドレスがfeedにならないので、疎通時にホスト部を指定するためにはどうすればいいかと調べてみると、ip token set ::feed dev <IPv6を受けるインターフェース名>と指定すればいけるようでした。

 ただ、これを標準のオプションで指定する方法はないようなので、pre-upで指定するしかありませんでした。

#---/etc/network/interfaces---
auto ens224.1000
iface ens224.1000 inet6 auto
dhcp 1
accept_ra 1
pre-up /sbin/ip token set ::feed dev ens224.1000

 とりあえずこの設定でIPv6周りの設定は再起動後も要件を満たすようになりました。ちなみに受け取ったDNSは以下でした。

#---/etc/resolv.conf---
search flets-east.jp. iptvf.jp.
nameserver 2404:1a8:7f01:b::3
nameserver 2404:1a8:7f01:a::3


 次にトンネルの部分ですが、これが問題でした。Debian 10に入っているifupではインターフェース種類にinet6 tunnelを指定できなかったため、ifup2パッケージを入れ以下の設定をしましたがだめでした。

auto sit0
iface sit0 inet6 tunnel
mode ipip6
dev ens224.1000
local <割り振られたPrefix>::feed
remote 2404:8e00::feed:140
address <割り振られたIPv4>
post-up /sbin/ip route add default dev sit0
post-down /sbin/ip li del sit0

 トンネルはできるのですが、元になるインターフェース(dev ens224.1000の部分)がうまく入らないため、sit0@NONEというインターフェースが出来上がり、またlocalのIPも指定したものが入りませんでした。

 そもそもPrefixが変わってもip tokenで対応できるようにしたのに、localを直接指定するのがイケてないですね…。いろいろ調べたのですが結局解決できなかったなめ、ifup2を消してifupを入れ直し、以下のスクリプトで対応することにしてしまいました。

# --- mkv6tun.sh ---
#!/bin/bash
PATH=$PATH:/usr/sbin/
DEV="$1"
TUN="$2"
REMOTE="2404:8e00::feed:140"
IPADDR="<もらったIPv4>"
LOCAL=`ip -6 a s dev $DEV|sed -nr "s/^\s+inet6 ([^(fe80)][0-9a-f:]*)\/.*/\1/p"`
USER="<もらったユーザーID>"
PASS="<もらったパスワード>"

ip -6 tun add $TUN mode ipip6 local $LOCAL remote $REMOTE dev $DEV
ip l se up $TUN
ip l se mtu 1460 dev $TUN
ip a ad dev $TUN $IPADDR
ip r add default dev $TUN

while :; do
ping -c1 -w1000 update.transix.jp
if [ $? -ne 0 ] ; then
sleep 1
else
logger update url: `/usr/bin/curl -s "http://update.transix.jp/request?username=${USER}&password=${PASS}"`
break
fi
done&


 このスクリプトは引数に "元になるインターフェース" "作りたいトンネル名"を指定するとよしなにやってくれます。curlのところは実際に通信が通るようになるまでちょと時間がかかるので、それをバックグラウンドでやるための処理です。それをしないとsystemdがいつまでもその処理を待ってしまうのでそれの対応です。

 まあ、割り振られるPrefixが変わることはそうそうないので、一度実行すればしばらくは不要な気もしますが、念の為実行するようにしました。思いつきで5分くらいで作ったスクリプトなので雑ですが、とりあえず動いているので大丈夫そうです。これをinterfacesのpost-upに組み込みます。

#---/etc/network/interfaces---
auto ens224.1000
iface ens224.1000 inet6 auto
dhcp 1
accept_ra 1
pre-up /sbin/ip token set ::feed dev ens224.1000
post-up /opt/script/mkv6tun.sh ens224.1000 sit0

 再起動後、curl checkip.amazonaws.comなどで指定したIPが返答されることを確認したら、無事に自動起動の設定が完了です。ここにくるまでに2日かかってしまいましたが。

iptablesを書く


 そのままではルーターにならないので、NATをするためのiptabesを書きます。/etc/sysctl.confにnet.ipv4.ip_forward=1を追記した後、sysctl -pで反映させる必要があります。iptablesについては一般教養だと思うのであまり深く書きませんが、参考設定としてiptables-saveの出力をおいておきます。ens192というのが内部のLANインターフェースという想定で、内部からの接続はガバガバに受け付けます。

#---/etc/iptables.up.rules---
*nat
:PREROUTING ACCEPT [889:57084]
:INPUT ACCEPT [60:10005]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o sit0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT
*filter
:INPUT DROP [32:1744]
:FORWARD ACCEPT [1643:1853819]
:OUTPUT ACCEPT [360:64590]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -i ens192 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A FORWARD -i ens192 -j ACCEPT
COMMIT

 -A POSTROUTING -o sit0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuが重要で、これをしないとMTU不整合で見えないページが出てきたりします。iptables < /etc/iptables.up.rulesで設定を反映させます。

 v6の方もガバガバなので多少締めます。 2404:8e00::feed(Transixのトンネル先)からの接続はガバガバに受け付けます。必要最低限に絞る作業に疲れました。

#---/etc/ip6tables.up.rules---
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1570:205385]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -s fe80::/10 -d fe80::/10 -p udp -m state --state NEW -m udp --sport 547 --dport 546 -j ACCEPT
-A INPUT -s 2404:8e00::feed:140/128 -j ACCEPT
-A INPUT -p icmp6 -j ACCEPT
COMMIT

 -A INPUT -s fe80::/10 -d fe80::/10 -p udp -m state --state NEW -m udp --sport 547 --dport 546 -j ACCEPTが重要で、これを指定しないとDHCPv6を受け付けられません。ハマりました。こちらもip6tables </etc/ip6tables.up.rules で反映させます。

 これらの設定をifup/ifdown時に反映させるために、/etc/network/if-pre-up.d/iptablesというスクリプトを作成します。+xで実行権限を付けないと反映されないので注意です。あとシバン(#!/bin/bash)も忘れず指定してください。

#---/etc/network/if-pre-up.d/iptables---
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules
/sbin/ip6tables-restore < /etc/ip6tables.up.rules

 これで無事に何度再起動してもルーターとして自動起動してくるようになります。長かった。

作業の要約


 長くなってしまったのでまとめます

ipip6トンネルを作成するためのスクリプト作成


/opt/script/mkv6tun.shなどとして作成します。chmod +xで実行権限を与えるのを忘れずに

#!/bin/bash
PATH=$PATH:/usr/sbin/
DEV="$1"
TUN="$2"
REMOTE="2404:8e00::feed:140"
IPADDR="<もらったIPv4>"
LOCAL=`ip -6 a s dev $DEV|sed -nr "s/^\s+inet6 ([^(fe80)][0-9a-f:]*)\/.*/\1/p"`
USER="<もらったユーザーID>"
PASS="<もらったパスワード>"

ip -6 tun add $TUN mode ipip6 local $LOCAL remote $REMOTE dev $DEV
ip l se up $TUN
ip l se mtu 1460 dev $TUN
ip a ad dev $TUN $IPADDR
ip r add default dev $TUN

while :; do
ping -c1 -w1000 update.transix.jp
if [ $? -ne 0 ] ; then
sleep 1
else
logger update url: `/usr/bin/curl -s "http://update.transix.jp/request?username=${USER}&password=${PASS}"`
break
fi
done&


/etc/network/interfacesの追記


 今回はens224のVLAN1000がWANになるNICですが、よしなに変えてください。post-upで上のスクリプトを指定します。

auto ens224.1000
iface ens224.1000 inet6 auto
dhcp 1
accept_ra 1
pre-up /sbin/ip token set ::feed dev ens224.1000
post-up /opt/script/mkv6tun.sh ens224.1000 sit0
post-down /sbin/ip li del sit0


iptables周りの設定


 NAT/パケットフォワーディングの設定を書きます。昔ながらのiptables-save形式ですが、他にも方法があればそちらでもいいと思います。ens192がLANインターフェースという想定です。
/etc/iptables.up.rules


*nat
:PREROUTING ACCEPT [889:57084]
:INPUT ACCEPT [60:10005]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o sit0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT
*filter
:INPUT DROP [32:1744]
:FORWARD ACCEPT [1643:1853819]
:OUTPUT ACCEPT [360:64590]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -i ens192 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A FORWARD -i ens192 -j ACCEPT
COMMIT


/etc/ip6tables.up.rules

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1570:205385]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -s fe80::/10 -d fe80::/10 -p udp -m state --state NEW -m udp --sport 547 --dport 546 -j ACCEPT
-A INPUT -s 2404:8e00::feed:140/128 -j ACCEPT
-A INPUT -p icmp6 -j ACCEPT
COMMIT


/etc/network/if-pre-up.d/にiptablesというスクリプトを作成します。+xで実行権限を付けないと反映されないので注意です。あとシバン(#!/bin/bash)も忘れず指定してください。

/etc/network/if-pre-up.d/iptables

#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules
/sbin/ip6tables-restore < /etc/ip6tables.up.rules


測定結果


 速度の測定結果は以下です。
https://beta.speedtest.net/result/9878034837



 PPPoEは下り30Mbps程度しか出ないことも多々あったのでだいぶ良くなったと思います。まあPPPoEも最初は数百Mbps出ていたので、こちらもトンネル先が詰まるまでの時間の問題かもしれませんが…。

 測定中の負荷は、Xeon 2695v2の上で動くVM(2vCPU/2GB/vmxnet3)ですが、atopで見ている限り1コアあたり20%程度irqに持っていかれる程度で、1Gbps環境では大した負荷ではないようです。まあiptablesにルールも大したこと書いてないので、これが増えてきたらどうなるかわかりませんが、最近の高クロックなCPUなら全く問題ないと思います。組み込み向けのCel N3000などでも物理で動かす限りは1Gbps程度なら問題ないと思います。

まとめ


 現状ではお手軽に、とは言えないものの、仮想環境(Linux)でもZoot Native 固定IP1を使うことは可能だとわかりました。transix IPv4接続(固定IP)形式を利用しているのであればほかでも同様だと思います。10G クロスの契約をしてもこの方法は使えそうですね。

 ただ、苦労をしたくないのであれば動作検証済みのネットワーク機器を入れるのがいいかと思います。実際途中で心が折れて中古のIX2106あたりを買おうかと思いました。あと少しで動きそうだけどなにかが足りない、という状況は、解決できないけど諦めもつかないという一番泥沼状態になりやすいですね。後半の動機は意地でした。

 Shorewallなどの検証もしてから切り替えようかと思ってるので実運用はまだできていませんが、いずれ切り替えていきたいと思います。固定IP1を契約した状態であっても(サポート的にはどちらか一方という回答をもらったものの)DS-Lite は利用できるので、併用して使っていくのはありだと思いました。

おわり

[ 6 コメント ] ( 217 回表示 )   |  このエントリーのURL  |  $star_image$star_image$star_image$star_image$star_image ( 2.5 / 60 )  |  

<戻る | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 進む> 最後へ>>