この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
いわさです。
オンプレミス側のプライベートネットワーク環境とAWSを接続して検証などを行いたい場合がよくあります。
VPNやDirectConnectの環境を用意するのはちょっと大変ですが、VPCでプライベートネットワーク環境を用意してVPCピアリングさせる程度であれば簡単に用意出来ますし、割と近い環境が再現出来るかなと思ってよく使っています。
ただし、毎度Webサーバーだったり、DNSサーバーだったりを構築するのは面倒です。
そこで今回はミドルウェアの設定部分も含めてテンプレート化しておきました。
そして、これだけの小さな構築にも関わらずまぁまぁ詰まったので公開しておきたいと思います。
テンプレート
テンプレートはこちらになります。
プライベートサブネットにWebサーバーとDNSサーバーを構築します。
Webサーバーは自己署名証明書を設定済みのPHPアプリケーションをデプロイし、内部DNSはDHCPオプションでVPCに関連付けしています。
内部DNSサーバーのフォワーダーにはAmazonProvidedDNSを指定し、通信はNATゲートウェイでアウトバウンドさせているので初期セットアップが失敗しないようにされています。
テンプレートで構築される構成は以下のようなシングルAZのシンプルなものです。
パラメータで各CIDRやWebアプリケーションのホストゾーンなどを設定する形になっています。
今回見送りましたが、そのうちアップデートしてNATゲートウェイではなくてプロキシサーバーを通すようにするつもりです。
少し抜粋すると、今回はほとんどユーザーデータで設定しています。
Webサーバー
こちらはWebサーバーです。
PHPをセットアップし、自己署名証明書を設定しています。
UserData:
Fn::Base64: !Sub
- |
#cloud-config
repo_update: true
repo_upgrade: all
packages:
- httpd
- mod_ssl
- openssl
- php
runcmd:
- openssl genrsa -out ca.key 2048
- openssl req -new -key ca.key -out ca.csr -subj "${sslsubject}"
- openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
- cp -p ca.crt /etc/pki/tls/certs/
- cp -p ca.key /etc/pki/tls/private/
- cp -p ca.csr /etc/pki/tls/private/
- sed -i 's/localhost/ca/g' /etc/httpd/conf.d/ssl.conf
- service httpd start
- chkconfig httpd on
write_files:
- path: /var/www/html/index.php
permissions: 0644
owner: root
content: |
<?php
echo "<pre>";
var_dump($_SERVER);
echo "</pre>";
?>
- { sslsubject: !Ref SslSubject }
証明書周りなどこちらの記事を参考にさせて頂きました。
DNSサーバー
こちらはDNSサーバーです。
BINDを使っています。
設定ファイルとゾーンファイルをそのまま作成しているだけですね。
一部動的パラメータを埋め込んでいます。
UserData:
Fn::Base64: !Sub
- |
#cloud-config
repo_update: true
repo_upgrade: all
packages:
- bind
runcmd:
- service named start
- chkconfig named on
write_files:
- path: /etc/named.conf
permissions: 0644
owner: root
content: |
options {
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
recursing-file "/var/named/data/named.recursing";
secroots-file "/var/named/data/named.secroots";
allow-query { any; };
recursion no;
dnssec-enable yes;
dnssec-validation yes;
bindkeys-file "/etc/named.root.key";
managed-keys-directory "/var/named/dynamic";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
forwarders { ${providedDns}; };
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
zone "${zonename}" IN {
type master;
file "${zonename}";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
- path: /var/named/${zonename}
permissions: 0644
owner: root
content: |
$TTL 86400
@ IN SOA dns.${zonename}. root.${zonename}. (
2021111401
3600
3600
604800
86400 )
IN NS ns.${zonename}.
IN A ${webServerIp}
ns.${zonename}. IN A 127.0.0.1
- { zonename: !Ref HosteZone, webServerIp: !GetAtt WebServer.PrivateIp, providedDns: !Ref AmazonProvidedDns }
確認
念の為確認もしておきます。
テンプレート実行直後は上記のようになり、以下のような形でこのプライベートネットワーク内に任意のHTTPクライアントをEC2で新規作成してアクセスしてみます。
[ec2-user@ip-10-103-0-216 ~]$ curl --insecure https://iwasa20211114.com/
<pre>array(61) {
["UNIQUE_ID"]=>
string(27) "YZDAWDfT4GNpMkXp9JwyPwAAAAQ"
["HTTPS"]=>
string(2) "on"
["SSL_TLS_SNI"]=>
string(17) "iwasa20211114.com"
問題なく名前解決出来ていますね。
さいごに
テンプレート作成を通して、OpenSSLやBINDなどAWSレイヤーより少し上の部分や、DHCPオプションなど普段触らない部分を結構トライ&エラー出来たのでおもしろかったです。
テンプレートのユーザーデータを見ていただくことわかるのですが、まとめてごちゃごちゃとやっております。
ユーザーデータで無理やりやりすぎたか...と少し思っているのでこうやったらもっと簡単に出来るよなどフィードバック頂けると幸いです。
Webアプリケーション部分は、PHPのサーバー変数をダンプ出力しているだけの状態です。
ゾーンファイルについては各パラメータ適当な感じでなので、こちらは構築時に適宜パラメータ調整すると良いと思います。
この環境を使って、VPC PeeringやPrivate Linkなどを使って別のネットワークやパブリックAWSサービスと通信検証する際などに使うことを想定しています。