Skip to content

Commit

Permalink
Merge pull request #2 from tmknight/testing
Browse files Browse the repository at this point in the history
Merge of testing in preparation for release 1.5.0
  • Loading branch information
tmknight authored Dec 17, 2022
2 parents 1c93f8c + 70900e5 commit fbe0b59
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 94 deletions.
111 changes: 48 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[![GitHubPackage][GitHubPackageBadge]][GitHubLink]
<!-- markdownlint-disable MD041 -->
[![GitHubPackage][GitHubPackageBadge]][GitHubPackageLink]
[![DockerPublishing][DockerPublishingBadge]][DockerLink]
[![DockerSize][DockerSizeBadge]][DockerLink]
[![DockerPulls][DockerPullsBadge]][DockerLink]
Expand All @@ -8,99 +9,83 @@
Leveraging the native NordVPN client and iptables to create the fastest, most stable connection possible.

# The Essentials

Build based on:

- Ubuntu `22.04`
- NordVPN `3.15.2`

Docker Hub repository:
- https://hub.docker.com/repository/docker/tmknight88/nordvpn
Examples of use:

Examples:
- [nordvpn_proxy.yml](https://github.com/tmknight/docker-nordvpn/blob/main/nordvpn_proxy.yml)

Docker Hub repository:

- <https://hub.docker.com/r/tmknight88/nordvpn>

# Requirements

Add [capabilities](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities):

- NET_ADMIN

Environment variables:

- TOKEN (or USER & PASS/PASSFILE)
- NET_LOCAL (technically not required for the container to work, but it should be set if local traffic is to be routed through VPN)

# Recommendations
IPv6 support is limited and generally [not supported](https://nordvpn.com/blog/ipv4-vs-ipv6/#:~:text=You%20might%20be%20wondering%20what,tunnel%20with%20the%20IPv4%20protocol.) by most VPN providers at this time. Therefore, it is recommended to disable IPv6 support in your container via [sysctl](https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime):

IPv6 support is limited and generally [not supported](https://nordvpn.com/blog/ipv4-vs-ipv6/#:~:text=You%20might%20be%20wondering%20what,tunnel%20with%20the%20IPv4%20protocol.) by most VPN providers at this time. - ` Therefore, it is recommended to disable IPv6 support in your container via [sysctl](https://docs.docker.com/engine/reference/commandline/run/#configure-namespaced-kernel-parameters-sysctls-at-runtime):

`net.ipv6.conf.all.disable_ipv6=1`

# Environment Variables

Generally, the default settings will provide a great experience, however, several environment variables are available to provide flexibility:

* `TOKEN` - RECOMMENDED and used in place of `USER` and `PASS` for NordVPN account
- Generated from your NordVPN account web portal
* `USER` - User for NordVPN account
- Not required when using `TOKEN`
* `PASS` - Password for NordVPN account
- Surround in single quotes to prevent issues with special characters such as `$`.
- Not required when using `TOKEN` or `PASSFILE`
* `PASSFILE` - File from which to get `PASS`
- If using [docker secrets](https://docs.docker.com/compose/compose-file/compose-file-v3/#secrets), this should be set to `/run/secrets/<secret_name>`
- This file should contain just the account password on the first line.
* `CONNECT` - [country]/[server]/[country_code]/[city]/[group] or [country] [city] (default = connect to the recommended server).
- Use [NordVPN API](https://github.com/tmknight/docker-nordvpn#additional-information) to get the list of countries, cities, etc.
- Provide a [country] argument to connect to a specific country
- Example `CONNECT=Australia`
- Provide a [server] argument to connect to a specific server
- Example `CONNECT=jp35`
- Provide a [country_code] argument to connect to a specific country
- Example `CONNECT=us`
- Provide a [city] argument to connect to a specific city
- Example `CONNECT=Hungary Budapest`
- Provide a [group] argument to connect to a specific servers group
- Example `CONNECT=P2P`
- `--group` value Specify a server group to connect to
- Example `--group p2p us`
* `PRE_CONNECT` - Command to execute before attempt to connect
* `POST_CONNECT` - Command to execute after successful connection
* `DNS` - Up to 3 DNS servers or Disable (setting DNS disables CyberSec; default = NordVPN DNS servers)
- Example `1.1.1.1,8.8.8.8`
* `FIREWALL` - TRUE or FALSE (default = TRUE)
* `KILLSWITCH` - TRUE or FALSE (FIREWALL must also be true; default = TRUE)
* `OBFUSCATE` - TRUE or FALSE (only valid when using OpenVpn; default = FALSE)
- Learn more at https://nordvpn.com/features/obfuscated-servers/
* `CYBER_SEC` - TRUE or FALSE (default = FALSE)
- Learn more at https://nordvpn.com/features/cybersec/
* `TECHNOLOGY` - Specify Technology to use (default = NordLynx)
- OpenVPN - Traditional connection.
- NordLynx - NordVpn wireguard implementation (much faster than OpenVPN)
* `PROTOCOL` - TCP or UDP (only valid when using OpenVPN; default = UDP)
* `NET_LOCAL` - Add a route to local IPv4 network once the VPN is up
- CIDR IPv4 networks: `192.168.1.0/24`
- The Docker network is automatically added
* `NET6_LOCAL` - Add a route to local IPv6 network once the VPN is up
- CIDR IPv6 networks `fe00:d34d:b33f::/64`
- The Docker network is automatically added
* `PORTS` - Semicolon delimited list of ports to whitelist for both UDP and TCP
- Example `PORTS=9091;9095`
* `PORT_RANGE` - Port range to whitelist for both UDP and TCP
- Example `PORT_RANGE=9091 9095`
* `CHECK_CONNECTION_INTERVAL` - Time in seconds to check connection and reconnect if need it. (default = 60)
- Example `CHECK_CONNECTION_INTERVAL=300`
* `CHECK_CONNECTION_URL` - URL for checking Internet connection. (default = https://www.google.com)
- Example `CHECK_CONNECTION_URL=www.custom.domain`
* `REFRESH_CONNECTION_INTERVAL` - Time in minutes to trigger VPN reconnection to help ensure best connection available (default = 120; disable = 0)
- Example `REFRESH_CONNECTION_INTERVAL=240`
| Variable | Default | Description |
|:-------------------------------:|:------------------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **BYPASS_LIST** | | Comma-separated list of domain names that should bypass VPN (i.e. these connections should not be secured); `FIREWALL` must be FALSE |
| **CHECK_CONNECTION_INTERVAL** | 60 | Time in seconds to check connection state and remediate as required |
| **CHECK_CONNECTION_URL** | <https://www.google.com> | URL used by `CHECK_CONNECTION_INTERVAL` |
| **CONNECT** | | [country]/[server]/[country_code]/[city]/[group] or [country] [city] (leave unset to connect to the recommended server; use [NordVPN API](https://github.com/tmknight/docker-nordvpn#additional-information) to get the list of countries, cities, etc.) |
| **CYBER_SEC** | FALSE | Learn more at [NordVPN](https://nordvpn.com/features/cybersec/) (TRUE/FALSE) |
| **DNS** | | A comma-separated list of IPv4/IPv6 addresses to be set as the interface's DNS servers, or non-IP hostnames to be set as the interface's DNS search domains (leave unset to use NordVPN servers) |
| **FIREWALL** | TRUE | Use the NordVPN firewall over iptables (TRUE/FALSE; Must be set to FALSE in order to use `BYPASS_LIST`) |
| **KILLSWITCH** | TRUE | Use the NordVPN kill switch; `FIREWALL` must also be TRUE (TRUE/FALSE) |
| **NET_LOCAL** | | Add a route to local IPv4 network once the VPN is up; the Docker network is automatically added; must be CIDR IPv4 format (e.g. `192.168.1.0/24`) |
| **NET6_LOCAL** | | Add a route to local IPv4 network once the VPN is up; the Docker network is automatically added; must be CIDR IPv6 format (e.g. `fe00:d34d:b33f::/64`) |
| **OBFUSCATE** | FALSE | Only valid when using TECHNOLOGY OpenVPN; learn more at [NordVPN](https://nordvpn.com/features/obfuscated-servers/) (TRUE/FALSE) |
| **PASS** | | Password for NordVPN account; surround in single quotes to prevent issues with special characters such as `$` (not required when using `TOKEN` or `PASSFILE`) |
| **PASSFILE** | | For use with `USER` and [docker secrets](https://docs.docker.com/compose/compose-file/compose-file-v3/#secrets), this should be set to `/run/secrets/<secret_name>`; this file should contain just the account password on the first line |
| **PORT_RANGE** | | Port range to whitelist for both UDP and TCP; (e.g. `PORT_RANGE=9091 9095`) |
| **PORTS** | | Semicolon delimited list of ports to whitelist for both UDP and TCP; (e.g `PORTS=9091;9095`) |
| **POST_CONNECT** | | Command to execute after successful connection |
| **PRE_CONNECT** | | Command to execute before attempt to connect |
| **PROTOCOL** | UDP | Only valid when using TECHNOLOGY OpenVPN (TCP/UDP) |
| **REFRESH_CONNECTION_INTERVAL** | 120 | Time in minutes to trigger VPN reconnection to help ensure best connection available |
| **TECHNOLOGY** | NordLynx | Specify Technology to use (NordLynx/OpenVPN) |
| **TOKEN** | | **RECOMMENDED**; use in place of `USER` and `PASS` for NordVPN account; generated from your NordVPN account web portal |
| **USER** | | User for NordVPN account (not required when using `TOKEN`) |

# Additional Information

Using the NordVPN API:
- https://sleeplessbeastie.eu/2019/02/18/how-to-use-public-nordvpn-api/

- <https://sleeplessbeastie.eu/2019/02/18/how-to-use-public-nordvpn-api>

# Credits
Scripts based on the excellent work of https://github.com/bubuntux/nordvpn

Scripts based on the excellent work of <https://github.com/bubuntux/nordvpn>

# Disclaimers
This project is independently developed for personal use; there is no affiliation with NordVpn or Nord Security companies. Nord Security companies are not responsible for, nor have control over, the nature, content and availability of this project.

This project is independently developed for personal use; there is no affiliation with NordVPN or Nord Security companies. Nord Security companies are not responsible for, nor have control over, the nature, content and availability of this project.

[GitHubPackageBadge]: https://github.com/tmknight/docker-nordvpn/actions/workflows/github-package.yml/badge.svg
[GitHubLink]: https://github.com/tmknight/docker-nordvpn
[GitHubPackageLink]: https://github.com/tmknight/docker-nordvpn/pkgs/container/nordvpn
[DockerPublishingBadge]: https://github.com/tmknight/docker-nordvpn/actions/workflows/docker-publish.yml/badge.svg
[DockerPullsBadge]: https://badgen.net/docker/pulls/tmknight88/nordvpn?icon=docker&label=Docker+Pulls&labelColor=black&color=green
[DockerSizeBadge]: https://badgen.net/docker/size/tmknight88/nordvpn?icon=docker&label=Docker+Size&labelColor=black&color=green
Expand Down
1 change: 1 addition & 0 deletions nordvpn.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ RUN apt-get update -qq \
curl \
iputils-ping \
libc6 \
dnsutils \
## only if desired to obtain the private key
# wireguard \
&& curl -so /tmp/nordrepo.deb https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn-release_1.0.0_all.deb \
Expand Down
6 changes: 3 additions & 3 deletions nordvpn_proxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ services:
mem_limit: 128m
memswap_limit: 128m
env_file: ./nord.env
environment: # Review https://github.com/tmknight/nordvpn#environment-variables
CHECK_CONNECTION_INTERVAL: 300
KILLSWITCH: true
environment: # Review https://github.com/tmknight/docker-nordvpn#environment-variables
CHECK_CONNECTION_INTERVAL: 120
BYPASS_LIST: iconfig.co,whatsmyip.com
ports:
- 8888:8118
sysctls:
Expand Down
21 changes: 15 additions & 6 deletions nordvpn_start.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash

shopt -s nocasematch
## Set iptables
## NET_LOCAL is blocked until VPN connected
00-firewall
Expand All @@ -12,17 +13,11 @@ then
fi

## if not using Nordlynx
shopt -s nocasematch
if [[ ${TECHNOLOGY} != "NordLynx" ]]
then
20-tun
fi

## Not sure about wanting to include this
## Seems prudent as these are non-VPN connections
## WIP
# 40-allowlist

## Start nordvpn daemon
rm /run/nordvpn/* 2>/dev/null
nordvpnd >/dev/null &
Expand All @@ -48,6 +43,20 @@ then
30-route6 >/dev/null
fi

## Not sure about wanting to include this
## Seems prudent as these are non-VPN connections
## WIP
if [[ -n ${BYPASS_LIST} ]]
then
if [[ -n ${FIREWALL} && "${FIREWALL}" == "false" || -z ${FIREWALL} ]]
then
40-bypasslist
else
echo -e $(date "+%F %T%z") "\tWARNING\tFIREWALL use overrides BYPASS_LIST; BYPASS_LIST will not be honored"
echo -e $(date "+%F %T%z") "\tWARNING\tPlease leave FIREWALL unset or FALSE for BYPASS_LIST to be honored"
fi
fi

## Expose private key with Wireguard
if [ $(which wg) ]
then
Expand Down
13 changes: 0 additions & 13 deletions scripts/40-allowlist

This file was deleted.

21 changes: 21 additions & 0 deletions scripts/40-bypasslist
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

[[ -n ${WHITELIST} && -z ${BYPASS_LIST} ]] && BYPASS_LIST=${WHITELIST}
if [[ -n ${BYPASS_LIST} ]]
then
gw="$(ip route | awk '/default/{print $3}')"
for domain in ${BYPASS_LIST//[;,]/ }
do
domain=$(echo "$domain" | sed 's/^.*:\/\///;s/\/.*$//')
echo -e $(date "+%F %T%z") "\tINFO\tEnabling unsecured connection to host '${domain}'"
## set iptables
iptables -A OUTPUT -o eth0 -d "${domain}" -j ACCEPT # 2>/dev/null
[[ -n $(dockerNetworks6) ]] && ip6tables -A OUTPUT -o eth0 -d "${domain}" -j ACCEPT # 2>/dev/null
## route IPs to eth0
ips=$(dig +short $domain | sed 's/^.*:\/\///;s/\/.*$//')
for ip in $ips
do
ip route | grep -q "$ip" || ip route add $ip via $gw dev eth0
done
done
fi
Loading

0 comments on commit fbe0b59

Please sign in to comment.