Help us understand the problem. What is going on with this article?

[AWS] 積年の夢の端緒 ~初心に還ってOpenVPN~

More than 1 year has passed since last update.

プロローグ

思えば、自分がAWS上でのVPNに触れたのは、数年前に出逢ったこちらの記事がきっかけでした。
今や、SoftEther/WindowsVPN/VyOSの経験を経て、思えば遠くに来たもんだ。
このたび、一周回って、OpenVPNをSSL-VPN(Point-to-Site VPN/SW-VPN)として改めてAWS上で利用する機会がありまして、今自分が具備する経験・知識を総動員して、下記にトライしました:

  • OpenVPNサーバ(EC2)に挿すNIC(ENI)を、PublicとPrivateで分けて2枚に!
  • CloudFormationでの全自動化!
    • OpenVPNサーバのインストール
    • CA作成~ファーストユーザの証明書/秘密鍵作成
    • CRL作成(dummyユーザを作成&削除)
    • ビルトインのec2-userを削除し、別のVPN管理者ユーザを作成(SSH接続&sudo利用、おっけー)
    • OpenVPNクライアント用の設定ファイルのテンプレートの出力
    • 【未着手】FlowLogs用設定投入(LogStream/LogGroup作成&IAM-Role作成)
    • 【未着手】OpenVPNログのローテーション機能を追加
  • 敢えてのOpenVPN Clientの利用(お気に入りのvpnuxClientもおっけー)
  • Man-in-the-Middle対策(よりセキュアに)
  • CRYPTRECの推奨暗号リストIPAの暗号推奨期間を受けて、AES256/SHA256(SHA1は非推奨)の採用(よりセキュアに)

⇒以下に挙げる設定値等に関して、こうしたらどう?とか、それはアカン!とかあったら、ご指摘いただけると幸いです。

環境構築手順

別にCloudFormationでなくても、下記の手順を踏めばおっけー。
(CloudFormationファイル(YAML)にご興味ある方、個別にご連絡いただければ♬)
①必要なSWのインストール
②OpenVPNサーバの設定
③OpenVPNサーバの環境構築手順(スクリプト)
④OpenVPNクライアントの設定

①必要なSWのインストール

Amazon Linuxであれば、下記でおっけー:

# yum update -y
# yum install ec2-net-utils -y
# yum install tcpdump -y (任意/オマケ)
# yum install openvpn -y
# yum install easy-rsa --enablerepo=epel -y

※CloudFormation中では「runcmd:」で実行しています。

②OpenVPNサーバの設定

下記の『server.conf』でおっけー:

server.conf
port  443
proto tcp
dev   tun

server VPNに割り当てるCIDR 255.255.255.0
ifconfig-pool-persist ipp.txt

push "route 《プライベートサブネットのCIDR》 255.255.255.0"  # Example

ca         ca.crt      # Certificate Authority
cert       server.crt  # Server Certificate
key        server.key  # Server Private Key
dh         dh2048.pem  # DH parametar key for DH key exchange
crl-verify crl.pem     # Certificate Revocation List
tls-auth   ta.key 0    # Symmetric key for TLS-Auth ("0" means "server")

cipher AES-256-CBC  # should match with client-side
auth SHA256         # should match with client-side

keepalive 10 60
ping-timer-rem
persist-tun
persist-key
comp-lzo
max-clients 30

status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

user  nobody
group nobody

verb 3

③OpenVPNサーバの環境構築手順(スクリプト)

下記の『openvpn_config.sh』を実行すればおっけー:

openvpn_config.sh
#!/bin/sh
export OPENVPN_CONFIG=/etc/openvpn
export KEY_HOME=/usr/share/easy-rsa/2.0
cd $KEY_HOME

# "Overwriting" env parameters in "vars" here
echo 'export KEY_COUNTRY="JP"' >> $KEY_HOME/vars
echo 'export KEY_PROVINCE="XXX"' >> $KEY_HOME/vars
echo 'export KEY_CITY="XXX"' >> $KEY_HOME/vars
echo 'export KEY_ORG="XXX"' >> $KEY_HOME/vars
echo 'export KEY_EMAIL="XXX@YYY.ZZZ"' >> $KEY_HOME/vars
echo 'export KEY_OU="IT Admin"' >> $KEY_HOME/vars

echo 'export KEY_SIZE=2048' >> $KEY_HOME/vars
echo 'export CA_EXPIRE=3650' >> $KEY_HOME/vars   # [Days]
echo 'export KEY_EXPIRE=3650' >> $KEY_HOME/vars  # [Days]

source $KEY_HOME/vars
$KEY_HOME/clean-all                     # Initialize CA
$KEY_HOME/pkitool --initca              # Build CA (in non-interactive mode)
$KEY_HOME/pkitool --server server       # Build server certificate & private key (in non-interactive mode)
$KEY_HOME/build-dh                      # Build DH parametar (prime number?) for DH key exchange

$KEY_HOME/pkitool $* dummy              # Preparation for generating crl file (creating "dummy" user cert)
$KEY_HOME/revoke-full dummy             # Generate crl (Certificate Revocation List)

openvpn --genkey --secret $OPENVPN_CONFIG/ta.key       # Generating tls-auth key (symmetric)

ln -s $KEY_HOME/keys/ca.crt     $OPENVPN_CONFIG
ln -s $KEY_HOME/keys/server.crt $OPENVPN_CONFIG
ln -s $KEY_HOME/keys/server.key $OPENVPN_CONFIG
ln -s $KEY_HOME/keys/dh2048.pem $OPENVPN_CONFIG

# crl.pem is specially treated.
mv $KEY_HOME/keys/crl.pem $OPENVPN_CONFIG
chmod 666 $OPENVPN_CONFIG/crl.pem
ln -s $OPENVPN_CONFIG $KEY_HOME/keys/crl.pem    

# Add a new OS/SSH user "vpnadmin" instead of the built-in user "ec2-user".
/usr/sbin/useradd vpnadmin
/usr/sbin/usermod -G wheel vpnadmin
mkdir /home/vpnadmin/.ssh
chown vpnadmin:wheel /home/vpnadmin/.ssh
chmod 700 /home/vpnadmin/.ssh
cp /home/ec2-user/.ssh/authorized_keys /home/vpnadmin/.ssh/authorized_keys
chown vpnadmin:wheel /home/vpnadmin/.ssh/authorized_keys
chmod 600 /home/vpnadmin/.ssh/authorized_keys
$KEY_HOME/pkitool $* vpnadmin

# Delete the built-in user for security
/usr/sbin/userdel -r ec2-user   

sysctl -w net.ipv4.ip_forward=1                     # Transient config
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf  # Permanent config

# IP masquerade (from VPN clients to AWS private servers)
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -A POSTROUTING -s VPNクライアントのCIDR -d 《プライベートサブネットのCIDR -j MASQUERADE

/sbin/chkconfig --add openvpn
service openvpn start

特記事項としては、『外部からの通信をAWSが受け付ける』ために、下記の(A)か(B)が必要:
(A)SecurityGroupで通信を許可する。
⇒Allow From 《VPNクライアントのCIDR》
(B)IPマスカレードの設定を投入する。
⇒《VPNクライアントのCIDR》からの通信を、OpenVPNサーバから来た通信に見せる(マスカレード=仮面舞踏会、♬きらめく光~):

iptables -t nat -A POSTROUTING -s 《VPNクライアントのCIDR》 -d 《プライベートサブネットのCIDR》 -j MASQUERADE

⇒AWSの仕様/制約に、「AWSが把握していない(払い出したのではない)IPアドレスは受け付けない(ドロップする)」というルールに基づく。
⇒(A)/(B)どちらが「正解」かはわからない。
⇒(A)/(B)いずれもおっけーなことは確認済み。
⇒「トレーサビリティ(A)」と「疎結合(B)」のいずれを取るかのトレードオフ。
⇒今回の自動化では(敷居がHigherな)「疎結合(B)」を採用。

