4

Edit: Read this, first:

Apart from the accepted answer, these errors occur when nginx is started without systemd. Kill nginx: ps -ax | grep nginx → find the nginx master pidkill ###; run nginx with systemd: systemctl start nginx.

If systemctl is not used to start nginx, systemctl stop nginx doesn't seem to work (at least on my server); so, systemctl restart nginx gives this error when it tries to start nginx a second time.

About my setup:

I'm on Debian 10, Buster, with a live server. I have tested both domain names, and they broadcast by themselves using these config files, but they do not broadcast when both config files are active.

What I'm trying to accomplish:

How do I set up two websites on a single ip address using nginx?

Error message(s):

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

nginx: [emerg] a duplicate default server for 0.0.0.0:443 in /etc/nginx/sites-enabled/example.com:22 line 2. default_server is used on port 443.

nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/example.com:23 line 3. default_server tried as http2 in one file and port 443 is used.

nginx: [emerg] duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/example.com:23 line 3. default_server tried as http2 in one file.

nginx: [emerg] invalid parameter "example.com" in /etc/nginx/sites-enabled/example.com:23 line 3: default_server tried as example.com

Config files (comments stripped):

There are two of these files (code seen below). My config files are exactly as-seen in the code block below with only one difference: in both files, example.com is a real, unique domain name that I own.

My config files live in /etc/nginx/sites-available, and they are symlinked to /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;
    }
}

Primary dissonance:

Another stack question says to rewrite these lines or comment one of them out. The rewrites either do not resolve the error or result in a situation where files are not publicly served (example.com goes nowhere).

Summary:

This question seems to be about line 2, line 3, or line 2 and 3.

Essentially, all of the leading how-to's either expressly tell the reader to use the code above -or- they don't mention these lines.

Wolfpack'08
  • 3,982
  • 11
  • 46
  • 78

4 Answers4

6

When you specify default_server flag on a listen directive, nginx will use that server block to serve any request where HTTP Host header does not match the server_name in any other server blocks (or the request missing Host header at all). You can use default_server flag on any particular IP:port combination given as parameter of listen directive only once. But you can use this flag several times on different IP:port combinations.

Some examples, assuming your server have several network interfaces:

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
    ...
}

Working example:

