Skip to content
This repository was archived by the owner on Mar 16, 2024. It is now read-only.

Commit 2fb155f

Browse files
author
wfg
committed
Update image to use Dante instead of Shadowsocks
1 parent b34c2c5 commit 2fb155f

File tree

10 files changed

+145
-144
lines changed

10 files changed

+145
-144
lines changed

.dockerignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
.git
2-
.gitignore
3-
packages.txt
42
README.md

Dockerfile

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
1-
FROM alpine:3.12
1+
FROM alpine:3.13.1 AS build
22

3-
LABEL maintainer="[email protected]"
3+
ARG DANTE_VERSION=1.4.2
44

5-
ENV KILL_SWITCH=on\
6-
VPN_LOG_LEVEL=3
5+
RUN apk add --no-cache build-base
6+
RUN wget https://www.inet.no/dante/files/dante-$DANTE_VERSION.tar.gz --output-document - | tar -xz \
7+
&& cd dante-$DANTE_VERSION \
8+
&& ac_cv_func_sched_setscheduler=no ./configure --disable-client \
9+
&& make install
710

8-
RUN \
9-
echo '@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories && \
10-
apk add --no-cache \
11+
12+
FROM alpine:3.13.1
13+
14+
ARG IMAGE_VERSION
15+
ARG BUILD_DATE
16+
17+
LABEL source="github.com/wfg/docker-openvpn-client"
18+
LABEL version="$IMAGE_VERSION"
19+
LABEL created="$BUILD_DATE"
20+
21+
COPY --from=build /usr/local/sbin/sockd /usr/local/sbin/sockd
22+
23+
ENV KILL_SWITCH=on \
24+
VPN_LOG_LEVEL=3 \
25+
HTTP_PROXY=off \
26+
SOCKS_PROXY=off
27+
28+
RUN apk add --no-cache \
1129
bind-tools \
1230
openvpn \
13-
shadowsocks-libev@testing \
1431
tinyproxy
1532

16-
RUN \
17-
mkdir -p /data/vpn && \
18-
addgroup -S shadowsocks && \
19-
adduser -S -G shadowsocks -g "shadowsocks user" -H -h /dev/null shadowsocks
33+
RUN mkdir -p /data/vpn \
34+
&& addgroup -S socks \
35+
&& adduser -S -D -G socks -g "socks" -H -h /dev/null socks
2036

2137
COPY data/ /data
2238

