Nginx不能在端口80上监听两次?

4

编辑:首先阅读此内容:

除了接受的答案外,当nginx在没有systemd的情况下启动时会出现这些错误。杀死nginx:ps -ax | grep nginx→找到nginx主进程idkill ###;使用systemd运行nginx:systemctl start nginx

如果没有使用systemctl来启动nginx,则似乎无法使用systemctl stop nginx停止nginx(至少在我的服务器上不行);因此,在尝试第二次启动nginx时,systemctl restart nginx会出现此错误。

关于我的设置:

我使用Debian 10、Buster和一台在线服务器。我已经测试过两个域名,并且它们使用这些配置文件自己广播,但是当两个配置文件都活动时,它们并不广播。

我的目标:

如何在单个IP地址上使用nginx设置两个网站?

错误信息:

nginx:[emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/example.com:22第2行。

nginx:[emerg] a duplicate default server for 0.0.0.0:443 in /etc/nginx/sites-enabled/example.com:22第2行。default_server在端口443上使用。

nginx:[emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/example.com:23第3行。在一个文件中尝试了default_server作为http2,并使用端口443。

nginx:[emerg] duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/example.com:23第3行。在一个文件中尝试了default_server作为http2

nginx:[emerg]在/etc/nginx/sites-enabled/example.com:23中无效的参数“example.com”第3行:default_server作为example.com尝试。

配置文件(已剥离注释):

有两个这些文件(见下面的代码)。我的配置文件与下面的代码块中看到的完全相同,唯一的区别是:在两个文件中,example.com是我拥有的真实独特的域名。

我的配置文件存放在/etc/nginx/sites-available,它们是符号链接到/etc/nginx/sites-enabled

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /var/www/example.com; #example.com is different in both files.
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com; #example.com is different in both files.

    location / {
        try_files $uri $uri/ =404;
    }
}

主要不协调:

另一个stackoverflow问题建议重新编写这些行或注释其中之一。 重写要么不能解决错误,要么导致文件无法公开访问(example.com找不到)。

总结:

这个问题似乎是关于第2行、第3行或第2行和第3行的。

基本上,所有的指南都明确告诉读者使用上述代码-或-他们不提及这些行。


你想在同一个80端口上运行你的两个应用程序吗? - Parveen yadav
4个回答

7

当在listen指令中设置default_server标志时,nginx将使用该server块来为任何HTTP Host头与其他服务器块中的server_name不匹配(或请求根本没有Host头)的请求提供服务。您可以在任何特定IP:端口组合的参数作为listen指令的参数只设置一次default_server标志。但是,您可以在不同的IP:端口组合上多次使用此标志。

以下是一些示例,假设您的服务器有几个网络接口:

server {
    listen 1.2.3.4:80 default_server; # this will be default server block for any request coming to 1.2.3.4 IP address on port 80
    ...
}
server {
    listen 5.6.7.8:80 default_server; # this will be default server block for any request coming to 5.6.7.8 IP address on port 80
    ...
}
server {
    listen 80 default_server; # this will be default server block for any request coming to any other IP address (except 1.2.3.4 and 5.6.7.8) on port 80
    ...
}

工作示例:

通常情况下,当我需要在同一台服务器上提供多个站点时,我使用以下配置(当然这是简化的,现在我们通常使用HTTPS,并将http://example.com重定向到https://example.com):

站点1配置文件

server {
    listen 80;
    server_name example1.com www.example1.com;
    ...
}

网站2配置文件

server {
    listen 80;
    server_name example2.com www.example2.com;
    ...
}

默认服务器配置文件

server {
    listen 80 default_server;
    server_name _;
    return 444;
}

由于在listen指令上使用了default_server标志,当请求的Host头部不包含我的网站名称(或请求根本没有Host头)时,第三个服务器块将被使用。我不希望那些不知道他们正在访问哪个网站的访客出现(这些通常是端口扫描器、漏洞搜索器等),所以我为他们使用特殊的nginx 444代码(关闭连接并不返回任何响应)。


Ivan,你能否提供验证我的服务器是否支持多个网络接口以及如何启用它们的步骤? - Wolfpack'08
1
您可以使用ifconfig命令(或在现代Linux发行版中使用ip addr)查看所有配置的网络接口。但实际上,您只需要在DNS配置中指定的IP地址上为您的域名提供服务请求。我只是试图更详细地解释devault_server标志的行为,以便比其他答案更清楚地说明。 - Ivan Shatsky
是的,我使用了 ip link show 命令,并找到了以下内容: 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 - Wolfpack'08
@Wolfpack'08已经添加了default_server标志的另一个使用示例,请查看。 - Ivan Shatsky
我能补充一点内容吗,因为你的回答已被接受并会引起最多的关注?我意识到这个问题不完全与我们正在讨论的有关。 - Wolfpack'08
当然可以,如果你发现有值得添加的东西。 - Ivan Shatsky

3

正如错误信息所提示的那样,您不能在同一IP地址和端口上有两个默认监听器。请从一个或两个服务器块的listen声明中删除default_server

    listen 80;
    listen [::]:80 ipv6only=on;

Calum,你是否愿意提供有关默认服务器可以替换的信息?我还收到了错误信息,称“example.com”不是可接受的替换内容(请参见编辑)。 - Wolfpack'08
你不需要用任何东西替换它。default_server选项意味着对于那个ip:port组合的任何请求,如果没有匹配到你的任何一个server_name,都应该由这个监听器来处理。你不能使用两个监听器来实现这一点,因为nginx不知道该使用哪一个。 - Calum Halpin
Calum,但问题在于:example.com是server_name之一。因此,当我使用example.com时出现错误,这不会让人感到奇怪吗? - Wolfpack'08
1
不,你不应该将服务器名称放入listen指令中。这就是为什么会出现“nginx:[emerg] invalid parameter "example.com" in /etc/nginx/sites-enabled/example.com:23”的原因。请参见https://nginx.org/en/docs/http/ngx_http_core_module.html#listen。 - Calum Halpin
您已经使用了server_name指令来指定应该使用服务器块的服务器名称。 - Calum Halpin
Calumn,这就是我在寻找的内容:http://nginx.org/en/docs/http/ngx_http_core_module.html#listen。哇,太酷了。我们发布了同样的链接。 - Wolfpack'08

2

当我在一个IP上配置了三个主机名时,遇到了这个问题。

我使用的是免费的SSL证书,只能签署一个主机名。因此,我申请了三个SSL证书。

server {
    listen      443 backlog=50000;
    server_name example1.com;

server {
    listen       443;
    server_name  example2.com;

server {
    listen       443  backlog=50000;
    server_name  example3.com;

当我使用nginx -t测试配置文件时,它显示:

nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/conf.d/example1_https.conf:2

nginx: configuration file /etc/nginx/nginx.conf test failed

我通过从example3.com中删除backlog=50000来修复它。

有谁能解释为什么积压会造成这样的问题吗? - Nitesh chauhan

1
你不能在同一地址上使用相同的端口运行两个应用程序。
你需要做的就是将一个应用程序的端口更改为80,另一个应用程序的端口更改为其他端口,比如3000。
如果你只想让你的应用程序在80端口上运行,那么只需从默认文件中删除:
/etc/nginx/sites-available/default
和(可选):
/etc/nginx/sites-enabled/default
你可以运行:
sudo rm -rf /etc/nginx/sites-available/default
sudo rm -rf /etc/nginx/sites-enabled/default
现在你就可以在80端口上运行一个应用程序了。

我想在sites-enabled中保留默认文件的备份... 但是它已经从sites-available中删除了(如果从sites-enabled中删除它,我认为它没有影响)。实际上,在这种情况下,我可以在端口80上运行其中之一。 - Wolfpack'08
只是为了明确起见,nginx是唯一在端口80/443上的东西(尽管也许不应该出现两次)。除非有人在地址栏中键入example.com:3000(例如),否则端口80和端口443难道不是我可以用来广播网站的唯一端口吗? - Wolfpack'08
Wolfpack,我认为你混淆了sites-availablesites-enabledsites-enabled通常用于正在提供服务的站点。 - Calum Halpin
@Wolfpack'08 80端口用于HTTP,443端口用于HTTPS(带SSL证书) - Parveen yadav
那么,你目前遇到的问题是什么? - Parveen yadav
@Parveenyadav 我正在寻找类似教程的东西,可以发现如何使用其他端口(例如3000),并从同一服务器上为多个网站提供唯一域名的服务。老实说,我觉得甚至不需要使用不同的端口,而不需要要求用户进行额外的工作(即,在浏览器中键入www.example1.com:3000而不是www.example1.com)。 - Wolfpack'08

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接