Private Internet Access Client (OpenVPN+Iptables+DNS over TLS on Alpine Linux)

Docker VPN client to private internet access servers using OpenVPN, Iptables and Unbound (Cloudflare DNS over TLS) on 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.

PIA Docker OpenVPN

Build Status Docker Build Status

GitHub last commit GitHub commit activity GitHub issues

Docker Pulls Docker Stars Docker Automated

? ?

Download size Image size RAM usage CPU usage
6.6MB 15.7MB 14MB Low

Features

  • Uses OpenVPN 2.4.6-r3 to connect to PIA servers
  • The firewall IPtables 1.6.2-r0 enforces the container to communicate only through the VPN or with other containers in its virtual network
  • Your DNS queries are encrypted using Unbound 1.7.3-r0 configure with Cloudflare's 1.1.1.1 DNS over TLS
  • Malicious domain names resolution is blocked with Unbound 1.7.3-r0
  • Lightweight, based on Alpine 3.8
  • 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 wget on duckduckgo.com
  • Connect other containers to it

Requirements

  • A Private Internet Access username and password - Sign up
  • Docker installed on the host
  • If you use an advanced firewall:
    • 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 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

  1. Make sure you have your /dev/net/tun device setup on your host with one of the following commands, depending on your OS:

    insmod /lib/modules/tun.ko
    

    Or

    sudo modprobe tun
    
  2. Create a network to be used by this container and other containers connecting to it with:

    docker network create pianet
    
  3. Create a file auth.conf in /yourhostpath (for example), with:

    • On the first line: your PIA username (i.e. js89ds7)
    • On the second line: your PIA password (i.e. 8fd9s239G)

Option 1: Using Docker only

  1. Run the container with (at least change /yourhostpath to your actual path):

    docker run -d --name=pia \
    --cap-add=NET_ADMIN --device=/dev/net/tun --network=pianet \
    -v /yourhostpath/auth.conf:/auth.conf:ro \
    -e REGION=Germany -e PROTOCOL=udp -e ENCRYPTION=normal \
    qmcgaw/private-internet-access
    

    Note that you can change REGION, PROTOCOL and ENCRYPTION, see the Environment variables section for more.

  2. Wait about 5 seconds for it to connect to the PIA server. You can check with:

    docker logs pia
    
  3. Follow the Testing section

Option 2: Using Docker Compose

  1. Download docker-compose.yml

  2. Edit it and change at least yourpath

  3. Run the container as a daemon in the background with:

    docker-compose up -d
    

    Note that you can change REGION, PROTOCOL and ENCRYPTION, see the Environment variables section for more.

  4. Wait about 5 seconds for it to connect to the PIA server. You can check with:

    docker logs -f pia
    
  5. Follow the Testing section

Testing

  1. Note that you can simply use the HEALTCHECK provided. The container will stop by itself if the VPN IP is the same as your initial public IP address.

Otherwise you can follow these instructions:

  1. Check your host IP address with:

    curl -s ifconfig.co
    
  2. Run the curl Docker container using your pia container with:

    docker run --rm --network=container:pia byrnedo/alpine-curl -s ifconfig.co
    

    If the displayed IP address appears and is different that your host IP address, the PIA client works !

Environment variables

Environment variable Default Description
REGION Switzerland Any one of the regions supported by private internet access
PROTOCOL tcp tcp or udp
ENCRYPTION strong normal or strong

If you know what you're doing, you can change the container name (pia), the hostname (piaclient) and the network name (pianet) as well.

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 pia container with:

    docker run -d --name=deluge --network=container:pia linuxserver/deluge
    
  • We launch a Hydra container with name hydra connected to the pia container 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

  1. 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;
    }
    
  2. 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
    
  3. 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 with their ISPs.
  • 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

  • Block malicious websites with Unbound
  • Add checks when launching PIA $?
Description
VPN client in a thin Docker container for multiple VPN providers, written in Go, and using OpenVPN or Wireguard, DNS over TLS, with a few proxy servers built-in.
Readme MIT 33 MiB
Languages
Go 99.4%
Dockerfile 0.6%