ページ更新: 2005-12-23 (金) (3227日前)

関連: 機材/ADSL/記録, Linux/netfilter

(2001-06-25 新規作成)

Linuxを「ルータ+NAPT+パケットフィルタ」として使う設定のメモ。

環境は Debian GNU/Linux Woody kernel 2.4.18-k6 (当初は kernel 2.2.18pre21を使用)

クライアントとして WindowsXP, Windows2000、Windows98SE、Linux なPCを数台繋げていますが、この文書ではそこら辺の設定(DHCPとか、DNSサーバとか)は主題ではないので、ほとんど触れていません。

目次

[編集]

機材の接続とパケットの経路 #

今回のADSLモデムは「Ethernetブリッジタイプ」で、PPPoEソフトを使う。

Linuxをルータにする場合、次の2通りの接続方法がある。

今回は当初は動作確認が容易な 1.の方法で接続し、後日 2. の方法に変更した。

[編集]

1. LinuxPCにLANインターフェイスを1つ使う #

NIC1枚でのパケット経路 1nic.png

特徴

  • Linux PCのNIC(LANインターフェイス)が1つで済む。
  • Linux PCのPPPoEを止めれば、ClientPCにPPPeEソフト(フレッツ接続ツールなど)を入れて繋ぐことができる。
  • PPPoEのパケットがLAN全体に流れる。帯域を食われないためにはスイッチングハブが必要。
[編集]

2. LinuxPCにLANインターフェイスを2つ使う #

NIC2枚でのパケット経路 2nic.png

特徴

  • Linux PCのNIC(LANインターフェイス)が2つ必要。
  • ClientPCでPPPeEソフト(フレッツ接続ツールなど)を使って繋ぐには、配線を変更する必要がある。
  • PPPoEのパケットはLinuxPCまでしか到達しない。
[編集]

PPPoEの手順 #

まずは、DebianのPPPoEパッケージを入れる。

# dpkg -s ppp | grep Version   ★pppのバージョンをみておく 
Version: 2.4.1-2

$ apt-cache search PPPoE        ★PPPoE関連パッケージを探す
pppoe - PPP over Ethernet driver
pppoeconf - configures PPPoE/ADSL
pppstatus - console-based PPP status monitor

$ apt-cache show pppoe          ★pppoeパッケージの情報をみる
Package: pppoe
Priority: optional
Section: net
Installed-Size: 196
Maintainer: Christian Hudon <chrish@debian.org>
Architecture: i386
Source: rp-pppoe
Version: 3.0-2
Depends: libc6 (>= 2.2.3-1), ppp (>= 2.3.10-1)
Filename: pool/main/r/rp-pppoe/pppoe_3.0-2_i386.deb
Size: 47656
MD5sum: a1b3f3ff1d2de0dad1f9cd1b598781f2
Description: PPP over Ethernet driver
 PPP over Ethernet (PPPoE) is a protocol used by
 many ADSL Internet service providers. This package allows
 you to connect to those PPPoE service providers.

# apt-get install pppoe          ★pppoeパッケージをインストールする

PPPoEの設定 /etc/ppp/peer/dsl-providor の次の個所を修正/追加。(2003.03.16追記:いまならpppoeconfパッケージを入れて、pppoeconfを実行するのが簡単。)

user xxxxxxx@nifty.com
pty "pppoe -I eth1 -T 80 -m 1414"        ★mruを1414にする

persist                                  ★常時接続する場合、自動再接続させる
maxfail 0                                ★常時接続する場合、リトライを無限回

パスワードは chap-secrets / pap-secrets に保存されている。また、pppconfig を実行したときにも更新されるようだ。(いまのところ深く追求してない)

で、早速接続してみる。

# ifconfig eth1 up
# /sbin/ifconfig eth1
eth1      Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
          Interrupt:9 Base address:0x200

# pon dsl-provider                       ★接続する
# /sbin/ifconfig ppp0                    ★IPアドレスとMTUを確認
ppp0      Link encap:Point-to-Point Protocol
          inet addr:XXX.XXX.XXX.XXX  P-t-P:ZZZ.ZZZ.ZZZ.ZZZ  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1454  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:338 (338.0 b)  TX bytes:315 (315.0 b)

$ /sbin/route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
ZZZ.ZZZ.ZZZ.ZZZ *               255.255.255.255 UH    0      0        0 ppp0
192.WWW.WWW.WWW *               255.255.255.0   U     0      0        0 eth0
default         ZZZ.ZZZ.ZZZ.ZZZ 0.0.0.0         UG    0      0        0 ppp0

これで接続完了。

ちなみにPPP接続を切るときは poff dsl-provider か poff -a を実行するべし。

[編集]

起動時に自動接続させる #

起動時に接続させるなら、/etc/ppp/ppp_on_boot.dsl を ppp_on_boot にコピーする。

ウチの場合、eth1を経由するため、次のようにした。

#!/bin/sh

# The location of the ppp daemon itself (shouldn't need to be changed)
PPPD=/usr/sbin/pppd

# The Ethernet interface the DSL modem is connected to. If you change this,
# you also need to edit the file /etc/ppp/peers/dsl-provider.
INTERFACE=eth1

# Bring the interface up
/sbin/ifconfig $INTERFACE up -arp ★ルータがMNVの場合「-arp」は消すこと。

$PPPD call dsl-provider
[編集]

NAPTとパケットフィルタの設定 #

NAPT(IP-Masquerade)とパケットフィルタを設定する。

[編集]

方針 #

  • kernel 2.4.* の netfilter (iptables) を使う。
  • LAN側のネットワークは 192.168.1.0/24
  • 次のIPからのパケットを拒否し、ログを取る。
    local, private, reserved, broadcast
  • icmp は全部通す。
  • ftpのPORTモード(PASVじゃないモード)を使うために、20 (ftp-data) を許可する。
  • identdは立てない。このままではftpの接続時に遅延(タイムアウト待ち)が入るので、(auth= tcp/113) をREJECTする。
  • tcpのSYNフラグが立っているパケットを拒否し、ログを取る。
  • 残りのパケットをすべて拒否し、ログを取る。
  • ip_conntrack を使う。これで、ポート1024-65535は自動的に開け閉めされるはず。
[編集]

netfilter (iptables)の場合 #

まずは、お約束。/etc/sysctl.conf に次の設定を行う。echo 1 > /proc/sys/net/ipv4/ip_forward と同じ意味。

net/ipv4/ip_forward=1

次に iptables パッケージを入れる。

# apt-get install iptables

modconf で次のモジュールを入れる。他にもあるが、自動的にロードされるため設定不要。

p_tables
ip_conntrack_ftp
ip_conntrack_irc
ip_nat_ftp
ip_nat_irc

パケットフィルタ設定をスクリプトを作って、実行する。次のスクリプトを作成した。

#!/bin/sh

iptables -F

## connect chain (INPUT/FORWARD ppp0..n -> block-chain)
iptables -A INPUT -i ppp+ -j block
iptables -A FORWARD -i ppp+ -j block
#iptables -P FORWARD DROP

## MASQUERADE

iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE

## chain: logdrop (logging and drop)
iptables -N logdrop
iptables -A logdrop -m limit -j LOG --log-prefix "netfilter "
iptables -A logdrop -j DROP

## chain: logreject (logging and reject)
iptables -N logreject
iptables -A logreject -m limit -j LOG --log-prefix "netfilter "
iptables -A logreject -j REJECT

## chain: block
iptables -N block

# drop local, private, reserved, broadcast
iptables -A block -s 127.0.0.0/8     -j logdrop
iptables -A block -s 10.0.0.0/8      -j logdrop
iptables -A block -s 0.0.0.0/8       -j logdrop
#iptables -A block -s 172.16.0.0/12   -j logdrop ★Flet's Squareに繋げるないなら、コメントを外す
iptables -A block -s 169.254.0.0/16  -j logdrop
iptables -A block -s 192.168.0.0/16  -j logdrop
iptables -A block -s 224.0.0.0/4     -j logdrop
iptables -A block -s 240.0.0.0/5     -j logdrop
iptables -A block -s 248.0.0.0/5     -j logdrop
iptables -A block -s 192.0.2.0/24    -j logdrop
iptables -A block -s 255.255.255.255/255.255.255.255 -j logdrop

