最近カンファレンスなどに出かけてオープンな無線LANアクセスポイントが提供されている場合、よく「セキュリティに気をつけて! VPNを使って下さい」てな掲示を見かけます。
そうだよねーと思って、ARMなLinuxマシン(NAS)をPPTPサーバに仕立ててみた時のメモです。(今時PPTP?とも思ったが、今使っているNASだとカーネルの都合上、IPsecはモジュールだけでなくカーネル自体の入れ替えが必要そう(?)だったので断念。)
PPPカーネルモジュールの導入
今回使うのはARM搭載のNAS上で動くLinuxですが、標準状態ではpppドライバが入っていませんでしたので、まずはこれを導入。
make menuconfig で
Device Drivers => Network device support =>PPP (point-to-point protocol) support を M に。
│ │ <M> PPP (point-to-point protocol) support │ │ │ │ [ ] PPP multilink support (EXPERIMENTAL) │ │ │ │ [*] PPP filtering │ │ │ │ <M> PPP support for async serial ports │ │ │ │ <M> PPP support for sync tty ports │ │ │ │ <M> PPP Deflate compression │ │ │ │ <M> PPP BSD-Compress compression │ │ │ │ <M> PPP MPPE compression (encryption) (EXPERIMENTAL) │ │
そしたら
% make modules
# make modules_install
PPPデーモン (pppd) の導入
最新版はppp-2.4.5ですが、ここではpoptop-1.3.4が対応するppp-2.4.3を入れる必要があります。
ダウンロード先: ftp://ftp.samba.org/pub/ppp/ppp-2.4.3.tar.gz
展開して configure && make && make install でOK。
Poptop (pptpd) の導入
http://poptop.sourceforge.net/ からpptpd-1.3.4をダウンロード。
ARM環境では、このままではビルドできるものの下記の通信エラーになって正常に動かないようです。
GRE: Discarding packet by header check
こちらを参考に、下記のパッチをあてておきます。(CVSから取ってくれば直ってたのかも。)
RCS file: /cvsroot/poptop/poptop/pptpdefs.h,v retrieving revision 1.4 diff -u -r1.4 pptpdefs.h --- pptpdefs.h 8 Dec 2006 00:01:40 -0000 1.4 +++ pptpdefs.h 20 Jul 2007 00:29:43 -0000 @@ -309,7 +309,7 @@ u_int32_t seq; /* sequence number. Present if S==1 */ u_int32_t ack; /* seq number of highest packet recieved by */ /* sender in this session */ -}; +} __attribute__((packed));
struct pptp_gre_header構造体のアラインメントが変わっちゃったんだなー。
あとはconfigure && make && make install。
/usr/local/以下に入りますが、pppdのライブラリ等が /usr/以下にある必要があるようなので、いくつかシンボリックリンクを張っておきます。ついでに /usr/sbin/pppd も。
# cd /usr/lib # ln -s /usr/local/lib/pppd # ln -s /usr/local/lib/pptpd # cd /usr/sbin # ln -s /usr/local/sbin/pppd
設定ファイルの編集
サンプル設定が pptpd-1.3.4/samples に入っているので、/etc 以下にコピーして編集します。
# cp samples/pptpd.conf /etc/ # mkdir /etc/ppp/ # cp samples/chap-secrets samples/options.pptpd /etc/ppp/
pptpd.confに、サーバ、クライアントがそれぞれ使用するIPアドレスの範囲を指定。
connections 4 localip 192.168.0.250 remoteip 192.168.0.251-254
これでサーバが 250、クライアントが251〜254になります。他の機器(サーバマシンのeth0等も含む)はこの範囲を使えなくなるので注意。
options.pptpd の方は、暗号化やpptpdの動作の設定。もともと脆弱なMS-CHAPは使わず(refuse-mschap)MS-CHAP-v2/MPPE-128を使用する(require-mschap-v2, require-mppe-128)設定となっていたため、dnsの設定だけ変更しました。
ms-dns 192.168.0.1
あとはchap-secrets にユーザ名/パスワードを書く。(平文かよーと思いつつ, rootのみ読めるようにしておくなどする。)
ルータの設定
ルータのフォワーディングの設定。今回設定したマシンはルータ配下にあるので、ルータをPPTPが通れるようにフォワーディング設定が必要です。
外部からのTCPポート1723、プロトコル番号47(GRE)をサーバマシンのIPアドレスにフォワードするように設定します。プロトコル番号47はポート番号とは別物なので注意。プロトコル番号の転送に対応していないルータだとNGかも。うちで使っているAtermは対応してました。
pptpdの起動
# pptpd
/var/log/messages にメッセージが出るので、 tail -f で確認しつつ、テスト接続してみると良いでしょう。
うちではiPod touchにVPN設定を作って、確認しました。設定の仕方は以下などを参考に。
iPhone'z: おすすめ!iPhoneでVPN設定環境を構築して活用すれば、できなかったことができ便利(構築方法)
接続した状態で ifconfig すると
ppp0 Link encap:Point-Point Protocol inet addr:192.168.0.250 P-t-P:192.168.0.251 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1396 Metric:1 RX packets:54 errors:0 dropped:0 overruns:0 frame:0 TX packets:58 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:4706 (4.5 KiB) TX bytes:18532 (18.0 KiB)
と、ppp0インターフェースが稼働しているのが分かります。
ppp0のMTUが1396になってしまいますが、本当は適切な値に調整すると良いらしい。
AppleTalkを外した
Linux-2.6.16の問題なのか分かりませんが、appletalkモジュールが有効の状態でPPTPが動くと、カーネルがパニックするようです。
古いMacがあるわけでもなくAppleTalkなんて使わないので、atalkdなどが起動しないようにしました。さらにこれだけだとafpdが勝手にモジュールをロードしてしまうようだったので、appletalkモジュール ( /lib/modules/`uname -r`/kernel/net/appletalk/appletalk.ko ) そのものを外してしまいました。
ちなみにパニックした時のログは以下。
kernel BUG at net/appletalk/ddp.c:1013! Unable to handle kernel NULL pointer dereference at virtual address 00000000 Backtrace: [<c0029290>] (__bug+0x0/0x58) from [<bf0070e4>] (atalk_sum_skb+0x1bc/0x1e4 [appletalk]) [<bf006f28>] (atalk_sum_skb+0x0/0x1e4 [appletalk]) from [<bf007128>] (atalk_checksum+0x1c/0x44 [appletalk]) [<bf00710c>] (atalk_checksum+0x0/0x44 [appletalk]) from [<bf00795c>] (atalk_rcv+0x148/0x644 [appletalk]) [<bf007814>] (atalk_rcv+0x0/0x644 [appletalk]) from [<c02720dc>] (netif_receive_skb+0x1b8/0x210) [<c0271f24>] (netif_receive_skb+0x0/0x210) from [<c02721e4>] (process_backlog+0xb0/0x190) r7 = C04FBF34 r6 = 00000000 r5 = C03A95C4 r4 = C327D800 [<c0272134>] (process_backlog+0x0/0x190) from [<c0272354>] (net_rx_action+0x90/0x174) [<c02722c4>] (net_rx_action+0x0/0x174) from [<c0058498>] (__do_softirq+0x60/0xd8) r8 = C039CBC0 r7 = 00000009 r6 = C04FA000 r5 = C039CC00 r4 = 00000001 [<c0058438>] (__do_softirq+0x0/0xd8) from [<c005855c>] (do_softirq+0x4c/0x58) r8 = 00000001 r7 = C0058ADC r6 = C039CBC0 r5 = 00000000 r4 = 60000013 [<c0058510>] (do_softirq+0x0/0x58) from [<c0058b54>] (ksoftirqd+0x78/0xb8) r4 = C04FA000 [<c0058adc>] (ksoftirqd+0x0/0xb8) from [<c0067424>] (kthread+0xf0/0x124) r6 = C04F9F50 r5 = C04FA000 r4 = 00000000 [<c0067334>] (kthread+0x0/0x124) from [<c0055700>] (do_exit+0x0/0x7dc) Code: eb00ab21 e59f0014 eb00ab1f e3a03000 (e5833000) <0>Kernel panic - not syncing: Aiee, killing interrupt handler!