2007/03/05(月)攻撃されるcgiと止まるサーバ

SPAMの激しい攻撃

どうもサーバがやけに重たいなぁーと思っていろいろ調べてみたら、とあるところに設置されている cgi が大量の攻撃を受けていた。

設置者が放置している掲示板で「まあ実害はないだろう」と思ってそのままにしておいたのですが*1、気付いたらそのcgiのおかげで1GBぐらいあるハズのサーバメモリが食いつぶされて、さらにswapまで食いつぶされていた(汗)

どれくらいSPAM投稿があったかと言うと、1分間に

[Tue Mar 06 03:03:03 2007] [client 84.19.176.62]
[Tue Mar 06 03:03:11 2007] [client 221.208.14.248]
[Tue Mar 06 03:03:22 2007] [client 222.33.65.154]
[Tue Mar 06 03:03:29 2007] [client 220.212.135.69]
[Tue Mar 06 03:03:32 2007] [client 82.141.146.20]
[Tue Mar 06 03:03:46 2007] [client 165.228.131.12]
[Tue Mar 06 03:03:46 2007] [client 220.212.135.69]
[Tue Mar 06 03:03:47 2007] [client 72.232.229.118]
[Tue Mar 06 03:03:58 2007] [client 72.232.206.66]

だけのアクセス。これがずーーーーっと続くわけで(以下略)。cgiの実行権限を外しました。

*1 : 利用者のユーザー領域に設置されているものですから、勝手にどうにかするのはあまりよろしくない

Ruby cgiが攻撃をうけている?

top でプロセス監視していると、たまに立ち上がる ruby プロセス(www権限)が 500MB ほど食っている模様。犯人はどこの cgi だ……(汗)

……これまた放置された tDiary でした。各記事に2000件ほどのSPAMが付いてまして、ここに対して書き込み動作をしたときのメモリ消費が次のとおりです。

USERNAME  SIZE   RES STATE  C  TIME   WCPU COMMAND
www       644M  583M kserel 0  0:07 20.14% ruby

放置されたcgiほど恐ろしいものはないと身にしみました(汗)*2

*2 : たかだか30MBのログを処理するのにこれだけメモリを食うtDiaryもどうかと思いますが……

cgi使用可能メモリの制限

ユーザーが設置するcgiをいちいち監視してられない上、この状況は恐ろしすぎるので cgi で利用可能なメモリをApache 側で制限することにしました

# cgi limit is 64MB 
RLimitMEM 67108864 67108864

PPPoE ルータ同志で IPsec を構築するときの問題

はてブ数 2007/01/31Linux

IPsecで一部の通信が遮断される謎

IPsec構築時の問題点に書いたことですが、一部の通信が遮断される問題の原因を追求しました。一言で言えば、IPsecパケットが PPPoE(フレッツ網) を通るには大きすぎてフラグメントしていることが原因でした。

より詳細な原因

ネットワーク図
192.168.10.0/24 <--LAN--> FreeBSD  <--Internet--> Linux 2.6 <--LAN--> 192.168.20.0/24

192.168.10.0 内のWindowsマシンから出るパケットは MTU(パケット最大サイズ)として 1454 が設定されています。しかし、フレッツ網を PPPoE で抜ける際に PPP でくるまれ、さらに IPsec でくるまれるためにこのサイズのパケットは通過できません(参考)。

次のようにIPパケットの断片化が発生しています。

# tcpdump -i tun0 esp
21:35:40 IP FreeBSD > Linux: ESP(spi=0x01053609,seq=0x450), length 268
21:35:40 IP FreeBSD > Linux: ESP(spi=0x01053609,seq=0x451), length 1432
21:35:40 IP FreeBSD > Linux: esp
21:35:40 IP FreeBSD > Linux: ESP(spi=0x01053609,seq=0x452), length 1044
21:35:40 IP Linux > FreeBSD: ESP(spi=0x0129b031,seq=0x402), length 76
21:35:40 IP FreeBSD > Linux: ESP(spi=0x01053609,seq=0x453), length 1432
21:35:40 IP FreeBSD > Linux: esp

