こんにちは、onprepack津村です。
(※onprepack = 最近cloudpack社内で流行ってる単語。)
地元のスーパーで柿が売られているのをみて、秋を感じています…。(しみじみ

VPCのプライベートサブネットに、VPNから乗り込む。

最近はGoogleAppsやサイボウズをはじめとして、グループウェア製品は、インストールタイプからSaaSに移行しつつあります。
インターネット上から誰でもアクセスでき、サーバを用意する必要が無いSaaSでの提供は、ビジネス上のコストを上手に下げてくれる効果があります。
しかし、一方で会社によっては、秘伝のタレのごとくコードを継ぎ足し作ったグループウェアから乗り換えられない(しかもスパゲッティでメンテできない)といった状況から、ミドルウェアの脆弱性やハードウェアの寿命を放置、もしくは場当たりのメンテナンスで延命している場合もあります。

例えば脆弱性のあるアプリケーションとわかっていても、IaaS上のセキュアな環境に移植し、VPN越しに利用する運用に切り替える事で、セキュリティの問題(の一部)とハードウェアの寿命について、考える必要がなくなります。
なおかつ、従来のNetScreen/SSG等といったセキュリティ専用アプライアンスに対する運用費の削減や、電気代、物理サーバの保守費などを軽減できる場合があります。

Amazon VPCのプライベートサブネットにVPN経由で接続する構成図

『OSS版ソフトイーサ』と『NATインスタンス』の美味しい組み合わせ

意外と思われるかもしれませんが、AWSのNATインスタンスは、AmazonLinux上のiptablesで実装されています。
故に、容易にカスタマイズをする事が可能です。

次に、SoftEther(ソフトイーサ)という国産VPNソフトウェアを使用します。
もともと、2003年にIPA未踏ソフトウェアに採択され、その後、フリーソフトウェア化、PaketixVPNとして商用化した後、2014年にOSS版として公開されました。
詳細は以下を御覧ください。
ソフトイーサ株式会社オフィシャルサイト
ソフトイーサ(Wikipedia)
SoftEther VPNプロジェクト(OSS版公開サイト)

ソフトイーサは、複数のプラットフォームに対応した、マルチプロトコルのVPNサーバ、および仮想NICドライバとクライアントの構成で提供されています。
具体的には、Windows, Linux, MacOSX, FreeBSD, Solarisのバイナリ、Windows版GUIクライアント、及びソースコードが公開されています。
ソフトイーサの特徴の1つとして、一般的なSSL(443/tcp)の疎通があれば容易に外部とプライベートなLayer2トンネルを張ることが可能です。これらはとても強力な機能であり、ネットワークに対するスキルの他、コンプライアンスについての知識を持ちあわせて使用することを推奨します。

NATインスタンスの実装について

NATインスタンスは、インターネットに疎通しないPrivate SubnetからPublicSubnetのInternetGatewayへパケットを転送する機能を持ちます。
具体的には、PublicSubnetに属しつつ、PrivateSubnetのデフォルトゲートウェイを担う属性です。

Amazon VPCのプライベートサブネットにVPN経由で接続: NATインスタンスの実装する構成図※AWS マネジメントコンソールより引用

AWSのファイヤーウォールはステートフルですが、NATインスタンスは別途iptalbesで実装されており、スクリプト上で動的に生成されています。
(/etc/sysconfig/iptablesは使用されていません。)
以降は、執筆時(2014.10.03)現在のVPCウィザードで作成可能なNATインスタンスを題材に解説します。
解析される際はインスタンス作成時に、Key pairの指定とSGの設定追加(22/tcp)をお忘れなく。:)
具体的には、以下のように実装されています。
まず、/etc/rc.localにて、以下のようにスクリプトが呼び出されます。

[root@ip-10-0-0-190 ~]# cat /etc/rc.local
#!/bin/sh
(snip)
# Configure PAT
/usr/local/sbin/configure-pat.sh

次に、/usr/local/sbin/configure-pat.shで、アドレスの取得およびiptables・sysctlの設定が行われます。
詳細は中略しますが、eth0のMACアドレスを特定のAPIに送り、VPCのCIDRを取得した後、IPマスカレード(PAT)とip_forwardなどが設定されます。
(なかなか面白い書き方のスクリプトです。)

以上から、NATインスタンスの転送速度については選択したインスタンス次第となり、一般的には一番小さいt2.microで十分事足りると考えます。
(もし大きなインスタンスを作ってしまっても、通常のEC2インスタンスですので、一度停止すればスケールダウン可能です。)

SoftEtherのインストールと仮想NICの設定

ここでは実際にSoftEtherをインストール・設定していきます。

コンポーネントのダウンロードと展開

OSS版ソフトイーサの配布先から、Linux版のバイナリを取得します。
SoftEtherダウンロードセンター

複数のソフトウェア・アーキテクチャが配布されていますが、以下のように選択します。
BetaとRTMがありますので、適宜ダウンロードし、NATインスタンス上に展開します。
Amazon VPCのプライベートサブネットにVPN経由で接続: SoftEtherインストール

必要パッケージのインストール

makeにあたり、gccおよびopenssl-develが足りない為、yumでインストールします。

# yum install gcc openssl-devel -y

サーバのmake

展開したvpnserverディレクトリでmakeします。
ライセンスについていくつかの設問がありますが、1 or 2で答えます。
全て終わるとmakeが実行され、vpnserverおよびvpncmdコマンドが展開されます。

# cd vpnserver
# make
--------------------------------------------------------------------

SoftEther VPN Server (Ver 4.10, Build 9473, Intel x64 / AMD64) for Linux Install Utility
Copyright (c) SoftEther Project at University of Tsukuba, Japan. All Rights Reserved.

--------------------------------------------------------------------


Do you want to read the License Agreement for this software ?

 1. Yes
 2. No

(snip)

make[1]: Leaving directory `/root/vpnserver'

なお、ここでは英語でSoftEtherに関する重要事項が英語で表記されています。

サーバの起動

SoftEther Serverを起動します。
root権限で、vpnserver startと実行します。

# ./vpnserver start
The SoftEther VPN Server service has been started.

# ps aux | grep vpnserver
root      1758  0.0  0.0  16636   492 ?        S

実行が完了すると、複数のプロセス及び443/tcp, 5555/tcp等のLISTENが確認できます。
(後ほどSGに設定をします)

自動起動設定

さて、起動時にVPNサーバが自動起動するように、NATインスタンスを設定します。
initスクリプトを書いても良いのですが、ここではrc.localへコマンドを追記します。
ここでは、vpnserverディレクトリを/usr/local/bin以下へ移動したことを前提に紹介します。

# ls /usr/local/bin/vpnserver/vpnserver
/usr/local/bin/vpnserver/vpnserver

# echo " # Start SoftEther VPN" >> /etc/rc.local

# echo "/usr/local/bin/vpnserver/vpnserver start" >> /etc/rc.local

# tail /etc/rc.local

(snip)
# Configure PAT
/usr/local/sbin/configure-pat.sh
 # Start SoftEther VPN
/usr/local/bin/vpnserver/vpnserver start

なお、ここでは省略していますが、変更対象のファイルはバックアップをしましょう。:)

SecurityGroupの設定

NATインスタンスのSGを設定します。
443/tcp(SSL)もしくは5555/tcp(SoftEther)が開いていれば、Windows版GUIクライアントから設定可能です。
今回は後々も使用する、443/tcpを開きます。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(03)

※この状態で放置しないでください※

この状態では、だれでもサーバの初期設定ができてしまう状態です。
上記の図では意図的にAnywhereにしていますが、初期設定が終わるまではIP制限をする事を検討してください。

サーバの詳細設定

SoftEtherサーバの詳細な設定を行います。
ここでは、以下の順に設定を投入します。

  1. SoftEtherVPNサーバの初期設定
  2. 仮想HUBの新規作成とユーザ追加
  3. ブリッジインターフェースの設定
  4. VPNプロトコル(SoftEtherプロトコル)の設定と確認

SoftEtherの概念と用語

SoftEtherの概念としては、以下のように対応します。

仮想HUB
いわゆるLayer2セグメント。個別に管理できるようパスワードが設定可能。
ユーザ
仮想HUBに接続する認証設定。仮想HUB毎に認証される為、それぞれユーザの設定が必要
ローカルブリッジ
仮想HUBをサーバが稼働するOSにNICを追加する設定。TAPデバイスもしくは物理インターフェースにブリッジされる。

今回の設定内容

今回は以下のように設定を行います。

  • 仮想HUB名:mikalab
  • 仮想HUBmikalabのユーザ:tsumura
  • ローカルブリッジ:mikalab = tap_00

SoftEtherVPNサーバの初期設定

まずは、Windows版GUIクライアントをWindowsマシンにインストールします。
ここでは、Windows7 Enterprise上に展開し、インターネット越しに設定を行います。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(04)
まず、クライアントへ接続する為、上記の赤枠部分を入力します。
接続設定名は、わかりやすい名前をつけてください。
ホスト名はFQDNもしくはIPアドレスを入力します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(05)
上記では『Blog-VPN』が追加されました。
対象のサーバを選択し、接続します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(06)
最初の接続でVPNサーバのパスワードを設定します。
この設定は、所謂rootパスワードと同じ意味を持っています。
適宜設定します。

仮想HUBの新規作成とユーザ設定

新たな仮想HUBを追加します。
すでに『DEFAULT』という仮想HUBが存在しますが、セキュリティを強化する為、あえて新しいハブを追加します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(07)
上記赤枠の「仮想HUBの作成」をクリックします。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(08)
ここでは『mikalab』という仮想HUBを定義しています。
「匿名ユーザに〜」の部分では、接続時に仮想HUB名をクライアントに通知しない事で、不用意なアタックを防ぐことが可能です。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(09)
これにより、『mikalab』という仮想HUBが追加されました。
次に、仮想HUBに対しユーザを追加するため、仮想HUB『mikalab』を選択し、『仮想HUBの管理』をクリックします。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(10)
ここでは、仮想HUBに接続するユーザ名およびパスワードを定義します。
また、今回は省略しますが、セキュリティポリシー(Layer2レベルでの通信制御)の設定が可能です。
11.5
SecureNAT機能(仮想NATサーバ・仮想DHCPサーバ)を有効にします。
ここでは一般的なブロードバンドルータと同等+α(静的ルーティングテーブル)の設定が可能です。

ブリッジインターフェースの設定

ここでは、ブリッジインターフェースを定義し、iptables上でNATが可能なよう定義を追加します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(11)
『ローカルブリッジ設定』をクリックします。
尚、対応する仮想HUBは事前に定義してください。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(12)
上記の赤枠部分3点を定義します。
仮想HUBは対応する仮想HUBを、tapデバイス名は任意ですが、接頭に「tap_」とつきます。
今回は『00』と設定し、『tap_00』となるよう定義します。
ローカルブリッジ追加後は、サーバOSに動的にtapデバイスが追加されます。

# ifconfig -a | grep HWaddr
eth0      Link encap:Ethernet  HWaddr 06:C9:F8:xx:xx:xx
tap_00    Link encap:Ethernet  HWaddr 00:AC:34:xx:xx:xx

iptables上でルーティングを可能にするには、カーネルパラメータ『net.ipv4.conf.《NIC名》.send_redirects』を『0』にします。

※ カーネルパラメータの変更
# sysctl -w net.ipv4.conf.tap_00.send_redirects=0
net.ipv4.conf.tap_00.send_redirects = 0

※確認
# sysctl net.ipv4.conf.tap_00.send_redirects
net.ipv4.conf.tap_00.send_redirects = 0

※恒久的に設定(NATインスタンスの実装にそってrc.localにて)
# echo "sleep 10" >> /etc/rc.local
※SoftEther VPNServerがバックグラウンドで起動後、tapインターフェースを作成するまで待つ。
# echo "sysctl -w net.ipv4.conf.tap_00.send_redirects=0" >> /etc/rc.local

本来はtap_*に自動的に適用するようスクリプトを書くべきとは思いますが、取り急ぎは/etc/sysctl.confの修正や上記の対応で問題ありません。
ただし、1つのパラメータを複数の方法で定義できるので、運用に注意してください。
最後に、Private Subnetに対するSNATを定義します。
一般的にはインターネット上からのトラフィックに対し定義しますが、ここではSoftEtherのtap_00インターフェースからのトラフィックに対して適用するよう定義します。

# iptables -t nat -A PREROUTING -p tcp -m tcp -s 192.168.0.0/16 --dport 80 -j DNAT --to-destination 10.0.1.26:80
※ 192.168.0.0/16 - SoftEther仮想HUB上でクライアントに払い出すIPアドレス(仮
※ 10.0.1.26 - PrivateSubnet内のWebサーバ

# rc.localに定義
# echo "iptables -t nat -A PREROUTING -p tcp -m tcp -s 192.168.0.0/16 --dport 80 -j DNAT --to-destination 10.0.1.26:80" >> /etc/rc.local

SoftEtherクライアントの設定と疎通確認

SoftEtherクライアントを実際にWindows上に設定し、疎通を確認したいと思います。
実際にはL2TP/IPSecやSSTP等のプロトコルも使用可能ですが、取り急ぎ443/tcpのみで動作するSoftEtherプロトコルにて動作を確認したいと思います。尚、すでにPrivateSubnetにWebServer(10.0.1.26:80)が稼働している事を前提とします。
まず、先のダウンロードセンターにて、Windows版のクライアントをダウンロードします。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(14)
インストールが完了すると、デスクトップに上記のアイコンが表示されますので、開きます。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(15)
新しい接続(※SoftEtherVPN Serverへの接続)設定を作成します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(16)
仮想LANカードが無い時は、上記のダイアログが表示されます。
「はい」をクリックして進みます。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(17)
仮想LANカードに名前をつけます。
今回はテスト的に接続するため、標準の「VPN」を使用しますが、複数セグメントへ接続する際はそれぞれの仮想HUB毎に仮想LANカードが必要な為、名前を管理します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(18)
無事にLANカードが作成できると、WIndowsに物理インターフェースと同じようにNICが追加されます。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(19)
次に、接続の設定を行います。
先の仮想HUBに作成した設定を行います。
尚、仮想HUB名は、先の設定では匿名にした為、ここでは表示されません。手打ちする必要があります。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(20)
上記のように設定が終わりましたら、設定名をダブルクリックして接続します。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(21)
無事に接続できると、上記のようにDHCPサーバからIPアドレスがリースされます。
Amazon VPCのプライベートサブネットにVPN経由で接続: 構築(22)
最後に、PrivateSubnetに作成したWebServerのIPアドレスにブラウザからアクセスすると、無事にウェブページが表示されています。

補足・おわりに

今回のエントリでは多々端折っていますが、実際には一部VDI等では、Windowsクライアントのシナリオが正常に動作しません。
これは、仮想HUBに接続しDHCPからデフォルトゲートウェイを受け取った際、仮想LANカードのメトリックが1に設定されている為、RDP等の接続ができなくなり、再起動する以外の対処ができません。
対処方法としては、デフォルトゲートウェイではなく、DHCPを使った静的ルーティングの配信(RFC3442)を使用する必要があります。

SoftEtherおよびNATインスタンスともに、Unix・ネットワークの高度な知識が必要です。
また、技術的スキルだけではなく、社内ネットワークに導入する場合など、コンプライアンスに対する知識も必要です。

SoftEtherはソフトウェアによる強力な異種プロトコル間Layer2トンネルの実装であり、今回の内容をベースにする事で、iPhone(iOS Device)/Android等のVPN接続のシナリオも構築可能です。
一方、NATインスタンスにも癖があり、iptablesと併用する事から、実用にする為には十分なLinuxやIPへのスキルと、危険なACLの設定が必要になります。
(個人的にはRDSのように、マネージドルータとして提供してほしいのですが…>AWSさま)

おあとがよろしいようで。

元記事はこちらです。
OSSとAWSで出来る、セキュア接続なプライベート環境