nginx 防止 ssl 窜到别的域名

1、进入 nginx 配置目录:

cd /usr/local/nginx/conf
mkdir ssl

2、生成自签名证书:

openssl req -x509 -nodes -days 1 -newkey rsa:2048 -keyout ssl/dummy.key -out ssl/dummy.crt -subj "/CN="

3、将下述代码添加到 nginx.conf

# 默认 server 块,拒绝其他域名的 SSL 请求
server {
    listen 443 default_server ssl;
    server_name _;

    # 使用自签名证书或无效证书
    ssl_certificate ssl/dummy.crt;
    ssl_certificate_key ssl/dummy.key;

    # 直接返回 403 或其他错误
    return 403;
}

4、重启 nginx

nginx -t
systemctl reload nginx

5、访问时,出现 403 错误,即是配置成功。


在 Nginx 中防止 SSL 证书被其他域名“窜用”(即防止未经授权的域名使用你的 SSL 证书),需要确保你的服务器配置只允许合法域名访问,并通过适当的配置阻止非法域名的 HTTPS 请求。以下是具体步骤和配置建议:

1. 明确你的域名

确保你的 SSL 证书只绑定到你控制的合法域名。检查证书的 CN(Common Name)或 SAN(Subject Alternative Name)字段,确保只包含你的域名。

2. 配置 Nginx 只接受合法域名的请求

在 Nginx 配置中,明确指定 server_name 指令,确保服务器只响应特定域名的请求。对于其他未配置的域名,可以设置一个默认的 server 块来拒绝访问。

示例配置:

# 主域名配置
server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /path/to/yourdomain.com.crt;
    ssl_certificate_key /path/to/yourdomain.com.key;

    # 其他 SSL 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root /var/www/yourdomain;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

# 默认 server 块,拒绝其他域名的 SSL 请求
server {
    listen 443 default_server ssl;
    server_name _;

    # 使用自签名证书或无效证书
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;

    # 直接返回 403 或其他错误
    return 403;
}

说明

  • server_name yourdomain.com www.yourdomain.com:明确指定合法域名。
  • server_name _:表示捕获所有未匹配的域名(默认 server 块)。
  • 默认 server 块使用一个“假”证书(可以是自签名证书)并返回 403 错误,防止非法域名通过 HTTPS 访问。

3. 启用 HSTS(HTTP Strict Transport Security)

HSTS 强制浏览器只通过 HTTPS 访问你的域名,防止中间人攻击和 SSL 剥离攻击。

配置 HSTS:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

说明

  • max-age=31536000:设置 HSTS 有效期为一年。
  • includeSubDomains:对所有子域名生效。
  • 确保在生产环境中测试后再启用 HSTS,因为一旦设置,浏览器会缓存此策略。

4. 限制 IP 或使用防火墙

如果其他域名通过 DNS 解析到你的服务器 IP,可以结合防火墙(如 iptables 或云服务商的防火墙)限制访问:

  • 只允许你的合法域名的 DNS 解析指向你的服务器。
  • 使用 Nginx 的 allowdeny 指令限制 IP 访问:
    server {
        listen 443 ssl;
        server_name yourdomain.com;
    
        allow 192.168.1.0/24;  # 允许的 IP 段
        deny all;              # 拒绝其他 IP
    
        ssl_certificate /path/to/yourdomain.com.crt;
        ssl_certificate_key /path/to/yourdomain.com.key;
    
        root /var/www/yourdomain;
    }

5. 防止 DNS 劫持

  • 确保你的域名 DNS 配置正确,使用可信的 DNS 提供商。
  • 启用 DNSSEC(DNS Security Extensions)以防止 DNS 欺骗。

6. 监控和日志

启用 Nginx 访问日志,监控是否有非法域名尝试访问你的服务器:

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

定期检查日志,查看是否有异常的 Host 请求头。

7. 使用 CAA 记录(可选)

在 DNS 中添加 CAA(Certification Authority Authorization)记录,限制哪些证书颁发机构(CA)可以为你的域名签发证书。例如:

yourdomain.com.  CAA 0 issue "letsencrypt.org"

这限制只有 Let’s Encrypt 可以为你的域名签发证书。

8. 测试配置

  • 使用 nginx -t 检查配置文件语法是否正确。
  • 重启 Nginx:systemctl restart nginx
  • 使用工具如 curl 或浏览器测试非合法域名是否被正确拒绝。

注意事项

  • 如果你使用的是通配符证书(*.yourdomain.com),子域名可能更容易被滥用,建议明确指定 SAN 列表。
  • 如果你的服务器被其他域名通过 DNS 解析指向(即 CNAME 或 A 记录指向你的 IP),需要结合防火墙或默认 server 块来防御。
  • 定期更新 SSL/TLS 配置,禁用不安全的协议和密码套件。

通过以上配置,可以有效防止 SSL 证书被其他域名“窜用”,确保你的 HTTPS 服务只为合法域名提供安全访问。如果需要更具体帮助,请提供你的 Nginx 配置或具体场景!

假设你指的是为 Nginx 的默认 server 块生成一个“错误证书”(即自签名证书,用于拒绝非法域名的 HTTPS 请求),以下是生成自签名证书的步骤,并将其配置为返回错误响应(如 403)。这种证书通常用于阻止其他域名“窜用”你的 SSL 服务。如果你的需求是其他类型的“错误证书”(如故意生成无效或损坏的证书),请进一步说明。

1. 生成自签名证书(用作“错误证书”)

