15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用
09.10.2024

如何配置 Nginx 监听多个端口

Nginx可以通过在其配置中的一个或多个`server`块内添加多个`listen`指令来同时监听多个端口。每个`listen`指令将Nginx绑定到特定的IP/端口组合,使单个服务器实例能够在不同端口上处理HTTP、HTTPS和自定义应用程序流量,而无需运行单独的进程。

此功能对于多租户环境、预发布/生产端口分离、反向代理架构和微服务路由至关重要——所有这些都可以从单个VPS Hosting实例实现。

前提条件

在继续之前,请确认以下内容:

  • Nginx已安装且服务处于活动状态(`systemctl status nginx`)
  • 您在服务器上拥有`root`或`sudo`权限
  • 您了解`/etc/nginx/nginx.conf`(全局配置)和`/etc/nginx/sites-available/`(每站点配置块)之间的区别
  • 防火墙规则(`ufw`、`iptables`或云安全组)允许您打算开放的端口上的流量
  • 如果配置HTTPS端口,则需要有效的SSL证书(自签名或CA颁发)

Nginx配置架构:您需要首先了解的内容

Nginx使用分层配置模型:`http`上下文包含一个或多个`server`块,每个块可以包含一个或多个`listen`指令。了解此层次结构可以防止最常见的配置错误。

涉及的关键指令:

  • `listen [address:]port [ssl] [http2] [default_server]` — 将服务器块绑定到特定端口和可选IP
  • `server_name` — 匹配`Host`头以将请求路由到正确的块
  • `default_server` — 指定哪个服务器块处理与其他`server_name`不匹配的请求

按发行版划分的配置文件位置:

发行版主配置站点配置
Ubuntu / Debian`/etc/nginx/nginx.conf``/etc/nginx/sites-available/`
CentOS / RHEL / AlmaLinux`/etc/nginx/nginx.conf``/etc/nginx/conf.d/`
Arch Linux`/etc/nginx/nginx.conf``/etc/nginx/sites-available/`
Docker(官方镜像)`/etc/nginx/nginx.conf``/etc/nginx/conf.d/`

在基于Debian的系统上,`sites-available/`中的文件必须符号链接到`sites-enabled/`才能生效:

“`bash

sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/

“`

步骤1:打开Nginx配置文件

对于影响所有虚拟主机的全局更改:

“`bash

sudo nano /etc/nginx/nginx.conf

“`

对于特定站点的配置(推荐用于生产环境):

“`bash

sudo nano /etc/nginx/sites-available/example.conf

“`

强烈建议使用特定站点的文件。它可以隔离更改、简化回滚,并防止单个配置错误导致所有托管服务停止运行。

步骤2:在单个服务器块中配置多个listen指令

最简单的多端口设置是将一个服务器块绑定到多个端口。无论客户端通过哪个端口连接,Nginx都将应用相同的路由逻辑。

“`nginx

server {

listen 80;

listen 8080;

server_name example.com;

root /var/www/html;

index index.html index.htm;

location / {

try_files $uri $uri/ =404;

}

access_log /var/log/nginx/example_access.log;

error_log /var/log/nginx/example_error.log warn;

}

“`

此配置的作用:

  • `listen 80;` — 接受标准HTTP流量
  • `listen 8080;` — 接受备用HTTP端口上的流量(常用于开发环境、内部API或负载均衡器健康检查)
  • 两个端口均从`/var/www/html`提供相同的内容

边缘情况——绑定到特定IP地址:在具有多个网络接口的服务器上(例如,公共IP和私有LAN IP),您可以限制Nginx监听的接口:

“`nginx

listen 192.168.1.10:8080;

listen 0.0.0.0:80;

“`

这在多宿主服务器配置中至关重要,可防止内部服务意外暴露于公共网络。

步骤3:在多个端口上配置HTTPS

HTTPS需要在`listen`指令上添加`ssl`参数以及有效的证书/密钥路径。以下示例将HTTPS绑定到标准端口443和自定义端口8443:

“`nginx

server {

listen 443 ssl;

listen 8443 ssl;

server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;

ssl_certificate_key /etc/nginx/ssl/example.com.key;

Modern TLS hardening

ssl_protocols TLSv1.2 TLSv1.3;

ssl_ciphers HIGH:!aNULL:!MD5;

ssl_prefer_server_ciphers on;

ssl_session_cache shared:SSL:10m;

ssl_session_timeout 10m;

root /var/www/html;

index index.html;

location / {

try_files $uri $uri/ =404;

}

}

“`