README.md

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OpenVPN Client for Docker
22
## What is this and what does it do?
3-
[`yacht7/openvpn-client`](https://hub.docker.com/r/yacht7/openvpn-client) is a containerized OpenVPN client. It has a kill switch built with `iptables` that kills Internet connectivity to the container if the VPN tunnel goes down for any reason. It also includes two types of proxy: HTTP (Tinyproxy) and SOCKS5 (Shadowsocks). These allow hosts and non-containerized applications to use the VPN without having to run VPN clients on those hosts.
3+
`ghcr.io/wfg/openvpn-client` is a containerized OpenVPN client. It has a kill switch built with `iptables` that kills Internet connectivity to the container if the VPN tunnel goes down for any reason. It also includes an HTTP proxy server ([Tinyproxy](https://tinyproxy.github.io/)) and a SOCKS proxy server ([Dante](https://www.inet.no/dante/index.html)). This allows hosts and non-containerized applications to use the VPN without having to run VPN clients on those hosts.
44

55
This image requires you to supply the necessary OpenVPN configuration file(s). Because of this, any VPN provider should work (however, if you find something that doesn't, please open an issue for it).
66

@@ -11,19 +11,19 @@ The idea for this image came from a similar project by [qdm12](https://github.co
1111

1212
## How do I use it?
1313
### Getting the image
14-
You can either pull it from Docker Hub or build it yourself.
14+
You can either pull it from GitHub Container Registry or build it yourself.
1515

16-
To pull from [Docker Hub](https://hub.docker.com/r/yacht7/openvpn-client), run `docker pull yacht7/openvpn-client`.
16+
To pull from GitHub Container Registry, run `docker pull ghcr.io/wfg/openvpn-client`.
1717

1818
To build it yourself, do the following:
1919
```bash
20-
git clone https://github.com/yacht7/docker-openvpn-client.git
20+
git clone https://github.com/wfg/docker-openvpn-client.git
2121
cd docker-openvpn-client
22-
docker build -t yacht7/openvpn-client .
22+
docker build -t ghcr.io/wfg/openvpn-client .
2323
```
2424

2525
### Creating and running a container
26-
The image requires the container be created with the `NET_ADMIN` capability and `/dev/net/tun` accessible. Below are bare-bones examples for `docker run` and Compose; however, you'll probably want to do more than just run the VPN client. See the sections below to learn how to use the [proxies](#shadowsocks-and-tinyproxy) and have [other containers use `openvpn-client`'s network stack](#using-with-other-containers).
26+
The image requires the container be created with the `NET_ADMIN` capability and `/dev/net/tun` accessible. Below are bare-bones examples for `docker run` and Compose; however, you'll probably want to do more than just run the VPN client. See the sections below to learn how to use the [proxies](#http_proxy-and-socks_proxy) and have [other containers use `openvpn-client`'s network stack](#using-with-other-containers).
2727

2828
#### `docker run`
2929
```bash
@@ -32,7 +32,7 @@ docker run -d \
3232
--cap-add=NET_ADMIN \
3333
--device=/dev/net/tun \
3434
-v <path/to/config>:/data/vpn \
35-
yacht7/openvpn-client
35+
ghcr.io/wfg/openvpn-client
3636
```
3737

3838
#### `docker-compose`
@@ -41,7 +41,7 @@ version: '2'
4141

4242
services:
4343
openvpn-client:
44-
image: yacht7/openvpn-client
44+
image: ghcr.io/wfg/openvpn-client
4545
container_name: openvpn-client
4646
cap_add:
4747
- NET_ADMIN
@@ -55,32 +55,25 @@ services:
5555
#### Environment variables
5656
| Variable | Default (blank is unset) | Description |
5757
| --- | --- | --- |
58-
| `KILL_SWITCH` | `on` | The on/off status of VPN kill switch. To disable, set to any value besides `on`. |
5958
| `SUBNETS` | | A list of one or more comma-separated subnets (e.g. `192.168.0.0/24,192.168.1.0/24`) to allow outside of the VPN tunnel. See important note about this [below](#subnets). |
60-
| `FORWARDED_PORTS` | | Port(s) forwarded by your VPN provider (e.g. `12345` or `9876,54321`) |
6159
| `VPN_LOG_LEVEL` | `3` | OpenVPN verbosity (`1`-`11`) |
62-
| `SHADOWSOCKS` | | The on/off status of Shadowsocks. To enable, set to `on`. Any other value, including leaving it unset, will cause the proxy to not start. |
63-
| `SHADOWSOCKS_PORT` | `8388` | The port on which Shadowsocks listens. If manually specified, choose a port over 1024. |
64-
| `SHADOWSOCKS_PASS` | `password` | A password is required to start Shadowsocks, so a default is specified. I recommend you change this if Shadowsocks is enabled. |
65-
| `TINYPROXY` | | The on/off status of Tinyproxy. To enable, set to `on`. Any other value, including leaving it unset, will cause the proxy to not start. |
66-
| `TINYPROXY_PORT` | `8888` | The port on which Tinyproxy listens. If manually specified, choose a port over 1024. |
67-
| `TINYPROXY_USER` | | Credentials for accessing Tinyproxy. If `TINYPROXY_USER` is specified, you must also specify `TINYPROXY_PASS`. |
68-
| `TINYPROXY_PASS` | | Credentials for accessing Tinyproxy. If `TINYPROXY_PASS` is specified, you must also specify `TINYPROXY_USER`. |
60+
| `HTTP_PROXY` | `off` | The on/off status of Tinyproxy, the built-in HTTP proxy server. To enable, set to `on`. Any other value (including unset) will cause the proxy server to not start. It listens on port 8080. |
61+
| `SOCKS_PROXY` | `off` | The on/off status of Dante, the built-in SOCKS proxy server. To enable, set to `on`. Any other value (including unset) will cause the proxy server to not start. It listens on port 1080. |
62+
| `PROXY_USERNAME` | | Credentials for accessing the proxies. If `PROXY_USERNAME` is specified, you must also specify `PROXY_PASSWORD`. |
63+
| `PROXY_PASSWORD` | | Credentials for accessing the proxies. If `PROXY_PASSWORD` is specified, you must also specify `PROXY_USERNAME`. |
6964

7065
##### Environment variable considerations
71-
###### `KILL_SWITCH`
72-
The kill switch allows connections outside of the VPN tunnel to the following two places: 1) the VPN server(s) specified in the configuration file and 2) all addresses specified in `SUBNETS`.
73-
7466
###### `SUBNETS`
75-
**Important**: The DNS server used by this container prior to VPN connection must be included in the value specified. For example, if your container is using 192.168.1.1 as a DNS server, then this address or an appropriate CIDR block must be included in `SUBNETS`. This is necessary because the kill switch blocks traffic outside of the VPN tunnel before it's actually established. If the DNS server is not whitelisted, the server addresses in the VPN configuration will not resolve.
67+
**Important**: The DNS server used by this container prior to VPN connection must be included in the value specified. For example, if your container is using 192.168.1.1 as a DNS server, then this address or an appropriate CIDR block must be included in `SUBNETS`. This is necessary because the kill switch blocks traffic outside of the VPN tunnel before it's actually established. If the DNS server is not allowed, the server addresses in the VPN configuration will not resolve.
7668

77-
The subnets specified will have routes created and whitelists added in the firewall for them which allows for connectivity to and from hosts on the subnets.
69+
The subnets specified will be allowed through the firewall which allows for connectivity to and from hosts on the subnets.
7870

79-
###### `SHADOWSOCKS` and `TINYPROXY`
80-
If enabling Shadowsocks or Tinyproxy, you'll want to publish the proxy's port in order to access the proxy. To do that using `docker run`, add `-p <host_port>:<container_port>` where `<host_port>` and `<container_port>` are whatever port your proxy is using (8388 and 8888 by default for Shadowsocks and Tinyproxy). If you're using `docker-compose`, add the below snippet to the `openvpn-client` service definition in your Compose file.
71+
###### `HTTP_PROXY` and `SOCKS_PROXY`
72+
If enabling the the proxy server(s), you'll want to publish the appropriate port(s) in order to access the server(s). To do that using `docker run`, add `-p <host_port>:8080` and/or `-p <host_port>:1080` where `<host_port>` is whatever port you want to use on the host. If you're using `docker-compose`, add the relevant port specification(s) from the snippet below to the `openvpn-client` service definition in your Compose file.
8173
```yaml
8274
ports:
83-
- <host_port>:<container_port>
75+
- <host_port>:8080
76+
- <host_port>:1080
8477
```
8578

8679
### Using with other containers
@@ -102,7 +95,7 @@ ports:
10295
In both cases, replace `<host_port>` and `<container_port>` with the port used by your connected container.
10396

10497
### Verifying functionality
105-
Once you have container running `yacht7/openvpn-client`, run the following command to spin up a temporary container using `openvpn-client` for networking. The `wget -qO - ifconfig.me` bit will return the public IP of the container (and anything else using `openvpn-client` for networking). You should see an IP address owned by your VPN provider.
98+
Once you have container running `ghcr.io/wfg/openvpn-client`, run the following command to spin up a temporary container using `openvpn-client` for networking. The `wget -qO - ifconfig.me` bit will return the public IP of the container (and anything else using `openvpn-client` for networking). You should see an IP address owned by your VPN provider.
10699
```bash
107100
docker run --rm -it --network=container:openvpn-client alpine wget -qO - ifconfig.me
108101
```
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/bin/sh
22

3+
echo -e "Running Dante SOCKS proxy server.\n"
4+
35
until ping -c 3 1.1.1.1 > /dev/null 2>&1; do
46
sleep 1
57
done
68

7-
ss-server -c /data/shadowsocks.conf
9+
sockd -f /data/sockd.conf

data/scripts/entry.sh

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ fi
3939
echo "
4040
---- Running with the following variables ----
4141
Kill switch: ${KILL_SWITCH:-off}
42-
Tinyproxy: ${TINYPROXY:-off}
43-
Shadowsocks: ${SHADOWSOCKS:-off}
44-
Whitelisting subnets: ${SUBNETS:-none}
42+
HTTP proxy: ${HTTP_PROXY:-off}
43+
SOCKS proxy: ${SOCKS_PROXY:-off}
44+
Allowing subnets: ${SUBNETS:-none}
4545
Using configuration file: $config_file_original
4646
Using OpenVPN log level: $vpn_log_level
4747
"
@@ -66,15 +66,14 @@ trap cleanup INT TERM
6666

6767
# NOTE: When testing with the kill switch enabled, don't forget to pass in the
6868
# local subnet. It will save a lot of headache.
69-
7069
if [ $KILL_SWITCH = "on" ]; then
7170
local_subnet=$(ip r | grep -v 'default via' | grep eth0 | tail -n 1 | cut -d " " -f 1)
7271
default_gateway=$(ip r | grep 'default via' | cut -d " " -f 3)
7372

7473
echo "Creating VPN kill switch and local routes."
7574

7675
echo "Allowing established and related connections..."
77-
iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
76+
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
7877

7978
echo "Allowing loopback connections..."
8079
iptables -A INPUT -i lo -j ACCEPT
@@ -114,18 +113,6 @@ if [ $KILL_SWITCH = "on" ]; then
114113
iptables -A INPUT -i tun0 -j ACCEPT
115114
iptables -A OUTPUT -o tun0 -j ACCEPT
116115

117-
echo "Allowing connections over VPN interface to forwarded ports..."
118-
if [ ! -z $FORWARDED_PORTS ]; then
119-
for port in ${FORWARDED_PORTS//,/ }; do
120-
if $(echo $port | grep -Eq '^[0-9]+$') && [ $port -ge 1024 ] && [ $port -le 65535 ]; then
121-
iptables -A INPUT -i tun0 -p tcp --dport $port -j ACCEPT
122-
iptables -A INPUT -i tun0 -p udp --dport $port -j ACCEPT
123-
else
124-
echo "WARNING: $port not a valid port. Ignoring."
125-
fi
126-
done
127-
fi
128-
129116
echo "Preventing anything else..."
130117
iptables -P INPUT DROP
131118
iptables -P OUTPUT DROP
@@ -136,29 +123,30 @@ else
136123
echo -e "WARNING: VPN kill switch is disabled. Traffic will be allowed outside of the tunnel if the connection is lost.\n"
137124
fi
138125

139-
if [ "$SHADOWSOCKS" = "on" ]; then
140-
echo -e "Running Shadowsocks.\n"
141-
sed -i \
142-
-e "/server_port/c\ \"server_port\": ${SHADOWSOCKS_PORT:-8388}," \
143-
-e "/password/c\ \"password\": \"${SHADOWSOCKS_PASS:-password}\"," \
144-
/data/shadowsocks.conf
145-
/data/scripts/shadowsocks-wrapper.sh &
126+
if [ "$HTTP_PROXY" = "on" ]; then
127+
if [ $PROXY_USERNAME ]; then
128+
if [ $PROXY_PASSWORD ]; then
129+
echo "Configuring proxy authentication."
130+
echo -e "\nBasicAuth $PROXY_USERNAME $PROXY_PASSWORD" >> /data/tinyproxy.conf
131+
else
132+
echo "WARNING: Proxy username supplied without password. Starting HTTP proxy without credentials."
133+
fi
134+
fi
135+
/data/scripts/tinyproxy_wrapper.sh &
146136
fi
147137

148-
if [ "$TINYPROXY" = "on" ]; then
149-
echo -e "Running Tinyproxy.\n"
150-
sed -i \
151-
-e "/Port/c Port ${TINYPROXY_PORT:-8888}" \
152-
/data/tinyproxy.conf
153-
154-
if [ $TINYPROXY_USER ]; then
155-
if [ $TINYPROXY_PASS ]; then
156-
echo -e "\nBasicAuth $TINYPROXY_USER $TINYPROXY_PASS" >> /data/tinyproxy.conf
138+
if [ "$SOCKS_PROXY" = "on" ]; then
139+
if [ $PROXY_USERNAME ]; then
140+
if [ $PROXY_PASSWORD ]; then
141+
echo "Configuring proxy authentication."
142+
adduser -S -D -g $PROXY_USERNAME -H -h /dev/null $PROXY_USERNAME
143+
echo "$PROXY_USERNAME:$PROXY_PASSWORD" | chpasswd 2> /dev/null
144+
sed -i 's/socksmethod: none/socksmethod: username/' /data/sockd.conf
157145
else
158-
echo "WARNING: Tinyproxy username supplied without password. Starting without credentials."
146+
echo "WARNING: Proxy username supplied without password. Starting SOCKS proxy without credentials."
159147
fi
160148
fi
161-
/data/scripts/tinyproxy-wrapper.sh &
149+
/data/scripts/dante_wrapper.sh &
162150
fi
163151

164152
echo -e "Running OpenVPN client.\n"
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#!/bin/sh
22

3+
echo -e "Running Tinyproxy HTTP proxy server.\n"
4+
35
until ping -c 3 1.1.1.1 > /dev/null 2>&1; do
46
sleep 1
57
done
68

7-
# This part is in the wrapper script because addr_tun requires the VPN connection
8-
# to be established.
9+
addr_eth=$(ip a show dev eth0 | grep inet | cut -d " " -f 6 | cut -d "/" -f 1)
910
addr_tun=$(ip a show dev tun0 | grep inet | cut -d " " -f 6 | cut -d "/" -f 1)
1011
sed -i \
12+
-e "/Listen/c Listen $addr_eth" \
1113
-e "/Bind/c Bind $addr_tun" \
1214
/data/tinyproxy.conf
1315

data/shadowsocks.conf

Lines changed: 0 additions & 11 deletions
This file was deleted.

data/sockd.conf

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Logging
2+
logoutput: /var/log/sockd.log
3+
errorlog: stderr
4+
5+
# Server address specification
6+
internal: eth0 port = 1080
7+
external: tun0
8+
9+
# Authentication methods
10+
clientmethod: none
11+
socksmethod: none
12+
13+
# Server identities
14+
user.unprivileged: socks
15+
16+
##
17+
## SOCKS client access rules
18+
##
19+
# Rule processing stops at the first match; no match results in blocking
20+
21+
# Block access to socks server from 192.0.2.22
22+
# client block {
23+
# # Block connections from 192.0.2.22/32
24+
# from: 192.0.2.22/24 to: 0.0.0.0/0
25+
# log: error # connect disconnect
26+
# }
27+
28+
# Allow all connections
29+
client pass {
30+
from: 0.0.0.0/0 to: 0.0.0.0/0
31+
log: error connect disconnect
32+
}
33+
34+
##
35+
## SOCKS command rules
36+
##
37+
# Rule processing stops at the first match; no match results in blocking
38+
39+
# Block communication with www.example.org
40+
# socks block {
41+
# from: 0.0.0.0/0 to: www.example.org
42+
# command: bind connect udpassociate
43+
# log: error # connect disconnect iooperation
44+
# }
45+
46+
# Generic pass statement - bind/outgoing traffic
47+
socks pass {
48+
from: 0.0.0.0/0 to: 0.0.0.0/0
49+
command: bind connect udpassociate
50+
log: error connect disconnect # iooperation
51+
}
52+
53+
# Block incoming connections/packets from ftp.example.org
54+
# socks block {
55+
# from: ftp.example.org to: 0.0.0.0/0
56+
# command: bindreply udpreply
57+
# log: error # connect disconnect iooperation
58+
# }
59+
60+
# Generic pass statement for incoming connections/packets
61+
socks pass {
62+
from: 0.0.0.0/0 to: 0.0.0.0/0
63+
command: bindreply udpreply
64+
log: error connect disconnect # iooperation
65+
}

data/tinyproxy.conf

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
# forward proxy
2-
31
User tinyproxy
42
Group tinyproxy
53

6-
Port
7-
Listen 0.0.0.0
4+
Port 8080
5+
Listen
86
Bind
97

108
Timeout 600
@@ -18,4 +16,4 @@ LogLevel Info
1816
MaxClients 100
1917
MinSpareServers 5
2018
MaxSpareServers 15
21-
StartServers 10
19+
StartServers 10

0 commit comments

Comments
 (0)