CentOS7でOCNバーチャルコネクト

更新履歴

2020/6/27 2.5 性能 を追加。CentOS8用のスクリプト注釈追記
2020/6/20 スクリプト修正、CentOS8用のスクリプト、ポートフォワードの設定例追加等
2020/3/23 ポート数を間違っていたのでスクリプトを修正

まえおき

前回 IPv4(PPPoE) + IPv6(IPoE) の環境を作りました。今回はさらにIPv4 over IPv6を追加して、IPv4なインターネットもIPoEを使えるようにしたいと思います

Linuxの知識もネットワークの知識もセキュリティの知識もない素人なのでつっこみどころがあるのはご容赦ください

今回接続までできていますが、仕様が変わってこの記事通りにやっても接続できなくなるがあります。ご了承ください

OCNについて

私のプロバイダはOCNなのですが、OCNは仕様がちょっと特殊で、2種類の回線が使われているようです。IPv6のグローバルアドレスの先頭4桁が「2409」のものと、「2400」のものです

OCNバーチャルコネクトが使えるのは「2400」の場合だけのようです。「2409」の方は残念ながら使えないとのこと

v6アルファ(OCNバーチャルコネクト+ルーターレンタル+サポート / 月500円)に申し込めば「2409」の方も「2400」に変わるようです

元々「2400」な方は、OCNバーチャルコネクト対応のルーターを用意するか、今回の記事のように少しがんばればv6アルファに申し込まなくても無料で IPv4 over IPv6 が使えます。不公平だなあ><

「2409」な方は今回の記事の内容のことをしても多分使えません…。少しずつ「2409」の人も「2400」に切り替わっていってるという話もあるので、待ってれば変わるかもしれません

環境

  • 回線:フレッツ光ネクスト
  • プロバイダ:OCN
  • ひかり電話なし、HGWなし
  • IPv6グローバルアドレス先頭「2400」

目標

IPv4(PPPoE) + IPv6(IPoE) から IPv4(PPPoE) + IPv4 over IPv6(IPoE) + IPv6(IPoE) にします。

今回もセンスのない図。IPv4 と IPv4 over IPv6を両立させ、ほどほどに都合よく使い分けるようにします。LAN下のすべての端末が使い分けられるようにします。一応hostapdも使っていて、無線LANのAPとしても機能しています

手順

OCNバーチャルコネクトはv6プラスと同じくMAP-Eです。v6プラスは割り当てられるポート数が240個なのに対し、OCNバーチャルコネクトの場合は960個?

参考サイト様

http://ipv4.web.fc2.com/map-e.html
https://gato.intaa.net/archives/13186
https://blog.babibubebo.org/archives/1269

必要な計算を自動でやってくれているサイト様、v6プラスの手順をわかりやすく解説してくれているサイト様、OCNバーチャルコネクトの仕様を解析してくれているサイト様、です

計算で得た情報とOCNの仕様をv6プラスの手順にあてはめるだけの簡単なお仕事です。感謝しながら進めていきたいと思います

BRのアドレスやマッピングの仕様なんかは簡単に変えられるようにできている気がしなくもないので、いつまで以下の方法が有効かは不安なところ…

計算

http://ipv4.web.fc2.com/map-e.html

にアクセスし、IPv6のグローバルアドレスをいれるだけです。いつの間にやらOCNバーチャルコネクトにも対応したようで、BRのアドレスも出してくれるようになりました

スクリプト

適当なお名前で

CentOS7の場合

CentOS7の場合、というかnftablesが導入されてない、firewall+iptablesの環境の場合

https://gato.intaa.net/archives/13186

こちらの参考サイト様のを参考にfirewalld、OCNバーチャルコネクト向けに書き直したものです。CE、IP4、PSIDはさきほど調べたものをいれます。ダイレクトルールの優先度は適当に…

元は匿名掲示板の方のスクリプトだったようですが、たった数行で分割されて割り当てられるポート番号を偏りなく使われるようになってて、強い人は凄いなあって素直に思います。ありがたく使わせていただくとします

32行目でゾーンに突っ込んでますが、ゾーンに登録しない方は32行目をコメントアウトして33行目等を使ってLANからトンネルへのフォワードの設定を追加するなどしてください

OCNバーチャルコネクト以外の、v6プラスなどのMAP-Eの場合はloop数を15に、1024となっているところ4096にすれば対応できると思います

実行権限をつけて実行

確認します

勝手にできる「ip6tnl0@NONE」と「ip6tnl1@enp2s0」ができています。enp2s0は私のWAN側のデバイス名です

ゲートウェイの確認

デフォルトゲートウェイが今作ったトンネルになっているか確認します

CentOS8の場合

CentOS8の場合、というよりfirewalld+nftablesの環境の場合、firewalldのダイレクト設定から設定しようとしてもうまくいきません

firewalldのバックエンドをiptablesに変更すると、nftablesへの変換の担当がfirewalldからiptablesに変わりますが、それでも解決しません

どちらもmode nthを使う記述をnftablesでも問題なく運用できるように変換してくれないようです

たとえばfirewalldのダイレクトルールをこのように設定してみると

nftablesにはこのように変換されますが、これだと動作が不安定で、mapを使って記述しないと安定しないようです

イメージとしてはこんな感じの設定にならないとダメみたいです。nftコマンドを使って直接nftablesを設定しないといけません

ということで、CentOS8の場合、現状firewalldだけでは安定したOCNバーチャルコネクト環境を構築できません。firewalldやiptablesでの変換か、nftables自体に更新が必要だと思われます

CentOS8.2でもダメなままだったので、nftablesを直接操作して構築する手段をとることにしました

https://qiita.com/kakinaguru_zo/items/2764dd8e83e54a6605f2

こちらでもやってる方がいらっしゃいます

参考にさせていただきながら、私はmode nthの部分だけnftablesを直接設定して、firewalldでも問題ない部分はfirewalldで設定してみることにしました。バラバラに設定するのは良いとは思えないのですが仕方なく。。。

※firewalldのバックエンドはiptablesを使ってます。nftablesの場合は19行目の「POSTROUTING_direct」を「POSTROUTING」に変えると良いと思います(未確認)

これでCentOS8でも安定したOCNバーチャルコネクト環境になりました

こちらもv6プラス等のMAP-Eの場合は、loopを15に、1024となっているところを4096にすれば対応できると思います

確認

https://v6test.ocn.ne.jp/

OCNの公式サイトで確認できます。IPv4とIPv6の両方がIPoEになっていたら成功です

IPv4がつながらない

先ほどのスクリプトではexternalゾーンに登録するようにしたので、externalゾーンのマスカレードの設定がされているかどうか、またはLANからトンネルデバイスへのフォワードの設定がされているか、確認します

原因がよくわからないならひとまずゲートウェイを戻してゆっくり原因を探します

IPv6がつながらない

接続できていたはずのIPv6がつながらなくなっている場合は、IPv6のルートを確認します

2400からはじまるアドレス宛にWAN側デバイスからのメトリックが小さいルートができてしまっていたら削除します

削除したら再確認

OCNバーチャルコネクトの設定はここでおしまい

IPマスカレードの確認

iptables

CentOS7の場合。またはCentOS8でfirewalldのバックエンドをiptablesにしている場合。Chain POSTROUTING_directの部分で、各ポートブロックにパケットが振り分けられているのを確認できます

nftables

CentOS8の場合

conntrack

conntrackコマンドでIPマスカレードの様子を確認できます

インストール

IPv4のアドレスはさっき調べた奴を。IPv4 over IPv6のグローバルIPになります。webブラウザで新しいページを開いてみたりすれば増えていきます。dportを見れば割り当てられたポート番号だけ使っているのも確認できます

性能

NATにも複数種類があることを今回知ったくらいの素人なので、的外れな見解になってしまうかもしれませんが、動作を詳細に確認してみます

先日500MB超の動画(mp4)をトップページに配置して話題になったニチバンのサイトですが、セッションバカ食いサイトとしても有名だそうで、MAP-Eのパフォーマンスを確認するベンチマークサイトとしても定評があるようです

先のスクリプトのループ数を1にして、ポートを16個しか使えない状態にします(私の場合1680番~1695番)

