2013年12月20日金曜日

Vista(HomePremium)からNATの外に出てWindows7(Pro)にL2TP/IPsecでVPN接続するテスト記録

2台のPCをL2TP over IPsecでVPN接続してみた。

[VPNクライアント・発信側]
Windows Vista HomePremium SP2 64bit
コンピュータ名:CliPC

[VPNサーバ・着信側]
Windows7 Professional SP1 32bit
コンピュータ名:SerPC
物理NICのIPアドレス:G.G.G.1 (グローバルアドレスのつもり)
仮想LoopbackのIPアドレス:192.168.22.1/24

[NAT対応]
NATを経由する L2TP over IPsec を使うためには、
NAT Traversal というのを有効にする必要があるらしい。
クライアント と サーバ 両方でレジストリの変更をする。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent
で
AssumeUDPEncapsulationContextOnSendRule 
DWORD(32ビット)値:1
を作成し、PCを再起動して作業完了。

クライアントもサーバも両方がNATの内側なら、
DWORD(32ビット)値:2
に、設定するらしい。

[[参考]]
How to configure an L2TP/IPsec server behind a NAT-T device in Windows Vista and in Windows Server 2008
http://support.microsoft.com/kb/926179/
※Windows7でも、同じ作業が必要らしいので行った。

[Microsoft管理コンソール(MMC)のショートカットを作成]
次の二つ
 セキュリティが強化されたwindowsファイアウォール
 証明書マネージャ(コンピューターアカウント・ローカルコンピューター用)
 ※certmgr.mscの通常起動では、現在のユーザ用で別物なので注意
は何度も使うので、管理者権限のあるユーザ+UACでmmc.exeを起動し、
スナップインの追加と削除でこの二つを追加し、
名前を付けて保存 で、ショートカットを作成した。

[セキュリティが強化されたwindowsファイアウォールの設定]
クライアントは、L2TP(UDP1701)宛の送信、
サーバはL2TP(UDP1701)宛の送受信を許可しておけばいけた。
もっと少ない許可でいけるかもしれないが、試していない。
※IPsecは、UDP500、UDP4500(NAT利用時)、ESP(プロトコル番号50 NAT非利用時)
 あたりを使うを使うらしいが、[NAT対応]による影響か、IPSecは特別扱いか、
 コアネットワークTeredo 許可(サービス はUDP全ポート)の影響か、
 理由は分からないが、これらのポート、プロトコルについては何も設定しなかった。
PPTPとSSTPは、許可を無効にしておく。
※サーバがPPTPを受け付けないようにするには、
 ココで設定するしか方法がわからなかった。

ちなみに、サーバ側がNAT内側ならば、NATの設定で
UDP500とUDP4500を当該サーバに転送すればよいらしい。
UDP1701は不要で、 IPSecパススルー という機能は、
NAT Traversalを用いる場合に使っては駄目らしいが分からない。

[[参考]]
iPhoneをVPNで @ 勝手にまとめウィキ - L2TP/Windows7
http://www58.atwiki.jp/iphonevpn/pages/17.html

[認証に事前共有キーを使ってL2TP IPsec VPN接続]
[[サーバ側の準備]]
証明書マネージャ で 個人 に 信頼されたルート証明機関 証明書 から、
有効期限内で目的 が <全て> の証明書を1つコピーする。
Microsoft Root Certificate Authority というのを使った。
※これはおまじない的な作業だが、必要らしい

ファイアウォール で セキュリティの規則 を 新規作成 する。
 カスタム
 エンドポイント1 を G.G.G.1 エンドポイント2は 任意
  ※NAT経由なら使うことはなさそうだが、エンドポイント2を指定すれば、
  クライアントのIPアドレス(通常グローバルアドレス)毎に異なる
  事前共有キー を設定できると思われる。
 受信接続と送信接続の認証を要求する
 詳細設定 で 追加 事前共有キー 
 プロトコル UDP エンドポイント1 を 1701 エンドポイント2は 任意
 ドメイン・プライベート・パブリック

ネットワーク接続(NIC一覧) ファイル メニュー から 新しい着信接続 を作る。
 ※VPN接続のクライアント認証で有効な ユーザ(と、その パスワード) を
  既存のユーザから選ぶが、VPN接続後にファイル共有や
  リモートデスクトップに使うIDとは別でかまわないっぽい。
  クライアント認証に、一応、長いパスワードを使いたいので、
  VPN接続のクライアント認証専用のユーザを追加することにした。
 作った着信の プロパティ IPv4 プロパティ で、クライアントに割り当てる
 IPアドレス範囲を設定する。仮想LoopbackのIPアドレスと同じサブネットの
 192.168.22.10 から 99 にした。