Typically, when I need to serve several sites on the same server, I use the following configuration (of course this is simplified, nowadays we typically use HTTPS with http://example.com to https://example.com redirection):

Site 1 config file

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

Site 2 config file

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

Default server config file

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

Because of default_server flag on listen directive third server block is used when the request's Host header doesn't contain one of my sites names (or the request does not have Host header at all). I don't expect visitors that doesn't know what site they are visiting (these are typically port scanners, vulnerability searchers etc.), so I use special nginx 444 code (close connection without any response) for them.

Ivan Shatsky
  • 13,267
  • 2
  • 21
  • 37
  • Ivan, would you be willing to post steps to verify if my server is capable of multiple network interfaces and how to enable them if-capable? – Wolfpack'08 Feb 23 '20 at 13:50
  • 1
    You can view all configured network interfaces with `ifconfig` command (or `ip addr` in modern linux distributions). But in fact you need to serve requests only on IP address specified for your domain in your DNS configuration. I'm just try to explain `devault_server` flag behavior in more details that the other answers does. – Ivan Shatsky Feb 23 '20 at 13:56
  • Yes, I used `ip link show` and found `2: ens3: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000` – Wolfpack'08 Feb 23 '20 at 13:58
  • @Wolfpack'08 Added another example of `default_server` flag usage, take a look. – Ivan Shatsky Feb 23 '20 at 14:25
  • Can I supplement your answer with one addition because your answer is accepted and will draw the most attention? I realized the issue is not entirely related to what we are talking about, here. – Wolfpack'08 Feb 25 '20 at 03:13
  • Of course you can if you found something worth to add. – Ivan Shatsky Feb 25 '20 at 03:43
3

As the error message suggests, you can't have two default listeners on the same IP address and port. Remove default_server from the listen declarations in one or both of your server blocks.

    listen 80;
    listen [::]:80 ipv6only=on;
Calum Halpin
  • 1,945
  • 1
  • 10
  • 20
  • Calum, would you be willing to add info about what replacements are acceptable for default_server? I also got errors saying that `example.com` wasn't an acceptable replacement (see edit). – Wolfpack'08 Feb 23 '20 at 13:52
  • You don't need to replace it with anything. The `default_server` option means that any requests to that ip:port pair that don't match one of your `server_name`s should be served by this listener. You can't do that with two listeners because nginx wouldn't know which to use. – Calum Halpin Feb 23 '20 at 13:58
  • Calum, but here's the thing: example.com is one of the `server_name`'s. So, doesn't it come off as odd that I get an error when using `example.com`? – Wolfpack'08 Feb 23 '20 at 14:00
  • 1
    No, you don't put your server name into the listen directive. That's why you're getting "nginx: [emerg] invalid parameter "example.com" in /etc/nginx/sites-enabled/example.com:23". See https://nginx.org/en/docs/http/ngx_http_core_module.html#listen. – Calum Halpin Feb 23 '20 at 14:03
  • You specify the server name that the server block should be used for with the `server_name` directive, as you already have. – Calum Halpin Feb 23 '20 at 14:05
  • Calumn, this is what I was looking for: http://nginx.org/en/docs/http/ngx_http_core_module.html#listen. Whoa, cool. We posted the same link. – Wolfpack'08 Feb 23 '20 at 14:14
2

I came to this issue when I config three host name on one IP.

I use a free ssl cercificate which can only sign on one hostname. So I apply three ssl certificates.

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;

When I use nginx -t to test the config file, it shows

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

I fixed it by remove the backlog=50000 from the example3.com

LF00
  • 27,015
  • 29
  • 156
  • 295
1

You can't run two applications on the same address with the same port.

What you need to do is just change port of your application one with 80 and other application with some other port say 3000.

If you want your application to run only with 80 port than just remove the default file from

/etc/nginx/sites-available/default

and optionally also from

/etc/nginx/sites-enabled/default

You can run

sudo rm -rf /etc/nginx/sites-available/default

sudo rm -rf /etc/nginx/sites-enabled/default

Now you will be able to run one of your application on port 80

Wolfpack'08
  • 3,982
  • 11
  • 46
  • 78
Parveen yadav
  • 2,252
  • 1
  • 21
  • 35
  • I'd like to keep a backup of the default file in sites-enabled.... But it is removed from sites-available (I think it has no effect if it's removed from sites-enabled). I can run one of them on port 80, indeed, in this situation. – Wolfpack'08 Feb 23 '20 at 13:45
  • Just to be clear, nginx is the only thing on port 80/443 (though perhaps it shouldn't be there twice). Aren't port 80 and port 443 the only ports I can use to broadcast a website unless someone types example.com:3000 (for example) into their address bar? – Wolfpack'08 Feb 23 '20 at 13:54
  • Wolfpack, I think you've confused `sites-available` and `sites-enabled`. `sites-enabled` is conventionally used for sites which are being served. – Calum Halpin Feb 23 '20 at 14:01
  • @Wolfpack'08 80 port is for HTTP and 443 for https (with SSL certificates) – Parveen yadav Feb 23 '20 at 14:41
  • so whats the current problem you are facing? – Parveen yadav Feb 23 '20 at 14:42
  • @Parveenyadav I'm looking for something like a tutorial where I can discover how to use other ports (such as 3000) and server multiple websites with unique domain names from the same server. Honestly, I feel like it shouldn't even be necessary to use different ports without requiring extra work from the user (i.e., typing www.example1.com:3000 into the browser rather than www.example1.com). – Wolfpack'08 Feb 24 '20 at 03:17