本来、IPパケットが断片化されようと、相手側のLinuxマシンで再構築され復元されるため、断片化により通信速度は低下しますが、通信自体は問題ありません。

 生パケット → IPsecカプセル化 → IPフラグメント(分割)  → Internet
 → IPパケット再構築 → IPsecのカプセルを解く → 生パケット

しかし 192.168.20.0 内にはパケットが届いておりません。Linuxマシンのインターフェイスまでは届いているのですが、iptables なのか、その先の IPsec なのか、ともかくうまく行っていないようです。

tcpmss を設定する

tcpはコネクション時に、TCPの中に含まれるデータサイズMSS(Maximum Segment Size、通常 MTU-40byte)をネゴシエーションします。

# tcpdump -i fxp0 port 8080
21:33:25 IP pc11.5955 > pc22.8080: S xxx(0) win 5840 <mss 1414,sackOK,timestamp 4032556 0,nop,wscale 2>
21:33:25 IP pc22.8080 > pc11.5955: S xxx(0) ack yyy win 65535 <mss 1460,nop,nop,sackOK>

このときの小さい方の数字をTCPの通信において使用します。これを tcpmss と言います。

IPsecやPPPoEのトンネル化などによりヘッダサイズが増大してしまうなら、この mss の値を MTU に対して小さく設定してあげればいいことになります。この操作をルータ側で強制的に行ってしまえば、結果的にIPsecにおける断片化(フラグメント)を防ぐことができます。

MTU > mss + IPsec & IP & TCPヘッダサイズ

通信路MTUの調査方法

ping コマンドでパケットサイズを指定することで、通信路のMTUを調べることができます。

# Linux/FreeBSDの場合
$ ping -l 1370 192.168.20.2
# Windowsの場合
> ping -s 1370 192.168.20.2

この場合、どちらも1370バイトのpingパケットを 192.168.20.2 に投げます。無事パケットが返ってくる限界値+28byteが経路MTUになります。mssはMTU-40になります。

Linux側による解決策

必要なmssの値はMTUから計算で出せるハズですが、なぜかそれではうまく行かず*1、結局試行錯誤で次のように設定しました。

iptables -A FORWARD -p tcp -s 192.168.10.0/24 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1344
iptables -A FORWARD -p tcp -d 192.168.10.0/24 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1344

試行錯誤は、tcpdump を用いて esp の断片化が起きないサイズを探り出すことにしました。IPsecのフッタの一部がサイズ可変らしく(?*2)、pingによる調査では不十分でした(それよりも低い値になった)。

FreeBSD側による解決策

FreeBSDのpppデーモンには、すでにtcpmssfixupという機能が付いているのですか、pppd を通過する段階ではすでにIPsecでカプセル化されているため無力です*3。同じ理由で、ipnat.conf でも、mssを調整する機能があるのですが、パケットが出て行くときしか書き換えられないためにIPsec では使用出来ません。

最初後述するように ipfw を使っていたのですが、pf できました。*4

デフォルトのカーネルで使用出来ると思います。rc.conf には次のように書きます。

pf_enable="YES"

pf.conf には次のように書きました。LAN側インターフェイスの 入力時 と 出力時 にそれぞれフィルタすることに注意してください。

int_if="fxp0"		# LAN interface
scrub in  on $int_if from 192.168.10.0/24 to 192.168.20.0/24 max-mss 1344
scrub out on $int_if from 192.168.20.0/24 to 192.168.10.0/24 max-mss 1344

/etc/rc.d/pf start」 する際に ALTQ がどうのと怒られますが、ALTQ関連機能を使用しなければ問題ないので気にしないでください。

# /etc/rc.d/pf start
Enabling pf.
No ALTQ support in kernel
ALTQ related functions disabled

