多要素認証の実装が簡単になるぞ!AWS Client VPN で SAML ベースのフェデレーション認証がサポートされました。

Auth0で試したかったんですけどね。やり方がわからなかったので公式ガイドにそってOktaで試しました。
2020.05.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

先日のアップデートで AWS Client VPN で SAML 2.0 経由のフェデレーション認証がサポートされるようになりました。

記事を書いてたところ、島川の記事がすでにあがってることに気づきましたが、このまま進みます。Okta側の設定など島川の記事のほうが丁寧に記載されていますので、あわせてお読みください!

何がうれしいのか

これまで AWS Client VPN では 「Active Directory 認証」およびクライアント証明書を利用する「相互認証」に限られていましたが、あらたに SAML 2.0 ベースの「フェデレーテッド認証」がサポートされました。これにより、以下のような点でメリットがあると考えます。

一元化された ID 管理

ID プロバイダ(IdP)を利用することで、ユーザー ID の一元化することが容易となります。

容易な多要素認証(MFA)対応

従来、AWS Client VPN で多要素認証を利用する場合、「Active Directory 認証」のみに限定されており、且つ、別途 RADIUS サーバーをユーザー側で準備する必要がありました。

フェデレーテッド認証であれば多要素認証を IdP 側の機能として利用できますので、容易に AWS Client VPN の多要素認証対応が可能となります。

対応リージョン

フェデレーテッド認証は以下のリージョンで利用可能です。

  • バージニア北部
  • オレゴン
  • オハイオ
  • 北カリフォルニア
  • カナダ中部
  • ムンバイ
  • ソウル
  • シンガポール
  • シドニー
  • 東京
  • アイルランド
  • フランクフルト
  • ロンドン
  • ストックホルム

フェデレーテッド認証の要件と考慮事項

SAML ベースのフェデレーテッド認証の要件と考慮事項があります。詳細については公式ガイドを参照してください。

  • SAML レスポンスと SAML アサーションは署名され、暗号化されていない必要があります
  • SAML レスポンスは最大 128 KB まで
  • AWS Client VPN は署名された認証リクエストを提供しません
  • SAML シングルログアウトはサポートされていません。ユーザーは AWS 提供のクライアントから切断、ログアウトするか、接続を終了します
  • クライアント VPN エンドポイントは単一の IdP のみをサポートします
  • IdP で有効になっている場合、多要素認証がサポートされます
  • AWS 提供のクライアントを使用してクライアント VPN エンドポイントに接続する場合、バージョン 1.2.0 以降を使用する必要があります
  • IdP 認証でサポートされているブラウザーは Apple Safari, Google Chrome, Microsoft Edge, Mozilla Firefox です
  • AWS 提供のクライアントは SAML レスポンス用にユーザーのデバイスの TCP ポート 35001 を予約します
  • IAM SAML ID プロバイダーのメタデータドキュメントが誤った URL または悪意のある URL で更新されると、ユーザー認証に問題が発生したり、フィッシング攻撃が発生することがあります。そのため、CloudTrail を使用して IAM SAML ID プロバイダーに対する更新を監視することが推奨されます

やってみる

サーバー証明書の登録

クライアントVPNエンドポイントを作成するには、使用する認証のタイプに関係なく、AWS Certificate Managerでサーバー証明書をプロビジョニングする必要があります。手順は公式ガイドを参考にしていますが、クライアント証明書については必要ありませんのでサーバー証明書のみ対応しています。

まず、OpenVPN easy-rsa リポジトリをローカルコンピューターに複製し、easy-rsa/easyrsa3フォルダーに移動し ます。

$ git clone https://github.com/OpenVPN/easy-rsa.git
Cloning into 'easy-rsa'...

remote: Enumerating objects: 49, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 2002 (delta 19), reused 39 (delta 13), pack-reused 1953
Receiving objects: 100% (2002/2002), 5.76 MiB | 2.80 MiB/s, done.
Resolving deltas: 100% (872/872), done.

$ cd easy-rsa/easyrsa3

新しい PKI 環境を初期化します。

$ ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /Users/marumo.atsushi/test-clientvpn/easy-rsa/easyrsa3/pki

新しい認証局(CA)を構築します。

$ ./easyrsa build-ca nopass
Using SSL: openssl LibreSSL 2.8.3
Generating RSA private key, 2048 bit long modulus
........................................................................................................................................+++
..................................................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/Users/marumo.atsushi/test-clientvpn/easy-rsa/easyrsa3/pki/ca.crt

サーバー証明書とキーを生成します。

$ ./easyrsa build-server-full server nopass
Using SSL: openssl LibreSSL 2.8.3
Generating a 2048 bit RSA private key
.....................................................................................................................................+++
..............................................................................................................+++
writing new private key to '/Users/marumo.atsushi/test-clientvpn/easy-rsa/easyrsa3/pki/easy-rsa-34319.SrFzOO/tmp.G1ZuTJ'
-----
Using configuration from /Users/marumo.atsushi/test-clientvpn/easy-rsa/easyrsa3/pki/easy-rsa-34319.SrFzOO/tmp.ZBWEPL
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Aug 25 02:53:04 2022 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

