ducmthai / openconnect-as-a-container

openconnect, the anyconnect client in a Docker container
26 stars 4 forks source link

Certificate #2

Open au-ganymede opened 2 months ago

au-ganymede commented 2 months ago

Hello,

Is it possible to use this script when connecting to the corporate network requires authentication with a certificate (codes are not used)? Unfortunately, I do not see such an option in the configuration file. I would be grateful for your help in this matter.

Currently, I use the following command to connect to the VPN from the terminal (macOS):

openconnect --protocol=gp --user=user@company.com --certificate=certificate.pem --sslkey=private-key.pem https://vpn.company.com/gatewa
ducmthai commented 2 months ago

You can modify the openconnect run file as followed and put the certificate and private key in $CERT_PATH and $PRIV_KEY_PATH:

#!/command/with-contenv bash

if [ ! -r ${OC_CFG} ]; then
  echo "Could not load config file from /vpn/vpn.config. Please check your volume config" 1>&2
  exit 1
fi

source ${OC_CFG}

if [ -z "$SERVER" ]; then
  echo "No server is set. Exiting."
  exit 1
fi

if [ -z "$USERNAME" ]; then
  echo "No username is set. Exiting."
  exit 1
fi

if [ -z "$CERT_PATH" ]; then
  echo "No certificate path set. Exiting."
  exit 1
fi

if [ -z "$PRIV_KEY_PATH" ]; then
  echo "No private key path set. Exiting."
  exit 1
fi

echo "Starting openconnect..."
openconnect --protocol=gp --user=$USER --certificate=$CERT_PATH --sslkey=$PRIV_KEY_PATH $SERVER --no-dtls

sleep infinity &

wait
au-ganymede commented 2 months ago

@ducmthai Thank you so much for your help and at such short notice! I really appreciate it.

Unfortunately, I think this is beyond me. In truth, I'm a graphic designer and my knowledge of both Doker and networks is pretty microscopic, so the instructions on GitHub aren't exactly clear to me.

I wanted to use Doker so that I didn't have to install the Palo Alto client on a private machine and delegate the VPN exclusively to a browser (Firefox or Chrome) using the SOCKS5 proxy.


EDIT:

Well, I remembered that there is such a thing as logs. I used the ganymede@macbook openconnect-as-a-container % docker logs vpn_proxy command and from it I think the main problem is the wrong path (?) to the certificate and key file. I would be grateful for any help in this matter, maybe luck will smile on me now and such a correction will be enough to make it all work for me....

ganymede@macbook openconnect-as-a-container % docker logs vpn_proxy
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
cont-init: info: running /etc/cont-init.d/01-contcfg
[env-init] PASSWORD set from FILE__PASSWORD
cont-init: info: /etc/cont-init.d/01-contcfg exited 0
cont-init: info: running /etc/cont-init.d/30-occfg
Set proxy without username and password
cont-init: info: /etc/cont-init.d/30-occfg exited 0
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
services-up: info: copying legacy longrun 3proxy (no readiness notification)
services-up: info: copying legacy longrun dnsmasq (no readiness notification)
services-up: info: copying legacy longrun openconnect (no readiness notification)
s6-rc: info: service legacy-services successfully started
Starting openconnect...
POST https://vpn.company.com/ssl-vpn/prelogin.esp?tmp=tmp&clientVer=4100&clientos=Linux
Connected to XXX.XXX.XX.XXX:443
Failed to open certificate file certificate.pem: No such file or directory
Loading certificate failed. Aborting.
Failed to open HTTPS connection to vpn.company.com
Failed to complete authentication
ganymede@macbook openconnect-as-a-container %


Here's what I did:

  1. I cloned the repository and entered the directory:
ganymede@macbook openconnect % git clone https://github.com/ducmthai/openconnect-as-a-container.git
Klonowanie do „openconnect-as-a-container”...
remote: Enumerating objects: 266, done.
remote: Counting objects: 100% (94/94), done.
remote: Compressing objects: 100% (59/59), done.
remote: Total 266 (delta 45), reused 68 (delta 25), pack-reused 172
Pobieranie obiektów: 100% (266/266), 80.72 KiB | 3.67 MiB/s, gotowe.
Rozwiązywanie delt: 100% (107/107), gotowe.
ganymede@macbook openconnect% ls
openconnect-as-a-container
ganymede@macbook openconnect % cd openconnect-as-a-container/
  1. As instructed, I replaced the contents of the `run' file for openconnect:
    
    #!/command/with-contenv bash

if [ ! -r ${OC_CFG} ]; then echo "Could not load config file from /vpn/vpn.config. Please check your volume config" 1>&2 exit 1 fi

source ${OC_CFG}

if [ -z "$SERVER" ]; then echo "No server is set. Exiting." exit 1 fi

if [ -z "$USERNAME" ]; then echo "No username is set. Exiting." exit 1 fi

if [ -z "$CERT_PATH" ]; then echo "No certificate path set. Exiting." exit 1 fi

if [ -z "$PRIV_KEY_PATH" ]; then echo "No private key path set. Exiting." exit 1 fi

echo "Starting openconnect..." openconnect --protocol=gp --user=$USER --certificate=$CERT_PATH --sslkey=$PRIV_KEY_PATH $SERVER --no-dtls

sleep infinity &

wait


3. I have copied the `certificate.pem` and `private-key.pem` files into the `openconnect-as-a-container` directory (not sure if this is the right place for them).

4. I have edited the `vpn.config` file (I don't know the endpoint - don't specify anything or just copy the server address? I'm not sure of the path to the files either.):

SERVER=vpn.company.com/gateway USERNAME=user@company.com PASSWORD:password_from_the_company DYNAMIC_TOKEN: false PROXY_USER= PROXY_PASS= CERT_PATH=certificate.pem PRIV_KEY_PATH=private-key.pem KEEP_ALIVE_ENDPOINT=vpn.company.com/gateway


5. I ran the command in the terminal: `sh build.sh 3.1.4.2`:
```bash
ganymede@macbook openconnect-as-a-container % sh build.sh 3.1.4.2
WARN[0000] /Users/sebastian/Desktop/DOCKER/docker-compose.yml: `version` is obsolete 
[+] Building 2.3s (16/16) FINISHED                                                        docker:desktop-linux
 => [openconnect internal] load build definition from Dockerfile                                          0.0s
 => => transferring dockerfile: 3.29kB                                                                    0.0s
 => [openconnect internal] load metadata for docker.io/library/alpine:3.17.3                              1.4s
 => [openconnect auth] library/alpine:pull token for registry-1.docker.io                                 0.0s
 => [openconnect internal] load .dockerignore                                                             0.0s
 => => transferring context: 126B                                                                         0.0s
 => [openconnect builder 2/6] ADD https://github.com/3proxy/3proxy/archive/0.9.4.tar.gz /0.9.4.tar.gz     0.8s
 => [openconnect builder 1/6] FROM docker.io/library/alpine:3.17.3@sha256:124c7d2707904eea7431fffe91522a  0.0s
 => [openconnect internal] load build context                                                             0.0s
 => => transferring context: 2.60kB                                                                       0.0s
 => CACHED [openconnect stage-1 2/4] RUN apk upgrade --update --no-cache     && apk --update --no-cache   0.0s
 => CACHED [openconnect builder 2/6] ADD https://github.com/3proxy/3proxy/archive/0.9.4.tar.gz /0.9.4.ta  0.0s
 => CACHED [openconnect builder 3/6] RUN apk add --update       alpine-sdk       bash       linux-header  0.0s
 => CACHED [openconnect builder 4/6] RUN S6_OVERLAY_URL_PREFIX="https://github.com/just-containers/s6-ov  0.0s
 => CACHED [openconnect builder 5/6] ADD rootfs /root-out                                                 0.0s
 => CACHED [openconnect builder 6/6] RUN chmod +x /root-out/opt/utils/healthcheck.sh     && chmod +x /ro  0.0s
 => CACHED [openconnect stage-1 3/4] COPY --from=builder /3proxy-0.9.4/bin /usr/local/bin                 0.0s
 => CACHED [openconnect stage-1 4/4] COPY --from=builder /root-out /                                      0.0s
 => [openconnect] exporting to image                                                                      0.0s
 => => exporting layers                                                                                   0.0s
 => => writing image sha256:2caa1f5d70b55645b2fbf2bf76a6175418e447d7469e5df543e26e38e6cb4d3b              0.0s
 => => naming to docker.io/ducmthai/openconnect:latest                                                    0.0s
  1. I ran the command: docker network create openconnect --subnet=10.30.0.1/16. This gave an error:
    Error response from daemon: invalid network config:
    invalid subnet 10.30.0.1/16: it should be 10.30.0.0/16

So again, as suggested, I created a subnet with a 0 at the end instead of a 1 (right/wrong?). docker network create openconnect --subnet=10.30.0.0/16

  1. I ran the command: docker build -t ducmthai/openconnect .:
    
    ganymede@macbook openconnect-as-a-container % docker build -t ducmthai/openconnect .
    [+] Building 1.1s (15/15) FINISHED                                                        docker:desktop-linux
    => [internal] load build definition from Dockerfile                                                      0.0s
    => => transferring dockerfile: 3.29kB                                                                    0.0s
    => [internal] load metadata for docker.io/library/alpine:3.17.3                                          0.6s
    => [internal] load .dockerignore                                                                         0.0s
    => => transferring context: 126B                                                                         0.0s
    => [builder 2/6] ADD https://github.com/3proxy/3proxy/archive/0.9.4.tar.gz /0.9.4.tar.gz                 0.4s
    => [builder 1/6] FROM docker.io/library/alpine:3.17.3@sha256:124c7d2707904eea7431fffe91522a01e5a861a624  0.0s
    => [internal] load build context                                                                         0.0s
    => => transferring context: 2.60kB                                                                       0.0s
    => CACHED [stage-1 2/4] RUN apk upgrade --update --no-cache     && apk --update --no-cache add           0.0s
    => CACHED [builder 2/6] ADD https://github.com/3proxy/3proxy/archive/0.9.4.tar.gz /0.9.4.tar.gz          0.0s
    => CACHED [builder 3/6] RUN apk add --update       alpine-sdk       bash       linux-headers       xz    0.0s
    => CACHED [builder 4/6] RUN S6_OVERLAY_URL_PREFIX="https://github.com/just-containers/s6-overlay/releas  0.0s
    => CACHED [builder 5/6] ADD rootfs /root-out                                                             0.0s
    => CACHED [builder 6/6] RUN chmod +x /root-out/opt/utils/healthcheck.sh     && chmod +x /root-out/etc/s  0.0s
    => CACHED [stage-1 3/4] COPY --from=builder /3proxy-0.9.4/bin /usr/local/bin                             0.0s
    => CACHED [stage-1 4/4] COPY --from=builder /root-out /                                                  0.0s
    => exporting to image                                                                                    0.0s
    => => exporting layers                                                                                   0.0s
    => => writing image sha256:3f2ca01900ebec758b50cd791411b4eaf139ed678c32e2b320bd1556287d5fce              0.0s
    => => naming to docker.io/ducmthai/openconnect                                                           0.0s

