らくがきちょう

なんとなく

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」も含めるようにしておきます。

lego --accept-tos \
     --path=/etc/letsencrypt \
     --email="email@example.com" \
     --dns="route53" \
     --domains="example.com" \
     --domains="*.example.com" \
     run

古いバージョンの lego は鍵アルゴリズムのデフォルト値が RSA2048 でした。 しかし、fix: CLI and key type. (#790) 以降は デフォルト値が EC384 に変更されていました。 今回使っている Cisco ASA 9.1 がたまたま ECDSA に非対応な為、lego で証明書を取得する際は明示的に鍵アルゴリズムに ASA 9.1 でも対応している RSA2048 を指定する必要があります。 この制約が無い場合は EC384 で発行した方があらゆる点でメリットが大きいと思われます。

lego --accept-tos \
     --path=/etc/letsencrypt \
     --email="email@example.com" \
     --dns="route53" \
     --domains="example.com" \
     --domains="*.example.com" \
     --key-type rsa2048 \
     run

PKCS12 フォーマットへ変換する

ASA へ秘密鍵・中間証明書・証明書をインポートする為に、lego で取得した一式を PKCS12 フォーマットへ変換します。

openssl pkcs12 -export \
    -in       example.com.crt \
    -inkey    example.com.key \
    -certfile example.com.issuer.crt \
    -out      example.com.p12

この際、Export Password を要求されます。 パスワードには何も入力せずに Enter だけでもコマンドは正常終了し、PKCS12 フォーマットも生成されます。 但し、Cisco ASA の仕様で「パスワードが設定されていない PKCS12 ファイルはインポート出来ない」ようなので、ここでは必ず任意のパスワードを指定するようにします。 生成された PKCS12 ファイルは cat 等では閲覧出来ない為、openssl を使って Base64 デコードし、内容を表示します。 ここで表示された内容を以降の手順で ASA へインポートすることになります。

$ openssl base64 -in example.com.p12
MIIVIQIBAzCCFOcGCSqGSIb3DQEHAaCCFNgEghTUMIIU0DCCD4cGCSqGSIb3DQEH
        ・
        ・
        ・
AAQUw2hE2mz10FUyI1Zk/7hhoCRQRmEECDAhybM6/PRyAgIIAA==

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 を入力するとインポート完了となり、パスワードや入力値に誤りが無ければ正常にインポートされます。

-----BEGIN PKCS12-----
MIIVIQIBAzCCFOcGCSqGSIb3DQEHAaCCFNgEghTUMIIU0DCCD4cGCSqGSIb3DQEH
        ・
        ・
        ・
AAQUw2hE2mz10FUyI1Zk/7hhoCRQRmEECDAhybM6/PRyAgIIAA==
-----END PKCS12-----
quit

パスワードが不一致だと以下のようなインポートエラーになってしまいます。

-----END PKCS12-----
quit
ERROR: Import PKCS12 operation failed

パスワードが一致しており、インポートに成功すると以下のように表示されました。

-----END PKCS12-----
quit
INFO: Import PKCS12 operation completed successfully

インポートされた証明書は show crypto ca certificates で確認出来ます。

Cisco ASA への証明書インポート

あとは Cisco ASA へ証明書をインポートした Trustpoint 名を指定し、設定を行うだけです。 SSL-VPN を待ち受けるインターフェイスは大抵の場合、outside だと思いますので、下記の例でも outside を指定しています。

ssl trust-point [TRUSTPOINT] outside

(RSA2048 では無く) ECDSA をインポートしようとした場合は以下のエラーが表示されました。

ERROR: ECDSA certificates are not supported for SSL