Restricting Rootless Podman Containers to a Local Network Without Internet Access
Introduction
In some environments, such as HPC clusters, rootless Podman containers should reach the local network but not the internet. You get this by putting them on an internal Podman network.
Problem
You need rootless containers limited to a controlled network with no internet access, while still allowing the containers to reach each other.
Resolution
Create an internal network (netavark backend)
On Rocky Linux 9 (and Rocky 8.x using netavark), an internal network has no route to the outside, so containers on it cannot reach the internet, but containers on the same network can still reach each other. Create one:
podman network create --internal no-inet-net
Run containers on it with --network:
podman run --rm -it --network no-inet-net rockylinux:9 bash
Tested on Rocky Linux 9.8 (podman 5.8.2): a container on the internal network has no internet, while one on the default network still does.
# on the internal network
ping -c2 8.8.8.8
ping: sendto: Network unreachable
To control the address range, set the subnet:
podman network create --internal --subnet 10.0.0.0/24 no-inet-net
Older setups using the CNI backend
netavark is the default since Podman 4.0 (fresh Rocky 9); a system upgraded from Rocky 8 can still use the older cni backend. Check it:
podman info --format '{{.Host.NetworkBackend}}'
If it reports cni, define the network as a CNI bridge. Create ~/.config/cni/net.d/no-inet-net.conflist:
{
"cniVersion": "0.4.0",
"name": "no-inet-net",
"plugins": [
{
"type": "bridge",
"bridge": "cni-podman1",
"isGateway": false,
"ipMasq": false,
"ipam": {
"type": "host-local",
"ranges": [[{ "subnet": "10.0.0.0/24" }]]
}
}
]
}
Here ipMasq: false disables the source NAT that containers use to reach the internet, and isGateway: false leaves the bridge with no gateway or default route off-host, together approximating --internal. Run containers with --network no-inet-net. CNI was removed in Podman 5.0, so this applies only to older hosts.
Notes
The network is per user: each rootless user must create it. The default_network setting in containers.conf does not help, because it applies only to containers run as root, not to rootless ones. Since a user can still pick another network with --network, enforce the isolation at the host firewall if it must be guaranteed. For no network access at all, use --network none.