I need some help if anyone could take the time and has the knowledge:
I’m basically new to podman and namespaces, relatively new to linux and a noob at networking. So figuring this out and getting it to work took many more hours than I would like to admit, but I still have a few problems. I have all my current Quadlets below in the spoiler (seperated by “—”). I am on Bazzite, which probably makes this even harder.
Questions:
-
- If I use “podman exec <container> ip route” (on e.g. qbittorrent) the default route goes through my actual network interface (actual ip adress) which I very much do not want (or through my killswitch dummy network from my VPN if on, which is better but still not ideal). Is there a way to completely remove my actual network from a container’s eyes? “podman exec <container> ip addr” shows 1 lo (local), 2 my actual network, 4 tun0 from gluetun. The traffic does go through gluetun correctly, but I don’t trust it 100%. Having the containers separated and NOT inside a pod gives the same result, since the containers share the network namespaces from the gluetun container when I do “Network=container:gluetun” (same as just having them in a pod as far as I understand). I tried to also create a podman network without a default gateway, but then gluetun cannot connect to the VPN in the first place.
-
- My setup works but is quite convoluted and probably has many unnecessary lines, so please give me any improvements you see
-
- Is User=1000, Group=1000, even sensible? For example in the homepage container those lines result in the container showing User “1000:1000” (from podman inspect). Would User=0, Group=0 (or no lines since I use UserNS=keep-id in the pod?), which shows as User=root (podman inspect) mean that it has actual root access or just that it is root INSIDE the container?
Thank you in advance for the answers, in case I don’t reply to your comment specifically.
spoiler
[Unit] Description=Arr-stack pod [Pod] PodName=arr-stack # Network # Network=vpn-only # User mapping / I don’t fully understand this yet, but the pod does not work without this (maps user id to specified ID inside the containers? So the containers have UID:GID 1000:1000?) UserNS=keep-id:uid=1000,gid=1000 # # Homepage Port Mapping PublishPort=3000:3000 # Jellyfin Port Mapping PublishPort=8096:8096/tcp # qBittorrent Port Mapping PublishPort=8080:8080 #PublishPort=6881:6881 #PublishPort=6881:6881/udp # Prowlarr Port Mapping PublishPort=9696:9696 # Flaresolverr Port Mapping PublishPort=8191:8191 # Radarr Port Mapping PublishPort=7878:7878 # Sonarr Port Mapping PublishPort=8989:8989 # Jellyseerr Port Mapping #PublishPort=8055:5055 #[Install] # WantedBy=default.target — [Unit] Description=Gluetun Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod [Container] ContainerName=gluetun Pod=arr-stack.pod Image=docker.io/qmcgaw/gluetun:v3 AutoUpdate=registry # Network # Network=vpn-only # UID/GID permissions / root + privileged for networking? PodmanArgs=–privileged User=0 Group=0 # Equivalent to cap_add: - NET_ADMIN # one wrong? AddCapability=NET_ADMIN AddCapability=CAP_NET_ADMIN # Required for Gluetun to delete the bridge’s default route, but does not work AddCapability=NET_RAW AddCapability=CAP_NET_RAW # Equivalent to “devices: - /dev/net/tun:/dev/net/tun” AddDevice=/dev/net/tun:/dev/net/tun # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=gluetun.env # Environment=FIREWALL_OUTBOUND_SUBNETS=10.90.0.0/24 / test from a specific podman network Environment=FIREWALL_INPUT_PORTS=8080 # Environment=VPN_SERVICE_PROVIDER= <123> Environment=VPN_TYPE=wireguard Environment=WIREGUARD_PRIVATE_KEY= <key> Environment=SERVER_COUNTRIES= <country> # for now: Environment=VPN_PORT_FORWARDING=off #Secret=openvpn_user,type=env,target=OPENVPN_USER #Secret=openvpn_password,type=env,target=OPENVPN_PASSWORD #Volume Volume=/var/home/user123/.config/arr-configs/gluetun:/gluetun:Z # SecurityLabel=disable [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=qBittorrent Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=qbittorrent Pod=arr-stack.pod Image=lscr.io/linuxserver/qbittorrent:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions / linuxserver images require UID:GID 0:0 at the start; they won’t start without it User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=qbittorrent.env Environment=WEBUI_PORT=8080 # Environtment=TORRENTING_PORT=6881 # Volume :Z (> :z) probably works as well and is saver for configs? Volume=/var/home/user123/.config/arr-configs/qbittorrent:/config:z Volume=/var/home/user123/Videos/Downloads:/downloads:z # Volume=/var/home/user123/Videos/Downloads/completed:/downloads:z,U # Volume=/var/home/user123/Videos/Downloads/incomplete:/incomplete:z,U # Volume=/var/home/user123/Videos/Downloads/torrents:/torrents:z,U [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=Prowlarr Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=prowlarr Pod=arr-stack.pod Image=lscr.io/linuxserver/prowlarr:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions / linuxserver images require UID:GID 0:0 at the start; they won’t start without it User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=prowlarr.env Environment=WEBUI_PORT=9696 # Volume Volume=/var/home/user123/.config/arr-configs/prowlarr:/config:z,U [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=Sonarr Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=sonarr Pod=arr-stack.pod Image=lscr.io/linuxserver/sonarr:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions / linuxserver images require UID:GID 0:0 at the start; they won’t start without it User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=sonarr.env Environment=WEBUI_PORT=8989 # Volume / Disable SecurityLabels due to SMB share, need to look this up SecurityLabelDisable=true Volume=/var/home/user123/.config/arr-configs/sonarr:/config:z Volume=/var/home/user123/Videos/Shows:/tv:z Volume=/var/home/user123/Videos/Downloads:/downloads:z [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=Radarr Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=radarr Pod=arr-stack.pod Image=lscr.io/linuxserver/radarr:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions / linuxserver images require UID:GID 0:0 at the start; they won’t start without it User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=radarr.env Environment=WEBUI_PORT=7878 # Volume / Disable SecurityLabels due to SMB share SecurityLabelDisable=true Volume=/var/home/user123/.config/arr-configs/radarr:/config:z Volume=/var/home/user123/Videos/Movies:/movies:z Volume=/var/home/user123/Videos/Downloads:/downloads:z [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=Flaresolverr Container # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=flaresolverr Pod=arr-stack.pod Image=ghcr.io/flaresolverr/flaresolverr:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=flaresolverr.env Environment=WEBUI_PORT=8191 Environment=LOG_LEVEL=info Environment=LOG_HTML=false Environment=CAPTCHA_SOLVER=none # Volume=flaresolverr:/app/ [Service] Restart=always #[Install] #WantedBy=default.target — [Unit] Description=Podman - Jellyfin # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container [Container] ContainerName=jellyfin Pod=arr-stack.pod Image=ghcr.io/jellyfin/jellyfin AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions / 1000:1000 might work? User=0 Group=0 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvironmentFile=jellyfin.env Environment=WEBUI_PORT=8096:8096/tcp #PublishPort=8096:8096/tcp #PublishPort=8920:8920 #PublishPort=7359:7359/udp #PublishPort=1900:1900/udp # Volume Volume=/var/home/user123/.config/arr-configs/jellyfin:/config:z Volume=/var/home/user123/Videos/jellyfin-cache:/cache:z Volume=/var/home/user123/Videos/Movies:/data/movies:z Volume=/var/home/user123/Videos/Shows:/data/shows:z [Service] # Inform systemd of additional exit status # SuccessExitStatus=0 143a Restart=always TimeoutStartSec=900 #[Install] # Start by default on boot #WantedBy=default.target — [Unit] Description=Homepage Dashboard # Dependencies # pod Wants=arr-stack-pod.service After=arr-stack-pod.service Requires=arr-stack-pod.service PartOf=arr-stack-pod.service # .pod is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=arr-stack.pod After=arr-stack.pod Requires=arr-stack.pod PartOf=arr-stack.pod # gluetun Wants=gluetun.service After=gluetun.service Requires=gluetun.service BindsTo=gluetun.service # .container is probably not quite what I want, but it works and I might as well keep it, in case they change the syntax Wants=gluetun.container After=gluetun.container Requires=gluetun.container BindsTo=gluetun.container # idk about this?: After=network-online.target Wants=network-online.target # Socket Wants=podman.socket After=podman.socket Requires=podman.socket [Container] ContainerName=homepage Pod=arr-stack.pod Image=ghcr.io/gethomepage/homepage:latest AutoUpdate=registry # Network Network=container:gluetun # UID/GID permissions User=1000 Group=1000 Environment=PUID=1000 Environment=PGID=1000 # EnvironmentFile=global.env Timezone=UTC Environment=TZ=Etc/UTC # EnvirontmentFile=homepage.env #Environment=LOG_LEVEL=debug Environment=HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev #PublishPort=3000:3000 # Podman socket (recommended on Bazzite) Volume=%t/podman/podman.sock:/var/run/docker.sock:ro #Volume=/var/run/docker.sock:/run/user/1000/podman/podman.sock:ro #Volume=/%t/podman/podman.sock:/run/user/1000/podman/podman.sock:ro # Volume / Config directory SecurityLabelDisable=true Volume=%h/apps/homepage:/app/config:Z Volume=%h/apps/homepage/icons:/app/public/icons:Z [Service] Restart=on-failure TimeoutStartSec=300 #[Install] #WantedBy=default.target
just_another_person@lemmy.world 1 day ago
Excaliburr@lemmy.dbzer0.com 1 day ago
Thanks for the answer.
To 1. Maybe I worded that poorly, I do understand that I can’t take out the engine haha (good analogy). I thought gluetun was supposed to set the default route (but it seems it either doesn’t or can’t), I’ll dig deeper into manually setting a default route for containers. My goal was to only have gluetun see my computer’s network and have the containers only see local network and gluetun’s tun0 network (with default routing through tun0). AFAIK pods share network namespaces, though, so that might not be possible? (even without pods?) 2. The quadlets are in the spoiler at the bottom of the post. I’ll move the spoiler up a bit 3. So they would be rootless containers, but have root access as 0:0, if I understand that correctly? linuxserver images require 0:0 or they won’t start, do you happen to know a workaround?
just_another_person@lemmy.world 1 day ago
If they require root at start, it’s more than likely they need to access devices or sockets on the host on startup. If it’s then transitioning to another uid/gid for the actual runtime in the container - which looks to be happening - its not quite rootLESS because it obviously requires root.
I’m unfamiliar with the linuxserver images, so don’t understand the need for root here.