Qrunch から引っ越し
ドキュメントを読むと IP アドレスでのサーバ証明書検証もやってくれそうな気配はある。
もし接続がホスト名ではなくIPアドレスを使用するのであれば、(いかなるDNS検索もせず)IPアドレスがマッチさせられます。
しかし psql から IPアドレスで接続して証明書を検証させようとすると、以下のようなエラーになった。
$ psql "port=5432 host=192.0.2.1 sslcert=./user.crt sslkey=./user.key sslrootcert=./ca.crt sslmode=verify-full dbname=postgres user=user"
psql: server certificate for "example.com" (and 1 other name) does not match host name "192.0.2.1"
バージョン 9.6.9
の src/interfaces/libpq/fe-secure-openssl.c
から関連部分を抜粋
verify_peer_name_matches_certificate()
/*
* First, get the Subject Alternative Names (SANs) from the certificate,
* and compare them against the originally given hostname.
*/
peer_san = (STACK_OF(GENERAL_NAME) *)
X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
if (peer_san)
{
int san_len = sk_GENERAL_NAME_num(peer_san);
for (i = 0; i < san_len; i++)
{
const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
if (name->type == GEN_DNS)
{
char *alt_name;
names_examined++;
rc = verify_peer_name_matches_certificate_name(conn,
name->d.dNSName,
&alt_name);
if (rc == -1)
got_error = true;
if (rc == 1)
found_match = true;
if (alt_name)
{
if (!first_name)
first_name = alt_name;
else
free(alt_name);
}
}
if (found_match || got_error)
break;
}
sk_GENERAL_NAME_free(peer_san);
}
/*
* If there is no subjectAltName extension of type dNSName, check the
* Common Name.
*
* (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
* dNSName is present, the CN must be ignored.)
*/
if (names_examined == 0)
{
X509_NAME *subject_name;
subject_name = X509_get_subject_name(conn->peer);
if (subject_name != NULL)
{
int cn_index;
cn_index = X509_NAME_get_index_by_NID(subject_name,
NID_commonName, -1);
if (cn_index >= 0)
{
names_examined++;
rc = verify_peer_name_matches_certificate_name(
conn,
X509_NAME_ENTRY_get_data(
X509_NAME_get_entry(subject_name, cn_index)),
&first_name);
if (rc == -1)
got_error = true;
else if (rc == 1)
found_match = true;
}
}
}
Subject Alternative Name に関しては
name->type == GEN_DNS
なケースしかチェックしないので、DNS:example.com
のような dNSName フィールドのみチェックし IP:192.0.2.1
のような iPAddress フィールドはスキップされるようだ。
CN に IP アドレスを入れておけば検証されると思われるが、
If there is no subjectAltName extension of type dNSName, check the Common Name.
とコメントにある通り、subjectAltname に dNSName があったら CN のチェックも行われないので、名前との共存は望めないようだ。
証明書を発行する時に DNS:192.0.2.1
のように subjectAltName に dNSName として IP アドレスを入れてしまう細工しておくと検証に成功するが、素直に名前を使うのが良いだろう。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント