AWS
route53
OpenVPN
SimpleAD

AWSにOpenVPN[AmazonLinux]を構築(冗長化 + SimpleADでユーザー認証編)

先日書かせていただきました

AWSにOpenVPN[AmazonLinux]を構築(ユーザー & パスワード認証編)は本内容のために書いた前段のものになります。

前回はOpenVPN ×1で、プライベートネットワークのEC2に接続するという個人趣味レベルの内容でしたが、今回は企業システムっぽく冗長化にしたいと思います。

(もっとさっさと書きたかったのだが、思いの外忙しく。。。間が空いてしまった。)

環境はこんな感じ

OpenVPN_冗長.png

これ実は特に難しくもなく、

1. AWSにOpenVPN[AmazonLinux]を構築(ユーザー & パスワード認証編)で1台構築

2. 構築したOpenVPN(EC2)をAMIイメージ作成

3. AMIイメージ → EC2起動。別のAZ、パブリックネットワークに配置

4. パブリックIPアドレス(EIP)を割り当て



NAT構成

NAT構成(VPNクライアントからプライベートネットワークにいるEC2への一方通行へ通信)の場合はこのまま利用できます。


ルーティング構成

ルーティング構成の場合は、追加したOpenVPNから払い出すIPアドレスのレンジは変える必要があります。

↓下記を編集


server.conf

# OpenVPNからクライアントへ払い出すIPアドレスのレンジ

# server 10.8.0.0 255.255.255.0
#↓修正
server 10.8.1.0 255.255.255.0

そして【Private ルートテーブル】にも経路情報を追記


後は、クライアントの構成ファイルに1行追記します。

追加したOpenVPNのパブリックIPです。


client.ovpn

# 1台目

remote [VPNサーバのFQDN or IPアドレス] 443
# 2台目
remote [VPNサーバのFQDN or IPアドレス] 443

これだけです。

上に記載したものが優先度が高いので、まずは1台目に接続しにいきます。

keep-aliveのデフォルト値まで応答がなかったら2台目に接続しにいきます。

冗長化としてはこれで完了です。(負荷分散ではないです:grinning:)

・・・・・・・・・・・・・・・・・・・・・・・・

・・・・・・・・・・・・・・・・・・・・・・・・

これで終わりではないです!!

実際に運用しようと考えた時、いろいろ問題があります。


  • ユーザー管理どうしよう?


    • ローカルのOSユーザーを2台でそれぞれ追加?イケてない



  • 接続先のEC2をプライベート向け(外部に公開しない)のWebサーバーとした時、InternalELBを前段にかましたい


    • InternalELBをRoute53で名前解決したい

    • でもRoute53のPrivateHostedZoneはVPC内でしか使えない:weary: (VPNクライアントはRoute53のレコードを参照してくれない)



てことで、タイトルにもあるAWS SimpleADを使って上の問題を両方解決してしまいます。


1. 環境構成

ということで、今回の構成はこんな感じです!

OpenVPN_冗長2.png

ポイントは


  • ユーザー管理


    • SimpleADで管理(OpenVPNユーザー)



  • InternalELB


    • Route53 PrivateHostedZoneのAliasレコードに登録(例:test-ielb.test.local)

    • VPNクライアントにはSimpleADのDNSを参照させることで、SimpleADがRoute53 PrivateHostedZoneに勝手にDNSフォワードしてくれる!(正確にはAmazonProviderDNSかな)



といったところになります!!


2. InternalELB

てことで、EC2(httpでWebページが表示できる状態のもの)にInternalELBを作成して、紐付けます。

詳細は割愛します。

InternalELB作成時点ではOpenVPNで接続したクライアント端末は下記への接続が可能です。

InternalELB作成時のDNS名:internal-xxxx-xxxxxxxx.ap-northeast-1.elb.amazonaws.com


3. Route53


3.1. PrivateHostedZone

AWSコンソールより【Route 53】をクリック

【Hosted zones】より「Create Hosted Zone」をクリック



Domain Name:test.local

Type:Private Hosted Zone for Amazon VPC

VPC ID:Webサーバー、InternalELBが所属するVPC


3.2. Record作成

作成したHosted zoneを選択

「Create Hosted Zone」をクリック



Name:test-ielb.test.local.

Type:A - IPv4 address

Alias:Yes

Alias Target:2. で作成したInternalELBのDNS名

レコードが作成されると同じVPCに所属するEC2(OpenVPNサーバー)からはtest-ielb.test.localが引けるようになる

ただし、OpenVPNクライアント端末はこの時点では名前で引けない


4. SimpleAD


4.1. SimpleAD作成

AWSコンソールより【Directory Service】をクリック

【Simple AD】を選択



ディレクトリDNS:simplead.local

NetBIOS:SIMPLEAD

ディレクトリのサイズ:管理するVPNユーザー数で決めればよい

サブネット:今回はプライベートサブネットに配置(OpenVPNが認証できればよい)

SimpleAD作成後はVPC DHCPオプションセットを作成し、VPC内のサーバがSimpleAD DNSを参照するように設定する。

項目

ドメインネームサーバー
xxx.xxx.xxx.xxx, yyy.yyy.yyy.yyy


4.2. OpenVPNサーバー側作業

SimpleADが作成されると、DNSサーバーのIPアドレスがコンソールより表示されるので、これをOpenVPNサーバーの/etc/openvpn/server.confに下記のように修正する


server.conf

# VPNクライアントの参照先DNS

push "dhcp-option DNS xxx.xxx.xxx.xxx"
push "dhcp-option DNS yyy.yyy.yyy.yyy"

OpenVPNサーバーのサービスを再起動

/etc/init.d/openvpn reload


4.3. OpenVPNクライアント側作業

一度切断し、再度OpenVPNを接続する

すると、クライアント側の接続ログに、追記したdhcp-option DNS xxx.xxx.xxx.xxx,dhcp-option DNS yyy.yyy.yyy.yyyが記載される。

nslookup

でSimpleADのDNSが参照されていればオッケー。

InternalELBのRoute53で登録したレコードの確認

ping test-ielb.test.local

IPが返ってくれば無事フォワード成功です。


注意事項

SimpleADは名前解決したいRoute53のHostedZoneとは異なるドメイン名で作成する必要があります。

HostedZoneと同じドメイン名の場合、SimpleADは自分が権威サーバーと判断し、

AmazonProvidedDNSにはフォワードされません。

例:

●フォワードされるパターン

Route53 PrivateHostedZone:test.local

SimpleAD ドメイン名:simplead.local

●フォワードされないパターン

Route53 PrivateHostedZone:test.local

SimpleAD ドメイン名:test.local


これについては逆引きも同じです。

逆引きのRoute53 PrivateHostedZoneは基本使えません。

SimpleAD側のDNSに逆引きゾーンが既に存在しているため、Route53に逆引きゾーンを作成してもフォワードされません。

逆引きを利用したい場合、SimpleAD DNSに逆引きレコードを登録するか、ゾーンを削除し、Route53にフォワードされるようにする必要があります。



5. OpenVPN LDAP認証設定

ここからOpenVPNユーザーをローカルユーザー&パスワード認証 → SimpleADユーザーへ変更し、

冗長化されたOpenVPNサーバーで同じユーザーが使えるようにします。


5.1. コンピュータをSimpleADに参加

ディレクトリを管理するのに必要なパッケージをインストールします。

yum -y install sssd realmd krb5-workstation

ディレクトリにインスタンスを参加させます。

realm join -U Administrator@simplead.local simplead.local --verbose

ドメイン参加状況を確認します。

# realm list

simplead.local
type: kerberos
realm-name: SIMPLEAD.LOCAL
domain-name: simplead.local
configured: kerberos-member
server-software: active-directory
client-software: sssd
required-package: oddjob
required-package: oddjob-mkhomedir
required-package: sssd
required-package: adcli
required-package: samba-common
login-formats: %U@simplead.local
login-policy: allow-realm-logins

同じことをもう一つのOpenVPNサーバー(サブ)でも実施しドメイン参加します。


5.2. SimpleAD AdministratorでSSHできることを確認しておく

SSHサービスを設定して、パスワード認証を許可します。

sshd_configのPasswordAuthenticationをyesに設定します。

vim /etc/ssh/sshd_config

PasswordAuthentication yes

インスタンスを再起動します。

shutdown -r now

再起動後完了後、再接続し、ドメイン管理者をsudoersリストに追加します。

visudo

以下を、sudoersファイルの最後に追記します。

## Add the "Domain Admins" group from the example.com domain.

%Domain\ Administrator@simplead.local ALL=(ALL:ALL) ALL

ここまでで、設定完了です。

試しに、Administratorユーザーで、インスタンスにログインしてみます。

Administratorのパスワードを入力し、無事ログインできれば成功です!

ssh -l Administrator@simplead.local [IPアドレス]

同じことをもう一つのOpenVPNサーバー(サブ)でも実施しドメイン参加します。


5.3. SimpleADに任意のユーザーを作成する

