SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|

2011-02-25(Fri) VPSまでトンネルを掘る

  先日より「さくらのVPS」を契約している……いや、先日、というか……先月、というか……実は、契約したのはかなり前(10月17日)だったりするのだが、その後、仕事が忙しくなったので、金だけ払って放置、という状態が続いていたのだった。

  まぁ、980円/月だし、ちょっとカジってみようか、という動機だったのだが、されど、980円/月である。使わなければもったいない話だ。とりあえず、20Gもあることだし、iSCSIターゲットの設定をして「外付けハードディスク」にでも仕立ててみようか、などと、変なことを考えてみた。

  ところが、iSCSIは暗号化をしない。よって、暗号化トンネルを確保してやる必要があるだろう。そんな時、OpenVPNがリングに上がるのである。あ、別に、iSCSIに限らずとも、nfsやsambaなどを利用するにしても、通信経路の暗号化はしておいた方がいいと思うので、今回の手順は有用なはずである。

  OpenVPNには、サーバとクライアントの概念がある。もちろん、通信経路としては双方向に利用できるが、関係としては一方向というわけである。クライアントが提出するデジタル証明書を、サーバが検証、接続を許すというカラクリだ。

  ここで少し迷うのは、自宅サーバとVPSのどちらをサーバ側とするか、であるが、まぁ、どっちも似たようなものだ。今回は、自宅サーバをサーバ側、VPSをクライアント側としてみた。

  まず、自宅側、つまり、サーバ側の設定である。ほぼそのまんま、だーっといく。

sheonite.itline.jp:/root # yum install openvpn
sheonite.itline.jp:/root # cd /etc/openvpn/
sheonite.itline.jp:/etc/openvpn # cp /usr/share/doc/openvpn-2.1/sample-config-files/server.conf .
sheonite.itline.jp:/etc/openvpn # cp -a /usr/share/openvpn/easy-rsa/ .
sheonite.itline.jp:/etc/openvpn # cd easy-rsa/2.0/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # vi vars
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # diff vars.org vars
64,68c64,68
< export KEY_COUNTRY="US"
< export KEY_PROVINCE="CA"
< export KEY_CITY="SanFrancisco"
< export KEY_ORG="Fort-Funston"
< export KEY_EMAIL="me@myhost.mydomain"
---
> export KEY_COUNTRY="JP"
> export KEY_PROVINCE="Aichi"
> export KEY_CITY="Nagoya" ★自宅は名古屋
> export KEY_ORG="ITLine, Inc."
> export KEY_EMAIL="hoge@fuga.jp"
★認証局/サーバの証明書への登録内容を入力
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # . ./vars
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # ./clean-all 
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # ./build-ca 
★Returnキー連打で、認証局の証明書と秘密鍵を作る
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # ./build-key-server itline.jp
★Returnキー連打で、サーバの証明書と秘密鍵を作り、認証局の証明書で署名する
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # ./build-dh 
★共通鍵交換用のパラメータを作る
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/ca.crt /etc/openvpn/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/itline.jp.crt /etc/openvpn/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/itline.jp.key /etc/openvpn/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/dh1024.pem /etc/openvpn/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cd /etc/openvpn/
sheonite.itline.jp:/etc/openvpn # vi server.conf
sheonite.itline.jp:/etc/openvpn # diff server.conf.org server.conf
79,80c79,80
< cert server.crt
< key server.key  # This file should be kept secret
---
> cert itline.jp.crt
> key itline.jp.key  # This file should be kept secret
★サーバの証明書と秘密鍵を指定する
162c162
< ;client-config-dir ccd
---
> client-config-dir ccd
★常に同じIPアドレスでトンネルを掘るための設定
sheonite.itline.jp:/etc/openvpn # mkdir ccd
sheonite.itline.jp:/etc/openvpn # vi ccd/darius.ddo.jp
sheonite.itline.jp:/etc/openvpn # cat ccd/darius.ddo.jp
ifconfig-push 10.8.0.101 10.8.0.102
★VPSクライアントホスト「darius.ddo.jp」は、常に10.8.0.101/10.8.0.102でトンネルを掘る
sheonite.itline.jp:/etc/openvpn # service openvpn start
★openvpnのサーバ側の待ち受け開始!
sheonite.itline.jp:/etc/openvpn # ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
★トンネルI/Fが出現、サーバ側の出入口は10.8.0.1
sheonite.itline.jp:/etc/openvpn # chkconfig openvpn on

  つぎに、VPS側、つまり、クライアント側の設定である。こっちも、ほぼそのまんま、だーっといく。

[root@www1234x ~]# yum install openvpn
[root@www1234x ~]# cd /etc/openvpn/
[root@www1234x openvpn]# cp /usr/share/doc/openvpn-2.1.1/sample-config-files/client.conf .
[root@www1234x openvpn]# cp -a /usr/share/openvpn/easy-rsa/ .
[root@www1234x openvpn]# cd easy-rsa/2.0/
[root@www1234x 2.0]# vi vars
[root@www1234x 2.0]# diff vars.org vars
64,68c64,68
< export KEY_COUNTRY="US"
< export KEY_PROVINCE="CA"
< export KEY_CITY="SanFrancisco"
< export KEY_ORG="Fort-Funston"
< export KEY_EMAIL="me@myhost.mydomain"
---
> export KEY_COUNTRY="JP"
> export KEY_PROVINCE="Tokyo"
> export KEY_CITY="Shinjyuku" ★VPSはたぶん新宿
> export KEY_ORG="ITLine, Inc."
> export KEY_EMAIL="hoge@fuga.jp"
★クライアントの証明書への登録内容を入力
[root@www1234x 2.0]# . ./vars
[root@www1234x 2.0]# ./clean-all 
[root@www1234x 2.0]# ./build-req darius.ddo.jp
★Returnキー連打で、クライアントの証明書(未署名)と秘密鍵を作る

  ここで、いったん自宅側に戻る。クライアントの証明書(未署名)に、認証局として署名をしてやらないといけないからだ。巷のサイトでは、このようにクライアント側ではなく、サーバ側でクライアントの証明書を作ってしまう手順を紹介している事例が多いが、そういうコトを書いてしまうということは「非対称鍵のなんたるかは全く理解できてません」と公表しているようなモンである。

  正しい手順では、ここで作った未署名のクライアントの証明書である、darius.ddo.jp.csrをサーバまで持ってくる。

sheonite.itline.jp:/etc/openvpn # cd easy-rsa/2.0/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp ~user/darius.ddo.jp.csr keys/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # ./sign-req darius.ddo.jp
★クライアントの証明書に認証局の証明書で署名する
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/ca.crt ~user/
sheonite.itline.jp:/etc/openvpn/easy-rsa/2.0 # cp keys/darius.ddo.jp.crt ~user/

  再び、VPS側へ。認証局の証明書と、クライアントの証明書(署名済)をクライアント側にセットするためだ。ca.crtとdarius.ddo.jp.crtをクライアント側へ持っていく。

[root@www1234x 2.0]# mv ca.crt keys/
[root@www1234x 2.0]# mv darius.ddo.jp.crt keys/
[root@www1234x 2.0]# cp keys/ca.crt /etc/openvpn/
[root@www1234x 2.0]# cp keys/darius.ddo.jp.crt /etc/openvpn/
[root@www1234x 2.0]# cp keys/darius.ddo.jp.key /etc/openvpn/
[root@www1234x 2.0]# cd /etc/openvpn/
[root@www1234x openvpn]# vi client.conf
[root@www1234x openvpn]# diff client.conf.org client.conf
42c42
< remote my-server-1 1194
---
> remote itline.jp 1194
★接続先であるOpenVPNサーバを指定する
89,90c89,90
< cert client.crt
< key client.key
---
> cert darius.ddo.jp.crt
> key darius.ddo.jp.key
★クライアントの証明書と秘密鍵を指定する
[root@www1234x openvpn]# service openvpn start
★openvpnのクライアント側の接続開始!
[root@www1234x sysconfig]# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.101  P-t-P:10.8.0.102  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:86 errors:0 dropped:0 overruns:0 frame:0
          TX packets:88 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:15903 (15.5 KiB)  TX bytes:10959 (10.7 KiB)
