Raspberry Pi 3 (Raspbian Jessie) でルーティングの設定をしてみた
まだ Wi-Fi側は同じサブネット内からしか通信できません
先日、ボンディングを試した際に、Wi-Fi(wlan0)を管理LAN的に使用しようとしたのですが、他のネットワークデバイスと同じサブネット(同一セグメント)だったので、きちんとルーティング設定をしないと通信できなくなるというアホな事をやらかしていました。そこで今回はルーティングの設定をやってみました。
自分はネットワークインフラについては素人なので、あちこちのホームページを参考にして設定しました。相変らず、今のところうまくいっている様子だというレベルでして、あくまで自分用の備忘録です。と言うことで、まだアホな事をやらかしている可能性もありますので、その点は御容赦。
参考URL:同じサブネットへのNIC 2枚指し、またはソースルーティングのおはなし
ボンディングは元に戻してしまいましたので、現在LANに接続しているのは Wi-Fi(wlan0), Gigabit Ethernet(eth1) の2つです。手順としては、
- Wi-Fi(wlan0), Gigabit Ethernet(eth1) のIPアドレスを固定
"/etc/network/interfaces" でルーティング設定
"/etc/iproute2/rt_tables" でルーティングテーブルに名前をつける
- ネットワーク再起動
- 動作確認
と言った感じ。
1. "/etc/dhcpcd.conf" で Wi-Fi(wlan0), Gigabit Ethernet(eth1) のIPアドレスを固定
Wi-Fi(wlan0), Gigabit Ethernet(eth1) のIPアドレスを固定します。Raspbian Jessie (Debian 8)でIPアドレスを固定する方法については検索すれば山ほど見つかりますので、詳しい内容については省略しますが、自分の設定はこんな感じです。
1) "/etc/network/interfaces" のifaceスタンザを編集
# interfaces(5) file used by ifup(8) and ifdown(8)
# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
〜略〜
auto lo
iface lo inet loopback
auto eth1
allow-hotplug eth1
iface eth1 inet manual
auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
|
2) "/etc/dhcpcd.conf" でIPアドレスを設定
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
〜略〜
interface eth1
static ip_address=192.168.0.100/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
static domain_search=
interface wlan0
static ip_address=192.168.0.200/24
static routers=
static domain_name_servers=
static domain_search=
|
以後、Gigabit Ethernet(eth1) のIPアドレスは 192.168.0.100 、Wi-Fi(wlan0) のIPアドレスは 192.168.0.200 に設定したという前程での話になります。
2. "/etc/network/interfaces" でルーティング設定
Gigabit Ethernet(eth1) のルーティングは自動で設定されるのに任せて、管理LAN的に使いたい Wi-Fi(wlan0)のルーティングだけ設定しました。
auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
post-up /sbin/ip rule add from 192.168.0.200 table 100 prio 10000
post-up /sbin/ip route add default dev wlan0 table 100
post-down /sbin/ip route del default dev wlan0 table 100
post-down /sbin/ip rule del table 100 prio 10000
|
設定の意味は、
Wi-Fi(wlan0) の起動後に、
Wi-Fi(wlan0) のIPアドレス192.168.0.200 から送信する際のルール(ルーティングテーブルID 100)を優先度10,000で追加
- ルーティングテーブルID 100に「
Wi-Fi(wlan0) デバイスを使いなさい」というデフォルトルート設定を追加
Wi-Fi(wlan0) の停止後に、
- ルーティングテーブルID 100のデフォルトルート設定を削除
- ルーティングテーブルID 100を削除
という意味になります。
3. "/etc/iproute2/rt_tables" でルーティングテーブルに名前をつける
ルーティングテーブルID 100じゃ分かりにくいので、"/etc/iproute2/rt_tables" でルーティングテーブルに名前をつけてあげます。(必須ではないので、別に数字だけでも構わない場合は不要)
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
100 wifi
|
4. ネットワーク再起動
# systemctl restart networking.service
|
とするか、Raspberry Piを再起動(reboot)します。
5. 動作確認
# ifconfig
eth1 Link encap:イーサネット ハードウェアアドレス xx:xx:xx:xx:xx:yy
inetアドレス:192.168.0.100 ブロードキャスト:192.168.0.255 マスク:255.255.255.0
inet6アドレス: fe80::8fa:240:fab2:c105/64 範囲:リンク
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:2813 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:2923 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:1144282 (1.0 MiB) TXバイト:808310 (789.3 KiB)
lo Link encap:ローカルループバック
inetアドレス:127.0.0.1 マスク:255.0.0.0
inet6アドレス: ::1/128 範囲:ホスト
UP LOOPBACK RUNNING MTU:65536 メトリック:1
RXパケット:997 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:997 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1
RXバイト:331927 (324.1 KiB) TXバイト:331927 (324.1 KiB)
wlan0 Link encap:イーサネット ハードウェアアドレス xx:xx:xx:xx:xx:zz
inetアドレス:192.168.0.200 ブロードキャスト:192.168.0.255 マスク:255.255.255.0
inet6アドレス: fe80::85a3:217a:fde:5e04/64 範囲:リンク
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:703 エラー:0 損失:41 オーバラン:0 フレーム:0
TXパケット:437 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:173384 (169.3 KiB) TXバイト:184981 (180.6 KiB)
# ip rule show
0: from all lookup local
10000: from 192.168.0.200 lookup wifi
32766: from all lookup main
32767: from all lookup default
# ip route show table wifi
default dev wlan0 scope link
|
wifiという名前のルーティングテーブルが優先度10,000に追加されています。送信しようとする際には、優先度順(値が小さい順)にマッチングするルーティングテーブルを検索して、マッチしたルールに従って送信する仕組みだそうな。で、Wi-Fi(wlan0) 192.168.0.200 から来た通信はルーティングテーブル wifi にマッチするので、その中に設定してあるルール「Wi-Fi(wlan0) デバイスを使いなさい」に従って送信されるという事になります。
Gigabit-Ethernet(eth1) 192.168.0.100 から来たものはルーティングテーブル wifi にはマッチしないので、優先度32,766の main テーブルにマッチすることになります。mainテーブルは、自動的に設定された内容になっていて、
# ip route show table main
default via 192.168.0.1 dev eth1 metric 203
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.100 metric 203
192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.200 metric 304
|
となっていました(*1)。3つのルールが設定されていますが、metricの値が小さい順に従って使用するルールが決められるので、
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.100 metric 203
default via 192.168.0.1 dev eth1 metric 203
|
という eth1だけのルールで送信されるようになると思います。(説明の都合上、順序を入れ替えました。)意味は、
- IPアドレス
192.168.0.100 からサブネット192.168.0.0/24 (自サブネット内)への送信には eth1デバイスを使いなさい
- そうでない場合(default: 自サブネット外への送信)には eth1デバイスを使って
192.168.0.1 へ送信しなさい
という事になりますかね。Wi-Fi(wlan0) のルールの方は、先にルーティングテーブル wifiにマッチして送信されてされていますので、使用されない事になると思います。(もしWi-Fi(wlan0) の metric値の方が小さくなるとeth1から出て行かなくなるから、Wi-Fi(wlan0) のルールは消した方が良いのかも?)
実際にそうなっているか実験してみます。TCP/IPのパケットをキャプチャして表示させたいので、先ず tcpdump をインストールします。
# apt-get update
# apt-get install tcpdump
|
同じサブネット上にある別のPCから、先ず eth1(192.168.0.100 )へ pingを打っておいて、tcpdump で見てみます。
# tcpdump -i eth1 -nl icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
15:33:26.742926 IP 192.168.0.xxx > 192.168.0.100: ICMP echo request, id 49450, seq 4, length 64
15:33:26.743014 IP 192.168.0.100 > 192.168.0.xxx: ICMP echo reply, id 49450, seq 4, length 64
|
eth1 の192.168.0.100 から入ってきた request に、192.168.0.100 から replyを返していますね。
次に wlan0(192.168.0.200 )の方へpingを打っておいて、
# tcpdump -i wlan0 -nl icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:36:17.309666 IP 192.168.0.xxx > 192.168.0.200: ICMP echo request, id 60459, seq 1, length 64
15:36:17.309802 IP 192.168.0.200 > 192.168.0.xxx: ICMP echo reply, id 60459, seq 1, length 64
|
こちらも192.168.0.200 から入ってきたrequest には192.168.0.200 から replyを返していますので、正しくルーティングされているという事になります。
この設定では Wi-Fi(wlan0) と通信できるのは同じサブネット内だけで、ルーターを越えて外へは出ていけません。そのため、ルーター外から Wi-Fi(wlan0) のIPアドレスに向けて pingを打っても応答しません。Wi-Fi を管理LAN的な使い方をするのであれば、この設定で構わないのですけど、Wi-Fi でもルーター越えさせたいのであれば、"/etc/network/interfaces" でルーティングテーブルwifi の設定を
auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
post-up /sbin/ip rule add from 192.168.0.200 table 100 prio 10000
post-up /sbin/ip route add 192.168.0.0/24 dev wlan0 src 192.168.0.200 table 100
post-up /sbin/ip route add default via 192.168.0.1 dev wlan0 table 100
post-down /sbin/ip route del default table 100
post-down /sbin/ip route del 192.168.0.0/24 table 100
post-down /sbin/ip rule del table 100 prio 10000
|
とでもすれば良いんじゃないかと思うのですが、これだと何故かルーティングテーブルwifi内にルールが全く設定されないんですよね。原因は分かってないのですが、コマンドを直叩きすると設定できるので、Wi-Fi(wlan0) の起動直後ではタイミングが早過ぎるのかも?と思っています。
これについては、もう少しジタバタしてみるつもり。
(*1):routeコマンドやnetstat -nrで表示されるのは、このmainルーティングテーブルだけの内容っぽいですね。
# route
カーネルIP経路テーブル
受信先サイト ゲートウェイ ネットマスク フラグ Metric Ref 使用数 インタフェース
default web.setup 0.0.0.0 UG 203 0 0 eth1
192.168.0.0 * 255.255.255.0 U 203 0 0 eth1
192.168.0.0 * 255.255.255.0 U 304 0 0 wlan0
|
|