DebianOSをルーター化
以前ラズベリーパイにOpenWrtというルーターOSをインストールしたことがありました。OpenWrtはルーター機能に特化したOSでしたが、今度は汎用OSであるDebianでルーターを作成してみようと思います。
ルーターは通信処理をハードウェア化することで処理速度を上げています。汎用OSによるルーター化は、それがされていない分処理速度は遅くなることもありますが、高価なルーターしか実装していないような機能を気軽に使えます。また、よく機器間の相性の問題と呼ばれる現象もOSが差異を吸収してくれる分少なくなります。
Debianのルーター化
環境に合わせてルーターに必要なアプリをインストールします。構成により使うライブラリは違ってくると思いますが、主に次のようなものがあります。
- iptables
OSインストール時にiptablesインストールされていることも多いと思います。これにより、ファイアウォールやIPv4のインターネット接続時に必要なNAPTを稼働させることができます。
- pppoe
PPPoE接続用のアプリです。ルーターPCからIPv4でインターネット接続時する場合に必要になります。
- pppoeconf
PPPoEの設定を簡略化してくれるアプリです。
- bridge-utils
bridgeを設定するためのアプリです。brige-utils自体はIPv4でもIPv6でも利用できるブリッジアプリですが、ここではIPv6のRAをブリッジする為(IPv6でインターネットに接続する為)に利用します。
- ebtables
ブリッジを使う場合の送受信、転送データののフィルタリングに使います。
- strongSwan
IPSec通信用のアプリです。
- xl2tpd
L2TPトンネリング用のアプリです。strongSwanと組み合わせることで、L2TP/IPSecを実現します。
- iptables-persitent
ipttables(ファイアウォール)の設定を永続化するためのアプリです。
- isc-dhcp-server
市販のインターネットルーターにはたいていDHCPサーバー機能が備わっていまが、それを実現するアプリです。
- bind9
DNSサーバーです。
- quagga
OSPFやRIPといったルーティング情報の送受信ができるようになります。
- hostapd
かつてラズベリーパイでゲストWi-Fiを構築した際に紹介したことがありますが、hostapdでWi-Fi環境を構築することができます。WPA2まで対応しています。
他、このブログでも設定したことのあるOpenVPNでVPNを構築したり、IPv4 over IPv6などのIPトンネルを使ったり、sambaを使ってWindows用のネットワークドライブを作ったりすることができます。
IPv4インターネットルーター
先に紹介した機能を使ってルーターを構成するサンプルとして、まずPPP接続を使ったIPv4インターネットルーターを作ってみます。
またIPv4環境のルーターとしてDebian OSを使う場合はIPフォワードの設定が必要です。/etc/sysctl.confで「net.ipv4.ip_forward=1」のエントリーを有効にさせてください。IPv6の場合は「net.ipv6.conf.all.forwarding=1」となります。
/etc/sysctl.conf
... # コメントアウトを解除 net.ipv4.ip_forward=1 ... net.ipv6.conf.all.forwarding=1 ...
先にNICが2つ必要なので、PCにセットしします。NICの追加やファームウェアのインストールの方法はリンク先のページを参照していただければと思います。USBのWi-Fiアダプタを設定していますが、PCIスロットの場合でも概ね流れは一緒です。(lsusbコマンドはlspciコマンドに置き換えてください。)
NICのひとつは後で自動設定されるPPP用なのでなにもしません。すべてコメントアウトしておいた方が後の設定でトラブルが少ないと思います。もうひとつはIPアドレスだけ設定した状態にします。ここで設定するIPアドレスはPCルーターのIPアドレスとなり、そのネットワーク上に配下の端末が接続されることになります。
/etc/network/interfaces
# PPP側 後でpppoeconfが自動設定してくれます # allow-hotplug eth0 # iface eth0 inet dhcp # ローカル側 allow-hotplug eth1 iface eth0 inet static address 192.168.1.1/24
IPv4ルーター化に必要なアプリは、iptables、iptable-persistent、pppoe、pppoeconfです。
もし、DHCPサーバー(isc-dhcp-server)も設定したい場合は、一緒にインストールして、リンク先の記事を参考にIPアドレスを設定した側のネットワークに設定してください。
$ su - ... # apt update ... # apt install iptables iptable-persistent pppoe pppoeconf ...
pppoeconfはPPPOE接続(IPv4のインターネット接続)をするためのパッケージであるpppoeの設定を簡易化するツールで、を実行すると次のような流れで、対話式の設定が進んでいきます。
基本的には接続の為のユーザー名とパスワードを入力するだけで、あとはデフォルトの選択肢のまま進めれば問題ありません。これらで設定する主な設定は/etc/ppp/ディレクトリに入ります。
対話は次のような流れになっています。
1./etc/ppp/peers/dsl-providerと/etc/netwrok/interfaces /etc/ppp/*-secretsに変更を加えるがいいか→yes
2.ダイヤルアップ接続のオプションを必要に応じて変更してもいいか→yes
3.プロバイダーのユーザー名入力
4.プロバイダーのパスワードを入力
5./etc/resolove.confに通知されるDNSアドレスを設定するか→yes
6.MSSの設定→yes(1452)
7.PPPDを使って、OS起動時に接続をスタートさせるか→yes
8.pon/poffをdls-providerに設定するか→yes
9.plogで接続状態を表示できる→ok
以上で、再起動時に自動でPPP接続がされるようになります。またponでリンアップ、poffで切断、plogでログの表示ができます。
もしかしたら筆者の環境だけなのかもしれませんが、pppoeconfを実行すると次のようなエラーが出ました。
これは、PPPOE接続にしたいNICにIPアドレスが設定されているとおきるようなのでNICの設定をすべてコメントアウトしました。
/etc/network/interfaces
... # allow-hotplug enp4s0 # iface enp4s0 inet dhcp ...
さらに設定が無事終わった後、再起動をかけるとPPPがリンクアップせずにplogでは次のようなメッセージがでていました。
Timeoute waiting for PADO packets Unable to complete PPPoE Discovery
設定したNICにIPv6のアドレス配布される環境だったのでそれが原因だと予想して、IPv6を止めたら解決しました。
IPv6を止める設定はQuiita:「【Debian 8 Jessie】IPv6を無効化する」を参考にさせていただきました。
/etc/sysctl.confに次の行を加えます。
/etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1sysctl.confに加えた設定自体は「sysctl -p」を実行すれば反映されるようなのですが、PPPのリンクアップにはOSの再起動が必要でした。
ファイアウォールはiptablesを使います。iptablesの基本事項に関してはリンク先の記事を参考にしていただければと思います。
利用環境によっても違うと思いますが、概ね次のような設定が必要だと思います。
# # ポリシーの設定 # iptables -P INPUT DROP # iptables -P OUTPUT ACCEPT # iptables -P FORWARD DROP # # ローカル環境からルーターへのアクセスを可能に # iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT # # 危険な転送を禁止(NETBIOS系) # iptables -A FORWARD -p tcp -m multiport --sport 135,137,138,139,445 -j DROP # # ローカル環境からインタネットへの転送を可能に # iptables -A FORWARD -i eth0 -j ACCEPT # # インターネット側からの通信は、内部から始めた通信のみ許可 # iptables -A FORWARD -i ppp0 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
もうひとつIPv4インターネットルーターには、NAPTが必要だと思います。これはiptablesのnatテーブルで利用できますので次のようにして、設定します。
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE
設定したこれらのiptablesの値は、OS再起動時に消えてしまいますのでiptables-persistentのファイルに保存します。
# iptables-save>/etc/iptables/rules.v4
これでIPv4インターネットルーターの設定は完了です。
IPv6インターネットルーター(ファイアウォール)
今度はIPv6で接続するルーターを考えてみたいと思います。IPv6のネイティブ接続の場合は、ルーターがなくてもONUからの直接接続でインターネットに接続できますので、ここではルーターというより、ファイアウォール的な役割として設定します。
IPv4版の再にも出てきましたが、まずNIC間の通信を許可します。
/etc/sysctl.conf
... # コメントアウトを解除 net.ipv6.conf.all.forwarding=1 ...
つぎに、brige-utilsを使ってブリッジを作成します。APTで取得できます。
# apt install bridge-utils
ツールをインストールした後、ブリッジの設定をします。interfacesの項目で既存のNICに設定してある項目はすべてコメントアウトして、次のような内容にします。IPv6環境では自動でbr0にアドレスが付与されまが、IPv4のアドレスも付与したい場合は、iface br0 inet のあとを「static」にして固定IPアドレスの設定したり、「dhcp」を設定して自動取得にすることができます。
/etc/network/interfaces
auto br0 iface br0 inet manual bridge_ports eth0 eth1
ブリッジにおいてはiptablesではなく、ebtablesを使ってデータの制御をします。ここではIPv6のパケットしかない前提で話をしますが、上記の設定だけだとIPv4のパケットもブリッジしますので注意してください。
次に紹介する設定はHANZUBON.JP:「DEBIANなマシンで IPV6 BRIDGE」を参考にさせていただき考えてみました。
ebtablesの記法はm--helpオプションでも出せるようですが、man:EBTABLESのページに日本語化済のオプションの詳細が載っています。
ルーターからのRAとノード間のNDはICMPv6として送信されますので、アドレス自動付与のために自ネットワーク間のICMP通信を許可します。
先にあげた参考サイトでは、ebtablesのBROUTEテーブルにfilterを設定していましたが、近年のiptables(nftables互換環境)では使えないようです。ここではFORWARDに設定しています。
# #転送の基本はDROP # ebtables -t filter -P FORWARD DROP # # 自ネットワーク(2001:a:b:c, fe80)のICMPv6転送を許可(ND,RA用) ebtables -t filter -A FORWARD -p IPv6 --ip6-protocol ipv6-icmp --ip6-source 2001:a:b:c::/64 -j ACCEPT ebtables -t filter -A FORWARD -p IPv6 --ip6-protocol ipv6-icmp --ip6-source fe80::/64 -j ACCEPT # # 許可端末(1)からの発信と着信を許可 # # Windows10だと通常、グローバルな接続時は「一時IPv6アドレス」を使ので注意してください # ebtables -t filter -A FORWARD -p IPv6 --ip6-source 2001:a:b:c::1 -j ACCEPT # ebtables -t filter -A FORWARD -p IPv6 --ip6-destination 2001:a:b:c::1 -j ACCEPT # ebtables -t filter -A FORWARD -p IPv6 --ip6-source fe80::1 -j ACCEPT # ebtables -t filter -A FORWARD -p IPv6 --ip6-destination fe80::1 -j ACCEPT # # IPのかわりに macアドレス(aa:bb:cc:dd:ee:ff)を指定すれば一時IPv6アドレスの考慮が不要です # ebtables -t filter -A FORWARD -p IPv6 -s aa:bb:cc:dd:ee:ff -j ACCEPT # ebtables -t filter -A FORWARD -p IPv6 -d aa:bb:cc:dd:ee:ff -j ACCEPT
ebtablesの方は自動的にテーブル情報を保持するアプリが見つけられなかったので、自分でスクリプトを組んで起動時に実行するようにしておきます。ファイルへの保存と復元は、iptables同様に、「ebtables-save」と「ebtables-restore」が利用できます。
ルーターPCへの入りと出のIPv6データの送受信制御はip6tablesで行います。これはローカル環境以外の通信はすべて遮断するものにすればいいと思います。
Netfilter-packet-flowの図では、ブリッジの際もnetowrkレベルでFORWARDフィルターを通過していると思うのですが、表の見方が間違っているのか、とにかく筆者の環境ではip6tablesでFOWARDのポリシーをDROPにしてもブリッジ通信には影響ありませんでした。
# ip6tables -P INPUT DROP # ip6tables -P OUTPUT DROP # ip6tables -P FORWARD DROP # ip6tables -A INPUT -s 2001:a:b:c::/64 -j ACCEPT # ip6tables -A OUTPUT -d 2001:a:b:c::/64 -j ACCEPT # ip6tables -A INPUT -s fe80::/64 -j ACCEPT # ip6tables -A OUTPUT -d fe80::/64 -j ACCEPT
ルーティング
ルーターといいながらここまでほとんどルーティングについて触れていませんでしたが、DebianOSには標準でルーティングテーブルを持っていますのでそれが利用できます。Debianのルーティングテーブルの設定の仕方はリンク先を参考にしていただければ幸いです。
参考にさせていただいたサイトの皆様、ありがとうございました。