端口8443常用的原因:

  • 允许在上游防火墙阻止端口443的环境中传输HTTPS流量
  • 用于开发/预发布环境,在不与443上的生产服务冲突的情况下运行安全服务器
  • 某些应用程序框架(Tomcat、Node.js代理)需要在非标准端口上公开HTTPS

重要注意事项:省略`ssl_protocols`和`ssl_ciphers`会导致Nginx使用可能较弱的默认值。始终明确定义TLS参数,尤其是在处理敏感数据的服务器上。如果您需要受信任的证书而不是自签名证书,来自受认可CA的SSL Certificates可以消除浏览器警告并满足现代HSTS要求。

步骤4:在不同端口上提供不同内容

当端口必须服务于不同的应用程序时——例如,端口80上的公共网站和端口8080上的内部管理面板——使用单独的`server`块:

“`nginx

server {

listen 80;

server_name example.com;

root /var/www/public;

index index.html;

location / {

try_files $uri $uri/ =404;

}

}

server {

listen 8080;

server_name example.com;

root /var/www/admin;

index index.html;

Restrict admin panel to internal network only

location / {

allow 10.0.0.0/8;

allow 192.168.0.0/16;

deny all;

try_files $uri $uri/ =404;

}

}

“`

基于端口的内容分离的实际使用场景:

  • 端口80/443:面向公众的网站
  • 端口8080:内部REST API或微服务端点
  • 端口8443:受IP白名单限制的安全管理仪表板
  • 端口9000:Prometheus抓取的指标端点(从不公开暴露)
  • 端口3000/5000:反向代理到Node.js或Python应用程序

步骤5:将Nginx用作多端口反向代理

一种常见的生产模式是使用Nginx将不同端口代理到不同的后端应用程序服务器:

“`nginx

server {

listen 80;

server_name app.example.com;

location / {

proxy_pass http://127.0.0.1:3000;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection 'upgrade';

proxy_set_header Host $host;

proxy_cache_bypass $http_upgrade;

}

}

server {

listen 8080;

server_name app.example.com;

location / {

proxy_pass http://127.0.0.1:4000;

proxy_http_version 1.1;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

“`

此模式是Dedicated Server上容器化部署的基础,其中多个Docker容器在不同的内部端口上运行,Nginx充当单一外部入口点。

步骤6:验证配置

在重启Nginx之前,务必先测试配置语法。语法错误将导致服务无法重新加载,从而使所有托管站点停止运行。

“`bash

sudo nginx -t

“`

成功时的预期输出:

“`

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

“`

如果出现错误,输出将指定文件和行号。在继续之前修复所有报告的问题。

对于零停机重新加载(在生产环境中优于完全重启):

“`bash

sudo systemctl reload nginx

“`

只有在更改`worker_processes`、`user`或其他主进程级指令时才需要完全重启:

“`bash

sudo systemctl restart nginx

“`

步骤7:验证Nginx是否在正确的端口上监听

应用配置后,使用`ss`(优于已弃用的`netstat`)确认Nginx已绑定到预期端口:

“`bash

sudo ss -tlnp | grep nginx

“`

示例输出:

“`

LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))

LISTEN 0 511 0.0.0.0:8080 0.0.0.0:* users:(("nginx",pid=1234,fd=7))

LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=8))

LISTEN 0 511 0.0.0.0:8443 0.0.0.0:* users:(("nginx",pid=1234,fd=9))

“`

如果某个端口未出现,请检查:

  1. 配置文件中的`listen`指令语法
  2. 是否有其他进程已占用该端口:`sudo ss -tlnp | grep :8080`
  3. `nginx -t`是否通过且无错误
  4. 可能阻止非标准端口绑定的SELinux或AppArmor策略

从命令行使用curl进行测试(比浏览器更可靠用于调试):

“`bash

curl -I http://example.com

curl -I http://example.com:8080

curl -Ik https://example.com

curl -Ik https://example.com:8443

“`

`-I`标志仅获取头信息。`200 OK`或`301 Moved Permanently`响应确认端口处于活动状态且Nginx正在正确响应。

步骤8:开放防火墙端口

如果主机防火墙阻止传入连接,则在Nginx中监听端口是不够的。确保端口被允许:

UFW(Ubuntu/Debian):

“`bash

sudo ufw allow 80/tcp

sudo ufw allow 443/tcp

sudo ufw allow 8080/tcp

sudo ufw allow 8443/tcp

sudo ufw reload

“`

firewalld(CentOS/RHEL/AlmaLinux):

“`bash

sudo firewall-cmd –permanent –add-port=8080/tcp

sudo firewall-cmd –permanent –add-port=8443/tcp

sudo firewall-cmd –reload

“`

iptables(直接):

“`bash

sudo iptables -A INPUT -p tcp –dport 8080 -j ACCEPT

sudo iptables -A INPUT -p tcp –dport 8443 -j ACCEPT

“`

在云基础设施(AWS EC2、DigitalOcean、Hetzner)上,您还必须在提供商级别更新安全组或云防火墙规则——仅更改主机级防火墙是不够的。

比较:单端口与多端口Nginx配置

功能单端口多端口(同一块)多端口(独立块)
配置复杂度
内容隔离完全
每端口访问控制不适用不可能完全支持
使用场景简单网站开发/预发布镜像微服务、管理面板
每端口反向代理单一上游单一上游独立上游
SSL终止每块共享证书每块独立证书
日志分离单一日志单一日志每端口日志文件

常见陷阱及如何避免

与现有服务的端口冲突:端口80可能已被Apache占用。在配置之前运行`sudo ss -tlnp | grep :80`。停止冲突的服务或将其重新配置为使用不同的端口。

`default_server`冲突:如果多个服务器块省略了`default_server`,或者多个块为同一端口声明了它,Nginx将按文件顺序使用第一个块。请明确指定:

“`nginx

listen 80 default_server;

“`

未覆盖IPv6:添加`listen 80;`仅绑定到IPv4。对于双栈服务器,请添加:

“`nginx

listen [::]:80;

listen [::]:8080;

“`

SELinux阻止非标准端口:在启用SELinux强制模式的RHEL/CentOS上,Nginx无法绑定到其策略中未包含的端口,除非获得明确许可:

“`bash

sudo semanage port -a -t http_port_t -p tcp 8080

sudo semanage port -a -t http_port_t -p tcp 8443

“`

更改后忘记重新加载:配置编辑在Nginx重新加载之前不会生效。在CI/CD管道中通过部署后的`nginx -t && systemctl reload nginx`步骤自动执行此操作。

实用决策矩阵

使用此清单确定适合您场景的多端口配置模式:

  • 相同内容,多个端口 — 在单个`server`块中使用多个`listen`指令
  • 每个端口不同内容 — 使用具有不同`root`目录的独立`server`块
  • 每个端口不同后端应用程序 — 使用独立的`server`块,其中`proxy_pass`指向不同的上游地址
  • 保护非标准端口 — 将`ssl`添加到`listen`指令并引用您的证书路径;确保证书的SAN涵盖该域名
  • 将端口限制为内部流量 — 添加`allow`/`deny`指令或仅将`listen`绑定到私有IP
  • VPS with cPanel上运行 — 验证cPanel内置的Apache/Nginx配置不会产生冲突;使用cPanel的”Include Editor”或专用Nginx配置插入目录
  • 管理多个控制面板选项 — 查看可用的VPS Control Panels,找到通过GUI公开Nginx端口管理的控制面板

常见问题

Nginx可以在多个服务器块上监听同一端口吗?

可以。多个`server`块可以共享同一端口。Nginx使用`server_name`指令来区分它们,该指令匹配HTTP `Host`头。如果没有匹配的`server_name`,则由`default_server`块处理请求。

添加更多监听端口会影响Nginx性能吗?

开销可以忽略不计。每个`listen`指令向Nginx主进程添加一个文件描述符。实际限制是系统的打开文件描述符上限(`ulimit -n`),而不是端口数量。对于高流量部署,请在`nginx.conf`中调整`worker_rlimit_nofile`和`worker_connections`。

如何将所有流量从端口8080重定向到端口80?

使用带有`return`指令的专用服务器块:

“`nginx

server {

listen 8080;

server_name example.com;

return 301 http://example.com$request_uri;

}

“`

为什么即使配置看起来正确,Nginx也没有在某个端口上监听?

四个最常见的原因是:(1)编辑后配置未重新加载,(2)另一个进程已绑定到该端口,(3)防火墙规则阻止了该端口,或(4)SELinux/AppArmor阻止了绑定。使用`ss -tlnp`、`nginx -t`和防火墙状态命令系统地排查每个原因。

我可以为同一域名的不同HTTPS端口使用不同的SSL证书吗?

可以。每个`server`块都有自己的`ssl_certificate`和`ssl_certificate_key`指令。两个服务器块可以分别监听端口443和8443,并引用完全不同的证书文件,即使对于同一个`server_name`也是如此。这在轮换证书或在过渡期间同时运行旧证书和新证书时非常有用。

15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用