2002年5月18日土曜日

Happy Linux Home-LAN with ADSL, rp-pppoe, ipchains, ipmasqadm, Dynamic DNS



「幸せな家庭内LANへのメモ ~ ADSL, rp-pppoe, ipchains, ipmasqadm, Dynamic DNS ~」


http://his.luky.org/doc/adsl.html



Ver0.3 2002-05-18 Copyright(C) 2002, Hisaaki Shibata/柴田 尚明@福岡
shibata@luky.org


Linuxを家庭のゲートウエイとしてADSLでInternet接続する場合の各種設定に関してメモにまとめました。

思い返せば1996年5月に

「IP masqueradeとkerneldによるon-demand PPPで幸せな家庭内LANへのメモ」

からはや5年経ち、Internetへの接続環境も大きく変わりました。

当時は個人での常時接続は一部のリッチなユーザのものでしたが、現在は月額数千円でMbitオーダの接続回線が手軽に使えるようになりました。

これらをより使いこなすためにLinuxを使って簡単に設定できるところをまとめます。

ご意見は、柴田までメールでお願いします。


尚、本ドキュメントは全文丸ごとであればどこへでも転載可能/リンク可能です(^^)





目次



0 .来歴・トピックス

1 .経緯

2 .関連情報/参考文献

3 .用意したhardware

4 .用意したsoftware


5 .動作確認をしたもの

6 .いくつかの問題点

7 .TODO

8 .謝辞





0.来歴・トピックス


[次へ][目次へ]


2001-09-16 Ver. 0.1


  • 新規作成

2001-10-09 Ver. 0.2

  • 誤記訂正/ADSL種別の記述追加

2002-05-16 Ver. 0.3

  • 誤記訂正とその後の経過を追記





1.経緯

[次へ][前へ][目次へ]


家庭内LANもすっかり定着・安定してきたわが家ですが、ここ5~6年の間に
外部接続は28.8kbpsでのモデム接続からISDNによるオンデマンドダイヤルアップ、
さらにはフレッツISDNによる常時接続へと進化してきました。



これらの進化は、接続時間を伸ばして常時接続にするという方向での進化でした。
家庭内のクライアント向けのサービスとしては、多少遅くても常時接続が出来ている
と言うことが重要であり、ほぼ要求を満たすものでした。



一方、外部へのサービスを行うというニーズに対しては、ある程度高速な接続が必要であり、外部の太いネットワークに接続されているところにサーバをハウジングしなければなかなか難しいものでした。



しかしここに来て、ADSL、CATV、無線接続、FTTHといった高速接続環境も広く普及が始まっています。

こうなると、自宅のサーバを公開することも夢ではなくなりました。

ハウジング先に「リセットスイッチを押してくださいm(_|_)m」とお願いすることも
必要ありませんし、ディスクを増やすのも自由自在です。

��お金が続く限りにおいてですが(^^;




この文書では、サーバ公開をする上で必要な各種設定についてLinuxで実現する方法を順に示していきます。

手順としては、まず接続(PPPoE)、家庭内を守るファイヤーウォール(ipchains)、
サーバを公開する方法(ipmasqadm)、公開したサーバにhost名を割り振る方法(BINDでのDynamic DNS)と言う流れで説明します。

間違いや、より良い方法などありましたら教えてください。






2.関連情報/参考文献

[次へ][前へ][目次へ]










3.用意したhardware

[次へ][前へ][目次へ]



  • 複数台のPC+NIC
  • HUB
  • UTP Cable
  • ADSL modem



実際の自宅のネットワーク構成(の一部(^^;)を下図に示します。


ちなみに、わが家はもともとISDNを引いており、ADSLを引く機会に、若干のコスト低減をもくろんで、メタル回線に戻そうとしたのですが、電話番号が変わると言われたため、そのままISDNを残しています。(タイプ2接続と呼ばれているものです。)



タイプ2だとISDNとの干渉が問題になるかとも心配したのですが、今のところ退官できるような不具合は全くありません。


割り当てられるIPアドレスが、接続都度変更になるのは何とかしてほしいけど...

ADSL modemはNTT西日本のレンタルであり、modemとマシンA(hets)の間は10B-Tですが、家庭内は100B-Tです。


家庭内LANを使う場合、プライベートaddress空間を使うべきですね。
私は、192.168.0.0/24を使っています。

今回の主役は、ゲートウェイとなっている下図中のノートPC機であるマシンA(hets)です。





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を使っています。ライセンス上の問題は何もありません(^^)。





4.用意したsoftware

[次へ][前へ][目次へ]



以下のソフトウエアや設定は、ADSL modemに接続されたマシンAで実施します。



4.1 Linux ディストリビューション



どのようなディストリビューションでもいいと思います。

最近、「楽だなぁー」と思うのはVineです。redhat用の豊富なrpmが使える上に、
debianで確立されたaptが使えます。

rpmの取得には堀尾さん@北九州が砂場で運営している
ftp.rpmlinux.com
がおすすめですね。

いじり倒すなら相変わらずSlackwareかPlamoだと思います。
Debianもきっちり作るにはおすすめです。



最近の自宅内のマシンはほとんどがDebian/Gnu Linux woodyになってしまいました。

一度apt-getの楽さを知ってしまうと「もう他ではだめ」なのかも知れません(^^; (2002-05-18)



4.2 linux-2.2.19.tar.bz2 or later



2.4系のカーネルは、自宅内の実験マシンでは既に実用的に使えていますが、
ゲートウェイとして安定的に使うのは、自分の慣れの意味もあり2.2系にしました。

カーネルはディストリビューション付属のものではなく、自前で再構築しています。


カーネルも自宅内のマシンのほとんどは2.4.xです。(2002-05-18)



4.3 rp-pppoe-3.3 or later



PPPoEの実装はいくつかありますが、2.2系列で良く使われるのはrp-pppoeです。

本家は

http://www.roaringpenguin.com/pppoe/

です。

lukyでも公式にミラーしていて

http://roaringpenguin.luky.org/pppoe/

からもとれます。


redhat系のディストリビューションをお使いであれば、rpmを持ってきてそのまま


rpm -i

するか、srpmを持ってきて

rpm --rebuild

としてrpmをつくってからインストールしてください。

tar.gzのソースを持ってきた方はtar xvfzした後に、展開されたディレクトリにcdして

./go

で構築できます。



実は、NTT西日本はフレッツADSLを契約すると各OS用の接続キットを
CD-ROMに詰め込んで送ってくれて、Linux用のPPPoEのキットもソース込で
付いてくるのですが、MTUの設定関連でアクセスできないWebサイトがあるとか
いろいろと不都合があり、結局はrp-pppoeに落ち着きました。

今では安定して動いています。




次に以下の設定fileを作ります。

専用の adsl-setup と言うコマンドでもある程度作れます。

詳しくは

how-to-connect.txt

を見てみましょう。




/etc/ppp/options.pppoe




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



/etc/ppp/pppoe.conf


コメント行は除きました。



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=""




/etc/ppp/pap-secrets


このファイルのオーナはroot、パーミッションは600すね。



# PAP secrets file
# Format:
#name remote secret
"ユーザID@ISPのドメイン名" * "パスワード"



/etc/ppp/chap-secrets


このファイルのオーナもroot、パーミッションは600すね。




# CHAP secrets file
# Format:
#name remote secret
"ユーザID@ISPのドメイン名" * "パスワード"




とりあえず、この状態でredhat系ならば


chkconfig --add adsl

その他の場合は

/usr/sbin/adsl-start

で接続するはずです。

redhat系以外の場合は /etc/rc.d/rc.local の最後の方にでも /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
[以下省略]






4.4 ipchains 1.3.10 or later



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
# last updated: 2001-02-15 Hisaaki Shibata
# original: 2000-07-09 Hisaaki Shibata

#<参考文献>
# Linux IPCHAINS-HOWTO by Rusty Russell
# v1.0.8, Tue Jul 4 14:20:53 EST 2000
# http://www.linuxdoc.org/HOWTO/IPCHAINS-HOWTO.html
#
# Top Ten Blocking Recommendations Using ipchains
# Paul Tiedemann August 8, 2000
# http://www.sans.org/infosecFAQ/firewall/blocking_ipchains.htm
#
# TrinityOS: A Guide to Configuring Your Linux Server for
# Performance, Security, and Managability
# David A. Ranch, dranch@trinnet.net October 15, 2000
# http://www.ecst.csuchico.edu/~dranch/LINUX/TrinityOS/cHTML/\
# TrinityOS-101500c.html
#
# 森岡さんの設定
# Message-Id: <20010120120521084.OZC.13014.t-mta2.odn.ne.jp@mta2.odn.ne.jp>

#<ネットワーク接続図>
# Flets ADSL経由で The Internet へ
# |
# ppp0 | Dynamic Address Assign 0.0.0.0/255.255.255.255
# +-----+-----+
# | |
# | | eth0
# | +----- PPPoE用インタフェース(ADSLモデムへストレート接続)
# | | 10.0.0.1/255.0.0.0
# | |
# +-----+-----+
# eth1 | 192.168.0.123/255.255.255.0
# |
# 家庭内部LANへ

#<下記のipchainsの設定ポリシー>
#

# ・input chainsは、必要なもののみACCEPTにして、それ以外は最後にDENY。
# ・output chainsは、全てACCEPTにする。(つまりdefaultのまま)
#
#
# ・PPPoE-LANに対してはipmasqueradeもroutingも行わない
# ・全てDENYにする。
#
#
# ・内部LANに対してはroutingを行う
# ・input chainsは、必要なもののみACCEPTにして、それ以外は最後にDENY。
# ・input chainsで許可したアクセスで且つ外部LANへのforward chainsは、
# 全てACCEPTにする。
# ・output chainsは、全てACCEPTにする。(つまりdefaultのまま)

#
#IPCHAINS="/sbin/ipchains -v "
IPCHAINS=/sbin/ipchains

# 結局、1024: 以降の全てが、リモートホストの短命ポート
# reph_portとは、remote ephemeral portの略
reph_port=1024:
echo "local ephemeral port=" $reph_port

#
# ping -bに答えない
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Enable bad error message protection
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# ipmasqのためにroutingする
echo 1 > /proc/sys/net/ipv4/ip_forward
# source routing禁止
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 > /proc/sys/net/ipv4/conf/default/accept_source_route
# IP defrag
echo 0 >/proc/sys/net/ipv4/ip_always_defrag
# TCP SYN Cookie Protection
echo 1 >/proc/sys/net/ipv4/tcp_syncookies
# source address 確認
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $f
done
# ICMP Redirect 受付けない
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do
echo 0 > $f
done
# source routed packets 受付けない
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
echo 0 > $f
done
# spoofed, source-routed, redirect packets のロギング
for file in /proc/sys/net/ipv4/conf/*/log_martians; do
echo "1" > $file
done

####################################################
# 2001.06.02 shibata@luky.org
/sbin/insmod ip_masq_ftp
/sbin/insmod ip_masq_irc
/sbin/insmod ip_masq_raudio
/sbin/insmod ip_masq_portfw

####################################################
#
# リモートからのオペレーションチョンボを行ったときに
# 困るので(^^;、default policyはACCEPTにしておく。
# (堅くしたい人はDENYにしてもいいけど)
# また、再設定時にも有効になるようにルールをフラッシュする。
$IPCHAINS -X
$IPCHAINS -P input ACCEPT
$IPCHAINS -F input
$IPCHAINS -P output ACCEPT
$IPCHAINS -F output
$IPCHAINS -P forward ACCEPT
$IPCHAINS -F forward

# まず最初に、スクリプト起動時に筒抜けになるのを防止するため、
# local loop back以外の全ての入口を閉じて forwarding も禁止する。
# 最後にこのinput chainをdeleteしないと何もできなくなる(^^;
# こうするべきであるが、スクリプトにチョンボがあって最後まで行かないと
# 困るので、初期ポリシーは素通しにしておく。

# local loop backに関しては全開
$IPCHAINS -A input -i lo -j ACCEPT

# 全ての戻りtcpパケット(localの短命ポート向けでSYNが立っていないもの)は許可
# ソースポートも縛る方がいいかもしれないが、コネクションが確立していない
# はずなので、これでよしとする
# ftpのPASVモードについては、もっと下の方で許可している
# ログ残さない
$IPCHAINS -A input -p tcp --dport $reph_port ! -y -j ACCEPT

# for home network
# eth1がsourceで、192.168.0.0/24からのもの
$IPCHAINS -A input -s 192.168.0.0/24 -i eth1 -j ACCEPT

# IP spoofing防止 (local loop back , private addr., local link ddr.)
# 下記の192.168.0.0/16からのパケットで、eth1からの正しいものは
# 直上のルールでACCEPTされているから、ここで弾かれるのはspoofing
# みてる暇がないのだが、統計情報取得のためログ取ってステ
$IPCHAINS -A input -b -s 127.0.0.0/8 -j DENY -l
$IPCHAINS -A input -b -s 10.0.0.0/8 -j DENY -l
$IPCHAINS -A input -b -s 172.16.0.0/12 -j DENY -l
$IPCHAINS -A input -b -s 169.254.0.0/16 -j DENY -l
$IPCHAINS -A input -b -s 192.168.0.0/16 -j DENY -l
$IPCHAINS -A input -b -s 240.0.0.0/5 -j DENY -l
$IPCHAINS -A input -b -s 255.255.255.255/32 -j DENY -l

# IP spoofing防止 (内部LAN)
# eth1 からで、ソースアドレスが 192.168.0.0/24以外のパケットはログ取ってステ
$IPCHAINS -A input -s ! 192.168.0.0/24 -i eth1 -j DENY -l

# やたら来るものもログ取って捨てる
# UDP echo Broadcast
$IPCHAINS -A input -p udp --dport 7 -j DENY -l
# Incoming NETBIOS Broadcast
$IPCHAINS -A input -p udp --dport 137:139 -j DENY -l
# Incoming RIP Broadcast
$IPCHAINS -A input -p udp --sport route --dport route -j DENY -l
# Incoming BOOTP Broadcast
$IPCHAINS -A input -p udp --dport bootps:bootpc -j DENY -l
# ICMP router discovery
$IPCHAINS -A input -p icmp --sport 9:10 -j DENY -l
# SUNRPC
$IPCHAINS -A input -p tcp --dport 111 -j DENY -l

# 全てのネットワークに対して開放するサービス
# ICMPは限定して通す
# ICMP echo
$IPCHAINS -A input -p icmp --sport 0 -j ACCEPT
# ICMP destination unreachable
$IPCHAINS -A input -p icmp --sport 3 -j ACCEPT
# ICMP source quench
$IPCHAINS -A input -p icmp --sport 4 -j ACCEPT
# ICMP echo request
$IPCHAINS -A input -p icmp --sport 8 -j ACCEPT
# ICMP time exceeded
$IPCHAINS -A input -p icmp --sport 11 -j ACCEPT
# ICMP parameter problem
$IPCHAINS -A input -p icmp --sport 12 -j ACCEPT

# IGMP
$IPCHAINS -A input -p igmp -j ACCEPT

# 全てのネットワークに対して開放するサービス
# ssh,DNS,www,https,smtp,ftp,ftp-data,auth,rsync,ntp,snmp,irc

# ftp-data 20 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 20 ! -y -j ACCEPT -l
$IPCHAINS -A input -p tcp --sport 20 --dport $reph_port -j ACCEPT
# for pasv transfer mode
$IPCHAINS -A input -p tcp --sport $reph_port --dport $reph_port ! -y -j ACCEPT

# ftp 21 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 21 -j ACCEPT -l

# ssh 22 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 22 -j ACCEPT

# 禁止だけど、一応エントリだけ書いておく
# # telnet 23 (tcp)
# $IPCHAINS -A input -p tcp --sport $reph_port --dport 23 -j ACCEPT

# smtp 25 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 25 -j ACCEPT

# time 37 (tcp+udp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 37 -j ACCEPT
$IPCHAINS -A input -p udp --sport $reph_port --dport 37 -j ACCEPT

# domain 53 (tcp+udp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 53 -j ACCEPT
$IPCHAINS -A input -b -p udp --sport $reph_port --dport 53 -j ACCEPT
$IPCHAINS -A input -p udp --sport 53 --dport 53 -j ACCEPT

# www 80 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 80 -j ACCEPT

# pop-3 110 (tcp)
# ssh経由でlocalhostからのみ許可なので、エントリだけ書く
# localhostからは、何でもありなので、書かない。
#$IPCHAINS -A input -p tcp --sport $reph_port --dport 110 -j ACCEPT

# auth 113 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 113 -j ACCEPT

# ntp 123 (tcp+udp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 123 -j ACCEPT -l
$IPCHAINS -A input -p udp --sport $reph_port --dport 123 -j ACCEPT -l
$IPCHAINS -A input -p tcp --sport 123 --dport 123 -j ACCEPT -l
$IPCHAINS -A input -p udp --sport 123 --dport 123 -j ACCEPT -l

# snmp 161 (tcp+udp)
#$IPCHAINS -A input -p tcp --sport $reph_port --dport 161 -j ACCEPT
#$IPCHAINS -A input -p udp --sport $reph_port --dport 161 -j ACCEPT

# snmp-trap 162 (udp)
#$IPCHAINS -A input -p udp --sport $reph_port --dport 162 -j ACCEPT

# irc 194 (tcp+udp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 194 -j ACCEPT
#$IPCHAINS -A input -p udp --sport $reph_port --dport 194 -j ACCEPT

# https 443 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 443 -j ACCEPT

# rsync 873 (tcp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 873 -j ACCEPT

# ircd 6660-6668 (tcp+udp)
$IPCHAINS -A input -p tcp --sport $reph_port --dport 6660:6668 -j ACCEPT
#$IPCHAINS -A input -p udp --sport $reph_port --dport 6660:6668 -j ACCEPT

# 家庭用ipmasq
$IPCHAINS -A forward -s 192.168.0.0/24 -d 0/0 -j MASQ

# 最後に、上記のchainsに該当しない input パケットを全てDENYする。
# forward パケットもDENYする。
# ログを残す
$IPCHAINS -A input -i ! lo -j DENY -l
$IPCHAINS -A forward -j DENY -l

# end of rc.ipchains




4.5 ipmasqadm-0.4.2 or later




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 -n no names

PROTO is the protocol, can be "tcp" or "udp"
LADDR is the local interface receiving packets to be forwarded.
LPORT is the port being redirected.
RADDR is the remote address.
RPORT is the port being redirected to.
PREF is the preference level (load balancing, default=10)


単純なポートの転送だけでなく、重みをつけて複数の転送を定義できることも
わかります。



ここでは、外部からマシン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


となります。これらも設定したい方はちょっとした変更で応用できます。





4.6 BIND-8.2.4 or later




今までの所で家庭内LANのサーバを外部に公開するまでは出来ましたが、
ダイナミックに割り振られるIPアドレスをどうやって人に伝えるのかという
問題があります。

また、IPアドレスをURIとして人に伝える事ができたとしても、
次のタイミングでIPアドレスがわかることがあるので、
ドキュメントとして残すことはできません。

これらを解決する方法としてDynamic DNSと言うものがあります。



世の中にはDynamic DNSのサービスを無償で提供しているプロバイダもあるようですが、
ドメイン名はそのプロバイダのものであり、サブドメイン部分またはホスト名部分だけ
が自前のものであるのは、私はちょっと頂けません。



外部にDNSに関して自由になるサーバがある事が前提(^^;になりますが、自前でDynamic
DNSサーバをあげてみましょう。

最近のBINDは非常に簡単にDynamic DNSが実現できます。



まず、静的なIPアドレスを持つDNS サーバをあげてみましょう。


以下のような設定を例とします。

より詳細な設定に関しては
2 .関連情報/参考文献

bind-8 のインストールメモ

などを参照してください。


/etc/named.conf




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; };
};



上記のポイントは allow-update のエントリです。

zone ファイルのエントリ更新を許可する host の IP アドレスを記述します。

この例では localhost の IP アドレスと、その DNS サーバのIPアドレスを記述しています。

(あちこちから勝手に更新されてはひどいことになりますので。)



固定アドレスで割り当てるzoneファイルは下記のように普通に作成します。

/etc/named.db/uriuri.com.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



上記のうち、hetsの行は、Dynamic DNSによって付け加えられたエントリーです。



動的なエントリの追加削除はnsupdateコマンドで実現できます。

試しに上記のサーバにloginして実行してみます。



root@hoop(6)$ nsupdate
> update delete hets.uriuri.com A
> update add hets.uriuri.com 300 A 61.xxx.yyyy.zzz
>




update addの後は、空リターンを実行し、その後はctrl-dで抜けます。



エラーも出なくてうまく行っているようだったら、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は以下のようなものです。すごく泥臭いですね(^^;

/home/shibata/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



アドレスに変更があると、携帯電話にメールが来るようにしています。

これは、一応知っておきたいという事と、携帯からさらに普通のe-mailに
転送することで、どういうタイミングでアドレスの再割り当てが発生しているかの
ログを残すためです。

さらに、DNSサーバ側にはrsyncでファイルを転送しています。

(メールでの転送からprocmail私に変えようかとも思って途中まで出来ているのですが、
ねぎ式を越えるのはなかなか難しそう。)



もちろんDNSサーバ側ではrsync --daemonを動かしておく必要があります。

ここではrsyncを動かすのに必要な/etcrsyncd.confの例だけを示しておきます。

/etc/rsyncd.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も示します。

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






5.動作確認をしたもの

[次へ][前へ][目次へ]




  • 家庭内LANの複数のhostから外部アクセスが出来ている
  • IPアドレス割り当ての変更があったことがDynamic DNSに反映される
  • 家庭内LAN上のWebサーバが、外部から参照できる



6.いくつかの問題点

[次へ][前へ][目次へ]


手間ひまをかけるよりも、安価な家庭用のブロードバンドルータと呼ばれるものが
出てきている(^^;



7. TODO

[次へ][前へ][目次へ]



7.1 必ずやる


(1)Dynamic DNSでのIPアドレス変更通知方式をもう少しまともにしたい


メールでの通知を行う方法も実施しました。簡単なので今は省略。(2002-05-18)

(2)外部向けのサーバの構築を急ぐ。具体的にはストリーミング系のサービスを行いたい。

こちらも、一時期自宅にUSBカメラを置いて灰皿と温度計を監視し、灰皿から煙が立ち上っていないか、またPC内の温度が上がりすぎていないかを外部から監視できるようにしていました。(2002-05-18)

7.2 気が向いたら...


(1)プロキシ(squid)やIRCエージェント(plum)、時刻同期サーバ(xntpd)なども
動かしているので、これらも追記するか別文書にまとめる。

(2)現在ノートPCで実現しているゲートウエイをOpenBlockSに移行する。



OpenBlockSでも動いたのですが、移行が面倒なのでそのままにしています。

また、その後B-Fletsに移行したのを期に専用BBルータであるCentury Systems社XR-300に移行しました。
XR-300のハード構造はOpenBlockSSと同じであり、OSもLinuxで動いています。iptablesの定義などもそのまま行けるので楽しちゃいました。(2002-06-18)

(3)bootable CD-ROMとFDの組合わせで今回の仕組みを実現する。


XR-300に移行しちゃったので、なしですm(_|_)m (2002-06-18)

(4)外部からのアタックレポートを公開する。


これはやめとこ(^^; (2002-06-18)

7.3 お金があったら...



(1)Bフレッツに移行。

実は既に申し込み済です。(2001-10-09)

上記に書いたように、現在B-Flets + XR-300環境です。

でもお金はありません(^^;; (2002-06-18)




8.謝辞

[次へ][前へ][目次へ]


私がLinuxを使えるようにしてくださったすべての方に感謝いたします。


また、この文書作成にあたっては、JFをはじめとする多くのドキュメントを参考にさせて頂いています。ありがとうございますm(_|_)m



尚、今回のADSL対応サーバ構築においては、九州ギガポッププロジェクト:qgpopにおけるADSL実験として、複数ISPでの比較をする機会を頂きました。

特にqgpopリーダの平原様と、ISITにてADSL実験を取纏めて下さった大部様に感謝の意を表します。


以上


[玄関へ]
[総本店へ]



Last modified: Sat May 18 11:48:22 JST 2002


0 件のコメント:

コメントを投稿