# accept icmp
iptables -A block -p icmp -j ACCEPT

# reject auth
iptables -A input -p tcp --dport 113 -j REJECT --reject-with tcp-reset

# accept to daemon
iptables -A block -p tcp --dport 80 -j ACCEPT ★http サーバを公開する場合

# accept ...

iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state --state NEW -i ! ppp+       -j ACCEPT

# drop
iptables -A block -j logdrop

##

exit

iptables -n -L で設定を確認、動作を確認し、次のコマンドを実行して設定を保存する。

# /etc/init.d/iptables save active

なお、パケットフィルタの無効時の設定を用意するなら、これもスクリプトにして実行してから、次のコマンドを実行する。

# /etc/init.d/iptables save innactive

有用なもの

  • m limit ログ出力行数を制御
    LOG ターゲットの --log-prefix オプション (ログを処理するとき便利)
[編集]

複数セッション接続 #

プロバイダ1つと、Flets's Squareに同時に接続する。

[編集]

PPPoEの設定 #

Flet's Square用にPPPoEの設定を用意する。設定はNTT東日本:フレッツ|ご利用者向け|フレッツ・スクウェア|フレッツ・スクウェア接続方法を参照のこと。

pppoeconfで作った設定ファイル /etc/ppp/peers/dsl-provider を /etc/ppp/peers/flets-squareにコピーし、次の個所を修正した。

user guest@flets ★修正
nodefaultroute  ★追加
noproxyarp    ★追加
#usepeerdns    ★コメントアウト

Flet's Squareに接続する。syslogを確認。

# pon flets-square

# tail /var/log/syslog
Mar 15 12:34:48 koca pppd[10626]: pppd 2.4.1 started by root, uid 0
Mar 15 12:34:48 koca pppd[10626]: Serial connection established.
Mar 15 12:34:48 koca pppd[10626]: Using interface ppp1
Mar 15 12:34:48 koca pppd[10626]: Connect: ppp1 <--> /dev/pts/2
Mar 15 12:34:48 koca pppoe[10629]: PADS: Service-Name: ''
Mar 15 12:34:48 koca pppoe[10629]: PPP session is 7009
Mar 15 12:34:48 koca pppd[10626]: local  IP address 172.26.XXX.XXX
Mar 15 12:34:48 koca pppd[10626]: remote IP address 172.26.YYY.YYY
[編集]

ルーティングの設定(手動) #

ルーティングテーブルを追加し、pingを打ってみる。ping先はFlet'sのDNSサーバ。DNSサーバアドレス一覧 で調べること。ルーティング先はフレッツ・スクウェア接続方法(ADSL-Bフレッツ、ブロードバンドルータご利用のお客さま) の、「静的ルーティング設定が必要な場合」を参照のこと。

(注意:2003.09時点でDNS、ルーティング先が変更されているが、本項目には反映していない。)

# route add -net 172.26.0.0 netmask 255.255.0.0 dev ppp1
          :

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.26.XX.XXX   *               255.255.255.255 UH    0      0        0 ppp1
133.160.XXX.XXX *               255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
172.26.0.0      *               255.255.0.0     U     0      0        0 ppp1 ★追加された
          :
default         133.160.XXX.XXX 0.0.0.0         UG    0      0        0 ppp0

# ping 172.26.35.131
PING 172.26.35.131 (172.26.35.131): 56 data bytes
64 bytes from 172.26.35.131: icmp_seq=0 ttl=255 time=17.7 ms
64 bytes from 172.26.35.131: icmp_seq=1 ttl=255 time=17.9 ms

--- 172.26.35.131 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 17.7/17.8/17.9 ms
#

NATPで使用するPCからも試してみる。失敗するときは、パケットフィルタ(iptables)の設定を確認すること。

C:> ping 172.26.35.131

Pinging 172.26.35.131 with 32 bytes of data:

Reply from 172.26.35.131: bytes=32 time=20ms TTL=254
Reply from 172.26.35.131: bytes=32 time=10ms TTL=254

Ping statistics for 172.26.35.131:
    Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 10ms, Maximum =  20ms, Average =  15ms
Control-C
^C
[編集]

DNSの設定 #

次に、フレッツスクウェア特有のホスト名(www.fletsやspeed.fletsなど)を引くために、DNSの設定を行う。

172.26.0.0/16の正引き・逆引きのみ、フレッツのDNSにforwardしてやる。この設定を現在使っているDNSサーバデーモンpdnsdでやる方法が解らなかったので(そもそもあるのか?)、手慣れたbind9に替えた。

設定はFreeBSDでPPPoE複数セッション接続で紹介されている物そのまんまで。

[編集]

ルーティング設定の自動化 #

最後に、フレッツスクウェアに接続したとき、ルーティング設定を自動的に行うようにする。

PPPoE接続したときには/etc/ppp/ip-upスクリプトが実行され、さらに/etc/ppp/ip-up.d/ のスクリプトが実行される。

/etc/ppp/ip-up.d/のスクリプトには、以下の値が環境変数として渡される。

フレッツスクウェアに接続した場合、次の値が渡された。

PPP_IFACE='ppp1'
PPP_TTY=
PPP_SPEED
PPP_LOCAL='172.26.184.XXX'
PPP_REMOTE='172.26.35.XXX'
PPP_IPPARAM=

そこで、PPP_REMOTEが172.26.XXX.XXXだったときroute設定を実行するように、/etc/ppp/if-up.d/route スクリプトを設置した。スクリプトの内容を以下に示す。

(注意:2003.09時点で、割り付けられるIPアドレスが追加されたが、以下のスクリプトには反映していない。)

#!/bin/sh -e

# Called when ppp connects

# for flet's square
# check PPP_REMOTE=172,26.XXX.XXX
SUBNET=`echo $PPP_REMOTE | cut -d. -f1,2`
if [ "x$SUBNET" = "x172.26" ] ; then
        route add -net 172.26.0.0 netmask 255.255.0.0 dev $PPP_IFACE
fi

このスクリプトの動作を確かめる。以下の下線部のように、フレッツスクウェアに接続したときにルーティングテーブルに172.26.0.0へのルートが作成されれば、OK。(★はコメント)

# poff flets-square ★切断して、
# route        ★ルーティングテーブルを見てみる。
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
133.160.XXX.XXX *               255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
default         133.160.XXX.XXX 0.0.0.0         UG    0      0        0 ppp0

# pon flets-square ★接続して、
# route        ★ルーティングテーブルを見てみる。
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.26.XX.XXX   *               255.255.255.255 UH    0      0        0 ppp1
133.160.XXX.XXX *               255.255.255.255 UH    0      0        0 ppp0
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
172.26.0.0      *               255.255.0.0     U     0      0        0 ppp1
default         133.160.XXX.XXX 0.0.0.0         UG    0      0        0 ppp0
#
[編集]

起動時に自動接続させる #

Linux起動後に自動的にフレッツスクウェアにに接続させるなら、/etc/ppp/ppp_on_boot に以下の下線部を付け加える。

#!/bin/sh

# The location of the ppp daemon itself (shouldn't need to be changed)
PPPD=/usr/sbin/pppd

# The Ethernet interface the DSL modem is connected to. If you change this,
# you also need to edit the file /etc/ppp/peers/dsl-provider.
INTERFACE=eth1

# Bring the interface up
/sbin/ifconfig $INTERFACE up -arp

$PPPD call dsl-provider

$PPPD call flets-square
[編集]

次のネタ(当分手を付けない)のメモ #

  • 複数セッションを張ったとき、デフォルトゲートウェイを持たない方pppに外部からアクセスさせるときは、たぶんipコマンド(iprouteパッケージ)で設定する必要あり。ip routeサブオプションあたりを使うのかも
  • kernel-mode PPPoEも試してみたい。