[[クライアント側の準備]]
新しい接続またはネットワークのセットアップ で、サーバへの接続を作成する。
作成後 プロパティ で詳細設定をしていく。
 セキュリティ タブ
  L2TP/IPsec  詳細設定で 事前共有キー 
 ネットワーク タブ
  IPv4 プロパティ 詳細設定 
   リモート ネットワークでデフォルト ゲートウェイを使う を解除

[[接続実行]]
VPN接続を数クリックで実行でるようになり、
クライアントからサーバの仮想Loopback(192.168.22.1)へアクセスできる
ようになった。
※ファイアーウォールの設定次第ではpingの反応すらないのは当然

バッチファイルで接続を実行するなら、
VPN接続のプロパティ オプション タブ で
接続中の進捗表示と名前、パスワードの入力を求める
を解除しておいて、
rasphone.exe -d 接続先の名前
を実行すればよい。

L2TP/IPsecで接続できてるか確認するには、
ファイアウォール 監視 セキュリティアソシエーション を見れば良いっぽい。

[[オマケ]]
IPsecに関連しそうなWindowsの サービス については以下の通り
 IKE and AuthIP IPsec Keying Modules 必須っぽい
 IPsec Policy Agent 任意っぽい

[[参考]]
クライアント版WindowsをL2TP/IPSecサーバーにしてiPhoneから接続する: 超私的まとめも
http://zzt231.cocolog-nifty.com/blog/2012/09/windowsl2tpipse.html


[認証に証明書を使ってL2TP IPsec VPN接続]
[[証明書の作成]]
debian wheezy openssl パッケージを使って、
個人的なCA(で、1つの証明書+秘密鍵)を作成し、
証明書については当該CA(秘密鍵)が発行する
サーバ用の 証明書+秘密鍵 (ファイル名 SerPC.p12) と
クライアント用の 証明書+秘密鍵 (ファイル名 CliPC.p12) を
作成した。CAの証明書は、SerPC.p12 でも CliPC.p12 でも、
Windowsでインポートすると一緒にインポートされる。

私は勘違いしていたのだが・・・
通常設定、あるいは仕様で、Windows Vista,7 は、
認証に証明書を使ってL2TP IPsec VPN接続 をする時は、
VPNクライアントとVPNサーバーの両方が、同一のCA(秘密鍵)で発行を受けた
証明書+秘密鍵 を持っていないといけない。
すなわち、VPNクライアントはCA1による証明書、
VPNサーバはCA1とは別のCA2による証明書になっている
証明書+秘密鍵 では、たとえ、CA1とCA2の両方のCAの証明書を
VPNクライアントとVPNサーバーの両方で、信頼されたルート証明機関 に
インポートしたとしても、VPN接続はできない。
そのため、Verisign を始め、信頼されたルート証明機関 に、
OSインストール時から入ってる証明機関から発行された証明書+秘密鍵
を持っている外部の知らないホストが、VPNサーバに接続してきた場合、
証明書の認証は通過して、あとはIDとパスワードだけで接続できてしまう・・・
という心配は無いっぽい。

IPSec の特段の注意事項
http://technet.microsoft.com/JA-JP/library/cc757905.aspx

ちなみに、VPNクライアントとVPNサーバーの両方が
同じ 証明書+秘密鍵 を使った場合、VPN接続はできる。


SerPC.p12 と CliPC.p12 の作成手順の抜粋は以下の通り。

mkdir oreore-ca/
cd oreore-ca
cp /usr/lib/ssl/misc/CA.sh ./
cp /etc/ssl/openssl.cnf ./
vi CA.sh
diff CA.sh /usr/lib/ssl/misc/CA.sh
< if [ -z "$DAYS" ] ; then DAYS="-days 7300" ; fi # 20 year
< CADAYS="-days 7300" # 20 years
※-days オプション で 証明書の有効期限を 20年に設定
---
< REQ="$OPENSSL req -config ./openssl.cnf $SSLEAY_CONFIG"
< CA="$OPENSSL ca -config ./openssl.cnf $SSLEAY_CONFIG"
※-config ./openssl.cnf の追加で、設定ファイルのパスを設定
---
<     $REQ -new -nodes -extensions v3_req -keyout newreq.pem -out newreq.pem $DAYS
※-newreq-nodes の部分で、設定ファイル内の [ v3_req ] 部分を有効にした。
---
<     $CA -policy policy_anything -extensions v3_req -out newcert.pem -infiles newreq.pem
※-signreq の部分で、設定ファイル内の [ v3_req ] 部分を有効にした
 [ v3_req ] では、証明書 の 目的 等を設定している。
 [ v3_req ] が無効なら、証明書 の 目的 は すべて になるようだ。
 ただし、通常、Windows7のVPNサーバは、目的 の設定を無視するようだ。
 無視しないようにする方法はわからなかったので、
 特に、クライアント認証(発信)では使うが、
 サーバ認証(着信)には使いたくない証明書があっても、
 VPN着信を作っていた場合、サーバ認証に使ってしまう。


