跳转到内容

Nginx 反向代理

版本数据实时来自 pkgseek.com
Terminal window
sudo dnf install -y nginx

启动并设置开机自启:

Terminal window
sudo systemctl enable --now nginx

验证:

Terminal window
sudo systemctl status nginx
curl -I http://localhost

开放防火墙端口:

Terminal window
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Nginx 在 EL 系统上的配置目录结构如下:

/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 站点配置目录(*.conf 自动加载)
│ └── default.conf # 默认站点配置
├── mime.types # MIME 类型定义
└── fastcgi_params # FastCGI 参数

主配置文件 /etc/nginx/nginx.conf 的核心结构:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /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;
}

每个站点配置为独立文件放在 /etc/nginx/conf.d/ 目录下。

创建 /etc/nginx/conf.d/static.example.com.conf

server {
listen 80;
server_name static.example.com;
root /var/www/static.example.com;
index index.html;
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
error_page 404 /404.html;
}

创建网站根目录:

Terminal window
sudo mkdir -p /var/www/static.example.com
echo "<h1>Hello from RunEntLinux</h1>" | sudo tee /var/www/static.example.com/index.html

测试并重载配置:

Terminal window
sudo nginx -t
sudo systemctl reload nginx

创建 /etc/nginx/conf.d/app.example.com.conf

server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
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;
}
}
upstream app_backend {
least_conn;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
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;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
server {
listen 80;
server_name ws.example.com;
location /ws {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}

SSL/TLS 配置(Let’s Encrypt + Certbot)

Section titled “SSL/TLS 配置(Let’s Encrypt + Certbot)”
  1. 安装 Certbot:

    Terminal window
    sudo dnf install -y certbot python3-certbot-nginx
  2. 申请证书(Certbot 会自动修改 Nginx 配置):

    Terminal window
    sudo certbot --nginx -d app.example.com

    或者仅获取证书,不修改配置:

    Terminal window
    sudo certbot certonly --nginx -d app.example.com
  3. 手动配置 SSL 站点。创建 /etc/nginx/conf.d/app.example.com.conf

    server {
    listen 80;
    server_name app.example.com;
    return 301 https://$host$request_uri;
    }
    server {
    listen 443 ssl http2;
    server_name app.example.com;
    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
    # 安全的 SSL 参数
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    location / {
    proxy_pass http://127.0.0.1:8000;
    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;
    }
    }
  4. 设置证书自动续期:

    Terminal window
    sudo systemctl enable --now certbot-renew.timer
    # 或手动测试续期
    sudo certbot renew --dry-run

在启用 SELinux 的系统上,Nginx 受到 httpd_t SELinux 策略的约束。

Nginx 无法读取自定义目录下的文件

Terminal window
# 查看当前 SELinux 上下文
ls -laZ /var/www/static.example.com/
# 设置正确的上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/static.example.com(/.*)?"
sudo restorecon -Rv /var/www/static.example.com/

Nginx 无法连接后端服务(反向代理 502 错误)

Terminal window
# 允许 httpd 发起网络连接
sudo setsebool -P httpd_can_network_connect 1

Nginx 无法连接特定端口的后端

Terminal window
# 查看 httpd 允许连接的端口
sudo semanage port -l | grep http_port
# 添加自定义端口
sudo semanage port -a -t http_port_t -p tcp 8000

Nginx 无法绑定非标准端口

Terminal window
# 允许 Nginx 监听自定义端口
sudo semanage port -a -t http_port_t -p tcp 8443
Terminal window
# 测试配置语法
sudo nginx -t
# 重载配置(不中断服务)
sudo systemctl reload nginx
# 查看活跃连接状态(需启用 stub_status 模块)
# 在某个 server block 中添加:
# location /nginx_status {
# stub_status on;
# allow 127.0.0.1;
# deny all;
# }
curl http://127.0.0.1/nginx_status
# 查看错误日志
sudo tail -f /var/log/nginx/error.log
# 查看访问日志
sudo tail -f /var/log/nginx/access.log

EL 10 AppStream 仓库中提供的 Nginx 版本已更新:

版本EL 9 系统仓库EL 10 系统仓库
Nginx1.22.x1.26.x

安装命令完全相同,EL 10 会自动安装对应版本:

Terminal window
sudo dnf install -y nginx
nginx -v # 确认版本

如需固定版本,参考软件包版本锁定