FreeBSD側による別の解決策(非推奨)

今更 ipfw の時代でもないので非推奨の方法です(動作自体は問題ないのですが煩雑です)。

結局、ipfw + tcpmssd を使用しました。tcpmssd は /usr/ports/net/tcpmssd よりインストールしました(パッケージでも構いません)。起動スクリプトがありませんので、tcpmssd.sh.txt/usr/local/etc/rc.d/tcpmss.sh として保存し使用してください。

カーネルのコンパイルオプションです。

options         IPFIREWALL
options         IPFIREWALL_VERBOSE
options         IPDIVERT

rc.conf です。mssではなくMTUを与えることに注意。

firewall_enable="YES"
firewall_type="/etc/ipfw.sh"
tcpmssd_enable="YES"
tcpmssd_flags="-p 50 -m 1372"

/etc/ipfw.sh です。IPsecを通過する tcpコネクションパケット を tcpmssd に飛ばし mss を書き換えます。

add 64900 divert 50 tcp from 192.168.10.0/24 to 192.168.20.0/24 tcpflags syn
add 64902 divert 50 tcp from 192.168.20.0/24 to 192.168.10.0/24 tcpflags syn

pfによる方法と同様に、FreeBSDマシンから直接 192.168.20.0/24 へ向かうパケットは ipfw のルールを通過せず、tcpmss を設定することは不可能です。

*1 : 時折パケットがロストする

*2 : 詳しい人補足願います

*3 : 出て行くときにはすでにIPsecでカプセル化されているので、書き換えようがない

*4 : IPFilter の機能不足で困ることが多かったのですが、今度から pf 使おう(汗)

さらなる疑問

IPsecにおいて、カプセル化後にIPパケットのフラグメントが発生した場合、本来ならば受信側がパケットを再構築して通信できるはずだと思うのですが……(速度が遅くなるのは仕方ないとしても)。

  • FreeBSD ←→ FreeBSDなら問題ないのか?
  • Linux ←→ Linuxなら問題ないのか?
  • FreeBSD(6.x) ←→ Linux(2.6.x)で通信可能にする手段は存在しないのか?

そもそも、Linux側には ip_conntrack (コネクション追跡)がインストールされているのでフィルタリングより前にESPパケットが再構築されているハズなのですが*5、フラグメントしたESPパケットの到着は確認できても、IPsecのカプセル化を解いた後のパケットは確認できていません。

色々調べたところ、Linuxはカプセル化する前にパケットを分割しますが、FreeBSDはカプセル化してからパケットを分割しています。この辺のミスマッチが怪しいですね。ip_conntrack がESPのフラグメントパケットを修復する際に、ヘッダ書き換え(?)か何か悪さしてるんじゃないかと思いますが……。

*5 : Linux 側 iptablesで確認しましたが、フラグメントパケットは記録されていませんでした。iptables にESPパケットが届いているのは確認できます

2007/01/23(火)FreeBSD をアップデート

make buildworld

久しぶりの make buildworld だったのですっかりやり方を忘れていましたが、6.1PREバージョンから 6.2-STABLE にアップデートしました。このサーバに関してはもう入れ直すことはないでしょう(故障するまで)。

OpenLDAP + Samba でドメインを構築しているのですが、slapd の起動順序がどうにも変更できず再起動のたびに参っていたのですが、調べてみると 5.x から起動順序ルールか変わったようで(それ以前は起動スクリプトの名前順)。nss_ldap を入れている都合上、どのデーモンよりも先に slapd を起動しないと色々大変なことになるんですが(デーモンを起動する度に ladp に接続に行って数分止まってしまう)、標準状態では一般デーモンと同じ優先度で起動するようになっていました。

というわけで、ネットワークの初期設定直後に起動するように変更。

