mirror of
https://github.com/wfg/docker-wireguard.git
synced 2025-12-20 00:15:42 +01:00
Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Anything used during development should be put in local/ to prevent accidental committing.
|
||||
local/
|
||||
88
README.md
Normal file
88
README.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# WireGuard client for Docker
|
||||
## What is this and what does it do?
|
||||
`wireguard` is exactly what it says on the tin (a containerized WireGuard client).
|
||||
It has a built-in kill switch to stop Internet connectivity if the VPN goes down for any reason.
|
||||
|
||||
## Why?
|
||||
Having a containerized VPN client lets you use container networking to easily choose which applications you want using the VPN instead of having to set up split tunnelling.
|
||||
|
||||
## How do I use it?
|
||||
### Getting the image
|
||||
You can either pull it from GitHub Container Registry or build it yourself.
|
||||
|
||||
To pull it from GitHub Container Registry, run
|
||||
```
|
||||
docker pull ghcr.io/wfg/wireguard
|
||||
```
|
||||
|
||||
To build it yourself, run
|
||||
```
|
||||
docker build -t ghcr.io/wfg/wireguard https://github.com/wfg/docker-wireguard.git#:build
|
||||
```
|
||||
|
||||
### Creating and running a container
|
||||
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 have [other containers use `wireguard`'s network stack](#using-with-other-containers).
|
||||
|
||||
#### `docker run`
|
||||
```
|
||||
docker run --detach \
|
||||
--name wireguard \
|
||||
--cap-add NET_ADMIN \
|
||||
--sysctl net.ipv4.conf.all.src_valid_mark=1 \
|
||||
--volume <path/to/config>:/etc/wireguard/wg0.conf \
|
||||
ghcr.io/wfg/wireguard
|
||||
```
|
||||
|
||||
#### `docker-compose`
|
||||
```yaml
|
||||
services:
|
||||
wireguard:
|
||||
image: ghcr.io/wfg/wireguard
|
||||
container_name: wireguard
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
sysctls:
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
volumes:
|
||||
- <path/to/config>:/etc/wireguard/wg0.conf
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
#### Environment variables
|
||||
| Variable | Default (blank is unset) | Description |
|
||||
| --- | --- | --- |
|
||||
| `ALLOWED_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. |
|
||||
|
||||
##### Environment variable considerations
|
||||
###### `ALLOWED_SUBNETS`
|
||||
If you intend on connecting to containers that use the WireGuard container's network stack (which you probably do), **you will want to use this variable**.
|
||||
|
||||
### Using with other containers
|
||||
Once you have your `wireguard` container up and running, you can tell other containers to use `wireguard`'s network stack which gives them the ability to utilize the VPN tunnel.
|
||||
There are a few ways to accomplish this depending how how your container is created.
|
||||
|
||||
If your container is being created with
|
||||
1. the same Compose YAML file as `wireguard`, add `network_mode: service:wireguard` to the container's service definition.
|
||||
2. a different Compose YAML file than `wireguard`, add `network_mode: container:wireguard` to the container's service definition.
|
||||
3. `docker run`, add `--network=container:wireguard` as an option to `docker run`.
|
||||
|
||||
Once running and provided your container has `wget` or `curl`, you can run `docker exec <container_name> wget -qO - ifconfig.me` or `docker exec <container_name> curl -s ifconfig.me` to get the public IP of the container and make sure everything is working as expected.
|
||||
This IP should match the one of `wireguard`.
|
||||
|
||||
#### Handling ports intended for connected containers
|
||||
If you have a connected container and you need to access a port that container, you'll want to publish that port on the `wireguard` container instead of the connected container.
|
||||
To do that, add `-p <host_port>:<container_port>` if you're using `docker run`, or add the below snippet to the `wireguard` service definition in your Compose file if using `docker-compose`.
|
||||
```yaml
|
||||
ports:
|
||||
- <host_port>:<container_port>
|
||||
```
|
||||
In both cases, replace `<host_port>` and `<container_port>` with the port used by your connected container.
|
||||
|
||||
### Verifying functionality
|
||||
Once you have container running `ghcr.io/wfg/wireguard`, run the following command to spin up a temporary container using `wireguard` for networking.
|
||||
The `wget -qO - ifconfig.me` bit will return the public IP of the container.
|
||||
You should see an IP address owned by your VPN provider.
|
||||
```bash
|
||||
docker run --rm -it --network=container:wireguard alpine wget -qO - ifconfig.me
|
||||
```
|
||||
16
build.py
Executable file
16
build.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import datetime
|
||||
import subprocess
|
||||
|
||||
|
||||
image_tag = 'latest'
|
||||
|
||||
docker_build_cmd = [
|
||||
'docker', 'build',
|
||||
'--build-arg', f'BUILD_DATE={str(datetime.datetime.utcnow())}',
|
||||
'--build-arg', f'IMAGE_VERSION={image_tag}',
|
||||
'--tag', f'ghcr.io/wfg/wireguard:{image_tag}',
|
||||
'./build',
|
||||
]
|
||||
subprocess.run(docker_build_cmd)
|
||||
17
build/Dockerfile
Normal file
17
build/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM alpine:3.16
|
||||
|
||||
RUN apk add --no-cache \
|
||||
wireguard-tools
|
||||
|
||||
# Make wg-quick docker-friendly
|
||||
RUN sed -i '/sysctl -q net.ipv4.conf.all.src_valid_mark=1/d' \
|
||||
"$(which wg-quick)"
|
||||
|
||||
COPY entry.sh /usr/local/bin
|
||||
|
||||
ENTRYPOINT [ "entry.sh" ]
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG IMAGE_VERSION
|
||||
LABEL build-date=$BUILD_DATE
|
||||
LABEL image-version=$IMAGE_VERSION
|
||||
45
build/entry.sh
Executable file
45
build/entry.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
cleanup() {
|
||||
wg-quick down "$1"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Find a config file and isolate the interface name
|
||||
config_file=$(find /etc/wireguard -type f -name '*.conf' | shuf -n 1)
|
||||
if [[ -z $config_file ]]; then
|
||||
echo "config file not found"
|
||||
exit 1
|
||||
fi
|
||||
interface=$(basename "${config_file%.*}")
|
||||
|
||||
# Bring up the WireGuard interface
|
||||
wg-quick up "$interface"
|
||||
|
||||
# > ...when used with interfaces that have a peer that specifies 0.0.0.0/0 as part of the ‘AllowedIPs’,
|
||||
# > [this iptables command] works together with wg-quick’s fwmark usage in order to drop all packets
|
||||
# > that are either not coming out of the tunnel encrypted or not going through the tunnel itself
|
||||
# Source: https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
|
||||
#
|
||||
# This also allows packets to the Docker network
|
||||
iptables --insert OUTPUT \
|
||||
! --out-interface "$interface" \
|
||||
--match mark ! --mark "$(wg show "$interface" fwmark)" \
|
||||
--match addrtype ! --dst-type LOCAL \
|
||||
! --destination "$(ip -o addr show dev eth0 | awk '$3 == "inet" {print $4}')" \
|
||||
--jump REJECT
|
||||
|
||||
# Create static routes for any ALLOWED_SUBNETS and punch holes in the firewall
|
||||
default_gateway=$(ip -4 route | grep default | awk '{print $3}')
|
||||
for subnet in ${ALLOWED_SUBNETS//,/ }; do
|
||||
ip route add "$subnet" via "$default_gateway"
|
||||
iptables --insert OUTPUT --destination "$subnet" --jump ACCEPT
|
||||
done
|
||||
|
||||
# Gracefully exit when signalled
|
||||
trap 'cleanup $interface' TERM INT QUIT
|
||||
|
||||
sleep infinity &
|
||||
wait
|
||||
13
docker-compose.yaml
Normal file
13
docker-compose.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
services:
|
||||
wireguard:
|
||||
image: ghcr.io/wfg/wireguard:latest
|
||||
container_name: wireguard
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
sysctls:
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
environment:
|
||||
- ALLOWED_SUBNETS=192.168.10.0/24
|
||||
volumes:
|
||||
- ./wg0.conf:/etc/wireguard/wg0.conf
|
||||
restart: unless-stopped
|
||||
Reference in New Issue
Block a user