create a wireguard vpn server setup with optional tweaks

This commit is contained in:
bodane 2025-01-12 00:29:25 +11:00
commit e1d11db71e
No known key found for this signature in database
GPG key ID: EC6CD40D2237842C
6 changed files with 251 additions and 0 deletions

3
.env Normal file
View file

@ -0,0 +1,3 @@
NODE_HOSTNAME=my.domain.name
SERVER_CNAME_NAMESPACE=my.domain.name
PEERS=changeme,changeme2

104
README.md Normal file
View file

@ -0,0 +1,104 @@
# Quick Setup Guide
The following process utilises docker containers to quickly provision a Wireguard VPN server.
## Information Gathering
Have the following known before proceeding.
- User account used to run the server.
- List of user(s) which will be VPN users (not essential, however less touches required later).
- Domain name DNS record for the server.
## Basic Setup
### Linux
1. Clone repository at your proposed server location.
```
git clone https://github.com/bodane/vpn-wireguard.git && cd vpn-wireguard
```
1. Run `vanilla-setup.sh`.
This script will:
- Create a new user.
- User will manage the VPN server components.
- Add user to sudo group.
- Install git, nano, and Docker
- Add user to Docker group.
1. Create your list of VPN users.
- Edit your `.env` file.
- Update `NODE_HOSTNAME=my.domain.name` and `SERVER_CNAME_NAMESPACE=my.domain.name` with your server DNS record.
- Update `PEERS` with your list of users, separated by commas.
**NOTE**: The user list can be updated later if not known and the container re-created without user impact. Will however disconnect users during this operation.
1. Build your Wireguard VPN server with one command.
```
docker compose up -d
```
## Add additional VPN users
1. Edit existing list of VPN users.
- Update `.env` file with your list of users.
- Add or remove users.
- All must be separated by commas.
1. Start up a new container. All past changes will persist due to the docker volumes being used.
This will setup new user VPN profiles while also leaving any present peers in-place.
```
docker compose down
docker compose up -d
```
## User Profile Location
While in the `vpn-wireguard` folder path. The user VPN profiles are located in the `config/` folder path.
## Optional Improvements
There are almost an infinite amount of configurations, however one great addition could be that we do block unsafe domains or known malicous domain names being accessed by users.
The basic script and Corefile included will assist with this configuration. We'll also use a couple of known public threat intel feeds to develop our own blacklist for use locally. How it works is, if the user were to perform a DNS query to resolve an unsafe domain, the CoreDNS server returns a DNS response of `0.0.0.0` back to the user for the target domain. This effectively prevents a request taking place to the remote host.
### Linux
1. Run `blacklist.sh` on your server endpoint. A `blacklist.txt` file will be created locally.
```
./optional-config/blacklist.sh
cp optional-config/Corefile config/coredns/Corefile
cp blacklist.txt config/coredns/blacklist.txt
```
1. Backup your current Corefile, place it in a easy to find path related to CoreDNS, and update the CoreDNS file to reference the newly created `blacklist.txt` file.
```
cp config/coredns/Corefile config/coredns/Corefile.bak
cp optional-config/Corefile config/coredns/Corefile
cp blacklist.txt config/coredns/blacklist.txt
```
1. Restart your Wireguard VPN server to have the changes all take effect.
```
docker restart lthn-vpn-wireguard-1
```
## Further improvements for consideration.
- Creating a cron schedule or similar to maintain a better active list of unsafe domains.

60
docker-compose.yml Normal file
View file

@ -0,0 +1,60 @@
version: "3.3"
services:
# Route via Traefik
router-traefik:
image: "traefik:v2.10"
env_file:
- .env
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.wireguard.address=:51820"
- "--certificatesresolvers.exitNode.acme.tlschallenge=true"
- "--certificatesresolvers.exitNode.acme.email=devops@lt.hn"
- "--certificatesresolvers.exitNode.acme.storage=/letsencrypt/acme.json"
- "--experimental.plugins.ldapAuth.modulename=github.com/wiltonsr/ldapAuth"
- "--experimental.plugins.ldapAuth.version=v0.0.22"
ports:
- "443:443"
- "80:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Wireguard VPN
vpn-wireguard:
image: linuxserver/wireguard:latest
cap_add:
- NET_ADMIN
- SYS_MODULE #optional
env_file:
- .env
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- SERVERURL=$NODE_HOSTNAME #optional
- SERVERPORT=51820 #optional
#- PEERS=1 #uncomment if wishing to not set usernames and only set a random number of peers.
- PEERDNS=auto #optional
- INTERNAL_SUBNET=10.13.13.0 #optional
- ALLOWEDIPS=0.0.0.0/0 #optional
- PERSISTENTKEEPALIVE_PEERS= #optional
- LOG_CONFS=true #optional
volumes:
- ./config:/config
- /lib/modules:/lib/modules #optional
ports:
- 51820:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
labels:
- "traefik.enable=true"
- "traefik.udp.routers.wireguard.rule=HostRegexp(`${SERVER_CNAME_NAMESPACE}`, `{subdomain:[a-z]+}.${SERVER_CNAME_NAMESPACE}`)"
- "traefik.udp.routers.wireguard.entrypoints=wireguard"
restart: unless-stopped

14
optional-config/Corefile Normal file
View file

@ -0,0 +1,14 @@
. {
# CoreDNS standard plugins
loop
errors
health
# Blocking unsafe domains
hosts /config/coredns/blacklist.txt {
fallthrough
}
# Forwarding for domains not in blocklists
forward . /etc/resolv.conf
}

View file

@ -0,0 +1,34 @@
#!/bin/bash
# Define the location for the local blacklist file
#BLACKLIST_FILE="/config/coredns/blacklist.txt"
BLACKLIST_FILE="blacklist.txt"
# URLs to download blocklists from
BLOCKLIST_URLS=(
"https://urlhaus.abuse.ch/downloads/text/"
"https://big.oisd.nl/domainswild2"
)
# Clear the current blacklist file
> $BLACKLIST_FILE
# Fetch each blocklist and format for CoreDNS
for url in "${BLOCKLIST_URLS[@]}"; do
# Download each list
curl -s "$url" | \
# Remove lines with IP addresses (matches any line containing an IP address)
grep -Ev '([0-9]{1,3}\.){3}[0-9]{1,3}' | \
# Remove lines with domain names containing non-standard ports (matches domains with a port number)
grep -Ev ':[0-9]{2,5}' | \
# For URLHaus, extract domains from full URLs if needed
grep -Eo 'https?://[^/"]+' | sed 's|https\?://||' | \
# Filter out comments and empty lines, and format for hosts
grep -v '^#' | grep -v '^$' | sed 's/^/0.0.0.0 /' >> $BLACKLIST_FILE
done
# Ensure no duplicate entries in the blacklist file
sort -u $BLACKLIST_FILE -o $BLACKLIST_FILE
# Reload CoreDNS to apply the new blacklist
#systemctl reload coredns

36
vanilla-setup.sh Normal file
View file

@ -0,0 +1,36 @@
#!/bin/bash
# Check if the script is run as root
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root or with sudo."
exit 1
fi
# Set the username as a variable
read -p "Enter the username you want to create: " USERNAME
# Create a new user with a home directory
useradd -m -s /bin/bash "$USERNAME"
# Set a password for the new user
passwd "$USERNAME"
# Give the new user sudo privileges
usermod -aG sudo "$USERNAME"
# Install git and nano
apt update
apt install -y git nano
# Install Docker
apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt update
apt install -y docker-ce
# Add the new user to the Docker group
usermod -aG docker "$USERNAME"
# Display success message
echo "User $USERNAME created, added to sudo and docker groups, and git, nano, and Docker installed."