その状態でニチバン様のサイトを数ページまわってみたときの様子を見てみました

16個のポートがすぐにもっていかれ、たちまちニチバンのサイトが開けなくなりました。すごい…。1684番が1回重複してるのが気になりますが、よくわからないのでスルーします

ニチバンのサイトは開けなくなりましたが、すぐ他のサイトにアクセスしてみるとアクセスできました

宛先が違えばすでに使ってるポート番号を重複利用できるようです

YAMAHAの古いルーターでMAP-Eをやるとすぐポートが枯渇してしまうのでポートセービングIPマスカレードがないと実質使えない、という話を聞きます。YAMAHAの場合

動作タイプ1 では、基本的に異なるセッションについてはそれぞれ異なる外側ポート番号を順に割り当てていくため、IPマスカレードで管理可能なセッション数は、ほぼ使用できる外側ポート番号の個数で頭打ちになります。

一方、動作タイプ2 のときはポートセービングIPマスカレードで外側ポートが割り当てられるため、使用している外側ポート番号の個数が少ない場合でも合計のセッション数は非常に多くなる可能性があります。

ポートセービングIPマスカレード仕様でポートを割り当てる動作タイプ2 のTCPセッションについては、この特殊なポート番号割り当てポリシーは適用されず、 単純にそれぞれの宛先ホストに対して使える外側ポート番号を順に割り当てていきます。

とのことです。今回動作タイプ2(ポートセービングIPマスカレード)のようにぞれぞれの宛先ホストに対してポート番号を割り当てて、ポート数以上のセッションを張れることを確認できたので、ポートの枯渇に関しては気にしなくてよさそうです

それにOCNバーチャルコネクトなら、ポート数も他サービスの240個ではなく1008個と多く割り当てられますしね

ポートフォワード

OCNバーチャルコネクト側のグローバルIPでサーバーが立てる手順を確認します

http://ipv4.web.fc2.com/map-e.html

ポート番号はこちらでも確認できます

例えば、私の場合は最初のブロックが1680-1695です

OCNバーチャルコネクトのグローバルIPアドレスのポート番号1680へのアクセスを、192.168.1.10の80(Webサーバー)に転送する設定例です

https://www.cman.jp/network/support/port.html

OCNバーチャルコネクトの方のグローバルIPとポート番号を組み合わせて確認

使い分け

ここからは IPv4(PPPoE) と IPv4(IPoE) と IPv6(IPoE) の使い分けについて考えます。IPv6についてはIPv6のアドレスとのやり取りになったら自動で使い分けられるのでIPv4の使い分けについて考えます

1つのルーターで両方出してる環境向けの話なので、そうじゃない方には参考にならないと思います

高速なIPoE、自分専用のPPPoEの2つ。こんなことできたらいいな、と思いつたことをちょっとやってみました

デフォルトゲートウェイをIPoEの方にして、条件によって一部PPPoE側からパケットを流していく、なんてことをしてみましょう

私の例ではインターフェイス名は

ppp0:PPPoE用のIF  ip6tnl1:IPv4(IPoE)用のIF  br0:ルーターのLAN側のIF

とします

下準備

ゲートウェイを条件によって変える場合はまずrp_filterの設定を変更します

この1行を追加

反映させます。これやっておかないとiptablesの挙動がぐちゃぐちゃになります。ドハマりしてしまいました。マークうつだけでフォワードしなくなるとかとにかく色々おかしなことになります

デフォルトゲートウェイをPPPoE側に設定したサブルートテーブルを作っておきます

ppp0をデフォルトゲートウェイとする10番テーブルを作りました

一応確認。条件を満たしたパケットだけこの10番テーブルを使わせてppp0からパケットを流す、という方針です

マーク値が1000だったら10番テーブルを使うよ、というルールを作ります。マーク値は後でiptablesで使います。MAP-Eのポート割り当てのときも使っていましたね

一応確認

マーク値が16進数になってますがまぁ気にしない気にしない

PPPoEのグローバルアドレスでサーバーをたてる

普段のネットサーフィンはIPoEの方で、だけどサーバーはポート番号を自由に使えるPPPoEで建てたい、なんてこともあると思います