# /usr/local/etc/rc.d/slapd.sh 変更後の設定
#
# PROVIDE: slapd
# REQUIRE: NETWORKING
# BEFORE: securelevel SERVERS
# KEYWORD: FreeBSD shutdown

次の記事がとても参考になりました。書かれた方には感謝。

(FreeBSD6) racoon2 による IPsec の設定

はてブ数 2007/01/18Linux

racoon2 とは

WIDE Project 内の Racoon2 Project によって開発されている、racoon に代わる IPsec 用 IKE deamon(鍵交換デーモン)です。現時点で 20061228a が最新版として公開されています。詳細は不明ですが、どうやらIKEv2に合わせ、全面的に書き直されているようで、従来のracoonとは設定ファイルの書式が異なります

ftp://ftp.racoon2.wide.ad.jp/pub/racoon2/

racoon2 による設定事例はほとんど見ることができないので、ここに事例とハマりどころを記しておきます。質問などありましたら、答えられる範囲でお答えします。なお、IPsecの詳細については割愛します。

設定の目的

  • IKEv1 を使用して鍵交換を行い、Linux 2.6.x との間で IPsec 通信路を設定する。
  • 事前共有鍵方式(pre_shared_key : psk)による鍵交換を行う。
  • ESP + トンネリングモードにより、それぞれルータとなっている FreeBSD、Linux 間でVPN接続を行う。
  • FreeBSD、Linux はそれ自身が PPPoE によるセッションを張っており、NATサーバを兼ねている。

全体像は図で示すと次のとおりです。ここでは、FreeBSD側の設定のみ述べます。

192.168.10.0/24 <--LAN--> FreeBSD (210.11.11.11) 
   <--Internet--> (210.22.22.22) Linux <--LAN--> 192.168.20.0/24

ports から racoon2 をインストール

FreeBSD では /usr/ports/security/racoon2 に Ports がありますので、そこから make install します。Linuxなどと接続する場合、IKEv1 プロトコルが必須になりますが、20060712a版はIKEv1に対応していません。Ports を最新版に置き換えるなどして、必ず 20061228a 以降のバージョンをインストールしてください。*1

# cd /usr/port/security/racoon2
# make
# make install

なお、旧racoon由来のツールは /usr/ports/security/IPsec-tools にあります。

*1 : Makefile などを見ることで確認できます

racoon2 による IPsec の設定上の注意

まず、racoon2 を設定する際は、次の点に注意してください。ハマります。

[FreeBSD] gif0インタフェースは必要ない

FreeBSDの handbook はじめ各種の記事には gif インタフェースが必要とかかれていますが、まったく必要ありません

gifインターフェイスを必要する説明では、gif インターフェイス自身が持っているIPのカプセル化機能を用いてVPNを構築し、このときのGLOBAL IP(インターネット)間の通信を IPsec にして暗号化する趣旨で書かれています。このことから、gif と同じカプセル化を実行できない Linux などと相互接続することは不可能ですし、IPsec自体にカプセル化の機能がありますので、多重にカプセル化するのはナンセンスです。

[FreeBSD] /etc/IPsec.conf は必要ない

同様に rc.conf に IPsec_enable の記述も必要ありません。racoon2 では、setkey によるこれらの設定を、racoon2.conf の中身を反映し自動で行ってくれます。

静的 routing は必要ない

IPsec 対象パケット(from 192.168.10.0/24 to 192.168.20.0/24)は、LAN を抜け FreeBSD のカーネルに入った時点で IPsec によりカプセル化(from 210.11.11.11 to 210.22.22.22) され Linux マシンに届けられます。この Linux マシンでカプセルを解かれ(from 192.168.10.0/24 to 192.168.20.0/24)、相手方LAN内に到達します。

この状況からもわかるとおり、FreeBSD、Linux のそれぞれのマシン上で特別な静的routingは不要です。下手に設定することで、IPsecがきちんと動作しなくなりますので注意してください。*2

psk.txt には秘密鍵(パスフレーズ)のみを書く

