你们一手创造的繁荣,花光一辈子却换不来一处自己的住所。

问题背景

在我当前的开发环境中,使用了 Nginx 作为反向代理来转发请求到 Tomcat 服务器。整个环境运行在一台 Windows 宿主机上,通过 VMware 虚拟机运行 Linux 系统,Nginx 和 Tomcat 均部署在该虚拟机中。网络配置采用 NAT 模式,使得宿主机可以通过映射的端口访问虚拟机内的服务。

具体网络设置如下:

宿主机配置:

在 hosts 文件中添加了以下配置,将 www.chhei.com 解析为 127.0.0.1:

127.0.0.1 www.chhei.com

vmware的NAT端口转发设置及虚拟机上端口配置:

将宿主机的 1080 端口映射到虚拟机的 80 端口。
Nginx 监听虚拟机的 80 端口,作为反向代理,将请求转发到虚拟机上运行的 Tomcat 的 8080 端口。
Tomcat 监听虚拟机的 8080 端口。
以下为我的nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log info;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    server{
        listen 80;
        server_name www.chhei.com;
        location / {
                proxy_pass http://localhost:8080;
        }
    }
}

在完成上述配置后,重启 Nginx 并尝试通过宿主机浏览器访问 www.chhei.com:1080,遇到以下错误:

2024/09/03 12:04:29 [crit] 7708#7708: *1 connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream, client: 192.168.125.2, server: www.cpf.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "www.cpf.com:1080", referrer: "http://www.cpf.com:1080/"

这意味着 Nginx 试图连接 Tomcat 时遭遇了权限问题,导致无法建立连接。最终导致浏览器返回 502 Bad Gateway 错误。

经过分析,可能导致 (13: Permission denied) 错误的原因有多种,以下是我排查并解决问题的过程。

1. SELinux 导致的权限问题

在启用了 SELinux(Security-Enhanced Linux)的系统上,SELinux 的安全策略可能会阻止 Nginx 连接到本地的 Tomcat 服务。这是一个常见的原因,特别是在默认开启 SELinux 的 Linux 发行版上。

解决方法:
临时禁用 SELinux 以确认问题是否由其引起:

sudo setenforce 0

然后重启 Nginx 并重新访问 www.chhei.com:1080,如果问题解决,则表明 SELinux 是导致问题的原因。我找了很多资料都没解决,最后靠这个解决了问题并成功访问到了部署在tomcat上的index.html
在这里插入图片描述
为了长期使用 SELinux 并解决这个问题,可以执行以下命令来允许 Nginx 进行网络连接:

sudo setsebool httpd_can_network_connect on -P

这条命令将 SELinux 的相关策略设置为允许 Nginx 进行网络连接,并且设置是持久化的。

2.Nginx 进程的权限问题

Nginx 进程通常以低权限用户(例如 nginx 或 www-data)运行,这些用户可能没有权限连接到某些本地端口
解决方法:
确认 Nginx 是以适当的用户运行。你可以通过检查 /etc/nginx/nginx.conf 文件中的 user 指令来确认:

user nginx;  # 或者 www-data

如果需要,可以暂时将 Nginx 以 root 用户运行以进行测试(不建议长期使用):

sudo nginx -g 'daemon off; user root;'

如果这样能够正常工作,那么问题确实是由于权限不足导致的,可能需要调整 Nginx 的运行用户或者相关权限。

3.Tomcat 绑定的地址问题

Tomcat 默认监听所有网络接口,但如果手动更改了 Tomcat 的 server.xml 配置文件,使其仅绑定到特定 IP 地址,这可能会导致 Nginx 无法连接。
解决方法:
确保 Tomcat 在 server.xml 中绑定到了所有接口 (0.0.0.0):

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

4.虚拟机的网络配置问题

确保 VMware 的 NAT 配置正确,并且宿主机能够通过 1080 端口正确映射到虚拟机的 80 端口,再由 Nginx 将请求转发至 Tomcat 的 8080 端口。
解决方法:
可以使用 curl 或 wget 命令从宿主机直接访问虚拟机的 8080 端口,以确认访问路径是否正常:

curl http://www.cpf.com:1080

如果返回正常的 HTTP 响应,说明端口映射是正确的。

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