CentOS7 を IPv4(PPPoE) + IPv6(IPoE) のルーターにする

更新履歴

2020/6/18
2.4 ndppd の修正と 2.5 firewalld の追加。CentOS 8.2でfirewalldのゾーンのマスカレード設定がIPv6を無視するようになってくれたので、IPv6-NATを使わない設定を追加

2020/3/29
便利なポートテストサイトを見つけて動作確認ができたので、ファイアウォールの設定追記。知識が怪しすぎて用語の使い方が酷すぎたのを少し整理。。。

はじめに

CentOS7をIPv4(PPPoE)のブロードバンドルーターとして稼働させていますが、今回はIPv6(IPoE)も使えるようにしたいと思います。タイトルはCentOS7ですが、修正を重ねてCentOS8.2向けの記事になってきてる気がします

Linuxの知識もネットワークの知識もセキュリティの知識もない素人なのでつっこみどころがあるのはご容赦ください。この記事を書く3日前にNDPとかIPv6リンクローカルアドレスとかを初めて聞いたくらいのレベルです

IPv4はそのままPPPoEで、IPv6のみIPoEを使うようにします。市販の家庭用のブロードバンドルーターだとPPPoEとIPoEの共存は2台のルーターが必要になることもあるようですが、今回は1台で両方使えるようにします

流行?のIPv4 over IPv6はこの記事では扱いません。

次の記事でやってます → CentOS7でOCNバーチャルコネクト

環境

  • 回線:フレッツ光ネクスト
  • プロバイダ:OCN
  • ひかり電話なし、HGWなし
  • 最終確認:CentOS 8.2(firewalldのバックエンドはiptables)

大体こんな環境です。タイトルはCentOS7ですが、最後に確認したのは8.2です。ご了承ください。

IPv4(PPPoE)

IPv4(PPPoE) + IPv6(IPoE)

雑な図ですが、上図から下図に変更します。IPv4(PPPoE)環境は全く変更せず、IPv6(IPoE)を追加します。IPv6対応サイトにアクセスするときにIPv6(IPoE)でアクセスするようにします。また、自分で建てているサーバーにIPv6(IPoE)でアクセスできるようにします

市販の家庭用IPv6のルーターは、IPv6ブリッジ(パススルー)のものとNDプロキシのものがあるようですが、セキュリティ面を考えブリッジを使わないルーターにします。IPv6環境下でもIPv4のようにWAN側とLAN側でわけ、セキュリティを確保します

基本的にはIPv6対応サイトへのアクセスとIPv6からのアクセスがPPPoEからIPoEに変わるだけで、それ以外については変わらないようにします

手順

以下、WAN側のインターフェイスをenp2s0、LAN側のインターフェイスをbr0としてすすめていきます

また、すでにプロバイダ等との契約が済んでいて、WAN側(enp2s0)にIPv6のグローバルIPが降ってきているものとします

sysctlの設定

まずはIPv6パケット転送を有効にしてルーターとして動作できるようにします

1行追加し、反映させます

radvdの設定

LAN内のPCがIPv6アドレスを自動で設定できるようにするためにradvdをインストールします

WAN側NICのIPv6のグローバルアドレスを確認します

inet6のfe80から始まらない方がグローバルアドレスです

interfaceにはLAN側のインターフェイスを指定します。prefixにはさきほど調べたグローバルアドレスのプレフィックスを入れます
(2400:xxxx:xxxx:xxxx::1:1/64 だったら 2400:xxxx:xxxx:xxxx::/64)

AdvLinkMTUを設定するとLAN内のNICのIPv6のMTUが自動で設定されます。統一したい場合はWAN側のMTUと同じ値をいれてしまいましょう

IPoEなら1500固定でいいと思いますが、Path MTU Discovery Black Holeの回避で1280にしたい方もいるかも。個別に設定したいならAdvLinkMTUオプション削除で

radvd.confのマニュアル – https://linux.die.net/man/5/radvd.conf

これでLAN内のPCにIPv6アドレスが自動で設定されるようになります。30秒ほど待って設定されているか確認します

LAN側のインターフェイスにも2400:xxxx:xxxx:xxxxからはじまるグローバルIPが設定されたら成功です。xxxx以降の部分はMACアドレスなどから自動で決まるようです

これでLANの端末にはすべて2400:xxxx:xxxx:xxxxから始まるグローバルIPアドレスが自動で振られるようになります

MACアドレスをもとに自動で振られることや、全部がグローバルIPってのはIPv4のときの感覚とはずいぶん違いますね

ルーティングの確認

ルーティングに問題があると通信ができないので確認します

私の例。2400:xxxx:xxxx:xxxx~のIPアドレスはグローバルアドレスですが、ルーターから見た場合はLANのPCのアドレスということになります。つまり2400:xxxx:xxxx:xxxx~とはLAN側のインターフェイス(br0)で通信しないといけません。

ということはメトリック値はLAN側のインターフェイスの方が低くなければいけません。この私の例の場合、WAN側(enp2s0)がLAN側(br0)より優先されてしまうので、LAN側への通信もWAN側(enp2s0)で行おうとしてしまい、通信に失敗してしまいます

もしWAN側のメトリック値がLAN側のメトリック値より低かった場合は、LAN側よりも高くします

確認。これでLAN側の端末へパケットが流れるようになります

LANにある他の端末からPingが通るか確認します。WindowsからPingを試した例です。ルーティングが正しければ、あとはPing拒否の設定をしていなければ通るはずです

LANのPCとルーターが通信できないと、LANのPCがインターネットにつながりません

ndppdの設定

NDプロキシの設定を自動でやってくれるndppdのインストールをします

ndppdを入手し、make&インストールします

設定ファイルをコピーし編集します

proxyにはWAN側デバイスを、ruleには radvd.conf でも使ったプレフィックスを使います。ifaceはなんとなくautoからLAN側のインターフェイスの明記に変えました

デーモン用ファイルをコピーして編集します

ndppdのパスを合わせます。PIDファイルの場所も適宜変更します

読み込んで起動します

firewalldの設定

CentOS 8.1(firewalld-0.7.1)以前の場合、ゾーンのマスカレードの設定を有効にすると、IPv4だけでなくIPv6のフォワードとNATの設定もする(してしまう)ので、特に設定しなくても通信できてしまいます

CentOS 8.2(firewalld-0.7.2)以降の場合はゾーンのマスカレードの設定はIPv4のみの有効になったので、本来不要なIPv6のNATをしなくなりました。フォワードの設定は自分で書く必要があります

-iの方はLAN側、-oの方はWAN側デバイスを指定します

CentOS 8.1(firewalld-0.7.1)以前の場合でIPv6のNATをしないようするなら、ゾーンのマスカレードの設定を使わずにダイレクトルールの方でIPv4のNATの設定を書く必要がありそうです

DNSの設定

使っているDNSサーバーがAレコード(IPv4アドレス)とAAAAレコード(IPv6アドレス)の両方を返すものであれば変更する必要はありません。Aレコードしか返さないものであれば変更する必要があります

例えばGoogle Public DNS(8.8.8.8)を使っている場合であれば変更する必要はありません

digコマンドでAAAAレコードを調べることができます。このようにAAAAレコードが返ってこなければDNSサーバーの設定を変更する必要があります

DNSサーバーを立てている場合はDNSサーバーの設定を、立てていない場合は /etc/resolv.conf 等PCのDNSの設定を変える必要があります

DNSサーバーへのアクセスもIPv6(IPoE)にしたい場合は使用するDNSサーバーをIPv6のアドレスに変更しましょう

例えばGoogle Public DNSであれば

2001:4860:4860::8888 / 2001:4860:4860::8844

です。これらもAレコードとAAAAレコードの両方が返ってくるので、IPv4にもIPv6にも使えます

接続確認

IPv6動作確認サイトにアクセスします

https://test-ipv6.com/index.html.ja_JP

問題なさそうであれば、radvdとndppdを自動起動するようにします

ファイアウォールの設定

IPv6でLAN内のサーバーを外部に公開したい場合、したくない場合の手順を確認します
IPv4のときと同じような感覚で運用できるような気がします

端末 IF zone IPv4アドレス IPv6アドレス
ルーター enp2s0 external 2400:xxxx:xxxx:xxxx::1:1
br0 internal 192.168.1.1 2400:xxxx:xxxx:xxxx:yyyy:yyyy:yyyy:xbr0
サーバー eno1 internal 192.168.1.10 2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas

たとえばLANにサーバーがあったとします。サーバーでWebサーバー(ポート番号8080)をたて、外部に公開する例を考えてみます。サーバーの8080番ポートはすでにあいてるものとします

ポートフォワード

IPv4の場合であれば、ポートフォワードの設定をして外部に公開しますが、IPv6でも同じような手順で公開できます

上がIPv4のポート転送の設定、下がIPv6のポート転送の設定です。IPv4をIPv6のアドレスに変えるだけで手順は同じです。これで

http://IPv4のグローバルアドレス:8080 や、ルーターのWAN側IPv6グローバルIPを使って
http://[2400:xxxx:xxxx:xxxx::1:1]:8080 でアクセスできます

サーバー側のグローバルIPを使って

http://[2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas]:8080

などとアクセスしようとしてもアクセスできません。IPv4のときのようなNATの内側と同じ感覚での運用になると思います

firewalldの説明だとゾーンでのポート転送はipv4限定となってるのですが使えてしまいます(バージョン次第?)

また、NDプロキシがなくてもアクセスできてしまうので、ndppdを起動してなくてもアクセスできてしまいます

通過許可

サーバーのグローバルIPを使って、ポートフォワードを使わすにサーバーにアクセスできるようにすることも可能です

LAN側のサーバーの8080ポートへのアクセスを通過許可する設定例です

これで、サーバーのグローバルIPを使って

http://[2400:xxxx:xxxx:xxxx:zzzz:zzzz:zzzz:znas]:8080

でアクセスできるようになります。ndppdを切るとアクセスできなくなります

ドメインを持っている場合は、IPv6のグローバルアドレスを追加すればIPv4とIPv6の両方に対応したWebサーバーになります

もちろんIPv4(またはIPv6)でのみ外部公開する、ということもできます

設定したらテストサイトを使って確認します

IPv6ポートテストサイト
http://www.ipv6scanner.com/cgi-bin/main.py
https://ipv6.chappell-family.com/ipv6tcptest/

参考サイト

https://yudai.arielworks.com/memo/2012/05/08/000441