Cisco ASA 9.1 に Let's Encrypt なワイルドカード証明書を SSL-VPN 用にインポートする
Let's Encrypt で取得したワイルドカード証明書を SSL-VPN (AnyConnect) で利用出来るようにする手順をメモしておきます。 ASA が SSL-VPN 用の Trustpoint に ECDSA を利用出来るようになったのは 9.4 以降らしいのですが、今回の環境は 9.1 の為、RSA を用いています。
環境¶
今回は下記を利用しました。 ASA 側では秘密鍵や CSR の作成は一切しておらず、鍵 / 証明書の用意は全て Linux 側で実施しました。
- AmazonLinux2 (※ AmazonLinux 固有の機能は利用していません)
- lego 2.6.0
- 証明書は Route53 での DNS 認証で取得 (簡単なので…)
- Cisco ASA 9.1.6
Cisco ASA の OS バージョンが低いのですが、ここがネックになり、ハマりました。
lego で証明書を取得する¶
Route53 を使い、lego でワイルドカード証明書を取得する場合、以下のように実行します。 ワイルドカードな「*.example.com
」だけでなく、ネイキッドな「example.com
」も含めるようにしておきます。
1 2 3 4 5 6 7 |
|
古いバージョンの lego は鍵アルゴリズムのデフォルト値が RSA2048 でした。 しかし、fix: CLI and key type. (#790) 以降は デフォルト値が EC384 に変更されていました。 今回使っている Cisco ASA 9.1 がたまたま ECDSA に非対応な為、lego で証明書を取得する際は明示的に鍵アルゴリズムに ASA 9.1 でも対応している RSA2048 を指定する必要があります。 この制約が無い場合は EC384 で発行した方があらゆる点でメリットが大きいと思われます。
1 2 3 4 5 6 7 8 |
|
PKCS12 フォーマットへ変換する¶
ASA へ秘密鍵・中間証明書・証明書をインポートする為に、lego で取得した一式を PKCS12 フォーマットへ変換します。
1 2 3 4 5 |
|
この際、Export Password を要求されます。 パスワードには何も入力せずに Enter
だけでもコマンドは正常終了し、PKCS12 フォーマットも生成されます。 但し、Cisco ASA の仕様で「パスワードが設定されていない PKCS12 ファイルはインポート出来ない」ようなので、ここでは必ず任意のパスワードを指定するようにします。 生成された PKCS12 ファイルは cat
等では閲覧出来ない為、openssl
を使って Base64 デコードし、内容を表示します。 ここで表示された内容を以降の手順で ASA へインポートすることになります。
1 2 3 4 5 6 |
|
ASA への証明書インポート¶
ASA への証明書インポートは crypto ca import [TRUSTPOINT] pkcs12 [PASSWORD]
で実施します。 [TRUSTPOINT]
には証明書を管理する任意の名前を指定します。 通常は管理上、分かりやすく FQDN を連想させる名前にしておけば良いと思われます。 [PASSWORD]
には PKCS12 フォーマットを生成した時に指定したパスワードを入力します。 もし、このパスワードが不一致だと、この後の手順で PKCS12 の内容を ASA に貼り付けた際にエラーとなってしまい、インポートに失敗します。
crypto ca import [TRUSTPOINT] pkcs12 [PASSWORD]
を実行すると複数行テキストを入力出来る状態になりますので、PKCS12 を Base64 デコードしたものの先頭に「-----BEGIN PKCS12-----
」を、最後に「-----END PKCS12-----
」と「quit
」を繋げて入力します。 quit
を入力するとインポート完了となり、パスワードや入力値に誤りが無ければ正常にインポートされます。
1 2 3 4 5 6 7 8 |
|
パスワードが不一致だと以下のようなインポートエラーになってしまいます。
1 2 3 |
|
パスワードが一致しており、インポートに成功すると以下のように表示されました。
1 2 3 |
|
インポートされた証明書は show crypto ca certificates
で確認出来ます。
Cisco ASA への証明書インポート¶
あとは Cisco ASA へ証明書をインポートした Trustpoint 名を指定し、設定を行うだけです。 SSL-VPN を待ち受けるインターフェイスは大抵の場合、outside だと思いますので、下記の例でも outside を指定しています。
1 |
|
(RSA2048 では無く) ECDSA をインポートしようとした場合は以下のエラーが表示されました。
1 |
|