racoon2.conf 内において、 remote の設定項目を例えば次のように書いたとします。

remote Linux-machine {
	ikev2 {
		(略)
		pre_shared_key "${PSKDIR}/linux.psk";
        };
};

このとき、linux.psk には Linux-machine により指定した IPsec 通信相手との共有鍵のみを直接記述します。ここを間違えると大ハマリします。次のように書いてはいけません

(うまく動作しない例)
210.11.11.11	test1
210.22.22.22	test2

これには2つの勘違いがあります。IPsec における事前共有鍵は、自分(FreeBSD)と相手(Linux)の通信において、ただ1つしか存在しません。

もう1つが重大な誤りです。旧racoonでは、このファイルの書式は問題ないのですが、racoon2 では、psk ファイルの中身を一切解釈しません。pskファイル全体で1つの秘密鍵を示します。例えば、秘密共有鍵が "test" だったとき、pskファイルの中身が

test

という 4byte のファイルなら正しく動作しますが、

test[LF]

という改行を含めた 5byte のファイルである場合、鍵交換に失敗します。

またpskファイルのパーミッションは必ず600にしておきます(600でないと、デーモンの動作に失敗すると思います)。

*2 : FreeBSD から直接 192.168.20.0/24 へ向けてパケットを投げる場合は静的routingの設定が必要ですが、詳細は後述します。基本的には必要ないと覚えておいてください。

racoon2 による IPsec の設定例

racoon2.conf を置いておきます。以下は抜粋です。

remote remote@ip210.22.22.22 {
    acceptable_kmp { ikev1; };
    ikev1 {
	logmode normal;
	my_id ipaddr 210.11.22.33;		←相手が自分を識別するときのID代わり
	peers_id ipaddr 210.22.22.22;		←通信相手を識別するID代わり
	peers_ipaddr 210.22.22.22 port 500;	←通信相手のIKE deamon
	kmp_enc_alg { 3des_cbc; };
	kmp_hash_alg { sha1; };
	kmp_dh_group { modp2048; };
	kmp_auth_method { psk; };
	pre_shared_key "${PSKDIR}/210.22.22.22"; ←この通信のpskのみが書かれたファイル
	exchange_mode main;
    };
};
selector 31 {
	direction outbound;
	src 192.168.10.0/24;
	dst 192.168.20.0/24;
	upper_layer_protocol "any";
	policy_index ip210.22.22.22;
};
selector 32 {
	direction inbound;
	dst 192.168.10.0/24;
	src 192.168.20.0/24;
	upper_layer_protocol "any";
	policy_index ip210.22.22.22;
};
policy ip210.22.22.22 {
	action auto_IPsec;
	remote_index remote@ip210.22.22.22;
	IPsec_mode tunnel;
	IPsec_index { IPsec_esp; };
	IPsec_level require;	←20061228a現在、unique は未実装。指定すると IPsec が動作しません。
	my_sa_ipaddr    210.11.11.11;
	peers_sa_ipaddr 210.22.22.22;
};

racoon2 を IKE として使用する場合、spmd デーモンと iked デーモンの2つに分かれています。FreeBSD では次のように設定・起動させます。

/etc/rc.conf
spmd_enable="YES"
iked_enable="YES"
手動での起動方法
# /usr/local/etc/rc.d/spmd start
# /usr/local/etc/rc.d/iked start

spmd は racoon2.conf の selector および policy の項目を読み出し setkey を実行します。spmd を起動させたあと、SPD エントリを確認すると次のようになります。

# setkey -DP
192.168.20.0/24[any] 192.168.10.0/24[any] any
        in IPsec
        esp/tunnel/210.22.22.22-210.11.11.11/require
        created: Jan 18 19:46:52 2007  lastused: Jan 18 22:17:32 2007
        lifetime: 0(s) validtime: 0(s)
        spid=16389 seq=1 pid=23230
        refcnt=1
192.168.10.0/24[any] 192.168.20.0/24[any] any
        out IPsec
        esp/tunnel/210.11.11.11-210.22.22.22/require
        created: Jan 18 19:46:52 2007  lastused: Jan 18 22:17:48 2007
        lifetime: 0(s) validtime: 0(s)
        spid=16388 seq=0 pid=23230
        refcnt=1

iked (racoon2)が相手方含めうまく動作し鍵交換に成功すれば、SADエントリが登録されIPsecの通信が確立されます。

# setkey -D
210.22.22.22 210.11.11.11
        esp mode=tunnel spi=126366317(0x0788326d) reqid=0(0x00000000)
        E: 3des-cbc  2a7834a 4c3204b2 85ebe60f 63897650 eea4cacd 302f1999
        A: hmac-sha1  ec8798a 0c05beba c96bf2d0 27476813 6b25fbd3
        seq=0x0000004a replay=4 flags=0x00000000 state=mature
        created: Jan 18 19:47:13 2007   current: Jan 18 22:35:10 2007
        diff: 2877(s)   hard: 28800(s)  soft: 28800(s)
        last: Jan 18 18:32:48 2007      hard: 0(s)      soft: 0(s)
        current: 19600(bytes)   hard: 0(bytes)  soft: 0(bytes)
        allocated: 74   hard: 0 soft: 0
        sadb_seq=1 pid=26699 refcnt=2
210.11.11.11 210.22.22.22
        esp mode=tunnel spi=129847243(0x07bd4fcb) reqid=0(0x00000000)
        E: 3des-cbc  d6d8a358 5ea1524f e93b927c 8b78ed33 43dc4656 1471817a
        A: hmac-sha1  19eaf381 15ab1ae4 a724f53d 6e56354f b959d443
        seq=0x00000004 replay=4 flags=0x00000000 state=mature
        created: Jan 18 19:47:13 2007   current: Jan 18 22:35:10 2007
        diff: 2877(s)   hard: 28800(s)  soft: 28800(s)
        last: Jan 18 18:32:32 2007      hard: 0(s)      soft: 0(s)
        current: 1028(bytes)    hard: 0(bytes)  soft: 0(bytes)
        allocated: 4    hard: 0 soft: 0
        sadb_seq=0 pid=26699 refcnt=1

鍵交換に成功しない限りSADエントリは登録されませんので、通信がうまくいかない場合の原因を racoon2 か IPのフィルタ か判別することができます。

鍵交換に失敗している場合
# setkey -D
NO SAD entries

動作確認と問題調査方法

設定上の注意を参照すれば、だいたいのトラブルは避けられると思いますが、トラブル対処方をいくつか書いておきます。

tcpdumpによる調査

racoon2 の IKE の動作、きちんとコネクションの確立用パケットが送られているかは次のように書きます。tun0 は、FreeBSDマシンのPPPoEデバイスで、Linuxなどではppp0などになります。調査時はLAN内のマシンから、相手側LANへpingを投げるなどします。

# tcpdump -i tun0 port 500
listening on tun0, link-type NULL (BSD loopback), capture size 96 bytes
19:22:04.467053 IP 210.11.11.11.isakmp > 210.22.22.22.isakmp: isakmp: phase 1 I ident
19:22:04.471308 IP 210.22.22.22.isakmp > 210.11.11.11.isakmp: isakmp: phase 1 R ident
19:22:04.620765 IP 210.11.11.11.isakmp > 210.22.22.22.isakmp: isakmp: phase 1 I ident
19:22:04.747872 IP 210.22.22.22.isakmp > 210.11.11.11.isakmp: isakmp: phase 1 R ident
19:22:04.976045 IP 210.11.11.11.isakmp > 210.22.22.22.isakmp: isakmp: phase 1 I ident[E]
19:22:04.981089 IP 210.22.22.22.isakmp > 210.11.11.11.isakmp: isakmp: phase 1 R ident[E]
19:22:05.985104 IP 210.11.11.11.isakmp > 210.22.22.22.isakmp: isakmp: phase 2/others I oakley-quick[E]
19:22:05.990244 IP 210.22.22.22.isakmp > 210.11.11.11.isakmp: isakmp: phase 2/others R oakley-quick[E]
19:22:05.991644 IP 210.11.11.11.isakmp > 210.22.22.22.isakmp: isakmp: phase 2/others I oakley-quick[E]

