Help us understand the problem. What is going on with this article?

SSL証明書でIPアドレスからホスト名が漏れる

IPアドレスからWebサーバの名前がわかるよー

下の結果は、curl でIPアドレスにHTTPSでアクセスしただけです。

% curl -v https://198.51.100.15/
*   Trying 198.51.100.15...
* TCP_NODELAY set
* Connected to 198.51.100.15 (198.51.100.15) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=test.example.com
*  start date: Jan 28 05:43:51 2020 GMT
*  expire date: Apr 27 05:43:51 2020 GMT
*  subjectAltName does not match 198.51.100.15
* SSL: no alternative certificate subject name matches target host name '198.51.100.15'
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (51) SSL: no alternative certificate subject name matches target host name '198.51.100.15'

わかりますか?

* Server certificate:
*  subject: CN=test.example.com
*  start date: Jan 28 05:43:51 2020 GMT
*  expire date: Apr 27 05:43:51 2020 GMT
*  subjectAltName does not match 198.51.100.15

Apache httpd のバーチャルホスト機能を使ってHTTPSサーバを複数ホストしている場合、IPアドレスでアクセスした場合 一番最初に定義されたバーチャルホストが使われる ので、その証明書を使って検証することになっています。

アスタリスクはすべてのアドレスにマッチしますので、主サーバはリクエストを扱いません。www.example.com は 最初にあるため、優先順位は一番高くなり、default もしくは primary のサーバと考えることができます。つまり、リクエストがどの ServerName ディレクティブにもマッチしない場合、 一番最初の VirtualHost により扱われます。
https://httpd.apache.org/docs/2.4/ja/vhosts/examples.html

いやそれは困る…

場合によっては困る場合もあるでしょう。
その場合、バーチャルホストの一番最初の定義に、ダミーの設定を挟むことで回避できます。

_default.conf
<VirtualHost _default_:443>
    LogFormat "%h %l %u %t ¥"%r¥" %>s %b ¥"%{Referer}i¥" ¥"%{User-Agent}i¥"" combined
    CustomLog logs/ssl_access_log combined

    Redirect 403 /

    SSLEngine on
    SSLCertificateFile conf.d/dummy.crt
    SSLCertificateKeyFile conf.d/dummy.key
</VirtualHost>

バーチャルホストをファイルごとに分けている場合、以下のように先頭にアンダーバーを付けたファイルがあれば最初に読み込まれます。
あるいは ssl.conf の最後に書いてもいいかもですね。

 $ ls -la /etc/httpd/conf.vhosts.d
total 8
drwxr-xr-x 2 keys keys   48 Feb  4 10:15 ./
drwxr-xr-x 7 root root  138 Jan 31 18:06 ../
-rw-rw-r-- 1 keys keys 1062 Feb  3 13:49 _defailt.conf
-rw-rw-r-- 1 keys keys 1092 Jan 31 23:21 test.example.com.conf

この設定で使うSSL証明書は自己署名証明書(オレオレ証明書)です。
CSRを作るときは Common Name だけ入力すれば大丈夫です。証明書の CN フィールドは、グローバルで設定した ServerName にしないと httpd の起動時に怒られるみたいです。

$ openssl genrsa 2048 > dummy.key
Generating RSA private key, 2048 bit long modulus (2 primes)
........+++++
.......................................................................+++++


$ openssl req -new -key dummy.key > dummy.csr
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.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

$ openssl x509 -days 3650 -req -signkey dummy.key < dummy.csr > dummy.crt
Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = localhost
Getting Private key

これでもう一度試してみると…

$ curl -v https://198.51.100.15/
*   Trying 198.51.100.15...
* TCP_NODELAY set
* Connected to 198.51.100.15 (198.51.100.15) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

自己署名証明書だ、と言って怒られて処理が終わります。

これでホスト名が漏れることを防ぐことができました。しかしもう一つ、問題が残っています。

“Redirect 403 /”

ブラウザが止めようとなんと言おうと、自己署名証明書を無視してアクセスすることはできます。
curl に --insecure (自己署名証明書を無視するオプション)を付けてアクセスしてみます。

% curl --insecure https://198.51.100.15/
<html>

<head>
<title>hoge</title>
</head>

<body>
<p1>Hoge!</p1>
</body>

</html>

この場合も先頭のバーチャルホストの内容が使われます。そこからホスト名やサービスの内容が漏れる場合もあるでしょう。

これを防ぐには、先の設定ファイルにはあらかじめ書いておきましたが、一行追加しておくと防げます。

Redirect 403 /

すると、IPアドレスでのアクセスはすべて 403 になり、見えなくなります。

$ curl --insecure https://198.51.100.15/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした