VyOS 1.4のAPIを利用できるようにする
目次
VyOSにLet’s Encryptで取得したサーバ証明書をインストールしたい、でもVyOS上のcertbotではなく、別のLinux上で用意しているcertbotで取得したサーバ証明書を使いたい、というモチベーションからVyOSでAPIを使えるようにしました。
別にこのようなモチベーションじゃなく、単純にVyOSの設定を自動化するためにAPIを使いたいという場合にも参考になると思いますので、記事にしておきます。
環境
- VyOS 1.4-rolling-202302080317
- rolling releaseなので仕様が変更になったり、バグが含まれる可能性があります。(実際バグを踏んで酷い目に遭いました…)
サーバ証明書をインストールする
APIを使うためにHTTPSでアクセスするので、サーバ証明書のインストールが必要です。
基本的には、公式ドキュメントの通りで問題なく対応できます。
証明書と秘密鍵の下処理
証明書や秘密鍵は以下のようなフォーマットになっています。
-----BEGIN CERTIFICATE----- ... certificate ... -----END CERTIFICATE-----
-----BEGIN PRIVATE KEY----- ... private key ... -----END PRIVATE KEY-----
VyOSへインストールする際は、以下の前処理をした上で設定する必要があります。
- BEGIN、END行を削除
- 改行を削除
これを行うために公式ドキュメントで紹介されている以下のコマンドを使って整形することにします。
証明書が置かれているLinux上でやっても、VyOSまで証明書を持ってきてVyOS上でやっても問題ありません。
tail -n +2 <証明書、秘密鍵のファイルパス> | head -n -1 | tr -d '\n'
このコマンドで出力された長い文字列を、以降の作業で使う事になります。
たとえば、後述の作業で使うLet’s Encryptの中間証明書を処理すると、以下のような結果になります。
[vyos@vyos ~]$ cat lets-encrypt-r3.pem -----BEGIN CERTIFICATE----- MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG /kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX nLRbwHOoq7hHwg== -----END CERTIFICATE----- [vyos@vyos ~]$ tail -n +2 lets-encrypt-r3.pem | head -n -1 | tr -d '\n' MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAwTzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAwWhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cPR5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdxsxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8ZutmNHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxgZ3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaAFHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRwOi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6WPTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wlikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQzCkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BImlJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1OyK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90IdshCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6ZvMldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqXnLRbwHOoq7hHwg==[vyos@vyos ~]$
サーバ証明書・秘密鍵のインストール
冒頭に記載の通り、別途取得済みのサーバ証明書を導入します。
どうやらVyOSにはcertbotが入っていて単独で証明書を作ることも出来るらしい?あと自己署名証明書も作れるようですが、今回それらは使いません。
$ configure # set pki certificate <証明書名> certificate <整形済みのサーバ証明書> # set pki certificate <証明書名> private key <整形済みの秘密鍵>
この状態でVyOSを再起動すると、壊れたコンフィグをロードできず、ゼロコンフィグ状態になるのでご注意ください。
CA証明書のインストール
LinuxのhttpdなどではCA証明書をインストールしなくても使えたりするのですが、VyOSでは導入必須のようです。
今回は自己署名証明書ではないので、CAの秘密鍵は不要で証明書だけインストールします。
今回はLet’s Encryptの証明書なので、Let’s Encryptのサイト上で公開されている証明書をダウンロードします。
Intermediate Certificates(中間証明書)と書かれているところにある、「Let’s Encrypt R3」の「Signed by ISRG Root X1」のpemファイルをダウンロードします。
この証明書も同様に整形をした上でインストールします。
これらの作業が全て終わればいったんコミットして保存しておきます。
# set pki ca LetsEncryptR3 certificate <整形済みのCA証明書> # commit # save
証明書名にLetsEncryptR3
と設定していますが、お好みで変えてもらって問題ありません。
証明書の一覧を表示
オペレーションモードのshow pki certificate
で正しく証明書が導入できているか確認しておきます。
# run show pki certificate Certificates: Name Type Subject CN Issuer CN Issued Expiry Revoked Private Key CA Present ----------- ------ ---------------- ----------- ------------------- ------------------- --------- ------------- ------------------- <cert name> Server CN=<common name> CN=R3 2023-02-11 09:00:42 2023-05-12 09:00:41 No Yes Yes (LetsEncryptR3)
APIを有効にする
APIを使えるように、httpsサービスの設定をしていきます。
API用のキーを生成
API用のキーは何でも良いと思いますが、今回はUUIDを使うことにします。
以下は実行例ですので、参考にする場合はお手元で実行してください。
# uuidgen 414e8804-2494-4dcd-bad1-534a30db272d
HTTPS VirtualHostの設定
今回は一つだけ、default VitualHostを作成します。(defaultの名称は何でも構いません。)
ここで設定するlisten-port
は、APIを実行するクライアントが接続するHTTPSのポート番号になります。
コンフィグモードで引き続き作業します。
# set service https certificates ca-certificate LetsEncryptR3 # set service https certificates certificate <証明書名> # set service https virtual-host default listen-address <待ち受けIPアドレス> # set service https virtual-host default listen-port <待ち受けポート> # set service https virtual-host default server-name <VyOSのFQDN>
APIを有効化
APIキーは上記で生成したUUIDを指定します。
繰り返しますが、実行例ですので、参考にする場合はお手元で生成したものをご利用ください。
api-restrict
は、指定したVirtual HostでのみAPIの実行を許可する設定です。
今回はdefaultしか作成していないので関係ありませんが、一応設定しておきます。
設定したらコミットして保存し、オペレーションモードに戻ります。
# set service https api keys id <APIキー名> key '414e8804-2494-4dcd-bad1-534a30db272d' # set service https api-restrict virtual-host 'default' # commit # save # exit
今回設定しませんが、set service https api port
でAPIの待ち受けポートを設定することができます。
これは内部で利用するポートなので、APIを実行するクライアントが接続するポートではありません。
デフォルトは8080/tcpなので、他で設定しているポートと重複する場合は変更してください。
HTTPS/APIの起動を確認する
ぱっと見では、httpsサービスの動作状況を確認するshow
コマンドが無さそうなので、ポートが待ち受けられていることを確認します。
$ ss -nlt State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ...(snip)... LISTEN 0 2048 127.0.0.1:8080 0.0.0.0:* LISTEN 0 511 <listen-addr>:<port> 0.0.0.0:* ...(snip)...
出力は省略していますが、HTTPSのlisten-address
とlisten-port
でポートが待ち受けられており、127.0.0.1:8080
でAPIのポートが待ち受けられていることが見て取れます。
クライアントからAPIにアクセスする
外部のクライアントからHTTPSアクセスも試してみます。
ブラウザから https://<VyOSのFQDN>:<待ち受けポート> へアクセスすると、nginxのデフォルトページが表示されます。
証明書に問題がなければ特に証明書エラーなども表示されません。
外部のクライアント(Linux)からcurlでAPIの実行も試してみます。
key
には事前に生成、設定したAPIキーを入力します。
$ curl --location --request POST 'https://<VyOSのFQDN>:<待ち受けポート>/retrieve' --form data='{"op": "showConfig", "path": []}' --form key='414e8804-2494-4dcd-bad1-534a30db272d'
問題がなければコンフィグがだだーっと表示されるはずです。
サーバ証明書をAPIで更新する
APIが使えるようになったのは良いのですが、Let’s Encryptは3ヶ月に1度証明書を更新することになります。
証明書を更新したら、API経由で新しい証明書をインストールするようにスクリプトを作っておきます。
上でしれっとコンフィグ取得をしてしまっていますが、APIの使い方については詳しくはドキュメントを参照してください。
APIでコンフィグを設定
APIでコンフィグ設定すると、自動でcommit
されてしまいます。
サーバ証明書は秘密鍵とセットで更新しなければなりませんので、certificate
とprivate key
の両方の設定を同時に行います。
手作業でcurlを実行する場合は、以下のコマンドになります。
忘れた頃だと思うので再度繰り返しますが、実行例ですので、APIキーはお手元で生成したものをご利用ください。
$ curl --location --request POST 'https://<VyOSのFQDN>:<待ち受けポート>/configure' --form data='[{"op": "set", "path": ["pki", "certificate", "<証明書名>", "certificate", "<整形済みのサーバ証明書>"]}, {"op": "set", "path": ["pki", "certificate", "<証明書名>", "private", "key", "<整形済みの秘密鍵>"]}]' --form key='414e8804-2494-4dcd-bad1-534a30db272d'
証明書が変更されてhttpsサービスが再起動することによるものなので正常な動作です。
APIでコンフィグを保存
APIでコンフィグを設定するとcommit
はされますが、save
はされません。
後追いでコンフィグ保存のAPIも実行します。
$ curl --location --request POST 'https://<VyOSのFQDN>:<待ち受けポート>/config-file' --form data='{"op": "save"}' --form key='414e8804-2494-4dcd-bad1-534a30db272d'
スクリプト化する
上記を手作業で定期実行するのは当然辛いので、スクリプトを作ってcronなどに登録しておきましょう。
スクリプトにする際、変数展開を考慮してシングルクォーテーションとダブルクォーテーションを変えたりしています。
#!/bin/sh APIKEY=414e8804-2494-4dcd-bad1-534a30db272d CERTIFICATE=$(/usr/bin/tail -n +2 /etc/letsencrypt/live/<証明書のCN>/cert.pem | /usr/bin/head -n -1 | /usr/bin/tr -d '\n') PRIVATE_KEY=$(/usr/bin/tail -n +2 /etc/letsencrypt/live/<証明書のCN>/privkey.pem | /usr/bin/head -n -1 | /usr/bin/tr -d '\n') curl --location --request POST 'https://<VyOSのFQDN>:<待ち受けポート>/configure' --form data="[{\"op\": \"set\", \"path\": [\"pki\", \"certificate\", \"<証明書名>\", \"certificate\", \"$CERTIFICATE\"]}, {\"op\": \"set\", \"path\": [\"pki\", \"certificate\", \"<証明書名>\", \"private\", \"key\", \"$PRIVATE_KEY\"]}]" --form key="$APIKEY" curl --location --request POST 'https://<VyOSのFQDN>:<待ち受けポート>/config-file' --form data='{"op": "save"}' --form key="$APIKEY"
APIを使うことで、FWのルールを動的に開放するなど使い方が広がりますね。
最近のコメント