Ubuntu Docker容器内VPN适配器创建失败,仅LCOW环境可成功?
Let's dig into this frustrating AnyConnect driver error you're hitting—especially since it only works in the LCOW environment. First, let's recap your setup to align on context:
Your Dockerfile
FROM ubuntu COPY anyconnect/ /anyconnect/ WORKDIR /anyconnect/vpn RUN echo y | ./vpn_install.sh WORKDIR / COPY start.sh . RUN chmod 777 start.sh EXPOSE 1080 ENTRYPOINT [ "/start.sh" ]
Your start.sh Script
#!/bin/bash # Allow tunneling. mkdir -p /dev/net mknod /dev/net/tun c 10 200 # Start services. /opt/cisco/anyconnect/bin/vpnagentd -d > agent-stdout.txt 2> agent-stderr.txt & # Connect to VPN. /opt/cisco/anyconnect/bin/vpn connect $1 # Run a daemon here that keeps the container alive.
Startup Command
docker run -it --rm --cap-add=NET_ADMIN vpn-connector uri.to.vpn.com
Error Output
state: Connecting
notice: Establishing VPN session...
notice: Establishing VPN - Initiating connection...
notice: Establishing VPN - Examining system...
notice: Establishing VPN - Activating VPN adapter...
state: Disconnecting
notice: Disconnect in progress, please wait...
error: The VPN client driver encountered an error. Please restart your computer or device, then try again.
state: Disconnected
Now let's walk through actionable troubleshooting steps:
1. Fix TUN Device Permissions
You're creating the /dev/net/tun device, but AnyConnect might not have the permissions to access it. Add this line right after creating the device in your start.sh:
chmod 666 /dev/net/tun
Also, confirm the host kernel has the tun module loaded: run lsmod | grep tun on your host. If it's missing, load it with sudo modprobe tun.
2. Wait for the VPN Agent to Fully Initialize
Your script starts vpnagentd in the background, then immediately tries to connect—this might be too fast. Add a delay or wait for the agent to be ready:
/opt/cisco/anyconnect/bin/vpnagentd -d > agent-stdout.txt 2> agent-stderr.txt & # Wait for the agent to set up its socket while [ ! -S /opt/cisco/anyconnect/var/vpnagent.sock ]; do sleep 1 done # Or use a simple delay if the socket check doesn't work # sleep 10
3. Test Host or Macvlan Network Mode
Docker's default bridge network can restrict low-level network operations AnyConnect needs. Try running the container with host network mode to bypass bridge restrictions:
docker run -it --rm --cap-add=NET_ADMIN --network host vpn-connector uri.to.vpn.com
If that works, you can also experiment with macvlan mode for better isolation than host mode.
4. Inspect Agent Logs Properly
Right now, your container exits after the VPN disconnects, so you might not be seeing full agent logs. Modify your start.sh to keep the container alive:
# After the connect command (even if it fails), keep the container running tail -f /dev/null
Then, in a separate terminal, pull the logs with:
docker exec <container-id> cat /agent-stderr.txt
The agent logs usually have specific details about why the cscotun0 interface failed to create.
5. Check Kernel & Security Module Restrictions
- Kernel Tun Support: Verify your host kernel has
CONFIG_TUNenabled. Runzcat /proc/config.gz | grep CONFIG_TUN—it should showCONFIG_TUN=yorCONFIG_TUN=m. - AppArmor/SELinux: These security modules might block AnyConnect's access to the tun device. Try disabling AppArmor for the container temporarily:
For SELinux-enabled hosts, check audit logs withdocker run -it --rm --cap-add=NET_ADMIN --security-opt apparmor:unconfined vpn-connector uri.to.vpn.comausearch -m avc -ts recentto see if it's blocking the agent.
6. Try a Different Base Image
The latest Ubuntu image might have compatibility issues with AnyConnect's driver. Test with an older LTS version like ubuntu:20.04 or a Debian-based image like debian:bullseye—some users report better stability with older, more mature distributions for VPN containers.
7. Compare LCOW to Standard Environments
Since it works in LCOW, investigate the differences:
- LCOW uses a lightweight VM for Windows containers, which might have a more permissive network stack or different kernel modules. Check if the LCOW kernel has tun-related features your standard host lacks.
- Test running the container in a fresh Linux VM (e.g., VirtualBox) to rule out host-specific configuration issues.
Advanced Debugging
If none of the above works, use strace to trace system calls from the VPN agent and see exactly where it fails:
strace -f /opt/cisco/anyconnect/bin/vpnagentd -d 2>&1 | grep -E "(open|tun|socket)"
This will show you all interactions with the tun device and sockets, pinpointing the exact error cause.
内容的提问来源于stack exchange,提问作者twitchax

