Exposing a listener
The work answers the door.
Phobos decides which socket in the wall the work may plug into, and puts a doorkeeper in front of it. Who can reach the door at all is the building's business.
The situation
The command starts a server that something outside has to reach: a web service under test, a protocol implementation, a task that is graded by talking to it.
The policy fragment
[bind]
allow 8080
[accept]
expose 18080 to 8080 from 198.51.100.0/24
Two ports, with different jobs. 8080 is the command's own listening port, and Landlock
refuses it a listener on any other, unless the base policy names port 0, as the shipped Java
policy does. 18080 is the port the container exposes, which the
inbound filter binds and which the command may not bind itself.
What this still forbids
- a listener on any port
[bind]does not name, refused in the kernel and against raw system calls, and alisten()on a socket that never bound, which the connect guard refuses - an inbound connection from any source outside
198.51.100.0/24 - an outbound connection, unless
[connect]names one - a datagram listener, which needs
allow 5353 udpand Landlock version 10
The tempting wrong version
[bind]
allow 8080
[accept]
expose 8080 to 8080 from 198.51.100.0/24
Fronting a port the command can itself bind lets it compete with the filter for that port and
receive connections the filter was meant to screen. Phobos refuses this with PHB-EPOLICY.
Three more are refused for related reasons: a public port below 1024, which cannot be bound
without a capability the run does not have; a backend port [bind] does not name, which would
leave the filter forwarding to a listener that never comes up; and two rules fronting one
public port with different backends.
A fourth passes and serves nobody:
[bind]
allow 8080
[accept]
expose 18080 to 8080 from
A rule with no source admits nobody. That is the fail-closed direction, and Phobos warns that
the service is unreachable rather than failing. The literal word from stays even where no
source follows it; a line without it is not an [accept] rule at all.
Notes
[accept] rule changes the run's postureIt removes --network none, because an external client cannot reach a container that has no
network. Phobos locks the listening port, and the connect guard keeps the listener on loopback.
Landlock's bind right is per port rather than per address, so the command may bind its backend
port on every interface. The guard pins every listener to the loopback device, so only this host
reaches the backend, through the filter. The container publishes the public port and nothing
else. A source address is a filter, never an identity.
- A
[bind]rule takes a bare port. A rule that names an address is refused, because Landlock cannot narrow a bind to a local address. - With
--no-networksystem-restriction, the[accept]rule starts no filter and the port is not locked either.phobos.shreports that rather than leaving it silent.