VPN、いわゆるVirtual Private Networkとは主に、インターネットというセキュリティに不安のある通信経路を用いて、遠隔地のネットワークを接続する仕組み全般を指す。基本的にはPPtP(Point-to-Point Tunneling Protocol)とL2TP(Layer 2 Tunneling Protocol)というPPPを母体としたプロトコルがある。ただL2TPには暗号化が無いのでこれにIPsec(技術解説)
を組み合わせる。基本はこの組み合わせが主流になっているようだ。
IPsecは、共有鍵方式を利用して通信パケットそのものを暗号化するが、暗号アルゴリズムを限定していないため、将来的な拡張にも対応している。
ただし、OSによってはカーネルの再コンパイルが必要になる場合があることなどがあり設定が面倒である。しかし、YAMAHA RTXルーターなどとの相性もよい。
近年ではOpenVPNによるVPNも普及している。
方式 | ISO層 | ネットワークセグメント | ブロードキャスト |
ルーティング(TUN) | 3層 | 別セグメント | 届かない |
ブリッジ方式(TAP) | 2層 | 同一セグメント | 届く |
公式日本語サイト。本家英語サイトよりも充実している。
OpenVPNを利用するにあたり、ネットワークに関する概念に一部、わかりづらい部分があるため説明を行う。インターネットは、セグメントと呼ばれるネットワーク単位(通常はCクラスなどの255個単位でセグメントに端末がぶら下がる。セグメントはネットマスクの設定によって管理単位が変更される)を相互に接続し、通常はRIPと呼ばれるルーティングプロトコルを用いて、データパケットの送受信が行われる。
OpenVPNでは遠隔地にあるネットワークセグメントを接続するに、実際の機器に割り振られないOpenVPNアプリ同士内だけで、仮想ネットワークセグメントを持ち、実在するネットワークセグメント同士を接続するというのが基本的な仕組みである。そのため、この仮想ネットワークの設定が複雑になりがちで、コンフィグがわかりづらく傾向がある。このページの説明ではわかりやすくするために、このOpenVPN同士内だけの仮想ネットワークセグメントを「独自OpenVPNセグメント」と呼ぶ。
必須ライブラリである、LZOデータ圧縮解凍ライブラリを最初に導入。
# wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz # tar zxvf lzo-2.06.tar.gz # cd lzo-2.06 # ./configure # make # make install
念の為に libpam も一緒に。
# yum install pam-devel
その後に本体をインストール
# wget http://swupdate.openvpn.org/community/releases/openvpn-2.3.2.tar.gz # tar zxvf openvpn-2.3.2.tar.gz # cd openvpn-2.3.2 # ./configure # make # make install
vpnが接続を行う前段階のために、お互いを公開鍵方式による認証を通じて暗号鍵を交換が行われる。そのため通信する双方に公開鍵を作成する必要がある。通常はサーバー側で作成し、各クライアントに必要な鍵を配布する。
DHパラメータの生成
# openssl dhparam -out dh2048.pem 2048
openvpnの設定ファイルの説明(特に必要なものを抜粋)
機能 | 例 | 概要 |
通信ポートの指定 | port 1192 | OpenVPNが通信するポート番号を指定する |
通信プロトコルの指定 | proto udp | 通信プロトコルに、udp か、tcp のどちらを利用するか指定。2つ指定はできない |
通信層の指定 | dev tun | ブリッジ接続なら tap、ルーティングなら tap を指定 |
CA局の証明書 | ca cacert.pem | 独自CAの証明書ファイルを指定 |
自分の証明書 | cert server.crt | 起動するOpenVPNの証明書 |
自分の公開鍵 | key server.key | 起動するOpenVPNの公開鍵 |
DHファイルの指定 | dh dh1024.pem | DHパラメータファイルの指定。サーバー公開鍵が2048ビットの時はこのDHも2048ビットで作成する |
仮想OpenVPNセグメントの指定 | server 10.66.77.0 255.255.255.0 | OpenVPN同士で利用する、仮想セグメントのネットワークを、指定する。通常、10.66.77.0 など、絶対に自分で利用していないローカルネットワーク番号を指定する。サーバー側のOpenVPNにとっては、自動的に末尾に1がIPアドレスとして割り当てられる。(例:10.66.77.1 が仮想OpenVPNセグメント内のIPアドレスになる。1番以外を指定する場合には、ipconfig ディレクティブを利用する。またこのserverディレクティブを利用するとこのサーバーに接続されるクライアントには、順に番号が連番で付与される。簡易DHCP機能 |
仮想OpenVPNセグメント内における自分のIP指定 | ipconfig 10.66.77.250 255.255.255.0 | 上記のserverで1番を付与されたくない場合に、利用する通常指定する意味はあまりない |
仮想IPの障害時保存 | ifconfig-pool-persist ipp.txt | 障害時の後の再接続時に、前回接続したIPアドレスで再接続する。基本指定しておく |
ブリッジ接続指定 | server-bridge | ブリッジ指定でサーバー起動する場合に指定。引数を指定することでIPアドレスの制限をかけることができる。例:server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 これは、10.8.0.4/255.255.255.0 をブリッジのIPアドレスとして、50番から100番までを許可するという指定になる |
ルーティング情報の出力 | push "route 192.168.10.0 255.255.255.0" | クライアント側に、指定の「静的」ルート情報を通知する。複数指定することも当然可能 |
ルーティング情報の出力 | push "redirect-gateway def1 bypass-dhcp | サーバー側のルーティング情報を、クライアント側にもバイパス指定する |
ルーティング情報の出力 | route "dhcp-option DNS 202.12.27.33" | DHCP通知の際にDNS情報を追加通知する。最後のIPアドレスはDNSアドレス。(主にWindowsクライアントに利用) |
ルーティング情報の出力 | route "dhcp-option WINS 202.12.27.33" | DHCP通知の際にWINS情報を追加通知する。最後のIPアドレスはWINSアドレス。(主にWindowsクライアントに利用) |
拠点接続指定 | client-to-client | 通常、サーバー側からクライアントを見る事ができないが、サーバーからも見えるようにすることで、相互にうう新できる。但しその場合、クライアント側のファイアーウォール指定に注意すること |
クライアント証明書の重複許可 | duplicate-cn | 正確には固有名の重複許可であるが、機能としてはこれを指定することで、複数のクライアントにすべて同じ証明書を利用することができる |
生存確認時間の指定 | keepalive 10 120 | 接続同士で定期的に生存中の通知を送るのに、何分置きで送るかを指定。1番めの数字が定期通知時間(秒)。2番めの数字が最大確認時間(秒)。例では10秒おきに生存チェックを行い、通信できなくても120秒までは接続チェックを行う |
TLS認証用の暗号ファイル | tls-auth ta.key 0 | ta.key は、openvpn --genkey --secret ta.key で作成できる。tls-auth モードを利用する場合、作成された ta.key は、サーバー、クライアント共に同じファイルを利用する必要がある。最後の数字は 0 の場合サーバー、1の場合はクライアントの意味となる |
暗号方式の指定 | cipher BF-CBC | 暗号方式として、BF-CBC(Blowfish)、AES-128-CBC(AES128)、DES-EDE3-CBC(Triple-DES)の3つが選択できる指定しない場合、初期値の BF-CBCが選択される |
lzo圧縮の指定 | comp-lzo | lzo圧縮機能を有効にする。基本は指定しておいたほうが良い |
デーモンユーザーの指定 | user openvpn group openvpn | OpenVPNがデーモン起動する場合のユーザーとグループを指定する。adduser などでユーザー作成を忘れないように |
障害時の接続維持 | persist-key persist-tun | 障害が発生しOpenVPNが再起動された時に、以前の接続を維持するように指定。通常は指定しておく |
ステータスログ | status openvpn-status.log | 起動中のOpenVPNの状態を1分毎に指定ファイルに保存する |
システムログ | log openvpn.log log-append openvpn.log | OpenVPNが出力するログを、syslog 以外に出力したい場合は、ここで指定する。通常は指定の必要はない |
ログレベルの指定 | verb 3 | 上記システムログ出力時のログ詳細レベルの指定。0 は出力無し、9 が最大出力。3 が普通のログ量 |
ログの繰り返し制限 | mute 20 | 表示されないシステムログにおいて、指定した回数を超えたメッセージは、強制的にログに出力するようにする(主にハッキングやアッタクの調査に役に経つ) |
上記の説明で設定は可能になると思うが、拠点間接続でのサーバー側設定のサンプルは下記の通り。
# vi server.conf port 1194 proto udp dev tun ca ca.crt cert server.crt key server.key dh dh2048.pem server 10.66.77.0 255.255.255.0 push "route 192.168.202.0 255.255.255.0" client-to-client duplicate-cn keepalive 10 120 comp-lzo user openvpn group openvpn status openvpn-status.log persist-key persist-tun verb 3
# vi client.conf dev tap proto udp remote vpn.mydomain.com 1194 resolv-retry infinite # サーバホスト名の名前解決を永遠に試みる nobind # ローカルポート番号をバインドしない user openvpn group openvpn persist-key persist-tun ca ca.crt cert client.crt key client.key client-to-client duplicate-cn ns-cert-type server comp-lzo verb 3
その他
tls-client # TLS認証を利用 pull # OpenVPNサーバのDHCP機能を利用して動的にIPアドレスを取得する場合はpullに設定
イーサネットブリッジとは異なる2つの拠点間をブリッジ接続して、同一のIPサブネット間のセキュアなトンネルを作りたい場合に利用する。(ハブ機能といった方が分かり易いか) 要するに、離れた場所にある物理イーサネットNICとOpenVPN駆動のTAPインタフェースをブリッジングすることにより,あたかも同じイーサネットのサブネットに入っているかのように,論理的に双方を結合させることが可能となる。特にゲーム対戦のようなサブネットでのブロードキャストを利用したい場合には必須といえる。
# yum install bridge-utils
これは、遠隔地にあるネットワーク番号の異なるセグメントを接続するような場合に利用する。例えば本社のネットワークが、192.168.0.0/24 支社のネットワークが 192.168.1.0/24 というような2つのセグメントを接続し、パケットをルーティングさせる。
特に複数の拠点を接続するような場合には非常に便利であり、ブリッジと違い無駄なパケットを送ることもなく、接続台数の制限も無い。
すでにネットワークを作成している場合はそれを選択するが、これからネットワークを設計する上での参考資料として、IPアドレスにおいてPrivateアドレスとしてIANA (Internet Assigned Numbers Authority)に登録されているのは以下の通り。
NETWORK | 逆MASK | 概要 |
10.0.0.0 | 10.255.255.255 | Aクラス 10/8 接頭 |
172.16.0.0 | 172.31.255.255 | 変則Bクラス 172.16/12 接頭 |
192.168.0.0 | 192.168.255.255 | Bクラス 192.168/16 接頭 |
上記の方法でOpenVPNをインストールすると、openvpn-2.1.1/easy-rsa/以下にRSAのファイル群がインストールされる。ここで、以下のファイルを編集する。
# cd openvpn-2.1.1/easy-rsa # vi ./vars export EASY_RSA="/usr/local/src/CA" <- データの作成場所 export KEY_SIZE=2048 <- 作成するキー長 export KEY_COUNTRY="US" <- 国のコード export KEY_PROVINCE="CA" <- 州や県など地域のコード export KEY_CITY="SanFran" <- 市のコード export KEY_ORG="MyCompany" <- 自分たちの組織の名前 export KEY_EMAIL="myEmail@gmail.com" <- 連絡用メールアドレス
# ./build-dh
openvpn-2.1.1/sample-config-files/の下に、server.confとclient.confのサンプルがおいてあるので、このファイルを修正して設定ファイルを作成する。
サーバー側の設定ファイルであるserver.confを修正
# vi server.conf port 1194 <- port番号を設定 proto tcp <- プロトコルを選択 ca ca.crt <- さきほど作成した証明書ファイル群 cert server.crt key server.key dh dh2048.pem server 192.168.100.0 255.255.255.0 <- clientに与えられるネットワーク(OpenVPN自体は末尾1番が割り振られる) push "route 192.168.0.0 255.255.255.0" <- clientに追加されるルート情報 client-to-client <- コメントを取る
フォルダ /etc/openvpn を作成し、先に作成した証明書などと、修正したserver.conf を含めファイルをコピーする。
# cd openvpn-2.1.1/easy-rsa/2.0/keys # cp ca.crt /etc/openvpn/ # cp server.crt /etc/openvpn/ # cp server.key /etc/openvpn/ # cp dh2048.pem /etc/openvpn/
# cd openvpn-2.1.1/sample-config-files/ # cp server.conf /etc/openvpn/ # cp openvpn-startup.sh /etc/openvpn/ # cp openvpn-shutdown.sh /etc/openvpn/ # cp firewall.sh /etc/openvpn/
このファイルでopenvpnを起動するが、このスクリプト内部で、iptablesの設定を行う、firewall.sh を呼び出しているところがあるので、ここは自分の環境に合わせて設定を行う。
ping 60 ping-restart 1800 persist-tun float
自分で設定を行う場合 VPNを深く理解するにあたり、自分でインターフェイスを作成することも後学の為になる。
# vi /etc/modules alias tap0 tun <- tun インターフェイスから実際のデバイス名を参照 # echo 1 > /proc/sys/net/ipv4/ip_forward <- IPパケットを転送するように設定
iptabelsにtunのフォワーディングを許可する。
iptables -A INPUT -i tun+ -j ACCEPT <- 入力パケットを許可する iptables -A OUTPUT -o tun+ -j ACCEPT iptables -A FORWARD -i tun+ -j ACCEPT iptables -A FORWARD -o tun+ -j ACCEPT
※tun+の後ろについている+は、tun0 tun1 tun2 など数字に対するワイルドカードなので、個別にコントロールする場合にはtun0 というようにすべて記載する必要がある
tunnel select 1 >ipsec tunnel 1 >ipsec sa policy 1 1 esp 3des-cbc md5-hmac >ipsec ike always-on 1 on >ipsec ike encryption 1 3des-cbc >ipsec ike esp-encapsulation 1 off >ipsec ike group 1 modp768 >ipsec ike hash 1 md5 >ipsec ike keepalive log 1 off >ipsec ike local address 1 AAA.AAA.AAA.AAA (RTX1100のLANアドレス) >ipsec ike pfs 1 off >ipsec ike pre-shared-key 1 text ********(事前共有キー) >ipsec ike remote address 1 BBB.BBB.BBB.BBB(MR504DVのWANアドレス) >ipsec auto refresh 1 on ip tunnel tcp mss limit auto tunnel enable 1 >ipsec auto refresh on nat descriptor type 1 masquerade nat descriptor masquerade static 1 1 AAA.AAA.AAA.AAA udp 500 nat descriptor masquerade static 1 2 AAA.AAA.AAA.AAA esp ip filter 1040 pass * AAA.AAA.AAA.AAA udp * 500 ip filter 1041 pass * AAA.AAA.AAA.AAA esp ip route 192.168.0.0/24 gateway tunnel 1
サーバーで作成した証明書ファイルをクライアントにコピーする。場所は/User/Library/openvpn/の下に、keysフォルダを作成し、そこにコピーする。その後、tunnelblick用の設定ファイルをコピーして編集する。
# vi config.tblk remote mydomain.ddns 1194 ←ドメインまたはダイナミックDNS ca keys/ca.crt cert keys/clientx.crt key keys/clientx.key ns-cert-type server ←忘れずに有効化する tls-auth keys/ta.key 1