[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
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
nginx (Ubuntu)
Status tracked in Cosmic
Bionic
High
Andres Rodriguez
Cosmic
Wishlist
Thomas Ward

Bug Description

[Impact]
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]

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

Success
-------
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!

Andres Rodriguez (andreserl) wrote :

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

Andres Rodriguez (andreserl) wrote :

@Thomas,

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

Andres Rodriguez (andreserl) wrote :

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
Andres Rodriguez (andreserl) wrote :

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

Andres Rodriguez (andreserl) wrote :

@Thomas,

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.

On 2018-08-20 06:48 PM, Andres Rodriguez wrote:
> 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.

iproute2 is pulled by ubuntu-minimal so it's installed almost
everywhere. Depending on iproute2 should thus be almost free in terms of
footprint. That's specifically why I suggest to use ss :)

The Bionic debdiff looked good to me as well. This will surely payoff to
reduce the amount of invalid bugs so thanks!

Regards,
Simon

Andres Rodriguez (andreserl) wrote :

@Simon, that makes sense! Thanks!

@Thomas, thanks for uploading the fix to cosmic. I'll proceed with the SRU!

Changed in nginx (Ubuntu Bionic):
importance: Wishlist → High
status: Triaged → In Progress
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package nginx - 1.15.2-0ubuntu2

---------------
nginx (1.15.2-0ubuntu2) cosmic; urgency=medium

  * d/control: Add `iproute2` dependencies for the binary
    nginx-{core,light,full,extras} packages, they got missed in the
    application of the diff in 1.15.2-0ubuntu1. (LP: #1782226)

 -- Thomas Ward <email address hidden> Tue, 21 Aug 2018 12:07:59 -0400

Changed in nginx (Ubuntu Cosmic):
status: Fix Committed → Fix Released
Eric Desrochers (slashd) wrote :

Sponsored for Bionic.

I changed the version from "1.14.0-0ubuntu2" to "1.14.0-0ubuntu1.1" as I found "1.14.0-0ubuntu2" in Cosmic and prevent possible interference.

- Eric

Changed in nginx (Ubuntu Bionic):
assignee: nobody → Andres Rodriguez (andreserl)

Hello Thomas, or anyone else affected,

Accepted nginx into bionic-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/nginx/1.14.0-0ubuntu1.1 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed.Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-bionic to verification-done-bionic. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-bionic. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance!

Changed in nginx (Ubuntu Bionic):
status: In Progress → Fix Committed
tags: added: verification-needed verification-needed-bionic
Thomas Ward (teward) wrote :

Tested and confirmed working in Bionic.

tags: added: verification-done verification-done-bionic
removed: verification-needed verification-needed-bionic
Łukasz Zemczak (sil2100) wrote :

What version has been used for verification?

Thomas Ward (teward) wrote :

1.14.0-0ubuntu1.1.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package nginx - 1.14.0-0ubuntu1.1

---------------
nginx (1.14.0-0ubuntu1.1) bionic; urgency=medium

  * Stable Release Update. Do not attempt to start nginx if other daemon
    is binding to port 80, to prevent install failure (LP: #1782226):
    - d/nginx{core,light,full,extras}.postinst: Add checks for whether
      port 80 is in use or not to determine whether or not to attempt
      starting of the NGINX service during install/upgrade.
    - d/control: Add dependencies to nginx-{core,light,full,extras} on
      `iproute2` as the postinst scripts now use `ss` to determine if
      Port 80 is open or not.

 -- Andres Rodriguez <email address hidden> Mon, 20 Aug 2018 18:41:42 -0400

Changed in nginx (Ubuntu Bionic):
status: Fix Committed → Fix Released

The verification of the Stable Release Update for nginx has completed successfully and the package has now been released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

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

Other bug subscribers

Bug attachments