vi openssl.cnf
diff openssl.cnf /etc/ssl/openssl.cnf
< #attributes  = req_attributes
※'extra' attributes とか、入力の省略
---
< countryName_default  = JP
※証明書サブジェクトのデフォルト値変更
---
< extendedKeyUsage = clientAuth,serverAuth
※[ v3_req ] 部分において、発行する 証明書 の 拡張キー使用法(EKU) を
 サーバー認証 と サーバ認証 に設定。
 ただし、Windows7のVPNサーバは、このあたりの設定を無視するので、
 意味が無い。気分の問題。

CA.sh -newca
※CAの情報を入力していく。
 一応、クライアント サーバ いずれとも無関係な感じにしておくと
 無難かなと思ったので、Common Name とかは、気をつけておいた。
openssl x509 -in ./demoCA/cacert.pem -out ./demoCA/cacert.crt
※これはオマケの処理だが、WindowsでCAの証明書のみを
 インポートしてみたいときは、これで作ったcacert.crtを使う。

CA.sh -newreq-nodes
※サーバ用の証明書を作る。注意点は、
 Common Name (e.g. server FQDN or YOUR name)で、
 サーバのDNS名を設定した方がよさそう。
 VPNクライアントが、VPNサーバをIPアドレスではなくDNS名で指定し、かつ、
 サーバーの証明書の名前と使用法の属性を検証する を有効にしていたとき、
 この2つのDNS名が一致するか確認することで、
 サーバの成りすまし防止ができるっぽい。
CA.sh -signreq
CA.sh -pkcs12 "SerPC Certificate"
mv newcert.p12 SerPC.p12

CA.sh -newreq-nodes
※クライアント用の証明書を作る。
 Common Name (e.g. server FQDN or YOUR name)は、
 クライアントのコンピュータ名を使っては!!!いけない!!!。
 コンピュータ名と一致すると、正当性の確認処理か何かが
 行われるためか、VPN接続を実行できなかった。
 DNS名も使わない方がよいかもしれない、わからない。
CA.sh -signreq
CA.sh -pkcs12 "CliPC Certificate"
mv newcert.p12 CliPC.p12

以上で証明書の作成は完了。

[[[参考]]]
セキュリティ・PKI/OpenSSL - yanor.net/wiki
http://yanor.net/wiki/?%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%BBPKI%2FOpenSSL

6-6(1)CAの構築 : 基礎から学ぶ無線LANの設定と設計
http://www.viva-musen.net/archives/21025477.html

[[サーバ側の準備]]
証明書マネージャ で 個人 に サーバ用の 証明書+秘密鍵 をインポートする。
一緒にインポートされたCAの証明書を、信頼されたルート証明機関 に移動する。
ファイアウォール での設定は、通常不要。
※事前共有キーでも証明書でも着信可にする方法は不明。
 特定の証明書+秘密鍵だけを着信可にする方法不明。
 エンドポイントの設定で、クライアントアドレス毎に
 選ぶことはできると思う。
ネットワーク接続(NIC一覧) ファイル メニュー から 新しい着信接続 を作る。
 ※VPN接続のクライアント認証で有効な ユーザ(と、その パスワード) を
  既存のユーザから選ぶが、VPN接続後にファイル共有や
  リモートデスクトップを使うIDとは別でかまわないっぽい。
  VPN接続のクライアント認証だけに使うユーザを作って使うことにした。
 作った着信の プロパティ IPv4 プロパティ で、クライアントに割り当てる
 IPアドレス範囲を設定する。仮想LoopbackのIPアドレスと同じサブネットの
 192.168.22.10 から 99 にした。

これにより、同じCA(秘密鍵)から発行を受けた、
証明書+秘密鍵 を持つクライアントからの接続を受け付ける準備ができた。

[[クライアント側の準備]]
証明書マネージャ で 個人 に クライアント用の 証明書+秘密鍵 をインポートする。
一緒にインポートされたCAの証明書を、信頼されたルート証明機関 に移動する。
※証明書+秘密鍵 の発行時 または プロパティ で証明書の目的を
 制限、限定できるような感じになっているが、残念ながら無視される。
 着信に使うつもりがなくても、VPNの着信接続が作られてあれば、
 この 証明書+秘密鍵 が着信にも有効となってしまう。回避方法不明。
新しい接続またはネットワークのセットアップ で、サーバへの接続を作成する。
作成後 プロパティ で詳細設定をしていく。
 セキュリティ タブ
  L2TP/IPsec  詳細設定
   [o]認証に証明書を使う
    [v]サーバーの証明書の名前と使用法の属性を検証する
    ※サーバの証明書+秘密鍵作成時、サーバのDNS名を正しく設定した場合のみ
 ネットワーク タブ
  IPv4 プロパティ 詳細設定 
   リモート ネットワークでデフォルト ゲートウェイを使う の チェックを解除

[[接続実行]]
VPN接続を数クリックで実行でるようになり、
クライアントからサーバの仮想Loopback(192.168.22.1)へアクセスできる
ようになった。
※ファイアーウォールの設定次第ではpingの反応すらないのは当然

バッチファイルとかで接続を実行するなら、
接続のプロパティ オプション タブ で
[ ]接続中の進捗表示と名前、パスワードの入力を求める
にしておいて、
rasphone.exe -d 接続先の名前
を実行すればよい。

L2TP/IPsecで接続できてるか確認するには、
ファイアウォール 監視 セキュリティアソシエーション を見れば良いっぽい。

[[オマケ]]
IPsecに関連しそうなWindowsの サービス については以下の通り
 IKE and AuthIP IPsec Keying Modules 必須っぽい
 IPsec Policy Agent 任意っぽい

[[参考]]
コンピューター証明書による認証を使用して RRAS を構成する
http://technet.microsoft.com/ja-jp/library/dd458982.aspx

How to configure verification of additional fields in peer certificates during IKE negotiation for L2TP/IPsec tunnel connections in Windows Vista
http://support.microsoft.com/kb/926182

2013年12月17日火曜日

Windows7 で Microsoft Loopback Adapter を使う

Windows7のPCで、当該PCにL2TP/IPsecでVPN接続した端末専用の
仮想サブネットを用意しようとしていた時、
出だしの、仮想ネットワークアダプタの追加方法から分からなかった。

Vistaでも同様だが、

コントロールパネル→デバイスマネージャー→「ネットワークアダプター」を選択した状態で、
メニューから「操作→レガシハードウェアの追加」→あとはウィザードに従い、
ネットワークアダプタのリストから、製造元を「マイクロソフト」、
ネットワークアダプターを「Microsoft Loopback Adapter」

で、可能でした。

このアダプタに、IPアドレスを振ったが、
"ネットワークと共有センター"で確認したところ、
"識別されないネットワーク"のアダプタにされていた。
このアダプタのみを、(ドメイン、パブリック ではなく)"プライベート"に
したかったが、方法がわからなかった。
"識別されていないネットワーク"の全てのアダプタを"プライベート"にする方法は、
Web検索すればスグわかったのだが・・・。

ちなみに、

レジストリエディタで
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
キーのサブキーから、DriverDescに「Microsoft Loopback Adapter」と書かれているもの
を探し、そこに
"DWORD"・"*NdisDeviceType"
(先頭の「*」も名前の一部なので注意)
の"キー"を作り、"値"を"1"に設定する というおまじない行為をすれば、
"プライベート"にできるという情報があったので、やってみた。

しかし、パブリック のままっぽい?
"ネットワークと共有センター"に表示されなくなっただけっぽい?
混乱を招く無駄な情報かもしれないが、
おしいところまで来てるかもしれないので記録しておく。



[参考]
Windows 7にLoopback Adapterを追加する
http://www.cyberarchitect.net/blog/archives/272

Vista Network Identification for Loopback Adpater
http://social.technet.microsoft.com/Forums/ja-JP/66b42761-1b8e-4302-9134-0bb685139f4e/vista-network-identification-for-loopback-adpater?forum=itprovistanetworking

IPv6スレ@IPv6板@IPv6 
http://like2ch.com/ag/ipv6/ipv6/1217217654/52

2013年6月20日木曜日

RAID1のLinux Raidを構成するディスク群から1つ取り外し、単体でマウントするテスト

ubuntu-12.04にて、raid1のmd0を構成するディスク(sda1+sdb1)から一つのディスク・sdb1を取り外し、 sdb1単体で内容そのままに別物と扱われるようにmd50を構成するテスト。
目的は、mdを使って、信頼度がソレナリのディスク丸ごとオンラインバックアップを実現するテスト目的。
なお、degratedしたmdの各ディスク内容を確認する処理としては、不適切な内容を含んでいる。
$ cat /proc/mdstat 
...
md0 : active raid1 sdb1[2] sda1[3]
      999412 blocks super 1.2 [2/2] [UU]
...

$ sudo blkid 
...
/dev/sda1: UUID="d2ce795b-4157-0ba2-c114-c2a3e10e9c9e" UUID_SUB="39e610d6-e07d-89a8-3b66-09e66413d935" LABEL="mdadmtest:0" TYPE="linux_raid_member" 
...
/dev/sdb1: UUID="d2ce795b-4157-0ba2-c114-c2a3e10e9c9e" UUID_SUB="d4933b1d-576b-bedf-9db8-edc8fe9fff51" LABEL="mdadmtest:0" TYPE="linux_raid_member" 
...
/dev/md0: UUID="bc6efd38-8656-4574-880a-11ade5736ca9" TYPE="ext4" 
...


$ sudo mdadm --manage /dev/md0 --fail /dev/sdb1 
mdadm: set /dev/sdb1 faulty in /dev/md0

$ sudo mdadm --manage /dev/md0 --remove /dev/sdb1 
mdadm: hot removed /dev/sdb1 from /dev/md0

$ sudo mdadm --assemble /dev/md50 --update uuid /dev/sdb1
mdadm: /dev/md50 assembled from 1 drive - need all 2 to start it (use --run to insist).

$ sudo mdadm --stop /dev/md50 
mdadm: stopped /dev/md50

$ sudo mdadm --assemble /dev/md50 --update name /dev/sdb1
mdadm: /dev/md50 assembled from 1 drive - need all 2 to start it (use --run to insist).

$ sudo mdadm --run /dev/md50 
mdadm: started /dev/md50

$ sudo fsck /dev/md50 
fsck from util-linux 2.20.1
e2fsck 1.42 (29-Nov-2011)
/dev/md50: recovering journal
/dev/md50: clean, 231/62464 files, 15217/249853 blocks

$ sudo tune2fs -U `uuidgen` /dev/md50
tune2fs 1.42 (29-Nov-2011)

$ cat /proc/mdstat 
...
md50 : active raid1 sdb1[2]
      999412 blocks super 1.2 [2/1] [_U]
...
md0 : active raid1 sda1[3]
      999412 blocks super 1.2 [2/1] [U_]
...

$ sudo blkid 
...
/dev/sda1: UUID="d2ce795b-4157-0ba2-c114-c2a3e10e9c9e" UUID_SUB="39e610d6-e07d-89a8-3b66-09e66413d935" LABEL="mdadmtest:0" TYPE="linux_raid_member" 
/dev/sdb1: UUID="482ff3e3-85fe-9789-66e9-e504ce85b5eb" UUID_SUB="d4933b1d-576b-bedf-9db8-edc8fe9fff51" LABEL="mdadmtest:50" TYPE="linux_raid_member" 
...
/dev/md0: UUID="bc6efd38-8656-4574-880a-11ade5736ca9" TYPE="ext4" 
/dev/md50: UUID="60d468cf-9ab8-4b63-93a0-c5da46333744" TYPE="ext4"
...

$ sudo mdadm --detail --scan
...
ARRAY /dev/md/0 metadata=1.2 name=mdadmtest:0 UUID=d2ce795b:41570ba2:c114c2a3:e10e9c9e
ARRAY /dev/md50 metadata=1.2 name=mdadmtest:50 UUID=482ff3e3:85fe9789:66e9e504:ce85b5eb
...

$ sudo mount -o ro /dev/md50 /mnt
  • fsckは、稼働中のmd0からfail,removeしたため必要
  • sdb1のuuid,nameおよびmd50のuuidを変更することにより、uuid指定で行っている処理、   たとえば、os boot時にmd0へsdb1が影響をおよぼすことはなくなるだろう。
  • /etc/mdadm/mdadm.confの下部の ARRARY リストにmd50を追加更新し、「sudo update-initramfs -u」をしておけば、 md50を再起動しても自動で構成できる。
  • (基本的なことだが、)/etc/fstabを更新すれば、md50を再起動しても自動でマウントしたりできる。