サーバー証明書とキーをACMにアップロードします。当環境は AWS CLIv2 のため fileb: を使用していますが、AWS CLIv1 環境の場合、file: を使用します。

$ mkdir server-cert
$ cp pki/ca.crt ./server-cert/
$ cp pki/issued/server.crt ./server-cert/
$ cp pki/private/server.key ./server-cert/
$ cd ./server-cert/

$ aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt

ID プロバイダーとの信頼を確立する

今回、IdP には Okta を利用しています。Okta からアプリケーション固有のメタデータ情報をエクスポートし、AWS アカウントにアップロードします。

Okta 管理コンソールの [Applications] を開き、[Add Appliication] をクリックします。

AWS ClientVPN を検索しクリックします。

[Add] をクリックします。

[Application label] を入力し [Done] をクリックします。

[Sign On] タブを開き、Settings の [Edit] を開きます。[memberOf] のプルダウンメニューから Matches regexを選択し、値に .* とします。

[ADVANCED SIGN-ON SETTINGS] でデフォルトのポート 35001 を指定し、[保存] します。

Okta メタデータをダウンロードするため Identity Provider metadata のリンクを右クリックし、リンク先を保存します。

IAM ID プロバイダーの設定

AWS コンソールから IAM 管理ダッシュボードを開きます。[ID プロバイダー] を開き、[プロバイダの作成] をクリックします。

プロバイダーのタイプは SAML を指定し、任意のプロバイダ名を入力。メタデータドキュメントには先ほどダウンロードした Okta メタデータを選択し、[次のステップ] をクリック、[作成] します。

AWS Client VPN エンドポイントの作成

VPC 管理コンソールを開き [クライアント VPN エンドポイント] を開き、[クライアント VPN エンドポイントの作成] をクリックします。

[名前タグ],[説明] を入力し、[クライアント IPv4 CIDR] を指定します。クライアント CIDR 範囲は /12〜/22 の範囲で指定しますが、VPC CIDR またはルートテーブル内のルートと重複しないように指定します。これはクライアントに割り当てられる IP 範囲になります。

[サーバー証明書 ARM] には先ほど AWS CLI でアップロードしたサーバー証明書を指定。[認証オプション] は [ユーザーベースの認証を使用]、そして今回あらたに対応した SAML ベースの認証である [統合認証] を指定します。[SAML プロバイダー ARN] は先ほど作成した IAM ID プロバイダーを指定します。

接続ログ記録は いいえ を指定し、その他のオプションパラメータはデフォルトのまま [クライアント VPN エンドポイントの作成] をクリックします。

AWS Client VPN エンドポイントオプションの設定

作成したクライアント VPN エンドポイントを選択し、[関連付け]をクリックします。

クライアント VPN エンドポイントを関連付ける VPC およびサブネットを選択し、[関連付け] をクリックします。

この時点では1つのサブネットしか関連付けていないため、必要に応じて可用性を高める場合は同手順を繰り返し、複数 AZ のサブネットで作成します。

次に承認ルールの設定を行います。承認ルールはネットワークへのアクセスを許可するファイアウォールとして機能します。[認証] タブを開き、[受信の承認] をクリックします。

ユーザーにアクセスを許可する CIDR を指定します。アクセスを付与する対象は [すべてのユーザーにアクセスを許可する] を選択し、[認証ルールの追加] をクリックします。もし、IDプロバイダー(IdP)で定義されたグループ ID や名前を使って制限する場合は [特定のアクセスグループのユーザーへのアクセスを許可する] を指定します。

接続の確認

[クライアント設定のダウンロード] をクリックし、構成プロファイルを取得します。

AWS VPN Client を起動し、[ファイル] - [プロファイルを管理] を開きます。[プロファイルを追加] をクリックします。プロファイルの表示名を入力し、先ほどダウンロードした構成プロファイルを指定し、追加します。

作成したプロファイルを指定し [接続] をクリックすると、シングルサインオンとして Okta への認証が求められますのでログインします。

もし、Okta で多要素認証を有効にしている場合、その認証も求められます。(多要素認証の実装が非常に簡単で良いですね!)

認証後、クライアント VPN が [接続済み] になることを確認します。

それでは、プライベートサブネットに作成した以下 EC2 にアクセスしてみましょう。セキュリティグループには、クライアント VPN エンドポイントに割り当てたセキュリティグループからの通信を許可しています。

$ ssh -i cm_marumoatsushi.pem ec2-user@192.168.2.132
Warning: Permanently added '192.168.2.132' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-192-168-2-132 ~]$

接続できましたね!検証は以上です!

さいごに

「Active Directory 認証」「相互認証」に加えて、SAML ベースの「フェデレーテッド認証」がサポートされました。Active Directory のない環境でもユーザーに紐づく接続管理が容易に実装できますね。

個人的には多要素認証で RADIUS サーバーが必要なくなるのが嬉しいですね。

今回は公式ガイドにそって Okta で試しましたが、弊社でよく利用される Auth0 も使ってみたいですね。(ちょろっと試したけど挫折しました…誰かー)

以上!大阪オフィスの丸毛(@marumo1981)でした!