下記の手順はOpenVPNサーバー(AmazonLinux)からコマンドでSimpleADにユーザーを作成する手順になりますが、実際はWindowServerを用意し、SimpleADにコンピュータを参加させ、「AD管理ツール」をインストールしてやったほうがわかりやすくて楽だと思います。

必要なパッケージを追加します。

yum -y install samba-common openldap-clients krb5-workstation adcli

ユーザーを追加します。Administratorのパスワードを聞かれるので入力します。

CN=ad-vpnuser01,CN=Users,DC=simplead,DC=localで作成されます。

net ads user ADD ad-vpnuser01 P@ssw0rd -C "ad-vpnuser01" -U Administrator@simplead.local -S simplead.local

あたらしいユーザーはパスワードが設定されてEnabledにセットされるまでは無効です。

ファイルを作成してユーザーオブジェクトのuserAccountControl値を512にセットすることでユーザーアカウントをEnabledにします。

vim uac.ldif


uac.ldif

dn:CN=ad-vpnuser01,CN=Users,DC=simplead,DC=local

changetype:modify
replace:userAccountControl
userAccountControl:512

前のステップで作成されたldifファイルをつかって変更を行うためにはopenldap-clientパッケージによって提供されるldapmodifyコマンドを使用します。

ldapmodify -h simplead.local -p 389 -D "cn=Administrator,cn=Users,dc=simplead,dc=local" -w [パスワード] -f uac.ldif

これでユーザーアカウントが有効になり利用できるようになり、Kerberosチケットを取得してテストできます。

# kinit ad-vpnuser01

Password for ad-vpnuser01@SIMPLEAD.LOCAL:
以下のコマンドを実行してKerborosチケットをみることができます。

# klist
Ticket cache: KEYRING:persistent:0:0
Default principal: ad-vpnuser01@SIMPLEAD.LOCAL

Valid starting Expires Service principal
07/27/2018 19:35:16 07/28/2018 19:35:11 krbtgt/SIMPLEAD.LOCAL@SIMPLEAD.LOCAL
renew until 08/03/2018 19:35:11

ドメインのユーザー一覧を表示します。ちゃんと、kanpeiが追加されていますね。

# net ads user -S simplead.local -U Administrator@simplead.local

AWSAdminD-9567264E07
Administrator
ad-vpnuser01
krbtgt
Guest


5.4. OpenVPNでLdap認証させる

下記をインストール



yum -y install openvpn-auth-ldap

/etc/openvpn/server.confを編集


server.conf

#plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-pam.so login

plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so "/etc/openvpn/auth/ldap.conf"

mkdir /etc/openvpn/auth

vim /etc/openvpn/auth/ldap.conf

下記ファイルでVPNユーザーで利用可能なOUやグループをフィルターします。

とりあえず、cn=Users,dc=simplead,dc=local配下のユーザーはVPN認証を許可します。


ldap.conf

<LDAP>

URL ldap://simplead.local:389
BindDN cn=Administrator,cn=Users,dc=simplead,dc=local
Password xxxxxxxx
Timeout 15
TLSEnable no
FollowReferrals yes
</LDAP>

<Authorization>
BaseDN "cn=Users,dc=simplead,dc=local"
SearchFilter "(&(sAMAccountName=%u))"
RequireGroup false
</Authorization>



ちなみにグループとかOUでフィルターするときはこんな感じ


ldap.conf

<LDAP>

URL ldap://simplead.local
BindDN cn=Administrator,cn=Users,dc=simplead,dc=local
Password xxxxxxxx
Timeout 15
TLSEnable no
FollowReferrals yes
</LDAP>

<Authorization>
BaseDN "dc=simplead,dc=local"
SearchFilter "(&(sAMAccountName=%u))"
RequireGroup true
<Group>
BaseDN "ou=vpngroup,dc=simplead,dc=local"
SearchFilter "(|(cn=testgroup)(cn=stagegroup))"
MemberAttribute "member"
</Group>
</Authorization>



VPNサービスを再起動

/etc/init.d/openvpn restart

同じことをもう一つのOpenVPNサーバー(サブ)でも実施しドメイン参加します。


5.5. OpenVPNクライアントで接続

一度切断し、再度接続します。

SimpleADで作成したユーザーとパスワードを入力し、接続できたら完了

スクリーンショット 2018-07-27 19.48.53.png

以上です。

これで、

1. OpenVPNの冗長化

2. Route53 PrivateHosted Zoneを使ったInternalで名前解決

3. SimpleADによるOpenVPNユーザーの管理

ができました。

ちょっとそれっぽくなりましたね。

終わり