★トンネルI/Fが出現、クライアント側の出入口は10.8.0.101
[root@www1234x sysconfig]# chkconfig openvpn on

  なお、以上の手順で証明書ファイルをやりとりする限り、暗号化された通信経路でやる必要はない。もちろんフロッピーやUSBメモリで運ぶ必要もない(無理だし)。ファイルどこかに置き忘れても構わない。なぜなら、証明書に対応する秘密鍵を各々のホストの上から「移動していない」からだ。

  これに関しては著名なITサイトですらアフォなことを書いている。まさに「非対称鍵のなんたるかは全く理解できてません」と公表している。要するに、以前に書いたこの記事と同じことなのだが、今回はクライアント側もLinuxであるだけに、サーバ側でクライアントの証明書を作らなければならない理由は皆無である。

  さて、あとはOpenVPSのポート番号である1194番について、双方のファイアウォールに穴を空けてから、10.8.0.101に向けてpingを打ってみよう。

# openvpn
-A INPUT -m udp -p udp --dport 1194 -j ACCEPT
sheonite.itline.jp:/root # ping 10.8.0.101
PING 10.8.0.101 (10.8.0.101) 56(84) bytes of data.
64 bytes from 10.8.0.101: icmp_seq=1 ttl=64 time=9.82 ms
64 bytes from 10.8.0.101: icmp_seq=2 ttl=64 time=9.10 ms
64 bytes from 10.8.0.101: icmp_seq=3 ttl=64 time=9.86 ms
64 bytes from 10.8.0.101: icmp_seq=4 ttl=64 time=9.59 ms
★pingを打つと……
 
sheonite.itline.jp:/root # tcpdump -i tun0
tcpdump: WARNING: arptype 65534 not supported by libpcap - falling back to cooked socket
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
23:12:56.979174 IP 10.8.0.1 > 10.8.0.101: ICMP echo request, id 63070, seq 1, length 64
23:12:56.988956 IP 10.8.0.101 > 10.8.0.1: ICMP echo reply, id 63070, seq 1, length 64
23:12:57.980163 IP 10.8.0.1 > 10.8.0.101: ICMP echo request, id 63070, seq 2, length 64
23:12:57.989201 IP 10.8.0.101 > 10.8.0.1: ICMP echo reply, id 63070, seq 2, length 64
23:12:58.980788 IP 10.8.0.1 > 10.8.0.101: ICMP echo request, id 63070, seq 3, length 64
23:12:58.990588 IP 10.8.0.101 > 10.8.0.1: ICMP echo reply, id 63070, seq 3, length 64
23:12:59.981796 IP 10.8.0.1 > 10.8.0.101: ICMP echo request, id 63070, seq 4, length 64
23:12:59.991334 IP 10.8.0.101 > 10.8.0.1: ICMP echo reply, id 63070, seq 4, length 64
★トンネルI/F上ではICMPパケットに見えるが……
 
sheonite.itline.jp:/root # tcpdump -i ppp0 port openvpn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ppp0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
23:12:56.979393 IP CEPci-12p34-567.ppp89.odn.ad.jp.openvpn > www1234x.sakura.ne.jp.46126: UDP, length 125
23:12:56.988794 IP www1234x.sakura.ne.jp.46126 > CEPci-12p34-567.ppp89.odn.ad.jp.openvpn: UDP, length 125
23:12:57.980387 IP CEPci-12p34-567.ppp89.odn.ad.jp.openvpn > www1234x.sakura.ne.jp.46126: UDP, length 125
23:12:57.989083 IP www1234x.sakura.ne.jp.46126 > CEPci-12p34-567.ppp89.odn.ad.jp.openvpn: UDP, length 125
23:12:58.981005 IP CEPci-12p34-567.ppp89.odn.ad.jp.openvpn > www1234x.sakura.ne.jp.46126: UDP, length 125
23:12:58.990467 IP www1234x.sakura.ne.jp.46126 > CEPci-12p34-567.ppp89.odn.ad.jp.openvpn: UDP, length 125
23:12:59.982007 IP CEPci-12p34-567.ppp89.odn.ad.jp.openvpn > www1234x.sakura.ne.jp.46126: UDP, length 125
23:12:59.991210 IP www1234x.sakura.ne.jp.46126 > CEPci-12p34-567.ppp89.odn.ad.jp.openvpn: UDP, length 125
★PPP接続上では暗号化されている、ということがわかる

  これにて一件落着!