nginx - 如何防止使用 HTTPS 处理具有未定义服务器名称的请求

信息安全 tls 网络扫描仪 nginx
2021-08-18 01:06:16

如何避免 nginx 使用 https 协议处理具有未定义服务器名称的请求。

以下配置使其适用于正常的 http 请求。它重置与空请求的连接host headers,等于server_name在 nginx 配置中:

server {
    listen      80;
    server_name "";
    return      444;
}

为清晰起见更新:

但是,当通过 https 发送的请求为空时,服务器会提供默认 ssl 支持服务器块的 html host header如何避免这种情况?

我想实现与空的 http 请求的确切行为host header-没有提供 html,连接重置(返回 444)。

阻止此类 https 请求并实现上述 https 连接行为的正确方法是什么?(我想避免为此使用正确的 SSL 证书,因为这可能只会暗示真正的服务器域中的垃圾邮件发送者。)


更新 13.03.2015

使用设置在 nginx 前面放置一个 haproxy

strict-sni

完全解决了我的问题。

4个回答

我已经通过生成一个不显示域名的假证书并将其添加为配置开始时的默认证书来解决它:

server {
    listen 443 default;
    server_name     _;

    ssl     on;
    ssl_certificate         /path/to/fake.crt;
    ssl_certificate_key     /path/to/fake.key;

    return 403;
}

是的,它需要一个支持 SNI 的 nginx(检查nginx -V)。


继续: 如何为测试目的创建自签名 SSL 证书

由于 SSL 工作方式的性质,SSL/TLS 握手是在将预期主机名提供给 Web 服务器之前执行的。这意味着在尝试访问站点时使用默认(第一个)证书,而不管使用的域名如何。

Apache 和 nginx 都是如此。

来自Apache 维基

通常,在同一个 IP 地址和端口上托管多个 SSL 虚拟主机是不可能的。这是因为 Apache 需要知道主机的名称才能选择正确的证书来设置加密层。但是被请求的主机名仅包含在 HTTP 请求标头中,这些标头是加密内容的一部分。因此,只有在已经协商加密之后才能使用它。这意味着无法选择正确的证书,并且客户端将收到证书不匹配警告并且容易受到中间人攻击。

nginx 文档

使用此配置,浏览器将接收默认服务器的证书,即www.example.com ,而不管请求的服务器名称如何。这是由 SSL 协议行为引起的。SSL 连接是在浏览器发送 HTTP 请求之前建立的,而 nginx 不知道请求的服务器的名称。因此,它可能只提供默认服务器的证书。

你如何解决这个问题?

最简单的解决方案是为您希望保护的每个站点使用单独的 IP 地址。

如果这不可行,则可以使用服务器名称指示 (SNI,RFC 6066)解决问题。这允许浏览器在握手期间将域名传递给服务器。

Nginx 和 Apache 都支持 SNI。您可以在文档中找到有关 nginx SNI 的更多信息

值得注意的是,SNI 只能用于域名,不能用于 IP 地址。在配置 Web 服务器以解决此问题时,您应该采取额外的预防措施,以便正确处理对 IP 的任何请求。

SNI 中只能传递域名,但是如果请求包含文字 IP 地址,则某些浏览器可能会错误地将服务器的 IP 地址作为其名称传递。不应依赖于此。

Apache Wiki 有更多关于实现SNI的信息。但即使是他们的文档也表明这个解决方案并不完美。

将基于名称的虚拟主机与 SSL 结合使用会增加另一层复杂性。如果没有 SNI 扩展,通常是不可能的(尽管虚拟主机的一个子集可能会起作用)。使用 SNI,有必要仔细考虑配置以确保维护安全性。

话虽如此,您可以看到此配置不像常规虚拟主机那样简单。为了进一步解决您的问题,我们需要了解有关您的配置的更多详细信息以及发送仅 IP 请求时的预期行为。

通常,要“阻止”未配置的域或 IP 请求,您会将其配置为默认站点,然后显示错误、重定向、退出等。

如果我了解您想要拒绝不包含 Host 标头的 HTTP-Requests,即使这些请求位于 SSL 连接(例如 https-Requests)内。这些是老式的 HTTP/1.0 请求,HTTP/1.1 需要 Host 标头,但大多数 HTTP/1.0 客户端已经发送了一个。可以通过以下方式阻止这些客户端:

    if ( $http_host = '' ) {
            return 444;
    }

但是,如果客户端使用带有垃圾或 IP 地址的 Host 标头,这将无济于事。因此,最好验证主机标头是否包含预期值(作为奖励,这也有助于防止 DNS 重新绑定攻击),例如

    if ( $http_host !~* ^(example\.com|www\.example\.com)$ ) {
            return 444;
    }

我使用了与@int_ua 提到的类似的方法,但有点棘手。

我将我的 nginx 配置为使用 RSA 和 ECDSA 作为 TLS 身份验证方法,但为默认服务器颁发了 DSA 证书。
由于没有可用的密码套件,TLS 握手会在提供任何页面之前失败。
我认为它与您配置的结果相同(HAproxy strict-sni),并相信我的方法会有更好的性能。

你可以查看我的配置结果:

无效 SNI:https
://207.246.127.148/    (您可以将主机配置到此 IP 地址并查看结果)
有效 SNI:https
   ://cloud.jemmylovejenny.tk/ 有效 SNI 链接指向同一个 IP地址如上

我会在这里给出我的配置:

SSL 配置
(我使用了一个 openssl equal ciphers补丁,所以密码有点奇怪......您也可以保留您的配置,但请记住不要包含任何 DSS 密码!)

    #Protocols
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    #
    #Key Exchange
    ssl_ecdh_curve X25519:P-256:P-384:P-224:P-521;
    ssl_dhparam /var/SSL/DH-param.pem;
    #
    #Cipher Suites
    ssl_ciphers "[TLS_AES_128_GCM_SHA256|TLS_CHACHA20_POLY1305_SHA256]:[TLS_AES_256_GCM_SHA384|TLS_AES_128_CCM_8_SHA256|TLS_AES_128_CCM_SHA256]:[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|DHE-RSA-CHACHA20-POLY1305]:[ECDHE-ECDSA-AES256-GCM-SHA384|ECDHE-RSA-AES256-GCM-SHA384]:[ECDHE-ECDSA-AES128-SHA|ECDHE-RSA-AES128-SHA]:[ECDHE-ECDSA-AES256-SHA|ECDHE-RSA-AES256-SHA]:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA";
    ssl_prefer_server_ciphers on;



默认服务器配置

##
# General
##
# Listen
listen 8080 default_server;
listen 8443 ssl spdy http2 default_server;
#
# Server Name
server_name _;

##
# SSL Settings
##
#
# Certificate
#  DSA
ssl_certificate /var/SSL/certificates/DEFAULT.dsa.crt;
ssl_certificate_key /var/SSL/keys/DEFAULT.dsa.key;

root /var/www/html/nginx/;



DSA 密钥是从 OpenSSL 生成的,证书是从我自己的 PKI 颁发的。如果需要,您可以使用此证书。
(这个证书永远不会从 nginx 服务器发送,所以这个证书的所有内容,包括 keylength 和有效期都是没有意义的)

证书:

-----BEGIN CERTIFICATE-----
MIIFrjCCBJagAwIBAgIUHVfGi/SP2d/B4vbxZSKSVEpSoGEwDQYJKoZIhvcNAQEL
BQAwgYExCzAJBgNVBAYTAkNOMSMwIQYDVQQKDBpKZW1teUxvdmVKZW5ueSBQS0kg
U2VydmljZTEeMBwGA1UECwwVcGtpLmplbW15bG92ZWplbm55LnRrMS0wKwYDVQQD
DCRKZW1teUxvdmVKZW5ueSBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwMTAx
MDAwMDAwWhcNMTkxMjMxMjM1OTU5WjAiMSAwHgYDVQQDDBdERUZBVUxUIFNTTCBD
RVJUSUZJQ0FURTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCVcFt4xWkIBtiN/Xay
O7Ls5EjBCFckvyBQpRJ5wmjrxepQbUK9xmiXmpkXOsEYHy14UQXswzKPBWiHsNDs
8apFoGAvjBxSg9Y07wd5VBnhBGvqd0VmD92eKAFW1sZZVoSrLwizfIde0sj9bZCD
KICt/0jdz0QGBZzXTtd4MOcjUQIVAPD9cVtRAdD6al8v/SV2YVQHZmafAoGBAI+A
tCrjcvK0PFILpwpGD/3gJI8o2oxKoPjjE3SM9b4mrN/2ixEGgGiXHOrEyZ7IgSjf
1Z6X2nuN+IgsNdJAZjNbnuacxbu4z5FmnO6i9IRXEqtKNzONeHJSG+7w7zUPfsPT
8sTxHU0Z5ynjiLz4GcnO5LVcMNbf2uEsl41fObB4A4GEAAKBgHOFoU8xns0qMFLz
h3ZiYScs2Rznw7xeo2HbM8hGI9zKWRoV49f9V2vHFjdPSLkPbzgoSqOxmGD7UZep
W0TcsSPVKIuKBw07vvJkpUG8U71mcedNN5+fNbIcgjKdTlIIbrEFYRFG6zrIcZ3/
WArPchw3RC+SRrBXW8+27T4+0PMao4IB5TCCAeEwHwYDVR0jBBgwFoAU4BPpj9H7
K19wMi69RQ9t6BLyNOcwHQYDVR0OBBYEFFrpB6sLpQwodD7KWPssHj0fkqjCMAkG
A1UdEQQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3Jscy5wa2kuamVtbXls
b3ZlamVubnkudGsvU0hBMlNlY3VyZVNlcnZlckNBLmNybDCBggYDVR0gBHsweTBt
BglghkgBpKInAQIwYDAtBggrBgEFBQcCARYhaHR0cHM6Ly9wa2kuamVtbXlsb3Zl
amVubnkudGsvY3BzMC8GCCsGAQUFBwICMCMaIWh0dHBzOi8vcGtpLmplbW15bG92
ZWplbm55LnRrL3JwYTAIBgZngQwBAgEwgYYGCCsGAQUFBwEBBHoweDAtBggrBgEF
BQcwAYYhaHR0cDovL29jc3AucGtpLmplbW15bG92ZWplbm55LnRrMEcGCCsGAQUF
BzAChjtodHRwOi8vY2FjZXJ0cy5wa2kuamVtbXlsb3ZlamVubnkudGsvU0hBMlNl
Y3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IB
AQCtgVPw2KLT/ntVYZE8AL71C0R1gsn9MKoqD6asaM16qK60G7YK8qC2I/5wWXAr
+zVeegvU/73qWq66DnIF333uZz3aeaXoIEfDRcfePVzWTG62cO2fPyTWyIczaPFf
NqQqoukM3UeBM0yIRSbiyRAFoyz0TWhdgSDXGrG+X5EvUnH6J+umnt/PNGaNnz1f
eXJBh79UnmCpMI6rW+7UG4F60xxQ/RQeRZZt//Ze5YzIDRjUQpXQ1a+9cHuPT8EY
Ft4xe4q5FgMVTBsu1zAfA/ViSDlHWAO8oioKkYDYHqYmLT6ERSoXNVK6WbNh4mem
AaF8T8DKQTHD5GKFBJSSkvF7
-----END CERTIFICATE-----



钥匙:

-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQCVcFt4xWkIBtiN/XayO7Ls5EjBCFckvyBQpRJ5wmjrxepQbUK9
xmiXmpkXOsEYHy14UQXswzKPBWiHsNDs8apFoGAvjBxSg9Y07wd5VBnhBGvqd0Vm
D92eKAFW1sZZVoSrLwizfIde0sj9bZCDKICt/0jdz0QGBZzXTtd4MOcjUQIVAPD9
cVtRAdD6al8v/SV2YVQHZmafAoGBAI+AtCrjcvK0PFILpwpGD/3gJI8o2oxKoPjj
E3SM9b4mrN/2ixEGgGiXHOrEyZ7IgSjf1Z6X2nuN+IgsNdJAZjNbnuacxbu4z5Fm
nO6i9IRXEqtKNzONeHJSG+7w7zUPfsPT8sTxHU0Z5ynjiLz4GcnO5LVcMNbf2uEs
l41fObB4AoGAc4WhTzGezSowUvOHdmJhJyzZHOfDvF6jYdszyEYj3MpZGhXj1/1X
a8cWN09IuQ9vOChKo7GYYPtRl6lbRNyxI9Uoi4oHDTu+8mSlQbxTvWZx5003n581
shyCMp1OUghusQVhEUbrOshxnf9YCs9yHDdEL5JGsFdbz7btPj7Q8xoCFFfXTHSl
C7tdLJO9vQFcyKMhU8TU
-----END DSA PRIVATE KEY-----