たとえばポート8080番でWebサーバーをたてたとします。

http://<PPPoEのIPv4アドレス>:8080/

とアクセスしてもアクセスできません。デフォルトゲートウェイがIPoE側なので、PPPoEの方にアクセスがあってもIPoEから返事が出されてしまいます

NG例

図でいうとこんな感じになってしまうんですね。PPPoE側とIPoE側でIPv4のグローバルアドレスが違うので、別の人から返事が出されてる!ってことになって届きません

ということで、外部からPPPoEの方にアクセスがあった場合は、PPPoEの方から返事を出すようにします

この例では優先度は適当に100にしました。マーク値はさっき作ったルールに合わせた1000です。ppp0は私のPPPoE用の、br0は私のLAN側のIF名。適宜直してください

私はど素人なので解説なんてものはまったくできないのですが、雑に言語化します

1行目は、ppp0から入ってきたパケットはルーティング判断の前にコネクションマーク1000をうつよ!って感じだと思います

2行目は、このルーターのアプリケーションで処理したパケットについてるコネクションマークを普通のマークに戻すよ!って感じだと思います。ppp0から入ってきたパケットだけコネクションマーク1000がついてるので、ppp0からのアクセスのみマーク1000が立ちます。ルーティングテーブルが通常のものから10番テーブルのものに変わるので戻りはppp0から戻ります

3行目は、LANから流れてきたパケットについてるコネクションマークを普通のマークに戻すよ!って感じだと思います。ppp0から入ってきて、LANにある別のサーバーに転送されて、戻ってきたものがこれでマーク1000が立ち、10番テーブルを使うようになります

2行目はルーターにあるサーバーアプリ用、3行目はLANにある別のサーバー用の記述ってことですね。ルーターでサーバーを立てていなければ2行目は不要です。これでppp0側の<PPPoEのIPv4アドレス>へのアクセスに正しくppp0から返信できるようになります

コネクションマークとマークはどう違うんだとかそういうのはぐぐってください。私もわからないのです

こんなイメージでしょうか。赤のPPPoEは外部からサーバーへのアクセスの専用回線になります。赤の戻りもppp0から出てるようにした方が正しい図なんですが、見た目が不格好になるので…

https://www.cman.jp/network/support/port.html

PPPoEの方のグローバルIPとポート番号を組み合わせて確認

特定の端末だけPPPoEを使わせる

そもそもサーバーだから受信しか考慮しないPPPoEだけで十分だ、ゲーム機なので一部のポート番号しか使えないMAP-Eじゃ困る、とかそんなときはIPアドレス指定でして割り振っちゃいましょう

LAN側の192.168.1.55からのパケットはマーク1000を打ってsubテーブル使うようにします=PPPoEを使いますよってことですね

試しにNintendo Switchに対してやってみましたが、接続テスト結果の「NATタイプ」がDからBに変わりました。オンラインゲームはしないので実際のゲームに問題があるかどうかまではチェックしてません

PS4もMAP-Eとは相性が悪いと聞いたことがあるので、ゲーム機はオンラインプレイをするならとりあえずPPPoE側にまわしてしまってもいいんじゃないでしょうか

余談ですが、Nintendo SwitchのNATタイプは、PPPoE側を使うようにした上で

このようにUDPをSwitchに転送するように設定すればAになります

iptablesがわかればもっと自在に振り分けられるようになると思います。私はわかりません

http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/index.html
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/traversinggeneral.html

感想

PPPoE用とIPoE用でルーターを2台用意する必要もなく、PPPoEしか使えない端末がIPoEしか使えない端末かの2択、にもならないですし、もちろんIPv6(IPoE)はLAN下のものはすべて使える状態になりました。とりあえず大体やりたいことはできたので満足です。無線の強度以外は家庭用の無線LANルーターよりよいものになった気がします

ただ、私のPPPoE環境は、ありがたいことになぜか休日やゴールデンタイムでも安定環境なのでOCNバーチャルコネクトの恩恵がほとんどなかったります。ここまでやっといてなんですが、IPv4(PPPoE) と IPv6(IPoE)だけの環境に戻すかもしれません…