Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save legoktm/a4a69603526a4f50ee5a7d0a0d98ab32 to your computer and use it in GitHub Desktop.
Save legoktm/a4a69603526a4f50ee5a7d0a0d98ab32 to your computer and use it in GitHub Desktop.
Setting up Podman IPv6-only Network

Setting up Podman IPv6-only Network

human (May 11, 2025, 02:22 PM)

How can I set up a podman network so it only has IPv6 and no IPv4?

assistant (May 11, 2025, 02:23 PM)

To set up a Podman network with only IPv6 and no IPv4, you'll need to create a custom network with specific IPv6 subnet configuration while disabling IPv4.

Here's how you can do it:

  1. First, create a new network with only IPv6 addressing:
podman network create --ipv6 --subnet fd00::/64 --gateway fd00::1 --disable-dns ipv6only

This command:

  • Creates a new network named "ipv6only"
  • Enables IPv6 with --ipv6 flag
  • Sets an IPv6 subnet (using a ULA range fd00::/64)
  • Sets a gateway address
  • Disables DNS to prevent potential IPv4 DNS resolution
  1. Verify the network was created properly:
podman network inspect ipv6only
  1. When running containers, explicitly connect them to this network:
podman run --network ipv6only --name my-ipv6-container alpine sh

If you need to modify an existing network or troubleshoot any issues, you might need to:

  • Remove the network with podman network rm ipv6only if you need to recreate it
  • Check for any host-level IPv4/IPv6 settings that might affect container networking
  • Verify that your host system has IPv6 properly configured

Would you like more information about how to validate the IPv6-only setup or how to configure multiple containers on this network?

human (May 11, 2025, 08:43 PM)

IPv4 still works though if I try curl -4 .... I want to fully disable any outbound IPv4 traffic

assistant (May 11, 2025, 08:43 PM)

You're right - simply creating an IPv6-only network doesn't completely prevent containers from making IPv4 connections. To fully disable outbound IPv4 traffic, we need to use network isolation and firewall rules. Here's a more comprehensive approach:

  1. First, create your IPv6-only network:
podman network create --ipv6 --subnet fd00::/64 --gateway fd00::1 --disable-dns ipv6only
  1. Add firewall rules to block IPv4 traffic using iptables. Create a script to set up these rules:
#!/bin/bash
# Get the network interface for the podman network
NETWORK_IF=$(podman network inspect ipv6only -f '{{.NetworkInterface}}')

# Block all IPv4 traffic from containers on this network
iptables -I FORWARD -i ${NETWORK_IF} -p all -m addrtype --src-type IPV4 -j DROP
iptables -I FORWARD -o ${NETWORK_IF} -p all -m addrtype --dst-type IPV4 -j DROP

# Allow IPv6 traffic
ip6tables -I FORWARD -i ${NETWORK_IF} -j ACCEPT
ip6tables -I FORWARD -o ${NETWORK_IF} -j ACCEPT

echo "IPv4 blocking rules added for interface ${NETWORK_IF}"
  1. Make the script executable and run it with sudo:
chmod +x block_ipv4.sh
sudo ./block_ipv4.sh
  1. For stronger isolation, you can use a custom CNI configuration. Create a file called ipv6only.conflist:
{
  "cniVersion": "0.4.0",
  "name": "ipv6only",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni-ipv6only",
      "isGateway": true,
      "ipMasq": true,
      "hairpinMode": true,
      "ipam": {
        "type": "host-local",
        "ranges": [
          [
            {
              "subnet": "fd00::/64",
              "gateway": "fd00::1"
            }
          ]
        ],
        "routes": [
          { "dst": "::/0" }
        ]
      }
    },
    {
      "type": "firewall",
      "backend": "iptables"
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    }
  ]
}
  1. Add this to your CNI configuration directory (typically /etc/cni/net.d/):
sudo cp ipv6only.conflist /etc/cni/net.d/
  1. Run your container with this network:
podman run --network ipv6only --name ipv6-container alpine sh
  1. To verify IPv4 is completely blocked, you can test from inside the container:
podman exec -it ipv6-container sh
ping 8.8.8.8  # Should time out
curl -4 ipv4.example.com  # Should fail
curl -6 ipv6.example.com  # Should work

This approach uses multiple layers of isolation to ensure IPv4 traffic is completely blocked while IPv6 traffic can flow normally. The firewall rules specifically target IPv4 packets and drop them before they can leave your network.

human (May 11, 2025, 08:44 PM)

I'm running this in systemd; could RestrictAddressFamilies help?

assistant (May 11, 2025, 08:45 PM)

Yes! Using RestrictAddressFamilies in systemd is an excellent approach for restricting network address families. This will be more effective and cleaner than network-level rules since it restricts capabilities at the process level.

Here's how to implement this in your systemd service:

[Unit]
Description=IPv6-only container service

[Service]
ExecStart=podman run --network ipv6only --name ipv6-container alpine sleep infinity
# Only allow IPv6 (AF_INET6) and local socket families (AF_UNIX, AF_NETLINK)
RestrictAddressFamilies=AF_INET6 AF_UNIX AF_NETLINK
# Prevents the service from accessing IPv4 sockets
RestrictNamespaces=~AF_INET

# Other recommended security settings
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

This configuration:

  1. Uses RestrictAddressFamilies=AF_INET6 AF_UNIX AF_NETLINK to only allow IPv6 sockets while permitting local UNIX sockets and netlink sockets (needed for network configuration)

  2. Explicitly restricts (~ means deny) the IPv4 namespace with RestrictNamespaces=~AF_INET

  3. Includes other security hardening options that are good practice for containerized services

To apply this:

  1. Save the above configuration to a file, e.g., /etc/systemd/system/ipv6-container.service

  2. Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now ipv6-container.service

This systemd approach is superior to network rules because:

  • It prevents the process from even creating IPv4 sockets
  • It's enforced by the kernel
  • There's no way for the container to bypass this restriction
  • It's cleaner than maintaining firewall rules

To verify it's working:

systemctl status ipv6-container.service
podman exec -it ipv6-container sh
# Try ping 8.8.8.8 which should fail immediately rather than time out
# Try curl -4 which should fail with a socket creation error

Would you like more details on any specific part of this systemd configuration?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment