返回

Nginx反向代理EC2 Java应用与CSF配置错误解决

Linux

Nginx反向代理EC2上Java应用与CSF配置问题解决

在云服务器(EC2)上运行Java应用程序时,常常需要使用Nginx作为反向代理服务器。通过反向代理,可以隐藏内部服务器的端口,并利用Nginx处理SSL加密、负载均衡和静态资源等任务。配合CSF(ConfigServer Security & Firewall)防火墙,可以进一步增强服务器的安全性。然而,配置不当可能导致SSL连接错误等问题,例如“ERR_SSL_PROTOCOL_ERROR”。 本文将探讨这类问题的常见原因以及相应的解决方案。

问题分析:SSL协议错误与配置

通常情况下, "ERR_SSL_PROTOCOL_ERROR" 错误意味着客户端(例如浏览器)和服务器(此处指 Nginx)之间在SSL协议握手阶段出现问题。 以下是一些常见原因:

  • SSL协议版本不匹配: Nginx支持的SSL协议版本与Java应用程序(例如运行在Jetty上的程序)不一致。
  • 证书配置错误: SSL证书的配置出现错误,如证书路径不正确,证书链不完整等。
  • 端口问题: 客户端尝试连接的端口与服务器实际监听的端口不一致。
  • proxy_pass协议不一致: proxy_pass配置的协议(HTTP或HTTPS)与后端Java应用的实际协议不匹配。
  • 防火墙规则限制: CSF可能阻止了Nginx与Java应用之间的通信。
  • SNI(Server Name Indication)配置问题: 如果使用多个SSL证书,需要正确配置SNI,确保Nginx能选择正确的证书服务对应的域名。

解决方案:优化Nginx配置与协议匹配

以下是一些解决方案,可用于排查和解决上述问题:

1. 确保SSL协议版本一致

确保Nginx配置的SSL协议版本与客户端和后端Java应用程序兼容。推荐使用TLS v1.2及以上版本,因为它们更加安全。

Nginx 配置示例:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name acttest.mydomain.com;

    ssl_certificate /etc/ssl/certs/certificate.crt;
    ssl_certificate_key /etc/ssl/certs/server.key;

    ssl_protocols TLSv1.2 TLSv1.3; # 推荐使用TLSv1.2及以上
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:4450; #  确定后端是HTTP
        include proxy_params;
    }
}

步骤:

  1. 检查Java应用程序是否支持TLS v1.2及以上版本。在Jetty中,可以通过配置 jetty.ssl.protocols 属性进行设置。
  2. 修改Nginx配置文件,确保 ssl_protocols 指令包含所需的TLS版本。
  3. 重新加载Nginx配置:sudo nginx -t && sudo nginx -s reload

安全提示: 避免使用过低的SSL/TLS版本,例如SSLv3或TLSv1.0,因为这些协议存在安全漏洞。

2. 检查证书配置

检查SSL证书是否有效,路径是否正确,证书链是否完整。可以使用在线SSL证书检查工具验证证书的有效性。

Nginx 配置示例:

server {
    listen 443 ssl;
    server_name acttest.mydomain.com;

    ssl_certificate /etc/ssl/certs/fullchain.pem; #  证书链
    ssl_certificate_key /etc/ssl/certs/privkey.pem; #  私钥
    ...
}

步骤:

  1. 确保证书文件存在且Nginx进程有读取权限。
  2. 确保 ssl_certificate 指向完整的证书链文件(包括服务器证书、中间证书和根证书)。
  3. 如果使用了Let's Encrypt证书,fullchain.pem 文件通常包含了完整的证书链。
  4. 重新加载Nginx配置:sudo nginx -t && sudo nginx -s reload

安全提示: 定期更新SSL证书,避免证书过期带来的安全风险。使用自动化证书管理工具,例如Certbot,可以简化证书更新过程。

3. 检查端口配置

检查Nginx监听的端口与客户端请求的端口是否一致。此外,也要检查 proxy_pass 指令中指定的后端服务器端口是否正确。

Nginx 配置示例:

server {
    listen 443 ssl;
    server_name acttest.mydomain.com;

    location / {
        proxy_pass http://127.0.0.1:4450; # 后端监听4450端口
        include proxy_params;
    }
}

步骤:

  1. 确认浏览器或客户端使用的端口是443 (HTTPS的默认端口)。
  2. 确认后端Java应用程序正在监听4450端口。
  3. 使用netstat -tulnp命令查看服务器的端口监听情况,确保java应用正确监听端口。
  4. 如果后端应用程序没有启用HTTPS, proxy_pass 指令应该使用 http:// 协议。
  5. 重新加载Nginx配置:sudo nginx -t && sudo nginx -s reload

4. 检查CSF防火墙规则

CSF防火墙可能会阻止Nginx与Java应用之间的通信。 确保CSF允许Nginx访问后端Java应用程序的端口。

步骤:

  1. 登录到EC2实例。
  2. 编辑CSF配置文件(通常是/etc/csf/csf.conf)。
  3. 添加Nginx的IP地址(通常是服务器的内网IP地址,例如 127.0.0.1)到 csf.allow 列表中。
  4. 允许Nginx访问Java应用程序的端口(例如4450)。
  5. 重启CSF防火墙:sudo csf -r

命令示例:

编辑/etc/csf/csf.conf文件:

# Allow incoming TCP ports
TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995,3306,4450" #添加4450端口

# Allow outgoing TCP ports
TCP_OUT = "20,21,22,25,53,80,110,113,143,443,465,587,993,995,3306"

# Allow incoming UDP ports
UDP_IN = "20,21,53"

# Allow outgoing UDP ports
UDP_OUT = "20,21,53,113,123"

安全提示: 配置防火墙规则时,只开放必要的端口,并限制允许访问的IP地址范围,降低安全风险。

5. proxy_params 配置

确认nginx包含proxy_params 文件。
检查步骤:

  1. 确认nginx配置文件正确包含 proxy_params文件
  2. 查看proxy_params的内容是否如下所示:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

保证反向代理可以正确传递Host和IP信息

总结

解决Nginx反向代理中出现的 "ERR_SSL_PROTOCOL_ERROR" 错误,需要综合考虑SSL协议版本、证书配置、端口配置和防火墙规则等因素。通过仔细检查和调整配置,通常可以解决此类问题。