GNS3 / gns3-server

GNS3 server
GNU General Public License v3.0
768 stars 258 forks source link

Docker container loses its network adapters sporadically #2363

Open florian-koehler opened 3 months ago

florian-koehler commented 3 months ago

The setup I am currently happily using GNS3 for topologies containing mainly lightweight containers. One of these images uses the IPSec solution from Strongswan. In my current topology, I have 4 to 8 IPSec routers based on said image.

Problem Sometimes the containers running the IPSec image are losing all of their configured network adapters/interfaces (eth0, eth1) except their loopback interface (lo). This lead to the network node being completely unreachable from the outside. Only manually reloading the node resolves the problem.

GNS3 version and operating system:

To Reproduce Since the error occurs rather infrequent (on average once a week), I don't really know, where it stems from or what causes it. I can give you a rough rundown of my setup though.

Dockerfile:

FROM python:3.11.6-bookworm

ARG ENV_LOCAL_ADDR=192.168.0.101
ARG ENV_LOCAL_TS=0.0.0.0/0
ARG ENV_REMOTE_ADDR=192.168.0.1
ARG ENV_REMOTE_TS=0.0.0.0/0
ARG ENV_REMOTE_PSK=<some psk>

RUN apt-get update

RUN apt-get install strongswan strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins libstrongswan-extra-plugins -y
RUN apt-get install strongswan-swanctl -y

EXPOSE 500/udp
EXPOSE 1701/udp
EXPOSE 4500/udp
WORKDIR /

COPY ./scripts/ /usr/bin/
RUN chmod +x /usr/bin/*

COPY ./configs/strongswan.conf /etc/
COPY ./configs/swanctl_template.conf /

COPY ./entrypoint.sh /
RUN chmod +x /entrypoint.sh

COPY ./setup_scripts/setup.py /

CMD ["/entrypoint.sh"]

entrypoint.sh:

# setup.py substitutes the swanctl config file template to match the configured environment variables
python3 /setup.py --local-addr $ENV_LOCAL_ADDR --local-ts $ENV_LOCAL_TS --remote-addr $ENV_REMOTE_ADDR --remote-ts $ENV_REMOTE_TS --remote-psk $ENV_REMOTE_PSK

# Start strongswan ipsec daemon
ipsec start
sleep 1s

pgrep charon
if [ $? -eq 0 ]; then
    echo "Charon started successfully."
else
    echo "Starting charon manually."
    /usr/lib/ipsec/charon --use-syslog
fi

echo "Waiting for charon to initialize unix socket."
while [ ! -S /var/run/charon.vici ]
do
    sleep 1
done

echo "Loading ipsec connections."
swanctl --load-all

/bin/bash

swanctl-template.conf

# Section defining IKE connection configurations.
connections {
    connVPN1 {
        version = 2
        mobike = no
        local_addrs = <LOCAL_ADDR>   # container host ip address
        remote_addrs = <REMOTE_ADDR>
        proposals = aes-sha1-modp1024
        local {
            auth = psk
            id = <LOCAL_ADDR>
        }
        remote {
            auth = psk
            id = <REMOTE_ADDR>       # id of remote ipsec endpoint
        }
        rekey_time = 77760
        over_time = 8640
        dpd_delay = 60
        dpd_timeout = 90        
        children {
            VPN1 {
                local_ts = <LOCAL_TS>
                remote_ts = <REMOTE_TS>

                esp_proposals = aes-sha1-modp1024
                rekey_time = 77760
                life_time = 86400
                rekey_bytes = 18874368
                dpd_action = clear
                start_action = start
            }
        }
    }
}

secrets {
    ike-VPN1 {
        id = <REMOTE_ADDR>      # id of remote ipsec endpoint
        secret = <REMOTE_PSK>
    }
}

Screenshots or videos Topology clip: image

I will add a screenshot of the "ip addr" command once it happens again.

Additional context I am using gns3-web-ui, but the problem is also visible, when connecting via ssh to the GNS3 VM and inspecting the corresponding container directly.

If I had to take a guess, I would say it has something to do with concurrent access to the network adapters or ubridge itself.

florian-koehler commented 2 months ago

Hi. I wanted to give you an update concerning the loss of network adapters in containers. As it turns out, the problem isn't limited to strongswan specific containers. It also happened with a barebone alpine container today. Hence I changed the title of the issue.

Alpine container data: image: alpine:latest

Network adapter config file ``` auto eth0 iface eth0 inet static address 192.168.221.10 netmask 255.255.255.0 gateway 192.168.221.254 ```

The VM uptime was 2 days and 6 hours.

Here is the docker inspect result from the VM:

docker inspect ``` gns3@gns3vm:~$ docker inspect cranky_allen [ { "Id": "23b48de74d9e5d0da6ff59ceba53afede22a80974c62d92a2a621a570ce31999", "Created": "2024-04-05T06:20:25.1796126Z", "Path": "/gns3/init.sh", "Args": [ "/bin/sh" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 2676, "ExitCode": 0, "Error": "", "StartedAt": "2024-04-05T06:20:31.9338924Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:9ed4aefc74f6792b5a804d1d146fe4b4a2299147b0f50eaf2b08435d7b38c27e", "ResolvConfPath": "", "HostnamePath": "/opt/docker/containers/23b48de74d9e5d0da6ff59ceba53afede22a80974c62d92a2a621a570ce31999/hostname", "HostsPath": "", "LogPath": "/opt/docker/containers/23b48de74d9e5d0da6ff59ceba53afede22a80974c62d92a2a621a570ce31999/23b48de74d9e5d0da6ff59ceba53afede22a80974c62d92a2a621a570ce31999-json.log", "Name": "/cranky_allen", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "unconfined", "ExecIDs": [ "ba434ad510560fb72481f599b6e6dd7bfc271957bb81ad46159bf207e063d329" ], "HostConfig": { "Binds": [ "/home/gns3/.local/share/GNS3/docker/resources:/gns3:ro", "/opt/gns3/projects/313cfde3-f3ca-491c-9519-f7ce6f00c739/project-files/docker/98c02c4f-c2df-4b10-a129-e1ae1385ec7c/etc/network:/gns3volumes/etc/network" ], "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": null, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "ConsoleSize": [ 0, 0 ], "CapAdd": [ "ALL" ], "CapDrop": null, "CgroupnsMode": "host", "Dns": null, "DnsOptions": null, "DnsSearch": null, "ExtraHosts": null, "GroupAdd": null, "IpcMode": "shareable", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": true, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": [ "label=disable" ], "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": null, "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": null, "DeviceCgroupRules": null, "DeviceRequests": null, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": null, "ReadonlyPaths": null }, "GraphDriver": { "Data": { "LowerDir": "/opt/docker/overlay2/a2b902dc6f5a7738627e2ae6411d965bd096dcadaa606bfd1f8150b4cb3a320a-init/diff:/opt/docker/overlay2/d33c6a244d640eaa7b7a349045c0407328ed72c41a477f3fabe4ac83fef8fb12/diff", "MergedDir": "/opt/docker/overlay2/a2b902dc6f5a7738627e2ae6411d965bd096dcadaa606bfd1f8150b4cb3a320a/merged", "UpperDir": "/opt/docker/overlay2/a2b902dc6f5a7738627e2ae6411d965bd096dcadaa606bfd1f8150b4cb3a320a/diff", "WorkDir": "/opt/docker/overlay2/a2b902dc6f5a7738627e2ae6411d965bd096dcadaa606bfd1f8150b4cb3a320a/work" }, "Name": "overlay2" }, "Mounts": [ { "Type": "bind", "Source": "/home/gns3/.local/share/GNS3/docker/resources", "Destination": "/gns3", "Mode": "ro", "RW": false, "Propagation": "rprivate" }, { "Type": "bind", "Source": "/opt/gns3/projects/313cfde3-f3ca-491c-9519-f7ce6f00c739/project-files/docker/98c02c4f-c2df-4b10-a129-e1ae1385ec7c/etc/network", "Destination": "/gns3volumes/etc/network", "Mode": "", "RW": true, "Propagation": "rprivate" } ], "Config": { "Hostname": "AlpineHost-2", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": true, "OpenStdin": true, "StdinOnce": false, "Env": [ "container=docker", "GNS3_MAX_ETHERNET=eth0", "GNS3_VOLUMES=/etc/network", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/sh" ], "Image": "alpine:latest", "Volumes": null, "WorkingDir": "", "Entrypoint": [ "/gns3/init.sh" ], "NetworkDisabled": true, "OnBuild": null, "Labels": {} }, "NetworkSettings": { "Bridge": "", "SandboxID": "", "SandboxKey": "", "Ports": {}, "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": {} } } ] ```