同様にIPsecracoon2 の IKE の動作、きちんとコネクションの確立用パケットが送られているかは次のように書きます。tun0 は、FreeBSDマシンのPPPoEデバイスで、Linuxなどではppp0などになります。調査時はLAN内のマシンから、相手側LANへpingを投げるなどします。

# tcpdump -i tun0 esp
listening on tun0, link-type NULL (BSD loopback), capture size 96 bytes
19:25:45.999494 IP 210.22.22.22 > 210.11.11.11: ESP(spi=0x0e0d347f,seq=0xe), length 116
19:25:46.000196 IP 210.11.11.11 > 210.22.22.22: ESP(spi=0x05d52d17,seq=0x11), length 116
19:25:47.001858 IP 210.22.22.22 > 210.11.11.11: ESP(spi=0x0e0d347f,seq=0xf), length 116
19:25:47.002553 IP 210.11.11.11 > 210.22.22.22: ESP(spi=0x05d52d17,seq=0x12), length 116
19:25:48.001502 IP 210.22.22.22 > 210.11.11.11: ESP(spi=0x0e0d347f,seq=0x10), length 116
19:25:48.002231 IP 210.11.11.11 > 210.22.22.22: ESP(spi=0x05d52d17,seq=0x13), length 116

racoon2 のデバッグモード

iked を起動する際、

# iked -D 0xff

とすることで詳細なデバッグメッセージを得ることができます。標準では syslog に投げられますので、syslog.conf を適切に設定して別ファイル(パーミッション600)に出力する方がよいでしょう。

# iked -F -D 0xff

としてフォアグランド動作にしてコンソールでデバッグしても良いのですが、この場合SADの登録に失敗するのでIPsecを動作させることはできません(Phase2までは成功します)。

IPsecの psk により生成された共有秘密が正しいかチェックするためには、ログから SKEYID, SKEYID_d, SKEYID_a, SKEYID_eが通信する相互のマシンで一致しているか確認してください(これらはその直前に記録された乱数である nonce 1, nonce 2 から生成されるので、確認時は必ず同じ通信を確認してください)。

ipfilter や iptables の確認

racoon2 のログに、IPsec-SA establish と書かれ、setkey -DできちんとSADが表示されている場合は、通信できない原因として IP 系のフィルタを疑ってください。また、静的ルーティングとして不要なルールが追加されていないかも確認してください。

FreeBSD、Linux それぞれ、正常にIPsec通信できる状態で、routingテーブルは次のようになっています。

FreeBSD
# netstat -rn    #210.xx.xx.xxはプロバイダgw
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            210.xx.xx.xx       UGS         1   208515   tun0
127.0.0.1          127.0.0.1          UH          0     6283    lo0
192.168.10         link#1             UC          0        0   eth0
192.168.10.1       00:02:b3:5c:bf:05  UHLW        2        0    lo0
210.xx.xx.xx       210.11.11.11       UH          1        0   tun0
Linux
# route -rn    #210.yy.yy.yyはプロバイダgw
210.yy.yy.yy    0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.20.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
0.0.0.0         210.yy.yy.yy    0.0.0.0         UG    0      0        0 ppp0

IPsecを実行しているマシンから直接相手側LANにアクセスする。

IPsecを構築しているFreeBSDマシンから、相手側LAN 192.168.20.0/24 アクセスするには、次のようなルーティングを追加します。

FreeBSDの場合
# route add 192.168.20.0/24 192.168.10.1     192.168.10.1はFreeBSDのLAN側IP

Linuxの場合はこの設定を行うと、IPsec通信自体が行われなくなりますので注意してください。

未解決の問題点

  • LAN内マシンから相手側LAN内マシンに対してftpを行うと、active mode (passive off) では通信ができない。Linuxのカーネルモジュール ip_nat_ftp が原因だと思われます(未確認)。
  • LAN内マシンから相手側LAN内マシンに対し VNC 通信を行うと、画面データがまったく送られてこない。→一応解決しました

参考資料

最初の pdf は racoon2 開発者たちによって書かれた技術資料なのでかなり参考になります。またracoon2 に付属のドキュメントが日本語でかかれていますので、それを読むことを勧めます*3。ソースを直接展開しても容易に読むことができます。

*3 : FreeBSDならば /usr/local/share/doc/racoon2 にあります。

2007/01/10(水)FedoraCore4→FedoraCore6へのアップグレード

サーバは結局、ケーブル不良なのか電源不足なのかデータ化けなのか、ディスク自体も正常で繋ぎなおしたら戻りました。せっかくなので、FedoraCore4から6へアップグレードすることに。

FedoraCoreアップグレード準備

これらを参照しながら行いました。

# wget ftp://ftp.kddilabs.jp/Linux/packages/fedora/core/6/i386/
os/Fedora/RPMS/fedora-release-6-4.noarch.rpm
# wget tp://ftp.kddilabs.jp/Linux/packages/fedora/core/6/i386/
os/Fedora/RPMS/fedora-release-notes-6-3.noarch.rpm
# wget ftp://ftp.kddilabs.jp/Linux/packages/fedora/core/6/i386/
os/Fedora/RPMS/fedora-release-notes-6-3.noarch.rpm
# rpm -i fedora-release-notes-6-3.noarch.rpm
# rpm -Uvh fedora-release-6-4.noarch.rpm

rpm -i fedora-release-notes-6-3.noarch.rpm」を実行するのが要注意点です。間違えて「rpm -Uvh fedora-release-notes-6-3.noarch.rpm」とすると、

error: Failed dependencies:
/etc/redhat-release is needed by (installed) initscripts-8.xx-x

という具合に意味不明に怒られてしまいます。

FedoraCoreアップグレード

普通に yum upgrade と行きたいところですが、

# yum upgrade
(中略)
Error: Missing Dependency: libcrypto.so.5 is needed by package ckermit
Error: Missing Dependency: libssl.so.5 is needed by package ckermit
Error: Unable to satisfy dependencies
Error: Package autofs needs kernel < 2.6.17, this is not available.
Error: Package ckermit needs libcrypto.so.5, this is not available.
Error: Package ckermit needs libssl.so.5, this is not available.
Error: Package hal needs kernel < 2.6.17, this is not available.

と怒られ失敗してしまいます。取るべき対策は

  • ckermitを削除する
  • kernelを手動でバージョンアップしてしまう

の2つです。

# yum remove chermit
# wget ftp://ftp3.iij.ad.jp/pub/linux/fedora/core/updates/6/i386/
kernel-2.6.18-1.2869.fc6.i686.rpm
# rpm -Uvh -nodeps kernel-2.6.18-1.2869.fc6.i686.rpm

と実行します。kernel は適当なサーバから適当なバージョンを取得してください。-nodeps オプションにより(依存関係を無視して)強制的にインストールします。このまま再起動せずにアップグレードを行ってください

# yum upgrade

コンソールのスクリーンシャッターをオフ 2007/01/12

コンソール画面が一定時間後に真っ暗になるスクリーンシャッター機能を制御するには、次のように時間指定(単位:分)指定すればいいらしい。/etc/rc.local あたりに記述。

/bin/setterm -blank 30

参考:コンソール画面が一定時間後に真っ暗になるのを制御するにはどうすればいいですか?