この文書は Debuan BNU/Linux 不徹底入門 (2003 年夏号) に投稿したものです.
2 台の woody マシンをルータにし、 それぞれの奥にあるローカルネットワークを VPN 化する手順について述べます。
私の勤務先ではこの春に研究室の引越しがありました。 今度入った部屋は 5F で眺めもよく、 また総床面積が広くなったのもありがたかったのですが、 床の強度の関係で重い装置 *1 を置けないため、 建物の 1F にこの装置専用の実験室が用意されました。 この装置は (高いだけあって) 比較的利用頻度が高く、 よってデータのやり取りも頻繁です。 そこで今回、 5F の研究室 (居室) と 1F の実験室の各ネットワークを VPN (Virtual Private Network) でつなぐことにしました。
今回の VPN の敷設にあたっては Linux での IPSec 実装である FreeS/WAN を用いました。 またゲートウェイの絡んだ通信を楽に行えるように、 iproute2 で経路情報を設定しました。 IPSec の設定については [1] を、 iproute2 と組み合わせる作業については [2] を参考にしました。
*1 X 線光電子分光装置といいます。とても高い。
VPN 通信の仲立ちをするマシンをセキュリティゲートウェイといいますが、 今回研究室側には LABOGW というマシン、 実験室側には EXPGW というマシンを置きました。 これらは学内のネットワークを介してつながっています。 その他、
というような状況です。 それぞれのホストにおける IP アドレスとインターフェースの関係は 上図で確認してください。
VPN 構築前に、それぞれの GW マシンの経路設定は適切に行い、 お互いの通信ができる状態にしておきました。 なお今回 LABOGW の default 経路は NAT マシンである SURF には向けず、 上流へはすべて 10.0.1.102 から直接出て行く形にしています。
今回使った LABOGW と EXPGW はそれぞれ woody マシンです。 インストールしたパッケージは
です。 freeswan はインストール後にいくつか質問されますが、
という感じで答えました。 Debian マシン以外の IPSec ルータと通信する際には、 鍵ペアのタイプを x509 にする必要があるかも知れませんが、 今回はそこまでちゃんと調べていません。
FreeS/WAN も iproute2 もカーネルの対応を必要とするパッケージですので、 ここでカーネルの再構築作業が必要となります。
いつものように/usr/src/ディレクトリで kernel-source-2.4.20.tar.bz2 をほどき、 kernel-source-2.4.20/ディレクトリに移動します。 これまでの設定があるようでしたら、 ここで例えば/boot/config-2.4.20 を .config としてコピーしておくといいでしょう。
FreeS/WAN 用のパッチは、 kernel-patch-freeswan をインストールすると /usr/src/kernel-patches/以下に展開されます。 環境変数 PATCH_THE_KERNEL を YES にしておくと、 make-kpkg はこれを自動的に認識してくれます。 したがってコマンドラインとしては、
env PATCH_THE_KERNEL=YES make-kpkg --config=menuconfig \ --revision=labogw.1 kernel_image
という感じになります。 menuconfig は私の好みです。 FreeS/WAN パッチがあたると config のエントリが増えますが、 make-kpkg はこのへんもちゃんと面倒をみてくれます。
今回新たに menuconfig で指定する内容は、 [Networking Options] を降りた先にあります。 FreeS/WAN 用には「--- IPSec options (FreeS/WAN) 」 の後ろにあるエントリ群を y または m にしておきます。 iproute2 用には「 IP: advanced routing 」およびその下層にあるエントリを y にしておきます。
menuconfig を終了するとビルドがはじまり、 カーネルパッケージができます。 通常の手順でインストール・再起動してください。
FreeS/WAN の設定は/etc/ipsec.conf ファイルで行います。 FreeS/WAN の語法はちょっと変わっていて、 自分側と相手側とを left と right を使って指定します。 これはどちらがどちらでも良く、 また実際には接続の双方で対応していなくても良いようです。 今回は、研究室側を left 、実験室側を right として構築してみました。
freeswan パッケージのインストール時には、 RSA 鍵ペアを作る指定をしました。 この結果の秘密鍵・公開鍵は、いずれも/etc/ipsec.secrets に記録されています。 公開鍵は DNS に登録することもできるようですが、 今回はそれぞれの GW マシンの ipsec.conf に記述しました。 公開鍵を取り出すには、left 側となる LABOGW では
ipsec showhostkey --left
とします。
# RSA 1024 bits labogw Sun Jul 6 20:05:28 2003 leftrsasigkey=0sAQPT2M686r9wq... (以下略)
というような標準出力が得られますので、適当にリダイレクトして leftrsasigkey=の行を LABOGW, EXPGW それぞれの ipsec.conf にそのままペーストします。
同様に right 側となる EXPGW では
ipsec showhostkey --right
とし、結果を同じく両者の ipsec.conf に貼り付けます。
この公開鍵エントリを含む ipsec.conf は、 left 側である LABOGW の設定では以下のようになります。
config setup interfaces=%defaultroute klipsdebug=none plutodebug=none plutoload=%search plutostart=%search uniqueids=yes conn %default keyingtries=0 disablearrivalcheck=no authby=rsasig conn lnet-xnet left=%defaultroute leftsubnet=192.168.0.0/24 leftrsasigkey=0sAQPT2M686r9wq... (以下略) rightsubnet=192.168.1.0/24 right=10.0.2.160 rightrsasigkey=0sAQODBPJwrbiu... (以下略) auto=add
EXPGW の ipsec.conf も、 lnet-xnet 中の 3 つのエントリが
left=10.0.1.102 right=%defaultroute auto=start
に置き換わることを除き、 LABOGW のものと全く同じです。 各エントリや%search, %defaultroute などの意味については ipsec.conf(5) の man ページを見てください。 auto の指定は、 add が待ち受け側、 start が接続にいく側を意味します。 両方を start にしても構いません *2。
これであとは/etc/init.d/ipsec start で起動できるのですが、注意点として
の二点があります。後者は FreeS/WAN の実装のせいだそうです。 Debian で手軽にこれらを設定するには、/etc/network/options で
ip_forward=yes spoofprotect=no
としておけばよいはずです。
*2 タイムラグの間に syslog にワーニングが出ますが。
ここまでの段階で、 192.168.0.0 のネットワークと 192.168.1.0 のネットワークにあるマシンは (それぞれ相手ネットワークへのゲートウェイとして自分側の GW を指定していれば) お互いに通信できるようになったはずです。 ただし FreeS/WAN の実装では、この状態だと
が行えません。 FreeS/WAN のドキュメントでは、 このためにはそれぞれ別々のトンネルを掘れ、 ということになっていますが、 iproute2 を用いると、 より手軽に上記の接続をすべて有効にできます。
このあたりは背景を含めて文献 [2] に詳しく、 以下では具体的な手順だけを述べます。 まず各 GW マシンの/etc/iproute2/rt_tables に
2 from.this.host
というエントリを追加します。 続いて LABOGW では
ip rule add iif lo table from.this.host priority 500 ip route add 192.168.1.0/24 table from.this.host dev ipsec0 src 192.168.0.5
を、 EXPGW では
ip rule add iif lo table from.this.host priority 500 ip route add 192.168.0.0/24 table from.this.host dev ipsec0 src 192.168.1.1
を実行します。これで各 GW マシンのローカルから発し、 相手ネットワークに向けたパケットは、 ipsec0 から出て行くようになります。 またそのパケットのソースアドレスはネットワーク側 (それぞれの eth1 側) の ip アドレスになるため、返信も VPN トンネルを通って帰ってくるようになります。
あとはこれらのコマンドをブート時にどのタイミングで実行するかですが、 このへんは環境によっていろいろだと思いますので読者にお任せします。
経路設定もちょっとめんどくさいですね。 私のところでは、 192.168.0.0 のネットワークにある各マシンは 従来 SURF を経路の default にしていたので、 SURF において
route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.0.5
を実行したところ、 192.168.0.0 と 192.168.1.0 の各マシンはほぼ通信できるようになりました。 ただし 192.168.1.0 のマシンも NAT マシンとしての SURF を使いたくなったら、 もう少し ip コマンドと格闘する必要がありそうです。 また将来 FreeS/WAN のセキュリティゲートウェイと NAT ゲートウェイを 一台のマシンで行わせることになったら、これもちょっと大変かもしれません。
あまり手軽とはいえない IPSec の環境設定ではありますが、 離れたネットワークで samba も NFS も NIS も使えるので、 なかなか快適になりました。 自分の設定の際には (特に iproute2 に関して) やや日本語の文献が乏しく苦労しましたので、 この文書が何らかの役に立てば幸いです。
[1]
FreeS/WAN による IPSec の導入と運用
[2]
Fun with iproute2 and FreeS/WAN