また、「ビルトインユーザec2-userの削除」は、ec2-userでSSHログインしている場合はエラーが起こる(自分自身を消そうとする)ので、別ユーザ(vpnadmin等)でSSHログインしなおしてから実行する必要がある。
(CloudFormationならイキナリvpnadminでの接続になる)

④VPNクライアントの設定

(甲) OpnVPNクライアントの場合
下記の設定ファイル『client.conf』でおっけー。

client.conf
client
dev tun
proto tcp

remote OpenVPNサーバのEIP 443

# Assuming the certificate files below are put in the same folder as the client config file:
ca       ca.crt        # Certificate Authority
cert     vpnadmin.crt  # Client Certificate
key      vpnadmin.key  # Client Private Key

remote-cert-tls server
;ns-cert-type server   # Will be deprecated
tls-auth ta.key 1      # ("1" means "client")

cipher AES-256-CBC     # should match with server-side
auth SHA256            # should match with server-side

comp-lzo
nobind
persist-key
persist-tun
resolv-retry infinite

verb 3

⇒OpenVPNクライアントからOpenVPNサーバとの接続コマンドは、コマンドプロンプトから下記のコマンドを一発(GUIとかもありますが):

C:\> openvpn --config client.ovpn

※注意点は、コマンドプロンプトを管理者権限で起動すること(スタティックルートを追加するため)

⇒ログがずるずる出て、『Initialization Sequence Completed』が出たらおっけー。

(乙) vpnuxClientの場合
下記の設定画面(2画面)でおっけー。

設定画面①
vpnuxClient設定①.jpg

設定画面②
vpnuxClient設定②.jpg

⇒ログがずるずる出て、『Initialization Sequence Completed』が出たらおっけー。

小咄:crl.pemファイルが読めなくてハマった噺ぃ~

当初、「crl.pem(証明書失効リスト)」ファイルも、「server.*」ファイルと同様に、EasyRSAで作成したディレクトリに存在するマスタファイルに対して/etc/openvpn(=OPENVPN_CONFIG)からシンボリックリンクを張るアプローチでした:

# ln -s $KEY_HOME/keys/crl.pem $OPENVPN_CONFIG

が、これだと『crl.pem cannot read』というエラーが発生する。パーミッションが原因だけど、$KEY_HOME/keysフォルダの権限も開放しないといけない?そこで、

# mv $KEY_HOME/keys/crl.pem $OPENVPN_CONFIG
# chmod 666 $OPENVPN_CONFIG/crl.pem
# ln -s $OPENVPN_CONFIG $KEY_HOME/keys/crl.pem

と変更したところグー。
「server.*」ファイルなんかもOPENVPN_CONFIGへmvしようかどうか、悩ましいところです。
(一番更新されうるだろうcrl.pemをmvしているから、基本不変なserver.*ファイルも。。。)

エピローグ

...SSL-VPNは、OpenVPNでもvpnuxClientでもそうだけど、コネクション初期化フェーズをログでtailしているときに、疎通が成功するときはログがずるずるスムーズに流れて『Initialization Sequence Completed』が登場する。これがカタルシスっっっ☆ ☆ ☆
(うまくいかないときは、『Restarting』やらなんやらでグダグダ)

参考情報

  1. AWS環境にOpenVPNでVPNを構築
    ⇒ワタクシのあらゆるVPN知識の産みのヲヤ。

  2. 基本的なOpenVPNの構築手順
    ⇒特にta.keyについて。EasyRSA 3.0は未着手。。。

  3. OpenVPN サーバ構築
    ⇒本格的ですごい。。。脱帽。

  4. OpenVPN クライアント設定
    ⇒3.のクライアント設定編。

  5. iptablesで特定のポートを別のホストへ転送する方法
    ⇒特にNATテーブル(IPマスカレード)の設定。

  6. sudoers は編集せずに sudoers.d の中に設定を書こう
    ⇒特にsudoersの追加を自動化する方法。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした