Linuxルータ

VMWareでローカルPCに作ったサーバに、LANに接続した自分のマシン(VMWareホスト)以外のクライアントからアクセスさせたくなったので、ゲストの1つをLinuxルータとして設定してみた。

iptables NATを使ったルータ

カーネルパラメータ設定
  • 設定埋め込み
    • 恒久的に設定する場合(/etc/sysctl.conf)
      • デフォルトの「net.ipv4.ip_forward = 0」の記述を編集しリロード。後述の理由により個人的にはこちらがオススメ。


# grep "net.ipv4.ip_forward" /etc/sysctl.conf
net.ipv4.ip_forward = 1
# /sbin/sysctl -p

    • 一時的に有効化する場合(/proc/sys/net/ipv4/ip_forward)
      • ただしこの場合、設定後にnetworkサービス再起動を行うと/etc/init.d/networkのstart処理内でsysctl.confがリロードされるため、/etc/sysctl.confにデフォルトである「net.ipv4.ip_forward = 0」が記述してあると、network開始時にパラメータ値が0に戻ってしまうため注意!


# echo 1 > /proc/sys/net/ipv4/ip_forward
# cat /proc/sys/net/ipv4/ip_forward
1

  • networkサービスの起動停止スクリプト修正
    • デフォルトではnetworkサービス停止処理内(stop)で、「net.ipv4.ip_forward = 1」の場合には「0」に戻す処理が実行され、その後network開始ではなくifupで個別に複数のI/Fをupした場合には異なるI/F間通信ができない。このため、必要が応じstop処理内の記述を修正する。


# diff -u /etc/init.d/network ~/network.orig
--- /etc/init.d/network 2008-08-21 21:23:21.000000000 +0900
+++ /root/network 2007-06-23 07:08:30.000000000 +0900
@@ -264,7 +264,7 @@
if [ -d /proc/sys/net/ipv4 ]; then
if [ -f /proc/sys/net/ipv4/ip_forward ]; then
if [ `cat /proc/sys/net/ipv4/ip_forward` != 0 ]; then
- #action $"Disabling IPv4 packet forwarding: " sysctl -w net.ipv4.ip_forward=0
+ action $"Disabling IPv4 packet forwarding: " sysctl -w net.ipv4.ip_forward=0
fi
fi
if [ -f /proc/sys/net/ipv4/ip_always_defrag ]; then

iptables設定
  • 設定内容と手順
    • 1.内部からの接続(OUTPUT)には制限を設けないACCEPT


# iptables -A FORWARD -i -o -s -d -j ACCEPT

    • 2.Linuxルータ外部からの接続(INPUT)はパケットのステートフル性を確認し、「--state ESTABLISHED,RELATED」となっているものを通過許可(ACCEPT)


# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT


# iptables -t nat -A POSTROUTING -o -s -j MASQUERADE

  • 稼動状態確認
    • 下記コマンドで設定が有効か確認(以下は172.16.10.0/24ネットワークから192.168.127.0/24ネットワークへルーティンするする場合の出力例)


# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 172.16.10.0/24 192.168.127.0/24
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

  • シェルにするとこんな感じ
    • 各パラメータは用途にあわせて書き換えること!


#!/bin/sh
#
######################################
# Define Variables
######################################
source_ip="172.16.10.0/255.255.255.0" # アクセス元ネットワーク
dest_ip="192.168.127.0/255.255.255.0"  # アクセス先ネットワーク
input_if=eth1   # パケット入り口ネットワーク I/F
output_if=eth0   # パケット出口ネットワーク I/F

######################################
# Reset & Flush
######################################
iptables -F
iptables -t nat -F
iptables -X

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

######################################
# Set iptables
######################################
iptables -A FORWARD -i $input_if -o $output_if -s $source_ip -d $dest_ip -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o $output_if -s $source_ip -j MASQUERADE
iptables -L

  • 設定を削除するには
    • 「-t nat」でnatテーブルを指定し、「-F」で初期化(テーブルの指定には「-t」オプションを使用)


# iptables -t nat -F

  • 設定をファイル保存するには
    • 下記コマンドで/etc/sysconfig/iptablesに保存する

# iptables save

    • 上記コマンドが使用できないディストリ、バージョンでは

# iptables-save > output.cfg


クライアントの静的ルーティング

Linuxルータに直接関わるものではないが、アクセスしたいマシンがデフォルトGW経由で目的のLinuxルータに到達できない場合に設定

>route add 192.168.127.0 mask 255.255.255.0 172.16.10.254 metric 1

# route add -net 192.168.127.0 gw 172.16.10.254 metric 1 netmask 255.255.255.0  dev bond1

    • 恒久的に必要であれば/etc/sysconfig/network-scripts/route-<デバイス名>ファイルを作成し、設定を記述する
      • この内容は/etc/sysconfig/netwrok-scripts/ifup-routesの中で読み込まれている模様
    • ファイルに記述する場合の書式は2種類
      • 1つ目:1行で記述するパターン(うまくいかない場合は2つ目の方法を試す)

{destination}/{mask} via {gateway}


GATEWAY?={gateway}
NETMASK?={mask}
ADDRESS?={destination}

    • ファイルに記述する場合には、設定後必ずnetworkサービスをrestartまたはreloadする

# service network reload