Ubuntu 16.04
sudo apt-get install python-certbot-nginx
nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/example.online:29
It should be no errors
server {
listen 80;
listen [::]:80;
server_name example.online;
root /home/example/deploy;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
listen [::]:80;
server_name www.example.online;
return 301 $scheme://example.online$request_uri;
}
@iamdubx did you figure this out? I'm having the same issue.
Same issue... It works for my default site, but not for custom sub domain
I'm having the same issue.
I do have a config to catch multiple domains though.
server {
listen 80;
listen [::]:80;
root /home/primarydomain/public;
index index.html index.htm;
server_name domain1.com *.domain1.com domain2.com *.domain2.com domain3.com *.domain3.com domain4.com *.domain4.com;
return 302 $scheme://primarydomain.com$request_uri;
access_log /var/log/nginx/others.access.log;
error_log /var/log/nginx/others.error.log;
location / {
try_files $uri $uri/ /index.html =404;
}
}
I get nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/others:19
for this config.
OS: Ubuntu 16.04. Any help?
Same problem.
I ran the command: certbot --redirect --nginx -d readacted.com -d www.redacted.com
my original conf file looks like:
server {
server_name redacted.com;
location / {
root /home/redacted/www;
index index.html;
}
}
server {
listen 80;
listen [::]:80;
server_name www.redacted.com;
return 301 $scheme://redacted.com$request_uri;
}
according to /var/log/letsencrypt/letsencrypt.log I see certbot is trying to do this:
server {
server_name redacted.com;
location / {
root /home/redacted/www;
index index.html;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/redacted.com-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/redacted.com-0001/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
listen 80;
listen [::]:80;
server_name www.redacted.com;
return 301 $scheme://redacted.com$request_uri;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.redacted.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.redacted.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
nginx complains that on the line listen [::]:443 ssl ipv6only=on; # managed by Certbot
the actual error message:
nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/redacted.com:23
a quick google brought up this page from 2010:
http://www.serverphorums.com/read.php?5,203912
which suggests that nginx gets confused due to some internal implementation detail.
I'm not an nginx expert, but I've tested that the following seems to work:
server {
server_name redacted.com;
location / {
root /home/redacted/www;
index index.html;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/redacted.com-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/redacted.com-0001/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
listen 80;
listen [::]:80;
server_name www.redacted.com;
return 301 http://redacted.com$request_uri;
listen [::]:443; # manually changed
ssl on; #manually changed
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.redacted.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.redacted.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
I'd love a better solution that this workaround ideally...
@ohemorange, do you know if we have an existing issue tracking this? It feels familiar to me but I don't remember whether or not it's something that we've looked into before.
I have never seen this before. Looks like they fixed the original bug, except when you're using IPv6. And since we just launched IPv6 support, that's why people are hitting this. The solution above will work; I'll see if there's a reason this hasn't been fixed in Nginx for IPv6 yet.
Actually, you don't even have to do the ssl on
change -- removing ipv6only=on
from either or both fixes the problem.
@joohoi, we probably want to fix this by either removing ipv6only=on
completely or only putting it in once per unique address line that we add. Do you have a sense of what would be best here?
Having the same issue here. Everything was fine for my first domain. The second domain started having these issues.
It looks like Certbot is unable to detect ipv6only directive completely for some reason. Removing that would fix the issue for most of the users. This can cause some issues with really old Nginx versions, as the behavior of ipv6only and the defaults have changed over the time.
Apologies for the nasty patch, but this fixed it for me, hopefully there will be a proper fix soon!
--- /usr/lib/python3/dist-packages/certbot_nginx/configurator.py.orig 2018-02-14 18:38:30.380863045 +0000
+++ /usr/lib/python3/dist-packages/certbot_nginx/configurator.py 2018-02-14 18:38:01.501018553 +0000
@@ -507,10 +507,10 @@ class NginxConfigurator(common.Installer
'[::]:{0}'.format(self.config.tls_sni_01_port),
' ',
'ssl']
- if not ipv6info[1]:
- # ipv6only=on is absent in global config
- ipv6_block.append(' ')
- ipv6_block.append('ipv6only=on')
+ #if not ipv6info[1]:
+ # # ipv6only=on is absent in global config
+ # ipv6_block.append(' ')
+ # ipv6_block.append('ipv6only=on')
if vhost.ipv4_enabled():
ipv4_block = ['\n ',
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial
$ nginx -V
nginx version: nginx/1.10.3 (Ubuntu)
built with OpenSSL 1.0.2g 1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads
$ apt show python-certbot-nginx
Package: python-certbot-nginx
Version: 0.21.1-1+ubuntu16.04.1+certbot+1
Priority: optional
Section: oldlibs
Maintainer: Debian Let's Encrypt <[email protected]>
Installed-Size: 9,216 B
Depends: python3-certbot-nginx
Download-Size: 2,470 B
APT-Manual-Installed: yes
APT-Sources: http://ppa.launchpad.net/certbot/certbot/ubuntu xenial/main amd64 Packages
Description: transitional dummy package
This is a transitional dummy package for the migration of certbot
from python2 to python3. It can be safely removed.
Same issue. Will this be addressed?
Sorry for the wall of text, but here we go.
To shed some light on the issue:
ipv6only option is used to be able to handle multiple listen statements per socket. Unfortunately it can only be used once in the server configuration for the socket. So Nginx will fail to start in case of:
server {
...
server_name first.example.org;
listen [::]:80 ipv6only=on;
listen 80;
}
server {
...
server_name second.example.org;
listen [::]:80 ipv6only=on;
listen 80;
}
With the recent versions of Nginx this problem does not exist if the ipv6only
setting is omitted completely, as the default value of the variable is ipv6only=on
. So the following is valid and working configuration in Nginx versions >= 1.3.4:
server {
...
server_name first.example.org;
listen [::]:80;
listen 80;
}
server {
...
server_name second.example.org;
listen [::]:80;
listen 80;
}
However the default value of ipv6only
variable in Nginx versions prior to 1.3.4 was ipv6only=off
, so older versions will fail with the following configuration:
server {
...
server_name first.example.org;
listen [::]:80;
listen 80;
}
Currently the situation with distribution packaging is that the only distribution that ships with older version of Nginx would be Debian Wheezy (Debian 7), which ships version 1.2.1 of Nginx from the default repositories.
If we would remove the ipv6only
detection and setting completely from Certbot, this would break for all users on Debian Wheezy. Fortunately EOL date for Wheezy is set for May 2018, so we're close to being able to remove this additional complexity from Certbot code altogether.
The current functionality of Certbot is parsing the complete Nginx configuration, detecting ipv6only=on
setting already present in one of the server{}
blocks and omitting addition of it if so. If however the value was not found, Certbot would then add it. This issue boils down to Certbot not being able to detect this already existing variable from some block of the users current configuration, and hence tries to add it to the server{}
block that's being configured.
To make decision of the route to fix this issue, we'd need a complete example configuration where Certbot fails in the way described above to be able to improve the detection of an already existing ipv6only=on
variable if we decide to fix it that way instead of removing this functionality altogether.
Thanks for the patch; that worked for me. FWIW, I'm on Ubuntu 17.
I had to remove all the
listen [::]:80;
listen 80;
To make it work
https://github.com/chilion - thanks! removing:
listen [::]:80;
listen 80;
worked for me as well.
I have two domains on one Ubuntu server. The first one worked no problem. Then I got the error as above. Your solution worked for me. I just installed nginx on a fresh server with fresh everything.
Thank you.
removing listen [::]:80
but leaving listen 80;
worked for me for installation on non-default domain
I comment listen [::]:443 in the subdomain setting, then it works. Is it okay
I just bumped into this issue. Any body trying to make sense of the the different listen
directives and ipv6only
.
I highly recommend this blog post, until I found this article I was not sure what do with all the different advice I was finding on the web.
https://stefanchrist.eu/blog/2015_01_21/Using%20ipv6only%20in%20Nginx.xhtml
This quote from the blog post was the light-bulb moment for me.
The parameter is different from e.g. the ssl flag. The flag ssl can be used in multiple server contexts and be switch on and off as you wish. The flag ipv6only can only be set once per port (and address). Only a single listen directive my contain the parameter and it will be valid for all server contexts using this port. If you use it twice, the nginx daemon won't start and will write the following error messages to his error log
Still exists, after purge python, reinstall this error thrown. Error somewhere in certbot
Commenting this line solves error, but creates other issues
server {
listen 443 ssl http2;
# listen [::]:443 ssl http2 ipv6only=on;
In case of multiple domains
Instead of
listen [::]:443 ssl http2 ipv6only=on;
Use
listen example.com:443 ssl http2 ipv6only=on;
Omit the listen
directive in all your server blocks.
This error shows up when there are two server blocks listening on the same domain with the same port.
Check all your configuration files in the sites-available folder for the duplicate listener. In my case certbot created duplicate a listener for 443 in the default file.
If you can provide configuration files to reproduce this with an up-to-date version of Certbot, I'd be interested to see them.
For the adventurers that may hit this ticket in the future via a lonesome search, and they can't figure why this happens when they don't have ipv6only=on
anywhere else.
You will get the same error/issue if you have reuseport
in your config.
I will admit, I am confused. According to the nginx documentation, there's a number of parameters for listen
, but only ipv6only
specifies "It can only be set once on start." Is this line just missing from the remaining parameters? Is it system-dependent? I'm starting to think that fixing this behavior in upstream might be the best course of action; it seems silly to only allow these options to be set once, anyway.
I'm unfortunately not an expert in linux sockets, so I can't form a proper opinion why those options can only be set once, but I'm sure there's a reason.
Maybe this post helps: https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/
What I do know is that, just like ipv6only
, reuseport
can also only be set once per a specific port (so only one listener can have it). Why this incidentally conflicts (for the lack of a better word) with ipv6only
, I have no clue.
Still, I feel like adding ipv6only=on
when running certbot is a bit futile.
It's no longer needed since nginx 1.3.4, which has been released in 2012, and it's technically EOL.
At very least, maybe there should be a version check and only add if it nginx < 1.3.4
before adding it.
We don't set it in Certbot. When we create a server block, we copy some directives from the existing default server block, or other template server block, including the listen directive along with its options. This lets Certbot work even if Nginx is behind a proxy or other type of port forwarding. We explicitly delete ipv6only=on
from the duplicated server block because the documentation indicates it can only be used once.
Ideally, we would do the same for all options that we know can't be duplicated in this way, but leave other options that the user might specifically want all their server blocks to have. To do that, we have to know which options are repeatable, which the documentation does not seem to indicate, and which we only seem to discover through people coming to us on issues like this one.
Thanks @joohoi
Your explanation & solution worked for me on Ubuntu 20 with nginx version: 1.18.0
I have 2 VPS: 1 is Ubuntu runs Nginx 1.10 works fine, the other is Centos runs Nginx 1.16 and has this error. Weird
Most helpful comment
Same problem.
I ran the command:
certbot --redirect --nginx -d readacted.com -d www.redacted.com
my original conf file looks like:
according to /var/log/letsencrypt/letsencrypt.log I see certbot is trying to do this:
nginx complains that on the line
listen [::]:443 ssl ipv6only=on; # managed by Certbot
the actual error message:
nginx: [emerg] duplicate listen options for [::]:443 in /etc/nginx/sites-enabled/redacted.com:23
a quick google brought up this page from 2010:
http://www.serverphorums.com/read.php?5,203912
which suggests that nginx gets confused due to some internal implementation detail.
I'm not an nginx expert, but I've tested that the following seems to work:
I'd love a better solution that this workaround ideally...