Using policy-rc.d to Stop Services in Debian Chroot
This article provides an overview of the policy-rc.d
mechanism in Debian-based operating systems and demonstrates how to use
it to block services from starting automatically within chroot
environments, image builds, and container setups.
What Is policy-rc.d?
In Debian and its derivatives, package maintainer scripts do not
invoke init scripts or systemd units directly during installation or
upgrade. Instead, they call a wrapper script named
invoke-rc.d.
Before invoke-rc.d executes any action—such as
start, stop, or restart—it checks
for the existence of /usr/sbin/policy-rc.d. If this file is
present and executable, invoke-rc.d executes it with the
target service name and requested action as arguments to query whether
the operation is permitted.
Why Block Services in a Chroot?
When you install packages via apt or dpkg
inside a chroot (or during a debootstrap process, Docker
build, or VM image creation), Debian defaults to starting newly
installed daemons immediately.
In a chroot, this default behavior causes several problems:
- Port Conflicts: Daemons may attempt to bind to network interfaces already used by the host system.
- Hanging Builds: Long-running daemon processes can cause automated build scripts to hang.
- Missing Subsystems: Daemons that depend on a fully
booted kernel, mounted virtual filesystems (like
/procor/sys), or a running D-Bus/systemd daemon will fail, causing package installation scripts to return non-zero exit codes.
How policy-rc.d Works
The interface specification dictates that
/usr/sbin/policy-rc.d returns specific exit codes to signal
whether an action is allowed:
- 0: Action is permitted.
- 101: Action is forbidden.
- 104: Action is forbidden, but the script fallback should occur if applicable.
When /usr/sbin/policy-rc.d exits with status
101, invoke-rc.d suppresses the execution of
the init script and exits cleanly with a status code of 0.
This allows package configuration to complete successfully without the
service ever running.
Implementing policy-rc.d
To block all services from starting within a chroot, create an
executable script at /usr/sbin/policy-rc.d that always
exits with 101.
Execute the following command inside the chroot environment:
printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d
chmod +x /usr/sbin/policy-rc.dVerification
Once the file is created, installing any daemon package will bypass service execution. The package manager output will typically display a message indicating that the action was denied by policy:
invoke-rc.d: policy-rc.d denied execution of start.
Cleaning Up
If the chroot environment will later be booted as a full operating system (such as when preparing a root filesystem for a physical machine or virtual machine), remove the script before final packaging:
rm -f /usr/sbin/policy-rc.dIf the chroot is used strictly as an isolated build environment or
container where daemons should never be managed via
invoke-rc.d, the file can remain in place permanently.