[SRU] Allow NGINX to install but not start during postinst if another process is bound to port 80

Bug #1782226 reported by Thomas Ward on 2018-07-17
This bug affects 1 person
Affects Status Importance Assigned to Milestone
nginx (Ubuntu)
Status tracked in Cosmic
Thomas Ward

Bug Description

Currently, NGINX installations trigger an installation "failure case" when another process is bound to port 80 and NGINX is trying to use its default configuration files.

This can lead to installation bug reports which are not actually bugs, or having to alter configuration files before completing installations.

It might be better for postinst to determine if we actually need to start or restart the service based on if something is listening on port 80.

[Test Case]

1. Install haproxy (or apache2)
2. Configure it to bind to port 80 (apache2 will be automatically configured)
3. Install nginx
4. The installation will be broken as it will fail to install.

1. Do (1), (2) and (3) as above.
2. The installation will succeed. nginx won't auto start allowing it do install correctly even if you have haproxy binding on port 80.

[Regression Potential]
Minimal. This change won't break installation of nginx. In fact it will allow it to install if another daemon is binding to port 80.

Thomas Ward (teward) on 2018-07-17
Changed in nginx (Ubuntu):
assignee: nobody → Thomas Ward (teward)
Thomas Ward (teward) wrote :
Changed in nginx (Ubuntu):
status: Triaged → In Progress
Changed in nginx (Ubuntu Bionic):
status: New → Triaged
importance: Undecided → Wishlist
Andres Rodriguez (andreserl) wrote :

I've tested this twice with two different daemons binding to port 80, and seems to work as expected both times. I would imagine lsof is now a dependency?

Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
Setting up libjpeg-turbo8:amd64 (1.5.2-0ubuntu6) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
Processing triggers for systemd (237-3ubuntu10) ...
Setting up libnginx-mod-mail (1.14.0-0ubuntu2.1~lp1782226.6) ...
Setting up libxpm4:amd64 (1:3.5.12-1) ...
Processing triggers for man-db (2.8.4-2) ...
Setting up libnginx-mod-http-xslt-filter (1.14.0-0ubuntu2.1~lp1782226.6) ...
Setting up libnginx-mod-http-geoip (1.14.0-0ubuntu2.1~lp1782226.6) ...
Setting up libwebp6:amd64 (0.6.1-2) ...
Setting up libjpeg8:amd64 (8c-2ubuntu8) ...
Setting up fontconfig-config (2.12.6-0ubuntu2) ...
Setting up libnginx-mod-stream (1.14.0-0ubuntu2.1~lp1782226.6) ...
Setting up libtiff5:amd64 (4.0.9-6) ...
Setting up libfontconfig1:amd64 (2.12.6-0ubuntu2) ...
Setting up libgd3:amd64 (2.2.5-4) ...
Setting up libnginx-mod-http-image-filter (1.14.0-0ubuntu2.1~lp1782226.6) ...
Setting up nginx-core (1.14.0-0ubuntu2.1~lp1782226.6) ...
Not attempting to start NGINX, port 80 is already in use.
Processing triggers for ureadahead (0.100.0-20) ...
Processing triggers for ufw (0.35-6) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...

Thomas Ward (teward) wrote :

Yep, I will probably have to add the dependency before taking this and uploading it.

Simon Déziel (sdeziel) wrote :

I have not looked at the detection code but it might be possible to use "ss" instead of lsof to detect if anything listens on a given port. "ss" comes from iproute2 so it's more widely available.

  $ ss -nto state listening 'sport = 80'
  Recv-Q Send-Q Local Address:Port Peer Address:Port
  0 0 *:80 *:*
  0 0 :::80 :::*

I tried suppressing the header with "-H/--no-header" but ss segfaults but that's for another LP :)

Thomas Ward (teward) wrote :

sdeziel: Are we 100% certain that iproute2 is available on all releases of Ubuntu? I'm pretty sure `lsof` is in all the Ubuntu repos as well (in the Main pocket).

Further, while `ss` gets the information I need (with `ss -tunl 'sport = 80'), the detection code currently tests the lsof output to see if there's anything detected. If there isn't, then it attempts to start the NGINX service. If there is, then it assumes that Port 80 is in use. Even if -H worked in the latest versions, `-H` doesn't work (doesn't exist) for `ss` in older releases such as Xenial, so if we intend to eventually SRU this change into other releases so we can stop having a ton of "Not a bug" bugs filed against the NGINX package, it wouldn't work.

Whereas, the `lsof -i :80` command works and only outputs the listening sockets, and leaves an empty reply if there's no listening socket.

It's also nasty, it seems, to remove the header currently from `ss`, and since -H segfaults I'm not sure that's a viable option currently.

Thomas Ward (teward) wrote :

sdeziel provided `ss -nlt 'sport = 80' | grep -v ^State` which will help ignore the header of `ss`. From there, I've now pushed a newer version to the PPA which uses `ss` instead of `lsof`, and also applies this to all the nginx flavors rather than nginx-core.

I then realized I forgot to add the `Depends: iproute2` so I'll have to add that as well and push a build up.

Once it's built, more tests should be done to make sure that it still behaves as intended. If it does, then I'll work on prepping an upload to Cosmic for this. We can determine SRU worthiness for this after this lands in Cosmic.

Thomas Ward (teward) on 2018-08-19
Changed in nginx (Ubuntu Cosmic):
status: In Progress → Fix Committed
Simon Déziel (sdeziel) wrote :

I tested with 1.14.0-0ubuntu2.1~lp1782226.8 as well as 1.15.2-0ubuntu1 and both work well during installations/upgrades with or without something else binding TCPv4/80 or TCPv6/80. Thanks!

I'll proceed to create a package to SRU this into Bionic.


It seems the Cosmic upload is missing the dependencies in debian/control for iproute2

FWIW, after re-reading this conversation thread, I realized that the dependency got changed to iproute2 instead of lsof.

Note that from a personal standpoint, I would have preferred on depending on lsof provided that it provides a single binary, while iproute2 provides a set of binaries that are really not needed when installing nginx. AS such lsof would have provided a smaller dependency footprint.

summary: - Allow NGINX to install but not start during postinst if another process
- is bound to port 80
+ [SRU] Allow NGINX to install but not start during postinst if another
+ process is bound to port 80
description: updated

I'm attaching the debdiff between the bionic version and the fixed version.


Please review the debdiff and after your +1 I'll upload to the Ubuntu Archive!.

Thomas Ward (teward) wrote :

Andres, if it looks good I can upload it as well, but the Cosmic package needs to release too - the Perl autopkgtests are holding up Cosmic.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments