Linuxを家庭のゲートウエイとしてADSLでInternet接続する場合の各種設定に関してメモにまとめました。
思い返せば1996年5月に
「IP masqueradeとkerneldによるon-demand PPPで幸せな家庭内LANへのメモ」
からはや5年経ち、Internetへの接続環境も大きく変わりました。
当時は個人での常時接続は一部のリッチなユーザのものでしたが、現在は月額数千円でMbitオーダの接続回線が手軽に使えるようになりました。
これらをより使いこなすためにLinuxを使って簡単に設定できるところをまとめます。
ご意見は、柴田までメールでお願いします。
尚、本ドキュメントは全文丸ごとであればどこへでも転載可能/リンク可能です(^^)
2001-09-16 Ver. 0.1
家庭内LANもすっかり定着・安定してきたわが家ですが、ここ5〜6年の間に 外部接続は28.8kbpsでのモデム接続からISDNによるオンデマンドダイヤルアップ、 さらにはフレッツISDNによる常時接続へと進化してきました。
これらの進化は、接続時間を伸ばして常時接続にするという方向での進化でした。 家庭内のクライアント向けのサービスとしては、多少遅くても常時接続が出来ている と言うことが重要であり、ほぼ要求を満たすものでした。
一方、外部へのサービスを行うというニーズに対しては、ある程度高速な接続が必要であり、外部の太いネットワークに接続されているところにサーバをハウジングしなければなかなか難しいものでした。
しかしここに来て、ADSL、CATV、無線接続、FTTHといった高速接続環境も広く普及が始まっています。
こうなると、自宅のサーバを公開することも夢ではなくなりました。
ハウジング先に「リセットスイッチを押してくださいm(_|_)m」とお願いすることも
必要ありませんし、ディスクを増やすのも自由自在です。
#お金が続く限りにおいてですが(^^;
この文書では、サーバ公開をする上で必要な各種設定についてLinuxで実現する方法を順に示していきます。
手順としては、まず接続(PPPoE)、家庭内を守るファイヤーウォール(ipchains)、
サーバを公開する方法(ipmasqadm)、公開したサーバにhost名を割り振る方法(BINDでのDynamic DNS)と言う流れで説明します。
間違いや、より良い方法などありましたら教えてください。
実際の自宅のネットワーク構成(の一部(^^;)を下図に示します。
ちなみに、わが家はもともとISDNを引いており、ADSLを引く機会に、若干のコスト低減をもくろんで、メタル回線に戻そうとしたのですが、電話番号が変わると言われたため、そのままISDNを残しています。(タイプ2接続と呼ばれているものです。)
タイプ2だとISDNとの干渉が問題になるかとも心配したのですが、今のところ退官できるような不具合は全くありません。
割り当てられるIPアドレスが、接続都度変更になるのは何とかしてほしいけど...ADSL modemはNTT西日本のレンタルであり、modemとマシンA(hets)の間は10B-Tですが、家庭内は100B-Tです。
Internet<-->ISP
|
NTT
|
[ADSL modem]
|
|eth0
.------+-----. .------------.
|A NIC | |B |
| |eth1 | |
| NIC+--------------+ +-------------+NIC |
|Note PC |192.168.0.123 | | 192.168.0.12| |
`------------'hets | | `------------'hat
| |
.------------. .--+--+--. .------------.
|C | | | |C |
| NIC+-----------+ +----------+NIC |
| | | HUB | | |
| | `--------' | |
`------------'hawk `------------'hill
|
各マシンの概略仕様はそのうち追記します。
すべてLinuxを使っています。ライセンス上の問題は何もありません(^^)。
以下のソフトウエアや設定は、ADSL modemに接続されたマシンAで実施します。
どのようなディストリビューションでもいいと思います。
最近、「楽だなぁー」と思うのはVineです。redhat用の豊富なrpmが使える上に、
debianで確立されたaptが使えます。
rpmの取得には堀尾さん@北九州が砂場で運営している
ftp.rpmlinux.com
がおすすめですね。
いじり倒すなら相変わらずSlackwareかPlamoだと思います。
Debianもきっちり作るにはおすすめです。
最近の自宅内のマシンはほとんどがDebian/Gnu Linux woodyになってしまいました。
一度apt-getの楽さを知ってしまうと「もう他ではだめ」なのかも知れません(^^; (2002-05-18)
2.4系のカーネルは、自宅内の実験マシンでは既に実用的に使えていますが、
ゲートウェイとして安定的に使うのは、自分の慣れの意味もあり2.2系にしました。
カーネルはディストリビューション付属のものではなく、自前で再構築しています。
カーネルも自宅内のマシンのほとんどは2.4.xです。(2002-05-18)
PPPoEの実装はいくつかありますが、2.2系列で良く使われるのはrp-pppoeです。
本家は
http://www.roaringpenguin.com/pppoe/
です。
lukyでも公式にミラーしていて
http://roaringpenguin.luky.org/pppoe/
からもとれます。
redhat系のディストリビューションをお使いであれば、rpmを持ってきてそのまま
| rpm -i |
| rpm --rebuild |
| ./go |
実は、NTT西日本はフレッツADSLを契約すると各OS用の接続キットを CD-ROMに詰め込んで送ってくれて、Linux用のPPPoEのキットもソース込で 付いてくるのですが、MTUの設定関連でアクセスできないWebサイトがあるとか いろいろと不都合があり、結局はrp-pppoeに落ち着きました。
今では安定して動いています。
次に以下の設定fileを作ります。
専用の adsl-setup と言うコマンドでもある程度作れます。
詳しくは
how-to-connect.txt
を見てみましょう。
lock noipdefault holdoff 10 # wait 10 secs before trying to reopen connection lcp-echo-failure 4 # Connection is timedout after 4 failed echo requests lcp-echo-interval 0 # Send an lcp echo request every 30 secs. mtu 1454 #required PPP transmit frame size for PPPoE to fit in 1500 mru 1454 #required PPP receive frame size for PPPoE to fit in 1500 receive-all #permits some flexabililty in converting ethernet frames noauth #AC will not have to authenticate itself to your system #nopcomp #RFC-2516 pcomp NOT RECOMMENDED. If they ask, ok to allow. noaccomp #RFC-2516 MUST NOT ask for ACFC |
ETH='eth0' #「ユーザID」と「ISPのドメイン名」は各人の設定に合わせてね USER='ユーザID@ISPのドメイン名' DEMAND=no DNSTYPE=SPECIFY USEPEERDNS=no # 「DNS1」「DNS2」もISPから指定があったサーバのIPアドレスに合わせてね DNS1=10.0.0.1 DNS2=10.0.0.2 CONNECT_TIMEOUT=30 CONNECT_POLL=2 ACNAME= SERVICENAME= PING="." CF_BASE=`basename $CONFIG` PIDFILE="/var/run/$CF_BASE-adsl.pid" SYNCHRONOUS=no CLAMPMSS=1412 LCP_INTERVAL=20 LCP_FAILURE=3 PPPOE_TIMEOUT=80 FIREWALL=NONE LINUX_PLUGIN= PPPOE_EXTRA="" PPPD_EXTRA="" |
# PAP secrets file # Format: #name remote secret "ユーザID@ISPのドメイン名" * "パスワード" |
# CHAP secrets file # Format: #name remote secret "ユーザID@ISPのドメイン名" * "パスワード" |
とりあえず、この状態でredhat系ならば
| chkconfig --add adsl |
| /usr/sbin/adsl-start |
接続状態での/sbin/ifconfigの結果は以下のようになります。
尚、ADSL modem側のNIC(Eth0)のIPアドレスは、この場合あまり意味がありません。
(と、言うかifupしなくても良いようです。)
eth0 リンク方法:イーサーネット ハードウェアアドレス 00:80:C8:87:53:3B
inetアドレス:10.0.0.1 ブロードキャスト:10.0.0.255 マスク:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:103766133 errors:0 dropped:0 overruns:0 frame:0
TX packets:88349239 errors:0 dropped:0 overruns:0 carrier:0
衝突(Collisions):1709 TXキュー長:100
RX bytes:734847061 (700.8 Mb) TX bytes:916605863 (874.1 Mb)
割り込み:9 ベースアドレス:0x300
eth1 リンク方法:イーサーネット ハードウェアアドレス 00:E0:98:05:05:6D
inetアドレス:192.168.0.123 ブロードキャスト:192.168.0.255 マスク:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:75336055 errors:3 dropped:1806 overruns:0 frame:489
TX packets:91333879 errors:0 dropped:0 overruns:0 carrier:0
衝突(Collisions):0 TXキュー長:100
RX bytes:1423775122 (1357.8 Mb) TX bytes:1926202346 (1836.9 Mb)
割り込み:10 ベースアドレス:0x340
lo リンク方法:ローカルループバック
inetアドレス:127.0.0.1マスク:255.0.0.0
UP LOOPBACK RUNNING MTU:3924 Metric:1
RX packets:166174 errors:0 dropped:0 overruns:0 frame:0
TX packets:166174 errors:0 dropped:0 overruns:0 carrier:0
衝突(Collisions):0 TXキュー長:0
RX bytes:10578912 (10.0 Mb) TX bytes:10578912 (10.0 Mb)
ppp0 リンク方法:Point-to-Pointプロトコル
inetアドレス:61.xxx.yyy.zzz P-t-P:211.aaa.bbb.ccc マスク:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1454 Metric:1
RX packets:2082098 errors:0 dropped:0 overruns:0 frame:0
TX packets:1799927 errors:0 dropped:0 overruns:0 carrier:0
衝突(Collisions):0 TXキュー長:10
RX bytes:2090397793 (1993.5 Mb) TX bytes:192075749 (183.1 Mb)
|
psの状況も示します。
PID TTY STAT TIME COMMAND
1 ? S 0:41 init [3]
[中略]
1968 ? S 0:00 /usr/sbin/pppd pty /usr/sbin/pppoe -p
/var/run/pppoe.conf-adsl.pid.pppoe -I eth0 -T 80 -U -m 1412
noipdefault noauth default-asyncmap defaultroute hide-password
nodetach local mtu 1492 mru 1492 noaccomp noccp nobsdcomp
nodeflate nopcomp novj novjccomp user ユーザ名@ISPドメイン名
lcp-echo-interval 20 lcp-echo-failure 3
1969 ? R 35:42 /usr/sbin/pppoe -p /var/run/pppoe.conf-adsl.pid.pppoe
-I eth0 -T 80 -U -m 1412
[以下省略]
|
Linuxのポートフィルタもipfw -> ipfwadm -> ipchainsと進化しています。
2.4系のカーネルではさらに機能豊富なiptablesを使うようです。
2.2系のカーネルを採用したほとんどのディストリビューションで
ipchainsは採用されているようなので、インストールに関しては省略します。
シンプルな設定に関しては2 .関連情報/参考文献に
示してある文献を参考にして設定すれば十分でしょう。
以下は、私がマシンAで設定しているものです。
穴を見つけたら、教えてください(^^;
#!/bin/sh # # fire wall setting on hets.luky.org /etc/rc.d/rc.ipchains # last updated: 2001-04-21 Hisaaki Shibata |
ipmasqで囲ったプライベートアドレス空間上のサーバを外部に公開する方法として
ipmasqadmを使ったポート転送(port forwarding)を使う方法があります。
man pageにもport forwardingに関して詳しい記述はないですが、簡単な使い方は
/usr/sbin/ipmasqadm portfw -h を実行すると、下記のように表示される。
Usage: portfw -a -P PROTO -L LADDR LPORT -R RADDR RPORT [-p PREF] add entry
portfw -d -P PROTO -L LADDR LPORT [-R RADDR RPORT] delete entry
portfw -f clear table
portfw -l list table
portfw
|
ここでは、外部からマシンAのポート80(www)へのアクセスに対して、
家庭内のマシンB(192.168.0.12)のポート80へ単純に転送する、
つまりマシンBを外部に公開する例を示します。
コマンドレベルだと以下のようになります。
/usr/sbin/ipmasqadm portfw -f /usr/sbin/ipmasqadm portfw -a -P tcp -L ppp0のIPアドレス 80 -R 192.168.0.12 80 |
しかし、これをこのままスクリプトに埋め込むことはできません。
と言うのも私が契約しているISPはADSLユーザに対して固定IPアドレスを割り振らず、
接続毎にダイナミックにIPアドレスを割り振るため、接続都度IPアドレスが
変わるからです。
また、こちらから故意にISPへの接続を切らない場合でもどういうタイミングだか
わかりませんが、接続が切られる事があります。
再接続後は全く別のIPアドレスが割り振られています。
(再接続するようなrp-pppoeの設定にしているからまだ良い方なのですが)
ISPから割り振られたIPアドレスは /usr/sbin/ifconfig ppp0を実行すると、 下記のように表示されますので、これをipmasqadmの引数として渡せば良さそうです。
ppp0 リンク方法:Point-to-Pointプロトコル
inetアドレス:61.xxx.yyy.zzz P-t-P:211.aaa.bbb.ccc マスク:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1454 Metric:1
RX packets:2091425 errors:0 dropped:0 overruns:0 frame:0
TX packets:1809497 errors:0 dropped:0 overruns:0 carrier:0
衝突(Collisions):0 TXキュー長:10
RX bytes:2092322201 (1995.3 Mb) TX bytes:193103042 (184.1 Mb)
|
最も手間をかけずにやるときは、私はsedやawkをshellと組み合わせて使います。
例えば、下記のような感じです。
#!/bin/sh
echo "/usr/sbin/ipmasqadm portfw -f" > /tmp/ipmasqfw.sh
LANG=c /sbin/ifconfig ppp0|grep inet|\
sed 's/ *inet addr:/\/usr\/sbin\/ipmasqadm portfw -a -P tcp -L /;
s/ P-t-P.*/ 80 -R 192.168.0.12 80/;' >> /tmp/ipmasqfw.sh
. /tmp/ipmasqfw.sh
/bin/rm -f /tmp/ipmasqfw.sh
|
もっと最適化したやり方があるとか、本当はテンポラリなファイルを作らない方が 良いとか、セキュリティ上/tmpじゃない方が良いとか、エラー時にはそれなりの 報告をするとかいろいろありますので、その辺りのチェック/変更を加えれば 尚良いかと思います。
また、ftpサーバを公開したい場合のコマンドラインは
/usr/sbin/ipmasqadm portfw -f /usr/sbin/ipmasqadm portfw -a -P tcp -L ppp0のIPアドレス 20 -R 192.168.0.12 20 /usr/sbin/ipmasqadm portfw -a -P tcp -L ppp0のIPアドレス 21 -R 192.168.0.12 21 |
今までの所で家庭内LANのサーバを外部に公開するまでは出来ましたが、
ダイナミックに割り振られるIPアドレスをどうやって人に伝えるのかという
問題があります。
また、IPアドレスをURIとして人に伝える事ができたとしても、
次のタイミングでIPアドレスがわかることがあるので、
ドキュメントとして残すことはできません。
これらを解決する方法としてDynamic DNSと言うものがあります。
世の中にはDynamic DNSのサービスを無償で提供しているプロバイダもあるようですが、 ドメイン名はそのプロバイダのものであり、サブドメイン部分またはホスト名部分だけ が自前のものであるのは、私はちょっと頂けません。
外部にDNSに関して自由になるサーバがある事が前提(^^;になりますが、自前でDynamic
DNSサーバをあげてみましょう。
最近のBINDは非常に簡単にDynamic DNSが実現できます。
まず、静的なIPアドレスを持つDNS サーバをあげてみましょう。
以下のような設定を例とします。
より詳細な設定に関しては2 .関連情報/参考文献の
bind-8 のインストールメモ
などを参照してください。
options {
directory "/etc/named.db";
/*
* If there is a firewall between you and nameservers you want
* to talk to, you might need to uncomment the query-source
* directive below. Previous versions of BIND always asked
* questions using port 53, but BIND 8.1 uses an unprivileged
* port by default.
*/
// query-source address * port 53;
};
//
// boot file for name server
//
// NOTE: unconverted directive 'type domain source host/file backup file'
zone "." {
type hint;
file "named.root";
};
// NOTE: unconverted directive 'domain luky.org'
zone "localhost" {
type master;
file "localhost.d";
};
zone "0.0.127.IN-ADDR.ARPA" {
type master;
file "localhost.rev";
};
zone "UriUri.com" {
type master;
file "uriuri.com.zone";
allow-update { 127.0.0.1; 211.8.90.175;};
allow-transfer { any; };
allow-query { any; };
};
|
固定アドレスで割り当てるzoneファイルは下記のように普通に作成します。
;BIND DUMP V8 $ORIGIN com. UriUri 172800 IN MX 10 hoop.uriuri.com. ;Cl=2 172800 IN NS hoop.uriuri.com. ;Cl=2 172800 IN SOA hoop.uriuri.com. root.hoop.uriuri.com. ( 2001091007 7200 1800 1209600 172800 ) ;Cl=2 $ORIGIN UriUri.com. hoop 172800 IN MX 10 hoop.uriuri.com. ;Cl=2 172800 IN A 211.8.190.175 ;Cl=2 localhost 172800 IN A 127.0.0.1 ;Cl=2 mail 172800 IN MX 10 hoop.uriuri.com. ;Cl=2 www 172800 IN CNAME hoop.uriuri.com. ;Cl=2 hets 1200 IN A 61.xxx.yyy.zzz ;Cl=2 ns 172800 IN CNAME hoop.uriuri.com. ;Cl=2 ftp 172800 IN CNAME hoop.uriuri.com. ;Cl=2 |
動的なエントリの追加削除はnsupdateコマンドで実現できます。
試しに上記のサーバにloginして実行してみます。
root@hoop(6)$ nsupdate > update delete hets.uriuri.com A > update add hets.uriuri.com 300 A 61.xxx.yyyy.zzz > |
エラーも出なくてうまく行っているようだったら、nslookupしてみます。
root@hoop(14)$ nslookup Default Server: hoop.uriuri.com Address: 211.8.190.175 > hets.uriuri.com Server: hoop.uriuri.com Address: 211.8.190.175 Name: hets.uriuri.com Address: 61.xxx.yyy.zzz > exit |
念のためlogも見てみます。
この場合のlogは/etc/named.db/uriuri.com.zone.logになります。
;BIND LOG V8
[DYNAMIC_UPDATE] id 47831 from [211.8.190.175].4991 at 1000640318 (named pid 1346):
zone: origin UriUri.com class IN serial 2001091007
update: {delete} hets.uriuri.com. IN A
update: {add} hets.uriuri.com. 300 IN A 61.xxx.yyy.zzz
|
後は、ADSLゲートウェイとなっているマシンA側のIPアドレス割り当てに変更が あったときに、DNSサーバ上で上記コマンドを実行すれば良いことがわかります。
ここで問題になるのは、二つの点です。
どうやってIPアドレスが変わったことを検知するのかという事と、変更後のIPアドレス
を持つマシンAからDNSサーバ上でnsupdateを実行するかという事です。
これに関するスマートな解は ねぎ式: Dynamic DNS で固定ホスト名にして遊ぼう に書かれていますので、これを利用する方が良いでしょう。
私も、先に知っていれば上記のやり方をそのままパクっていたと思いますが、 私はもっと泥臭いやり方でやってます(^^;
まず、マシンA側でIPアドレスの変更を検知する方法ですが、
cronで1分毎にppp0に割り当てられているIPアドレスをチェックしています。
検知方法自体はipmasqadmのところで実現していますから、
これをちょっと修正すれば良いことがわかります。
具体的にはcrontabに下記のような記述をしています。
* * * * * /home/shibata/check_ip.sh |
check_ip.shは以下のようなものです。すごく泥臭いですね(^^;
#!/bin/sh /bin/mv -f /tmp/pppoe_ip.now /tmp/pppoe_ip.old /sbin/ifconfig ppp0|grep inet > /tmp/pppoe_ip.now diff /tmp/pppoe_ip.old /tmp/pppoe_ip.now > /tmp/pppoe_ip.diff if [ -s /tmp/pppoe_ip.diff ]; then /bin/mail -s hets.pppoe-ip_change 携帯電話のメールアドレス < /tmp/pppoe_ip.diff RSYNC_PASSWORD=hogehoge /usr/bin/rsync -av -e ssh /tmp/pppoe_ip.now nameduser@hoop.euqset.org::named) fi echo > /dev/null #end |
もちろんDNSサーバ側ではrsync --daemonを動かしておく必要があります。
ここではrsyncを動かすのに必要な/etcrsyncd.confの例だけを示しておきます。
# # /etc/rsyncd.conf # for hoop.uriuri.com # #global uid = nobody gid = nogroup use chroot = no max connections = 2 syslog facility = local5 pid file = /var/run/rsyncd.pid [named] path = /home/named comment = hoop.uriuri.com /home/named read only = no hosts allow = 61.0.0.0/8,hoop.uriuri.com auth users = nameduser secrets file = /etc/rsyncd.secrets |
さて、DNSサーバ側では以下のような設定にしてます。これまた泥臭い(^^;
まず、crontabです。
* * * * * /home/named/dnsup.sh |
上記で起動しているdnsup.shも示します。
#!/bin/sh
/bin/cat /home/named/hets.uriuri.com-templ > /home/named/hets.uriuri.com-ip
/bin/cat /home/named/pppoe_ip.now|\
sed 's/.* addr:/update add hets.uriuri.com 300 A /;
s/ *P-t-P.*//'>>/home/named/hets.uriuri.com-ip
echo >>/home/named/hets.uriuri.com-ip
/usr/bin/nslookup hets.uriuri.com hoop.uriuri.com|tail -2|head -1|sed 's/Address: *//' > /home/named/dns.now
/bin/cat /home/named/pppoe_ip.now|sed 's/.* addr://;s/ *P-t-P.*//' > /home/named/dns.next
/usr/bin/diff /home/named/dns.now /home/named/dns.next > /home/named/dns.diff
if [ -s /home/named/dns.diff ]
then
/usr/bin/nsupdate /home/named/hets.uriuri.com-ip
/usr/bin/nslookup hets.uriuri.com hoop.uriuri.com|\
mail -s "hets.uriuri.com IP change" shibata@luky.org
else
echo >/dev/null
fi
|
手間ひまをかけるよりも、安価な家庭用のブロードバンドルータと呼ばれるものが 出てきている(^^;
メールでの通知を行う方法も実施しました。簡単なので今は省略。(2002-05-18)(2)外部向けのサーバの構築を急ぐ。具体的にはストリーミング系のサービスを行いたい。
こちらも、一時期自宅にUSBカメラを置いて灰皿と温度計を監視し、灰皿から煙が立ち上っていないか、またPC内の温度が上がりすぎていないかを外部から監視できるようにしていました。(2002-05-18)
OpenBlockSでも動いたのですが、移行が面倒なのでそのままにしています。(3)bootable CD-ROMとFDの組合わせで今回の仕組みを実現する。
また、その後B-Fletsに移行したのを期に専用BBルータであるCentury Systems社XR-300に移行しました。
XR-300のハード構造はOpenBlockSSと同じであり、OSもLinuxで動いています。iptablesの定義などもそのまま行けるので楽しちゃいました。(2002-06-18)
XR-300に移行しちゃったので、なしですm(_|_)m (2002-06-18)(4)外部からのアタックレポートを公開する。
これはやめとこ(^^; (2002-06-18)
実は既に申し込み済です。(2001-10-09)
上記に書いたように、現在B-Flets + XR-300環境です。
でもお金はありません(^^;; (2002-06-18)
私がLinuxを使えるようにしてくださったすべての方に感謝いたします。
また、この文書作成にあたっては、JFをはじめとする多くのドキュメントを参考にさせて頂いています。ありがとうございますm(_|_)m
尚、今回のADSL対応サーバ構築においては、九州ギガポッププロジェクト:qgpopにおけるADSL実験として、複数ISPでの比較をする機会を頂きました。
特にqgpopリーダの平原様と、ISITにてADSL実験を取纏めて下さった大部様に感謝の意を表します。