9.4 KiB
Private Internet Access Client (OpenVPN+Iptables+DNS over TLS on Alpine Linux)
VPN client to tunnel to private internet access servers using OpenVPN, IPtables, DNS over TLS and Alpine Linux
Optionally set the protocol (TCP, UDP) and the level of encryption using Docker environment variables.
A killswitch is implemented with the iptables firewall, only allowing traffic with PIA servers on needed ports / protocols.
| Image size | RAM usage | CPU usage |
|---|---|---|
| 15.7MB | 14MB | Low |
It is based on:
- Alpine 3.8 for a tiny image
- OpenVPN 2.4.6-r3 to tunnel to PIA servers
- IPtables 1.6.2-r0 enforces the container to communicate only through the VPN or with other containers in its virtual network (killswitch)
- Unbound 1.7.3-r0 configured with Cloudflare's 1.1.1.1 DNS over TLS
- Malicious hostnames list used with Unbound (see
BLOCK_MALICIOUSenvironment variable) - Malicious IPs list used with Unbound (see
BLOCK_MALICIOUS)
Extra features
- Connect other containers to it
- Restarts OpenVPN on failure using another IP address corresponding to the PIA server domain name (usually 10 IPs per subdomain name)
- Regular Docker healthchecks using duckduckgo.com to obtain your current public IP address and compare it with your initial non-VPN IP address
- Openvpn and Unbound do not run as root
Requirements
- A Private Internet Access username and password - Sign up
- Docker installed on the host
- If you use a firewall on the host:
- Allow outgoing TCP port 853 for Cloudflare DNS over TLS initial resolution of PIA server domain name.
- Allow outgoing TCP port 443 for querying duckduckgo.com to obtain the initial IP address for the healthcheck.
- Allow outgoing TCP port 501 for TCP strong encryption
- Allow outgoing TCP port 502 for TCP normal encryption
- Allow outgoing UDP port 1197 for UDP strong encryption
- Allow outgoing UDP port 1198 for UDP normal encryption
Setup
-
Make sure you have your
/dev/net/tundevice setup on your host with one of the following commands, depending on your OS:insmod /lib/modules/tun.koOr
sudo modprobe tun -
Create a network to be used by this container and other containers connecting to it with:
docker network create pianet -
Create a file auth.conf in
./, with:- On the first line: your PIA username (i.e.
js89ds7) - On the second line: your PIA password (i.e.
8fd9s239G)
- On the first line: your PIA username (i.e.
-
Launch the container with:
docker run -d --name=pia -v ./auth.conf:/auth.conf:ro \ --cap-add=NET_ADMIN --device=/dev/net/tun --network=pianet \ -e REGION="CA Montreal" -e PROTOCOL=udp -e ENCRYPTION=strong \ qmcgaw/private-internet-accessor use docker-compose.yml with:
docker-compose up -dNote that you can change
REGION,PROTOCOLandENCRYPTION, see the Environment variables section -
Wait about 5 seconds for it to connect to the PIA server. You can check with:
docker logs -f pia -
Follow the Testing section
Testing
You can simply use the Docker healthcheck. The container will mark itself as unhealthy if the public IP address is the same as your initial public IP address. Otherwise you can follow these instructions:
-
Check your host IP address with:
wget -qO- https://ipinfo.io/ip -
Run the curl Docker container using your pia container with:
docker run --rm --network=container:pia alpine:3.8 wget -qO- https://ipinfo.io/ipIf the displayed IP address appears and is different that your host IP address, the PIA client works !
Environment variables
| Environment variable | Default | Description |
|---|---|---|
REGION |
CA Montreal |
Any one of the regions supported by private internet access |
PROTOCOL |
udp |
tcp or udp |
ENCRYPTION |
strong |
normal or strong |
BLOCK_MALICIOUS |
off |
on or off |
If you know what you're doing, you can change the container name (pia) and the network name (pianet)
Connect other containers to it
Connect other Docker containers to the PIA VPN connection by adding --network=container:pia when launching them.
EXTRA: Access ports of containers connected to the VPN container
You have to use another container acting as a Reverse Proxy such as Nginx.
Example:
-
We launch a Deluge (torrent client) container with name deluge connected to the
piacontainer with:docker run -d --name=deluge --network=container:pia linuxserver/deluge -
We launch a Hydra container with name hydra connected to the
piacontainer with:docker run -d --name=hydra --network=container:pia linuxserver/hydra -
HTTP User interfaces are accessible at port 8112 for Deluge and 5075 for Hydra
-
Create the Nginx configuration file nginx.conf:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; server { listen 1001; location / { proxy_pass http://deluge:8112/; proxy_set_header X-Deluge-Base "/"; } } server { listen 1002; location / { proxy_pass http://hydra:5075/; } } include /etc/nginx/conf.d/*.conf; } -
Run the Alpine Nginx container with:
docker run -d --name=proxypia -p 8001:1001 -p 8002:1002 \ --network=pianet --link pia:deluge --link pia:hydra \ -v /mypathto/nginx.conf:/etc/nginx/nginx.conf:ro nginx:alpine -
Access the WebUI of Deluge at localhost:8000
For more containers, add more --link pia:xxx and modify nginx.conf accordingly
EXTRA: For the paranoids
- You might want to build the Docker image yourself
- The download and unziping is done at build for the ones not able to download the zip files through their ISP
- Checksums for PIA openvpn zip files are not used as these files change often
- You should use strong encryption for the environment variable
ENCRYPTION - Let me know if you have any extra idea :) !
TODOs
- Iptables should change after initial ip address is obtained
- More checks for environment variables provided
- Add checks when launching PIA $?
- VPN server for other devices to go through the tunnel
License
This repository is under an MIT license