使用 OpenSSL 生成一个自签名证书和私钥,专门用于默认 server 块。

命令:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/dummy.key -out /etc/nginx/ssl/dummy.crt

参数说明

  • req -x509: 生成自签名证书。
  • -nodes: 不加密私钥(避免输入密码)。
  • -days 365: 证书有效期 365 天。
  • -newkey rsa:2048: 生成 2048 位 RSA 私钥。
  • -keyout /etc/nginx/ssl/dummy.key: 私钥路径。
  • -out /etc/nginx/ssl/dummy.crt: 证书路径。

输入信息:

运行命令后,OpenSSL 会要求输入证书信息。由于这是用于“错误”目的,信息可以随意填写,例如:

Country Name (2 letter code) [AU]: CN
State or Province Name (full name) [Some-State]: Unknown
Locality Name (eg, city) []: Unknown
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Dummy
Organizational Unit Name (eg, section) []: Dummy
Common Name (e.g. server FQDN or YOUR name) []: invalid.domain
Email Address []: none@invalid.domain

结果
生成文件:

  • /etc/nginx/ssl/dummy.key(私钥)
  • /etc/nginx/ssl/dummy.crt(证书)

2. 配置 Nginx 使用错误证书

在 Nginx 中配置一个默认 server 块,使用该自签名证书,并返回错误响应(如 403)以拒绝非法域名的 HTTPS 请求。

示例配置:

server {
    listen 443 default_server ssl;
    server_name _;

    # 使用自签名证书
    ssl_certificate /etc/nginx/ssl/dummy.crt;
    ssl_certificate_key /etc/nginx/ssl/dummy.key;

    # 拒绝所有请求
    return 403;
}

说明

  • server_name _: 捕获所有未匹配的域名。
  • ssl_certificatessl_certificate_key: 指向自签名证书和私钥。
  • return 403: 拒绝非法域名的 HTTPS 请求,返回 403 错误。

3. 设置文件权限

确保证书和私钥文件的安全权限:

mkdir -p /etc/nginx/ssl
chmod 600 /etc/nginx/ssl/dummy.key
chmod 644 /etc/nginx/ssl/dummy.crt
chown root:root /etc/nginx/ssl/dummy.key /etc/nginx/ssl/dummy.crt

4. 测试和重启 Nginx

  • 检查配置语法:
      nginx -t
  • 重启 Nginx:
      systemctl restart nginx

5. 验证

使用 curl 或浏览器访问一个非法域名(解析到你的服务器 IP),应返回 403 错误或证书警告:

curl -k https://invalid.domain

输出类似:

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

注意事项

  • 用途:这种“错误证书”主要用于默认 server 块,防止非法域名通过 HTTPS 访问你的服务器。它不会被客户端信任,浏览器会显示“不安全”警告。
  • 生产环境:对于合法域名,使用 Let’s Encrypt 或其他 CA 签发的证书。自签名证书仅适合测试或默认拒绝场景。
  • 证书路径:确保 /etc/nginx/ssl/ 存在,或替换为你的实际路径。
  • 日志监控:启用访问日志,检查是否有非法域名请求:
      access_log /var/log/nginx/access.log;
      error_log /var/log/nginx/error.log;

如果你的“错误证书”需求是指其他场景(如测试证书错误、生成特定类型的无效证书等),请提供更多细节,我可以进一步定制方案!

要生成一个无效的证书(例如,用于测试目的),可以创建一个自签名证书并故意设置一个负的或零的-days值,或者让证书立即过期。你已经尝试了-days -1,但OpenSSL不允许负值。相反,你可以设置-days 0来生成一个立即过期的证书,这将使其无效。

以下是一个生成无效自签名证书的命令:

openssl req -x509 -nodes -days 1 -newkey rsa:2048 -keyout ssl/dummy.key -out ssl/dummy.crt

说明:

  • -days 1:设置证书有效期为1天,这意味着证书在生成后一天将过期,因此是无效的。
  • 其他参数与你提供的命令相同:
    • -x509:生成自签名证书。
    • -nodes:不加密私钥。
    • -newkey rsa:2048:生成2048位的RSA私钥。
    • -keyout ssl/dummy.key:私钥输出文件。
    • -out ssl/dummy.crt:证书输出文件。

其他生成无效证书的方法:

  1. 使用过去的日期
    你可以使用-startdate设置一个过去的开始日期和一个已过期的结束日期。例如:

       openssl req -x509 -nodes -newkey rsa:2048 -keyout ssl/dummy.key -out ssl/dummy.crt -startdate -dateopt iso_8601 -set_serial 1 -days 1 -startdate 20200101000000Z -enddate 20200102000000Z

    这会创建一个在2020年1月1日开始并在2020年1月2日过期的证书,当前(2025年)已经是无效的。

  2. 不提供必要字段
    你可以故意省略证书中的必要字段(如Common Name, CN),但OpenSSL通常会要求输入这些字段。如果想自动化,可以使用空的-subj

       openssl req -x509 -nodes -days 1 -newkey rsa:2048 -keyout ssl/dummy.key -out ssl/dummy.crt -subj "/CN="

    某些系统可能认为缺少有效CN的证书是无效的。

注意事项:

  • 确保ssl/目录存在(可以用mkdir ssl创建)。
  • 生成的证书会因为过期(-days 0)而被大多数系统视为无效,适合测试环境。
  • 如果你需要特定的“无效”场景(例如,错误的签名、无效的CA等),请告诉我,我可以为你定制更具体的命令!

如果需要进一步帮助或有其他要求,请随时告知!