LPIC-1 101-500 study materials
LPIC-1 101-500 study resources

Keeping a certified nginx version on an Ubuntu host

LPIC-1 101-500 · Put your knowledge to work in context.

All case studies

Keeping a certified nginx version on an Ubuntu host

An Ubuntu 20.04 server runs a certified application that supports only nginx 1.18, the version shipped in focal-updates. To experiment with HTTP/3 an admin added the nginx.org repository and its signing key to /etc/apt/sources.list.d/. Two weeks later, apt-get -s dist-upgrade lists nginx 1.25.x plus a vendor libssl1.1 build that would replace Ubuntu's. The security team still requires the monthly openssl, openssh and libc6 updates. The admin runs apt-mark hold nginx and reports the host as fixed; nobody has removed the vendor source, because 'we might still want HTTP/3 later'. A leftover /etc/apt/preferences.d file from an earlier project pins the docker-ce repository at priority -1.

1. Does `apt-mark hold nginx` guarantee nginx stays at 1.18? State what it protects against and what it does not, specifically on this host.

Read the worked answer

A hold pins the installed version of that one package: apt will not upgrade, downgrade or automatically remove it. It is not a version selector and it is not package-set aware.

What it fails to cover here:

  • Split packages. Ubuntu's nginx is a metapackage over nginx-common and nginx-core. Holding only nginx leaves nginx-common free to move to the vendor version, after which the held metapackage's dependencies no longer line up and apt starts proposing removals. Hold the whole set: apt-mark hold nginx nginx-common nginx-core.
  • The libssl1.1 swap. That is a different package with its own dependencies; a hold on nginx does not touch it. Replacing the system's libcrypto underneath openssh and every other TLS consumer is the actual risk on this host, and it is unaddressed.
  • Security updates for nginx itself. When Ubuntu issues an advisory for 1.18, the hold blocks it silently. A hold is a decision with an expiry date; record one and review with apt-mark showhold.
  • Visibility. Holds live in dpkg's selection state; apt-mark showhold or dpkg --get-selections | grep hold shows them, but nothing on disk explains why. Another admin will find the state and guess.

So: better than nothing, insufficient as the fix.

2. Write a configuration that keeps nginx at 1.18 while leaving openssl/openssh free to update, and describe how you verify it without changing the system. Is there a simpler option given the facts?

Read the worked answer

Version pin, in /etc/apt/preferences.d/nginx-stay.pref:

Package: nginx nginx-common nginx-core
Pin: version 1.18.0-0ubuntu1*
Pin-Priority: 1001

1001 is above 1000, so this is a forced version: it wins over any newer version in any repository and even permits a downgrade if 1.25 has already been installed. A priority of 990 would only make 1.18 preferred, and a manual apt install nginx could still pull 1.25.

Verify read-only first:

apt-cache policy nginx          # candidate should be 1.18.0-0ubuntu1.x at 1001
apt-get -s dist-upgrade         # no nginx line; libssl1.1 still from Ubuntu
apt list --upgradable

Simpler option: the vendor repository exists only for an experiment nobody has approved. Pin: origin nginx.org with Pin-Priority: -1 disables that origin for every package it ships, one stanza, covering nginx and the vendor libssl1.1 in a single decision. That is the better call here - it removes the failure mode instead of negotiating with it - and the leftover docker-ce pin at -1 shows the team already uses this pattern. Trade-off: a -1 origin pin means anyone who later needs that repo must edit a file that reads like a ban, so comment it with the reason and the expiry date.

3. A colleague side-loads nginx_1.18.0-0ubuntu1.4_amd64.deb with `dpkg -i`, and `dpkg -l nginx` shows status iU. Explain the state and give the safe repair path.

Read the worked answer

dpkg -l columns are desired-state and current-state. iU = install requested, currently unpacked but not configured: files are on disk, maintainer scripts have not completed, because dpkg -i performs no dependency resolution and something the package needs is missing or the wrong version.

Why the obvious repair is dangerous here: apt-get -f install (or apt --fix-broken install) resolves the missing dependencies from the configured sources. With the nginx.org repo enabled, the vendor libssl1.1 is a legal answer, so you can 'fix' the broken nginx and silently swap the system crypto library - exactly the outcome the whole exercise was meant to prevent.

Safe path:

  1. Disable the vendor source (comment the list file) or set the origin pin first.
  2. apt-get update.
  3. apt-get -f install, then dpkg --configure -a for anything left half-configured.
  4. Confirm: dpkg -l | grep -v '^ii' should show no iU/iF entries, and apt-cache policy libssl1.1 should still show the Ubuntu version as installed and candidate.

Note also that a force-installed 1.18 side-load can conflict with the distro's nginx-common files; if dpkg reported file overwrites, verify with dpkg -S before declaring the host fixed.