8. I pasted the command that runs the container:
```bash
docker run -d \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
--name=vpn_proxy \
--dns=1.1.1.1 --dns=1.0.0.1 \
--privileged=true \
--restart=always \
-e "PROXY_PORT=3128" \
-e "HTTP_PROXY_PORT=3129" \
-e "LOCAL_NETWORK=192.168.0.1/24" \
-e "FILE__PASSWORD=/vpn/passwd" \
-e "OPENSSL_CONF=/etc/ssl/openssl.cnf" \
-e "EXT_IP=XXX.XXX.XX.XXX" \
-v /etc/localtime:/etc/localtime:ro \
-v "$(pwd)"/vpn.config:/vpn/vpn.config:ro \
-v "$(pwd)"/vpnpasswd:/vpn/passwd:ro \
-v "$(pwd)"/vpntoken:/vpn/token \
-p 3128:3128 \
-p 3129:3129 \
ducmthai/openconnect:latest

I don't know if all of these above parameters are necessary since I'm using a certificate without codes/tokens?

-e "EXT_IP=<get_yours_at_ifconfig.co/ip>. - I don't understand this at all. If I don't specify an IP address, the container won't work properly? Anyway, I used the web service mentioned and entered the IP address I got.

Unfortunately, in my opinion, there is no connection to the VPN server at all. I used the ping command (I don't know how reliable this is) and although it queries google.com, it no longer sees the company's services, which are restricted to the company's network.

ganymede@macbook DOCKER % docker exec -it vpn_proxy /bin/bash
d241b9169107:/# ping google.com
PING google.com (142.251.36.78): 56 data bytes
64 bytes from 142.251.36.78: seq=0 ttl=63 time=24.600 ms
64 bytes from 142.251.36.78: seq=1 ttl=63 time=21.817 ms
64 bytes from 142.251.36.78: seq=2 ttl=63 time=21.759 ms
64 bytes from 142.251.36.78: seq=3 ttl=63 time=24.020 ms
64 bytes from 142.251.36.78: seq=4 ttl=63 time=21.189 ms
64 bytes from 142.251.36.78: seq=5 ttl=63 time=22.087 ms
^C
--- google.com ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max = 21.189/22.578/24.600 ms
d241b9169107:/# ping service.company.com
ping: bad address 'service.company.com'
d241b9169107:/# 

This is what it looks like from my side.

Before I found your script, I tried to run OpenConnect in a Docker container and even succeeded, because the container connected to the VPN server and I was able to ping or curl/wget domains that were only accessible from the company network.

I also added a Dante proxy server and forwarded ports, but although the system (I think) could see the forwarded port, no traffic was going through. I've disabled the firewall and nothing, but as I've written before, I'm completely unfamiliar with it.


Dockerfile:

# Use a specific version of the Ubuntu base image to avoid mismatches
FROM ubuntu:20.04

# Set a non-interactive front-end for easier Docker building
ENV DEBIAN_FRONTEND=noninteractive

# Install network utilities including ping
RUN apt-get update && apt-get install -y \
    iputils-ping \
    traceroute \
    curl

# Update and install necessary packages
RUN apt-get update && \
    apt-get -y upgrade && \
    apt-get install -y openconnect iproute2 dante-server --fix-missing

# List all files installed by the dante-server
RUN dpkg -L dante-server

# Verify if dante-server installed successfully
RUN which dante-server || echo "Dante-server binary location not found"

# Attempt to locate the sockd binary
RUN which sockd || find / -name sockd -type f || echo "sockd binary not found"

# Clean up to reduce image size
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Copy the configurations and scripts
COPY certificate.pem /etc/openconnect/
COPY private-key.pem /etc/openconnect/
COPY sockd.conf /etc/
COPY entrypoint.sh /entrypoint.sh

# Ensure the entrypoint script is executable
RUN chmod +x /entrypoint.sh

EXPOSE 8888

# Execute the entrypoint script on container start
ENTRYPOINT ["/entrypoint.sh"]
CMD ["sleep", "infinity"]

Dante configuration:

internal: 0.0.0.0 port = 8888
external: eth0

clientmethod: none
socksmethod: none
user.privileged: root
user.unprivileged: nobody

client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: connect disconnect
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: connect disconnect
    command: bind connect udpassociate
}

Entrypoint script:

#!/bin/bash

# Start the OpenConnect VPN connection (in background)
echo "$VPN_PASSWORD" | openconnect \
    --protocol=gp \
    --user=$VPN_USER \
    --passwd-on-stdin \
    --certificate=/etc/openconnect/certificate.pem \
    --sslkey=/etc/openconnect/private-key.pem \
    "$VPN_SERVER_URL" &

# Delay to ensure connection stability
sleep 10

# Start the Dante SOCKS server using the correct binary name
/usr/sbin/danted -f /etc/sockd.conf

# Keep the script running
wait $!

Docker run:

docker run -it --rm --privileged --name=myvpn \
-e VPN_USER='user@company.com' -e VPN_PASSWORD='**********' -e VPN_SERVER_URL='https://vpn.company.com/gateway' \
-p 8888:8888 openconnect-socks

Container:

netstat -tulnp | grep 8888
tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN  

macOS:

ganymede@macbook GlobalProtect % nc -v 127.0.0.1 8888
Connection to 127.0.0.1 port 8888 [tcp/ddi-tcp-1] succeeded!

Curl fail:

ganymede@macbook GlobalProtect % curl --socks5 127.0.0.1:8888 --socks5-hostname 127.0.0.1:8888 -v http://onet.pl
*   Trying 127.0.0.1:8888...
* Connected to 127.0.0.1 (127.0.0.1) port 8888
* Recv failure: Connection reset by peer
* SOCKS4: Failed receiving initial SOCKS5 response: Failure when receiving data from the peer
* Closing connection
curl: (97) Recv failure: Connection reset by peer
ganymede@macbook GlobalProtect %
au-ganymede commented 2 months ago

Continued

I tinkered a bit and managed to connect to the VPN.

However, a similar issue occurred as with my previous, own method, which I illustrated above, namely the connection inside the container was established, ping and curl work for the service hidden behind the corporate network, but proxy rejects all attempts to connect through setting up Firefox via SOCKS5 or trying to test with curl in the terminal. And I don’t know what to do.

I tested this on two computers.

Macbook M1 and M3 (both running macOS Sonoma 14.4.1). On both, the firewalls are disabled. The M3 is fresh out of the box, the only things I installed on it are Firefox, Brew, and Docker.

I think this rules out the influence of third-party applications on the connection.

There is listening on the ports, but the connections are not going through. I also don’t see any errors in the logs (nothing appears in the logs when trying to establish a connection through the proxy).


Ports

In a container

ff153b881395:/# netstat -tulnp | grep -e 3129 -e 3128
tcp        0      0 0.0.0.0:3129            0.0.0.0:*               LISTEN      182/3proxy
tcp        0      0 0.0.0.0:3128            0.0.0.0:*               LISTEN      182/3proxy

In the system

ganymede@macbook ~ % nc -v 127.0.0.1 3128
Connection to 127.0.0.1 port 3128 [tcp/ndl-aas] succeeded

Connection

In a container

ganymede@macbook openconnect-as-a-container % docker exec -it vpn_proxy /bin/bash 
ff153b881395:/# ping google.com
PING google.com (142.250.203.142): 56 data bytes
64 bytes from 142.250.203.142: seq=0 ttl=115 time=106.399 ms
64 bytes from 142.250.203.142: seq=1 ttl=115 time=125.724 ms
64 bytes from 142.250.203.142: seq=2 ttl=115 time=110.234 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 106.399/114.119/125.724 ms
ff153b881395:/# ping service.company.com
PING service.company.com (XXX.18.0.XXX): 56 data bytes
64 bytes from XXX.18.0.XXX: seq=0 ttl=61 time=53.767 ms
64 bytes from XXX.18.0.XXX: seq=1 ttl=61 time=49.910 ms
64 bytes from XXX.18.0.XXX: seq=2 ttl=61 time=63.906 ms
64 bytes from XXX.18.0.XXX: seq=3 ttl=61 time=84.899 ms
^C
--- service.company.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 49.910/63.120/84.899 ms
ff153b881395:/

Curl also worked.

In the system

ganymede@macbook ~ % curl -v -x socks5h://127.0.0.1:3128 http://www.google.com
*   Trying 127.0.0.1:3128...
* Connected to 127.0.0.1 (127.0.0.1) port 3128
* Recv failure: Connection reset by peer
* SOCKS4: Failed receiving initial SOCKS5 response: Failure when receiving data from the peer
* Closing connection
curl: (97) Recv failure: Connection reset by peer

ganymede@macbook ~ % curl -v -x socks5://127.0.0.1:3128 http://www.google.com
*   Trying 127.0.0.1:3128...
* Connected to 127.0.0.1 (127.0.0.1) port 3128
* Recv failure: Connection reset by peer
* SOCKS4: Failed receiving initial SOCKS5 response: Failure when receiving data from the peer
* Closing connection
curl: (97) Recv failure: Connection reset by peer

Firefox


Logs

Docker

2024-05-12 01:26:17 s6-rc: info: service s6rc-oneshot-runner: starting
2024-05-12 01:26:17 s6-rc: info: service s6rc-oneshot-runner successfully started
2024-05-12 01:26:17 s6-rc: info: service fix-attrs: starting
2024-05-12 01:26:17 s6-rc: info: service fix-attrs successfully started
2024-05-12 01:26:17 s6-rc: info: service legacy-cont-init: starting
2024-05-12 01:26:17 cont-init: info: running /etc/cont-init.d/01-contcfg
2024-05-12 01:26:17 cont-init: info: /etc/cont-init.d/01-contcfg exited 0
2024-05-12 01:26:17 cont-init: info: running /etc/cont-init.d/30-occfg
2024-05-12 01:26:17 cont-init: info: /etc/cont-init.d/30-occfg exited 0
2024-05-12 01:26:17 s6-rc: info: service legacy-cont-init successfully started
2024-05-12 01:26:17 s6-rc: info: service legacy-services: starting
2024-05-12 01:26:17 services-up: info: copying legacy longrun 3proxy (no readiness notification)
2024-05-12 01:26:17 services-up: info: copying legacy longrun dnsmasq (no readiness notification)
2024-05-12 01:26:17 services-up: info: copying legacy longrun openconnect (no readiness notification)
2024-05-12 01:26:17 s6-rc: info: service legacy-services successfully started
2024-05-12 01:26:17 Starting openconnect...
2024-05-12 01:26:17 POST https://vpn.company.com/ssl-vpn/prelogin.esp?tmp=tmp&clientVer=4100&clientos=Linux
2024-05-12 01:26:17 Connected to XXX.XXX.XX.XXX:443
2024-05-12 01:26:17 Using client certificate '/DC=com/DC=domain1/DC=domain2/DC=domain3/OU=Company/OU=Users/CN=Name Surname'
2024-05-12 01:26:17 Client certificate has expired at: Apr 13 13:06:44 2024 GMT
2024-05-12 01:26:17 SSL negotiation with vpn.company.com
2024-05-12 01:26:17 Connected to HTTPS on vpn.company.com with ciphersuite TLSv1.2-ECDHE-RSA-AES256-GCM-SHA384
2024-05-12 01:26:17 POST https://vpn.company.com/ssl-vpn/login.esp
2024-05-12 01:26:17 Enter login credentials
2024-05-12 01:26:17 GlobalProtect login returned authentication-source=EXTERNAL_CI_ldap-auth_profile
2024-05-12 01:26:17 GlobalProtect login returned portal-userauthcookie=0v5VGjm09qkoWQaMbdYi6UkCCsNdo5BXZEk1PStgIVvksEE5COS8l8xU+uAlQ38/J2L+yJcL86nP9xgQFiNUO6z0KFBs0ii1uXwzA0e5rOiubVIwjuUloJCBiTgsNS+JL4Yk4eL30sk4lId5xc80cP/EiWAbhia8Vb3zEibQ==
2024-05-12 01:26:17 GlobalProtect login returned portal-prelogonuserauthcookie=ZxKzdad7JzvMKYGRpQKEhPRGWsp3HlNMkyx3RMmymypnWYUXH5eobHjyMkXOnCmIfAGULX/YrW+I6Ih7bNAyAkfEKNrxbEYuswXiKLqFbRgLXcih3TBDwCBh/UjEbftaFJl/1qdxz2ujeqClTFJEtOok8RQJReRn==
2024-05-12 01:26:17 GlobalProtect login returned usually-equals-4=4
2024-05-12 01:26:17 GlobalProtect login returned usually-equals-unknown=unknown
2024-05-12 01:26:17 POST https://vpn.company.com/ssl-vpn/getconfig.esp
2024-05-12 01:26:17 Tunnel timeout (rekey interval) is 180 minutes.
2024-05-12 01:26:17 Idle timeout is 180 minutes.
2024-05-12 01:26:17 POST https://vpn.company.com/ssl-vpn/hipreportcheck.esp
2024-05-12 01:26:17 No MTU received. Calculated 65454 for ESP tunnel
2024-05-12 01:26:17 ESP session established with server
2024-05-12 01:26:17 ESP tunnel connected; exiting HTTPS mainloop.
2024-05-12 01:26:17 Configured as 10.XX.XXX.XXX, with SSL disconnected and ESP established
2024-05-12 01:26:17 Session authentication will expire at Tue Jun 11 01:26:17 2024
2024-05-12 01:26:17 
2024-05-12 01:26:18 Starting dnsmasq...
2024-05-12 01:26:18 Adding route to 192.168.0.1/24 via 172.17.0.1
2024-05-12 01:26:18 
2024-05-12 01:26:18 Error: Invalid prefix for given prefix length.
2024-05-12 01:26:18 Starting 3proxy...
2024-05-12 01:26:18 dnsmasq: started, version 2.90 cachesize 150
2024-05-12 01:26:18 dnsmasq: DNS service limited to local subnets
2024-05-12 01:26:18 dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth no-cryptohash no-DNSSEC loop-detect inotify dumpfile
2024-05-12 01:26:18 dnsmasq: reading /etc/resolv.conf
2024-05-12 01:26:18 dnsmasq: using nameserver 10.1.0.18#53
2024-05-12 01:26:18 dnsmasq: using nameserver 10.1.0.2#53
2024-05-12 01:26:18 dnsmasq: read /etc/hosts - 9 names

3proxy

1715469810.553  Err:00000 Client:0.0.0.0:8080 Remote:0.0.0.0:0 ExternalIP:0.0.0.0:0 ReqRecv:0:0 0 Accepting connections [166/2991119136]
1715469810.555  Err:00000 Client:0.0.0.0:3129 Remote:0.0.0.0:0 ExternalIP:0.0.0.0:0 ReqRecv:0:0 0 Accepting connections [166/2991074080]
1715469810.556  Err:00000 Client:0.0.0.0:3128 Remote:0.0.0.0:0 ExternalIP:0.0.0.0:0 ReqRecv:0:0 0 Accepting connections [166/2991029024]

Current configuration

OpenConnect run

#!/command/with-contenv bash

if [ ! -r ${OC_CFG} ]; then
  echo "Could not load config file from /vpn/vpn.config. Please check your volume config" 1>&2
  exit 1
fi

source ${OC_CFG}

if [ -z "$SERVER" ]; then
  echo "No server is set. Exiting."
  exit 1
fi

if [ -z "$USERNAME" ]; then
  echo "No username is set. Exiting."
  exit 1
fi

if [ -z "$PASSWORD" ]; then
  echo "No password is set. Exiting."
  exit 1
fi

if [ -z "$CERT_PATH" ]; then
  echo "No certificate path set. Exiting."
  exit 1
fi

if [ -z "$PRIV_KEY_PATH" ]; then
  echo "No private key path set. Exiting."
  exit 1
fi

echo "Starting openconnect..."
echo $PASSWORD | openconnect --protocol=gp --user=$USERNAME --passwd-on-stdin --certificate=$CERT_PATH --sslkey=$PRIV_KEY_PATH $SERVER

sleep infinity &

wait

Dockerfile

# Alpine version
ARG ALPINE_VERSION=3.17.3
# 3proxy version
ARG THREE_PROXY_REPO=https://github.com/3proxy/3proxy
ARG THREE_PROXY_BRANCH=0.9.4
ARG THREE_PROXY_URL=${THREE_PROXY_REPO}/archive/${THREE_PROXY_BRANCH}.tar.gz

# Build 3proxy
FROM alpine:${ALPINE_VERSION} as builder
ARG THREE_PROXY_REPO
ARG THREE_PROXY_BRANCH
ARG THREE_PROXY_URL
ADD ${THREE_PROXY_URL} /${THREE_PROXY_BRANCH}.tar.gz

RUN apk add --update \
      alpine-sdk \
      bash \
      linux-headers \
      xz \
      curl \
    && cd / \
    && tar -xf ${THREE_PROXY_BRANCH}.tar.gz \
    && cd 3proxy-${THREE_PROXY_BRANCH} \
    && make -f Makefile.Linux \
    && mkdir /root-out

# set version for s6 overlay
ARG S6_OVERLAY_VERSION="3.1.4.2"

# add s6 overlay
RUN S6_OVERLAY_URL_PREFIX="https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}" \
    && S6_OVERLAY_ARCH="$(uname -m)" \
    && S6_OVERLAY_NOARCH_TAR_FILE="s6-overlay-noarch.tar.xz" \
    && S6_OVERLAY_ARCH_TAR_FILE="s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" \
    && S6_OVERLAY_NOARCH_URL="${S6_OVERLAY_URL_PREFIX}/${S6_OVERLAY_NOARCH_TAR_FILE}" \
    && S6_OVERLAY_ARCH_URL="${S6_OVERLAY_URL_PREFIX}/${S6_OVERLAY_ARCH_TAR_FILE}" \
    && S6_OVERLAY_SYMLINKS_NOARCH_TAR_FILE=s6-overlay-symlinks-noarch.tar.xz \
    && S6_OVERLAY_SYMLINKS_ARCH_TAR_FILE=s6-overlay-symlinks-arch.tar.xz \
    && S6_OVERLAY_SYMLINKS_NOARCH_URL="${S6_OVERLAY_URL_PREFIX}/${S6_OVERLAY_SYMLINKS_NOARCH_TAR_FILE}" \
    && S6_OVERLAY_SYMLINKS_ARCH_URL="${S6_OVERLAY_URL_PREFIX}/${S6_OVERLAY_SYMLINKS_ARCH_TAR_FILE}" \
    && echo "Downloading from ${S6_OVERLAY_NOARCH_URL} and ${S6_OVERLAY_ARCH_URL}" \
    && curl -L ${S6_OVERLAY_NOARCH_URL} -o /tmp/${S6_OVERLAY_NOARCH_TAR_FILE} \
    && curl -L ${S6_OVERLAY_ARCH_URL} -o /tmp/${S6_OVERLAY_ARCH_TAR_FILE} \
    && curl -L ${S6_OVERLAY_SYMLINKS_NOARCH_URL} -o /tmp/${S6_OVERLAY_SYMLINKS_NOARCH_TAR_FILE} \
    && curl -L ${S6_OVERLAY_SYMLINKS_ARCH_URL} -o /tmp/${S6_OVERLAY_SYMLINKS_ARCH_TAR_FILE} \
    && tar -C /root-out -Jxpf /tmp/${S6_OVERLAY_NOARCH_TAR_FILE} \
    && tar -C /root-out -Jxpf /tmp/${S6_OVERLAY_ARCH_TAR_FILE} \
    && tar -C /root-out -Jxpf /tmp/${S6_OVERLAY_SYMLINKS_NOARCH_TAR_FILE} \
    && tar -C /root-out -Jxpf /tmp/${S6_OVERLAY_SYMLINKS_ARCH_TAR_FILE} \
    && echo "Download latest vpnc-script" \
    && VPN_SCRIPT_URL="https://gitlab.com/openconnect/vpnc-scripts/raw/master/vpnc-script" \
    && mkdir -p /root-out/etc/vpnc \
    && curl -L ${VPN_SCRIPT_URL} -o /root-out/etc/vpnc/vpnc-script

ADD rootfs /root-out
RUN chmod +x /root-out/opt/utils/healthcheck.sh \
    && chmod +x /root-out/etc/services.d/*/run \
    && chmod +x /root-out/etc/vpnc/vpnc-script \
    && chmod +x /root-out/etc/cont-init.d/01-contcfg \
    && chmod +x /root-out/etc/cont-init.d/30-occfg

FROM alpine:${ALPINE_VERSION}
ARG THREE_PROXY_BRANCH

RUN apk upgrade --update --no-cache \
    && apk --update --no-cache add \
        bash \
        tzdata \
        openconnect \
        dnsmasq \
    && rm -rf /var/cache/apk/*

COPY --from=builder /3proxy-${THREE_PROXY_BRANCH}/bin /usr/local/bin
COPY --from=builder /root-out /

RUN mkdir -p /var/log/3proxy
RUN chmod 755 /var/log/3proxy 

COPY certificate.pem /vpn/certificate.pem
COPY private-key.pem /vpn/private-key.pem

# Init
ENTRYPOINT [ "/init" ]

vpn.config

SERVER=vpn.company.com/gateway
USERNAME=name.surname@company.com
PASSWORD='***********************'
CERT_PATH=/vpn/certificate.pem
PRIV_KEY_PATH=/vpn/private-key.pem
KEEP_ALIVE_ENDPOINT=vpn.company.com/gateway
PROXY_USER=
PROXY_PASS=

Docker run

docker run -d \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
--name=vpn_proxy \
--dns=1.1.1.1 --dns=1.0.0.1 \
--privileged=true \
--restart=always \
-e "PROXY_PORT=3128" \
-e "HTTP_PROXY_PORT=3129" \
-e "LOCAL_NETWORK=192.168.0.1/24" \
-e "OPENSSL_CONF=/etc/ssl/openssl.cnf" \
-e "EXT_IP=XXX.XXX.XX.XXX" \
-v /etc/localtime:/etc/localtime:ro \
-v "$(pwd)"/vpn.config:/vpn/vpn.config:ro \
-p 3128:3128 \
-p 3129:3129 \
ducmthai/openconnect:latest
ducmthai commented 2 months ago

You can try with using another LOCAL_NETWORK cidr, I don't know what is the CIDR block that your host and containers are running on, but 192.168.0.1/24 is not.

btw, kudos for specifying very detailed commands and logs :)