Multiple additions and fixes #12

- Unbound ran as `nonrootuser`
- Readme updated
- auth.conf replaced by `USER` and `PASSWORD` env variables
- Removed Nginx section from readme for now
- Reworked entrypoint with more checks
- Malicious IPs and hostnames building is done at Docker build to gain time at launch
- docker-compose updated to reflect changes
This commit is contained in:
Quentin McGaw
2018-11-14 14:38:10 +02:00
parent 3c79ba33bb
commit d3dc6c74d8
5 changed files with 170 additions and 187 deletions

View File

@@ -11,22 +11,24 @@ LABEL org.label-schema.schema-version="1.0.0-rc1" \
org.label-schema.url="https://github.com/qdm12/private-internet-access-docker" \ org.label-schema.url="https://github.com/qdm12/private-internet-access-docker" \
org.label-schema.vcs-description="VPN client to tunnel to private internet access servers using OpenVPN, IPtables, DNS over TLS and Alpine Linux" \ org.label-schema.vcs-description="VPN client to tunnel to private internet access servers using OpenVPN, IPtables, DNS over TLS and Alpine Linux" \
org.label-schema.vcs-usage="https://github.com/qdm12/private-internet-access-docker/blob/master/README.md#setup" \ org.label-schema.vcs-usage="https://github.com/qdm12/private-internet-access-docker/blob/master/README.md#setup" \
org.label-schema.docker.cmd="docker run -d -v ./auth.conf:/auth.conf:ro --cap-add=NET_ADMIN --device=/dev/net/tun qmcgaw/private-internet-access" \ org.label-schema.docker.cmd="docker run -d --cap-add=NET_ADMIN --device=/dev/net/tun -e USER=js89ds7 -e PASSWORD=8fd9s239G qmcgaw/private-internet-access" \
org.label-schema.docker.cmd.devel="docker run -it --rm -v ./auth.conf:/auth.conf:ro --cap-add=NET_ADMIN --device=/dev/net/tun qmcgaw/private-internet-access" \ org.label-schema.docker.cmd.devel="docker run -it --rm --cap-add=NET_ADMIN --device=/dev/net/tun -e USER=js89ds7 -e PASSWORD=8fd9s239G qmcgaw/private-internet-access" \
org.label-schema.docker.params="REGION=PIA region,PROTOCOL=udp or tcp,ENCRYPTION=strong or normal,BLOCK_MALICIOUS=on or off" \ org.label-schema.docker.params="REGION=PIA region,PROTOCOL=udp/tcp,ENCRYPTION=strong/normal,BLOCK_MALICIOUS=on/off,USER=PIA user,PASSWORD=PIA password,EXTRA_SUBNETS=extra subnets to allow on the firewall" \
org.label-schema.version="" \ org.label-schema.version="" \
image-size="17.1MB" \ image-size="20MB" \
ram-usage="13MB to 80MB" \ ram-usage="13MB to 80MB" \
cpu-usage="Low" cpu-usage="Low to Medium"
ENV ENCRYPTION=strong \ ENV USER= \
PROTOCOL=tcp \ PASSWORD= \
ENCRYPTION=strong \
PROTOCOL=udp \
REGION="CA Montreal" \ REGION="CA Montreal" \
BLOCK_MALICIOUS=off BLOCK_MALICIOUS=off \
EXTRA_SUBNETS=
ENTRYPOINT /entrypoint.sh
HEALTHCHECK --interval=5m --timeout=15s --start-period=10s --retries=2 \ HEALTHCHECK --interval=5m --timeout=15s --start-period=10s --retries=2 \
CMD [ "$(wget -qqO- 'https://duckduckgo.com/?q=what+is+my+ip' | grep -ow 'Your IP address is [0-9.]*[0-9]' | grep -ow '[0-9][0-9.]*')" != "$INITIAL_IP" ] || exit 1 CMD [ "$(wget -qqO- 'https://duckduckgo.com/?q=what+is+my+ip' | grep -ow 'Your IP address is [0-9.]*[0-9]' | grep -ow '[0-9][0-9.]*')" != "$INITIAL_IP" ] || exit 1
RUN V_ALPINE="v$(cat /etc/alpine-release | grep -oE '[0-9]+\.[0-9]+')" && \ RUN apk add -q --progress --no-cache --update openvpn wget ca-certificates iptables unbound unzip && \
echo https://dl-3.alpinelinux.org/alpine/$V_ALPINE/main > /etc/apk/repositories && \
apk add -q --progress --no-cache --update openvpn wget ca-certificates iptables unbound unzip && \
wget -q https://www.privateinternetaccess.com/openvpn/openvpn.zip \ wget -q https://www.privateinternetaccess.com/openvpn/openvpn.zip \
https://www.privateinternetaccess.com/openvpn/openvpn-strong.zip \ https://www.privateinternetaccess.com/openvpn/openvpn-strong.zip \
https://www.privateinternetaccess.com/openvpn/openvpn-tcp.zip \ https://www.privateinternetaccess.com/openvpn/openvpn-tcp.zip \
@@ -37,13 +39,26 @@ RUN V_ALPINE="v$(cat /etc/alpine-release | grep -oE '[0-9]+\.[0-9]+')" && \
unzip -q openvpn-strong-tcp.zip -d /openvpn-tcp-strong && \ unzip -q openvpn-strong-tcp.zip -d /openvpn-tcp-strong && \
apk del -q --progress --purge unzip && \ apk del -q --progress --purge unzip && \
rm -rf /*.zip /var/cache/apk/* /etc/unbound/unbound.conf && \ rm -rf /*.zip /var/cache/apk/* /etc/unbound/unbound.conf && \
adduser -S nonrootuser addgroup nonrootgroup --gid 1000 && \
adduser nonrootuser -G nonrootgroup -D -H --uid 1000
COPY --from=qmcgaw/dns-trustanchor /named.root /etc/unbound/root.hints COPY --from=qmcgaw/dns-trustanchor /named.root /etc/unbound/root.hints
COPY --from=qmcgaw/dns-trustanchor /root.key /etc/unbound/root.key COPY --from=qmcgaw/dns-trustanchor /root.key /etc/unbound/root.key
COPY --from=qmcgaw/malicious-hostnames /malicious-hostnames.bz2 /etc/unbound/malicious-hostnames.bz2 COPY --from=qmcgaw/malicious-hostnames /malicious-hostnames.bz2 /tmp/malicious-hostnames.bz2
COPY --from=qmcgaw/malicious-ips /malicious-ips.bz2 /etc/unbound/malicious-ips.bz2 COPY --from=qmcgaw/malicious-ips /malicious-ips.bz2 /tmp/malicious-ips.bz2
RUN cd /tmp && \
tar -xjf malicious-hostnames.bz2 && \
tar -xjf malicious-ips.bz2 && \
while read hostname; do echo "local-zone: \""$hostname"\" static" >> blocks-malicious.conf; done < malicious-hostnames && \
while read ip; do echo "private-address: $ip" >> blocks-malicious.conf; done < malicious-ips && \
tar -cjf /etc/unbound/blocks-malicious.bz2 blocks-malicious.conf && \
rm -f /tmp/*
COPY unbound.conf /etc/unbound/unbound.conf COPY unbound.conf /etc/unbound/unbound.conf
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
RUN chown unbound /etc/unbound/root.key && \ RUN chown nonrootuser:nonrootgroup -R /etc/unbound && \
chmod 700 /entrypoint.sh chmod 700 /etc/unbound && \
ENTRYPOINT /entrypoint.sh chmod 500 /entrypoint.sh && \
chmod 400 \
/etc/unbound/root.hints \
/etc/unbound/root.key \
/etc/unbound/unbound.conf \
/etc/unbound/blocks-malicious.bz2

126
README.md
View File

@@ -2,6 +2,8 @@
*Lightweight VPN client to tunnel to private internet access servers* *Lightweight VPN client to tunnel to private internet access servers*
**WARNING: auth.conf is now replaced by the environment variables `USER` and `PASSWORD`, please update your configuration**
[![PIA Docker OpenVPN](https://github.com/qdm12/private-internet-access-docker/raw/master/readme/title.png)](https://hub.docker.com/r/qmcgaw/private-internet-access/) [![PIA Docker OpenVPN](https://github.com/qdm12/private-internet-access-docker/raw/master/readme/title.png)](https://hub.docker.com/r/qmcgaw/private-internet-access/)
[![Build Status](https://travis-ci.org/qdm12/private-internet-access-docker.svg?branch=master)](https://travis-ci.org/qdm12/private-internet-access-docker) [![Build Status](https://travis-ci.org/qdm12/private-internet-access-docker.svg?branch=master)](https://travis-ci.org/qdm12/private-internet-access-docker)
@@ -20,7 +22,7 @@
| Image size | RAM usage | CPU usage | | Image size | RAM usage | CPU usage |
| --- | --- | --- | | --- | --- | --- |
| 15.7MB | 14MB | Low | | 20MB | 14MB to 80MB | Low to Medium |
It is based on: It is based on:
@@ -33,13 +35,13 @@ It is based on:
## Extra features ## Extra features
- With environment variables, choose: - Only use environment variables:
- the PIA region - the [destination region]((https://www.privateinternetaccess.com/pages/network/))
- the protocol `TCP` or `UDP` - the protocol `tcp` or `udp`
- the level of encryption - the level of encryption `normal` or `strong`
- Connect other containers to it - Connect other containers to it
- The *iptables* firewall allows traffic only with needed PIA servers (IP addresses, port, protocol) combination - The *iptables* firewall allows traffic only with needed PIA servers (IP addresses, port, protocol) combination
- OpenVPN restarts on failure using another PIA IP address in the same region - OpenVPN restarts on failure using another PIA IP address for the same region
- Docker healthchecks using [duckduckgo.com](https://duckduckgo.com) to obtain your public IP address and compare it with your initial non-VPN IP address - Docker healthchecks using [duckduckgo.com](https://duckduckgo.com) to obtain your public IP address and compare it with your initial non-VPN IP address
- Openvpn and Unbound do not run as root - Openvpn and Unbound do not run as root
@@ -48,8 +50,8 @@ It is based on:
- A Private Internet Access **username** and **password** - [Sign up](https://www.privateinternetaccess.com/pages/buy-vpn/) - A Private Internet Access **username** and **password** - [Sign up](https://www.privateinternetaccess.com/pages/buy-vpn/)
- [Docker](https://docs.docker.com/install/) installed on the host - [Docker](https://docs.docker.com/install/) installed on the host
- If you use a firewall 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 853 for Cloudflare DNS over TLS initial resolution of PIA server domain name, **you should then BLOCK it**
- Allow outgoing TCP port 443 for querying duckduckgo.com to obtain the initial IP address for the healthcheck. - Allow outgoing TCP port 443 for querying duckduckgo.com to obtain the initial IP address *only at the start of the container*, **you should then BLOCK it**
- Allow outgoing TCP port 501 for TCP strong encryption - Allow outgoing TCP port 501 for TCP strong encryption
- Allow outgoing TCP port 502 for TCP normal encryption - Allow outgoing TCP port 502 for TCP normal encryption
- Allow outgoing UDP port 1197 for UDP strong encryption - Allow outgoing UDP port 1197 for UDP strong encryption
@@ -66,24 +68,16 @@ It is based on:
Or Or
```bash ```bash
sudo modprobe tun modprobe tun
``` ```
1. Create a network to be used by this container and other containers connecting to it with:
```bash
docker network create pianet
```
1. 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`)
1. Launch the container with: 1. Launch the container with:
```bash ```bash
docker run -d --name=pia -v ./auth.conf:/auth.conf:ro \ docker run -d --name=pia -v ./auth.conf:/auth.conf:ro \
--cap-add=NET_ADMIN --device=/dev/net/tun --network=pianet \ --cap-add=NET_ADMIN --device=/dev/net/tun --network=pianet \
-e REGION="CA Montreal" -e PROTOCOL=udp -e ENCRYPTION=strong \ -e REGION="CA Montreal" -e PROTOCOL=udp -e ENCRYPTION=strong \
-e USER=js89ds7 -e PASSWORD=8fd9s239G \
qmcgaw/private-internet-access qmcgaw/private-internet-access
``` ```
@@ -93,7 +87,7 @@ It is based on:
docker-compose up -d docker-compose up -d
``` ```
Note that you can change `REGION`, `PROTOCOL` and `ENCRYPTION`, see the [Environment variables section](#environment-variables) Note that you can change all the [environment variables](#environment-variables)
1. Wait about 5 seconds for it to connect to the PIA server. You can check with: 1. Wait about 5 seconds for it to connect to the PIA server. You can check with:
```bash ```bash
@@ -124,102 +118,38 @@ You can simply use the Docker healthcheck. The container will mark itself as **u
| Environment variable | Default | Description | | Environment variable | Default | Description |
| --- | --- | --- | | --- | --- | --- |
| `REGION` | `CA Montreal` | Any one of the [regions supported by private internet access](https://www.privateinternetaccess.com/pages/network/) | | `REGION` | `CA Montreal` | One of the [PIA regions](https://www.privateinternetaccess.com/pages/network/) |
| `PROTOCOL` | `udp` | `tcp` or `udp` | | `PROTOCOL` | `udp` | `tcp` or `udp` |
| `ENCRYPTION` | `strong` | `normal` or `strong` | | `ENCRYPTION` | `strong` | `normal` or `strong` |
| `BLOCK_MALICIOUS` | `off` | `on` or `off` | | `BLOCK_MALICIOUS` | `off` | `on` or `off` |
| `USER` | `` | Your PIA username |
| `PASSWORD` | `` | Your PIA password |
| `EXTRA_SUBNETS` | `` | Comma separated subnets allowed in the container firewall |
If you know what you're doing, you can change the container name (`pia`) and the network name (`pianet`) `EXTRA_SUBNETS` can be in example: `192.168.1.0/24,192.168.10.121,10.0.0.5/28`
## Connect other containers to it ## Connect other containers to it
Connect other Docker containers to the PIA VPN connection by adding `--network=container:pia` when launching them. Connect other Docker containers to the PIA VPN connection by adding `--network=container:pia` when launching them.
--- ## For the paranoids
## EXTRA: Access ports of containers connected to the VPN container - You can review the code which essential consits in the [Dockerfile](https://github.com/qdm12/private-internet-access-docker/blob/master/Dockerfile) and [entrypoint.sh](https://github.com/qdm12/private-internet-access-docker/blob/master/entrypoint.sh)
- Build the images yourself:
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:
```bash ```bash
docker run -d --name=deluge --network=container:pia linuxserver/deluge docker build -t qmcgaw/private-internet-access https://github.com/qdm12/private-internet-access-docker.git
``` ```
- We launch a *Hydra* container with name **hydra** connected to the `pia` container with: - The download and unziping of PIA openvpn files is done at build for the ones not able to download the zip files
- Checksums for PIA openvpn zip files are not used as these files change often (but HTTPS is used)
```bash - Use `-e ENCRYPTION=strong -e BLOCK_MALICIOUS=on`
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*:
```txt
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;
}
```
1. Run the Alpine [Nginx container](https://hub.docker.com/_/nginx) with:
```bash
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
```
1. Access the WebUI of Deluge at [localhost:8000](http://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 ## TODOs
- [ ] Test pia with port mappings and without pia_net and nginx - [ ] Malicious IPs and hostnames with wget at launch+checksums
- [ ] Iptables should change after initial ip address is obtained - [ ] Su Exec (fork and addition)
- [ ] More checks for environment variables provided - [ ] SOCKS proxy/Hiproxy/VPN server for other devices to use the container
- [ ] Add checks when launching PIA $?
- [ ] VPN server for other devices to go through the tunnel OR hiproxy
## License ## License

View File

@@ -10,15 +10,12 @@ services:
- /dev/net/tun - /dev/net/tun
networks: networks:
- pianet - pianet
volumes:
- /yourpath/auth.conf:/auth.conf:ro
environment: environment:
- PROTOCOL=tcp - USER=
- PASSWORD=
- PROTOCOL=udp
- ENCRYPTION=strong - ENCRYPTION=strong
- REGION=CA Montreal - REGION=CA Montreal
- EXTRA_SUBNETS=
restart: always restart: always
networks:
pianet:
external: true

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
exitOnError(){ exitOnError(){
# $1 should be $? # $1 must be set to $?
status=$1 status=$1
message=$2 message=$2
[ "$message" != "" ] || message="Error!" [ "$message" != "" ] || message="Error!"
@@ -11,7 +11,35 @@ exitOnError(){
fi fi
} }
printf "\n =========================================\n" exitIfUnset(){
# $1 is the name of the variable to check - not the variable itself
var="$(eval echo "\$$1")"
if [ -z "$var" ]; then
printf "Environment variable $1 is not set\n"
exit 1
fi
}
exitIfNotIn(){
# $1 is the name of the variable to check - not the variable itself
# $2 is a string of comma separated possible values
var="$(eval echo "\$$1")"
for value in ${2//,/ }
do
if [ "$var" = "$value" ]; then
return 0
fi
done
printf "Environment variable $1=$var must be one of the following: "
for value in ${2//,/ }
do
printf "$value "
done
printf "\n"
exit 1
}
printf " =========================================\n"
printf " =========================================\n" printf " =========================================\n"
printf " ============= PIA CONTAINER =============\n" printf " ============= PIA CONTAINER =============\n"
printf " =========================================\n" printf " =========================================\n"
@@ -25,9 +53,37 @@ printf "Iptables version: $(iptables --version | cut -d" " -f2)\n"
############################################ ############################################
# CHECK PARAMETERS # CHECK PARAMETERS
############################################ ############################################
exitIfUnset USER
exitIfUnset PASSWORD
exitIfNotIn ENCRYPTION "normal,strong"
exitIfNotIn PROTOCOL "tcp,udp"
exitIfNotIn BLOCK_MALICIOUS "on,off"
cat "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn" &> /dev/null cat "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn" &> /dev/null
exitOnError $? "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn is not accessible" exitOnError $? "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn is not accessible"
# TODO more for SUBNET in ${EXTRA_SUBNETS//,/ }; do
if [ $(echo "$SUBNET" | grep -Eo '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/([0-2]?[0-9])|([3]?[0-1]))?$') = "" ]; then
printf "Subnet $SUBNET is not a valid IPv4 subnet of the form 255.255.255.255/31 or 255.255.255.255\n"
exit 1
fi
done
#####################################################
# Writes to protected file and remove USER, PASSWORD
#####################################################
printf "Writing USER and PASSWORD to protected file /auth.conf..."
echo "$USER" > /auth.conf
exitOnError $?
echo "$PASSWORD" >> /auth.conf
exitOnError $?
chown nonrootuser /auth.conf
exitOnError $?
chmod 400 /auth.conf
exitOnError $?
printf "DONE\n"
printf "Clearing environment variables USER and PASSWORD..."
unset -v USER
unset -v PASSWORD
printf "DONE\n"
############################################ ############################################
# CHECK FOR TUN DEVICE # CHECK FOR TUN DEVICE
@@ -41,36 +97,18 @@ printf "TUN device OK\n"
############################################ ############################################
# BLOCKING MALICIOUS HOSTNAMES AND IPs WITH UNBOUND # BLOCKING MALICIOUS HOSTNAMES AND IPs WITH UNBOUND
############################################ ############################################
touch /etc/unbound/blocks-malicious.conf printf "Malicious hostnames and ips blocking is $BLOCK_MALICIOUS\n"
printf "Unbound malicious hostnames blocking is $BLOCK_MALICIOUS\n" if [ "$BLOCK_MALICIOUS" = "on" ]; then
if [ "$BLOCK_MALICIOUS" = "on" ] && [ ! -f /etc/unbound/blocks-malicious.conf ]; then tar -xjf /etc/unbound/blocks-malicious.bz2 -C /etc/unbound/
printf "Extracting malicious hostnames archive..." printf "$(cat /etc/unbound/blocks-malicious.conf | grep "local-zone" | wc -l ) malicious hostnames and $(cat /etc/unbound/blocks-malicious.conf | grep "private-address" | wc -l) malicious IP addresses blacklisted\n"
tar -xjf /etc/unbound/malicious-hostnames.bz2 -C /etc/unbound/
exitOnError $?
printf "DONE\n"
printf "Extracting malicious IPs archive..."
tar -xjf /etc/unbound/malicious-ips.bz2 -C /etc/unbound/
exitOnError $?
printf "DONE\n"
printf "Building blocks-malicious.conf for Unbound..."
while read hostname; do
echo "local-zone: \""$hostname"\" static" >> /etc/unbound/blocks-malicious.conf
done < /etc/unbound/malicious-hostnames
exitOnError $?
while read ip; do
echo "private-address: $ip" >> /etc/unbound/blocks-malicious.conf
done < /etc/unbound/malicious-ips
exitOnError $?
printf "$(cat /etc/unbound/malicious-hostnames | wc -l ) malicious hostnames and $(cat /etc/unbound/malicious-ips | wc -l) malicious IP addresses added\n"
rm -f /etc/unbound/malicious-hostnames* /etc/unbound/malicious-ips*
else else
touch /etc/unbound/blocks-malicious.conf echo "" > /etc/unbound/blocks-malicious.conf
fi fi
############################################ ############################################
# SETTING DNS OVER TLS TO 1.1.1.1 / 1.0.0.1 # SETTING DNS OVER TLS TO 1.1.1.1 / 1.0.0.1
############################################ ############################################
printf "Launching Unbound daemon to connect to Cloudflare DNS 1.1.1.1 at its TLS endpoint...\n" printf "Launching Unbound daemon to connect to Cloudflare DNS 1.1.1.1 at its TLS endpoint..."
unbound unbound
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
@@ -94,7 +132,7 @@ printf "$INITIAL_IP\n"
############################################ ############################################
printf "Setting firewall for killswitch purposes...\n" printf "Setting firewall for killswitch purposes...\n"
printf " * Detecting local subnet..." printf " * Detecting local subnet..."
SUBNET=$(ip route show default | tail -n 1 | awk '// {print $1}') SUBNET=$(ip route show default | tail -n 1 | cut -d" " -f 1)
exitOnError $? exitOnError $?
printf "$SUBNET\n" printf "$SUBNET\n"
printf " * Reading parameters to be used for region $REGION, protocol $PROTOCOL and encryption $ENCRYPTION..." printf " * Reading parameters to be used for region $REGION, protocol $PROTOCOL and encryption $ENCRYPTION..."
@@ -122,7 +160,7 @@ printf "DONE\n"
for ip in $VPNIPS; do printf " $ip\n"; done for ip in $VPNIPS; do printf " $ip\n"; done
printf " * Adding IP addresses of $PIADOMAIN to /openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn...\n" printf " * Adding IP addresses of $PIADOMAIN to /openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn...\n"
for ip in $VPNIPS; do for ip in $VPNIPS; do
if [ $(grep "remote $ip $PORT" "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn") != "" ]; then if [ "$(grep "remote $ip $PORT" "/openvpn-$PROTOCOL-$ENCRYPTION/$REGION.ovpn")" != "" ]; then
printf " remote $ip $PORT (already present)\n" printf " remote $ip $PORT (already present)\n"
else else
printf " remote $ip $PORT\n" printf " remote $ip $PORT\n"
@@ -139,43 +177,42 @@ exitOnError $?
iptables -t nat --delete-chain iptables -t nat --delete-chain
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
printf " * Blocking all output traffic..." printf " * Block output traffic..."
iptables -F OUTPUT iptables -F OUTPUT
exitOnError $? exitOnError $?
iptables -P OUTPUT DROP iptables -P OUTPUT DROP
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
printf " * Adding rules to accept local loopback traffic..." printf " * Accept established and related output traffic..."
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
exitOnError $? exitOnError $?
printf "DONE\n"
printf " * Accept local loopback output traffic..."
iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
printf " * Adding rules to accept traffic of subnet $SUBNET..." printf " * Accept output traffic with local subnet $SUBNET..."
iptables -A OUTPUT -d $SUBNET -j ACCEPT iptables -A OUTPUT -d $SUBNET -j ACCEPT
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
for EXTRASUBNET in ${EXTRA_SUBNETS//,/ }
do
printf " * Accept output traffic with extra subnet $EXTRASUBNET..."
iptables -A OUTPUT -d $EXTRASUBNET -j ACCEPT
exitOnError $?
printf "DONE\n"
done
for ip in $VPNIPS; do for ip in $VPNIPS; do
printf " * Adding rules to accept traffic with $ip on port $PROTOCOL $PORT..." printf " * Accept output traffic to $ip on interface eth0, port $PROTOCOL $PORT..."
iptables -A OUTPUT -j ACCEPT -d $ip -o eth0 -p $PROTOCOL -m $PROTOCOL --dport $PORT iptables -A OUTPUT -j ACCEPT -d $ip -o eth0 -p $PROTOCOL -m $PROTOCOL --dport $PORT
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
done done
printf " * Adding rules to accept traffic going through the tun device..." printf " * Accept all output traffic on tun0 interface..."
iptables -A OUTPUT -o tun0 -j ACCEPT iptables -A OUTPUT -o tun0 -j ACCEPT
exitOnError $? exitOnError $?
printf "DONE\n" printf "DONE\n"
############################################
# USER SECURITY
############################################
printf "Changing /auth.conf ownership to nonrootuser with read only access..."
err=$(chown nonrootuser /auth.conf 2>&1)
if [ "$(echo "$err" | grep "Read-only file system")" = "" ]; then exitOnError $?; fi
err=$(chmod 400 /auth.conf 2>&1)
if [ "$(echo "$err" | grep "Read-only file system")" = "" ]; then exitOnError $?; fi
printf "DONE\n"
############################################ ############################################
# OPENVPN LAUNCH # OPENVPN LAUNCH
############################################ ############################################
@@ -184,8 +221,10 @@ printf " * Region: $REGION\n"
printf " * Encryption: $ENCRYPTION\n" printf " * Encryption: $ENCRYPTION\n"
printf " * Protocol: $PROTOCOL\n" printf " * Protocol: $PROTOCOL\n"
printf " * Port: $PORT\n" printf " * Port: $PORT\n"
printf " * Initial IP address: $(echo "$VPNIPS" | head -n 1)\n\n" printf " * Initial VPN IP address: $(echo "$VPNIPS" | head -n 1)\n\n"
cd "/openvpn-$PROTOCOL-$ENCRYPTION" cd "/openvpn-$PROTOCOL-$ENCRYPTION"
exitOnError $? "Can't access /openvpn-$PROTOCOL-$ENCRYPTION"
openvpn --config "$REGION.ovpn" --user nonrootuser --persist-tun --auth-retry nointeract --auth-user-pass /auth.conf --auth-nocache openvpn --config "$REGION.ovpn" --user nonrootuser --persist-tun --auth-retry nointeract --auth-user-pass /auth.conf --auth-nocache
printf "\nOpenVPN exited with status $?\n" status=$?
printf "\n =========================================\n"
printf " OpenVPN exit with status $status\n"
printf " =========================================\n"

View File

@@ -2,8 +2,8 @@ server:
# See https://www.nlnetlabs.nl/documentation/unbound/unbound.conf/ # See https://www.nlnetlabs.nl/documentation/unbound/unbound.conf/
# logging # logging
verbosity: 0 verbosity: 0
val-log-level: 2 val-log-level: 0
use-syslog: no use-syslog: yes
# performance # performance
num-threads: 1 num-threads: 1
@@ -45,6 +45,8 @@ server:
do-ip4: yes do-ip4: yes
do-ip6: no do-ip6: no
interface: 127.0.0.1 interface: 127.0.0.1
port: 53
username: "nonrootuser"
# other files # other files
include: "/etc/unbound/blocks-malicious.conf" include: "/etc/unbound/blocks-malicious.conf"