commit
311afb19ce
@ -0,0 +1,25 @@ |
||||
# Global Settings |
||||
TZ=Europe/Berlin |
||||
LOCAL_STACK_DIR=/srv/docker/volumes/openvpn |
||||
|
||||
# OpenVPN General Settings |
||||
PUBLIC_IP=0.0.0.0 |
||||
|
||||
# OpenVPN - General |
||||
OGEN_PORT=1194 |
||||
OGEN_PROTOCOL=udp |
||||
OGEN_IPV6=n |
||||
OGEN_DNS_ONLY=n |
||||
OGEN_DNS1=pihole |
||||
|
||||
# OpenVPN - DNS |
||||
ODNS_PORT=1195 |
||||
ODNS_PROTOCOL=udp |
||||
ODNS_IPV6=n |
||||
ODNS_DNS_ONLY=y |
||||
ODNS_DNS1=pihole |
||||
|
||||
# Pi-Hole Settings |
||||
PHOLE_DNS1=1.1.1.1 |
||||
PHOLE_DNS2=1.0.0.1 |
||||
PHOLE_WEBPASSWORD=passwordhere |
@ -0,0 +1 @@ |
||||
.env |
@ -0,0 +1,22 @@ |
||||
FROM debian:9 |
||||
|
||||
LABEL maintainer="Meliurwen <meliruwen@gmail.com>" |
||||
|
||||
ADD ./bin /bin |
||||
|
||||
RUN apt-get -q update && apt-get -qq install procps dnsutils \ |
||||
ca-certificates gnupg openvpn iptables openssl wget ca-certificates curl && \ |
||||
rm -rf /var/lib/apt/lists/* && \ |
||||
chmod a+x /bin/* && \ |
||||
mkdir -p /var/log/openvpn && \ |
||||
apt-get autoremove --purge && \ |
||||
apt-get clean |
||||
|
||||
VOLUME ["/etc/openvpn"] |
||||
VOLUME ["/root"] |
||||
|
||||
EXPOSE 1195/udp |
||||
|
||||
WORKDIR /etc/openvpn |
||||
|
||||
ENTRYPOINT ["start.sh"] |
@ -0,0 +1,28 @@ |
||||
#Set default policy of chain |
||||
iptables -P FORWARD DROP |
||||
|
||||
|
||||
#iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o 172.25.0.0/24 -j MASQUERADE |
||||
|
||||
# Allow traffic initiated from VPN to access LAN |
||||
#iptables -I FORWARD -i tun0 -o $NIC -s 10.8.0.0/24 -d 172.25.0.0/24 -m conntrack --ctstate NEW -j ACCEPT |
||||
|
||||
# Allow established traffic to pass back and forth |
||||
#iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d $DNS1/32 -o $NIC -j MASQUERADE |
||||
#iptables -A INPUT -i tun0 -j ACCEPT |
||||
#iptables -A FORWARD -i $NIC -o tun0 -j ACCEPT |
||||
#iptables -A FORWARD -i tun0 -o $NIC -j ACCEPT |
||||
#iptables -A INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT |
||||
|
||||
|
||||
#iptables -A FORWARD -i tun0 -o $NIC -s 10.8.0.0/24 -d 172.25.0.0/24 -j ACCEPT |
||||
#iptables -A FORWARD -i $NIC -o tun0 -s $DNS1/32 -d 10.8.0.0/24 -j ACCEPT |
||||
#iptables -P FORWARD DROP |
||||
|
||||
#allow traffic to route from VPN subnet to specific host in subnet |
||||
iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d $DNS1/32 -j ACCEPT |
||||
#allow traffic from host in server subnet back to VPN subnet |
||||
iptables -A FORWARD -o tun0 -s $DNS1/32 -d 10.8.0.0/24 -j ACCEPT |
@ -0,0 +1,5 @@ |
||||
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE |
||||
iptables -A INPUT -i tun0 -j ACCEPT |
||||
iptables -A FORWARD -i $NIC -o tun0 -j ACCEPT |
||||
iptables -A FORWARD -i tun0 -o $NIC -j ACCEPT |
||||
iptables -A INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT |
@ -0,0 +1,4 @@ |
||||
ip6tables -t nat -A POSTROUTING -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE |
||||
ip6tables -A INPUT -i tun0 -j ACCEPT |
||||
ip6tables -A FORWARD -i $NIC -o tun0 -j ACCEPT |
||||
ip6tables -A FORWARD -i tun0 -o $NIC -j ACCEPT |
@ -0,0 +1,4 @@ |
||||
mkdir -p /dev/net |
||||
if [ ! -e /dev/net/tun ]; then |
||||
mknod /dev/net/tun c 10 200 |
||||
fi |
@ -0,0 +1,214 @@ |
||||
#!/bin/bash |
||||
|
||||
# Secure OpenVPN server installer for Debian, Ubuntu, CentOS, Fedora and Arch Linux |
||||
# https://github.com/angristan/openvpn-install |
||||
|
||||
isRoot () { |
||||
if [ "$EUID" -ne 0 ]; then |
||||
return 1 |
||||
fi |
||||
} |
||||
|
||||
tunAvailable () { |
||||
if [ ! -e /dev/net/tun ]; then |
||||
return 1 |
||||
fi |
||||
} |
||||
|
||||
|
||||
initialCheck () { |
||||
if ! isRoot; then |
||||
echo "Sorry, you need to run this as root" |
||||
exit 1 |
||||
fi |
||||
if ! tunAvailable; then |
||||
echo "TUN is not available" |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
|
||||
|
||||
installQuestions () { |
||||
if [ -z "$IPV6_SUPPORT" ]; then |
||||
IPV6_SUPPORT=n |
||||
fi |
||||
if [ -z "$PORT" ]; then |
||||
PORT=1194 |
||||
fi |
||||
if [ -z "$PROTOCOL" ]; then |
||||
PROTOCOL=udp |
||||
fi |
||||
if [ -z "$DNS1" ]; then |
||||
DNS1='1.1.1.1' |
||||
fi |
||||
|
||||
CIPHER="AES-128-GCM" |
||||
CERT_CURVE="prime256v1" |
||||
CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" |
||||
DH_CURVE="prime256v1" |
||||
HMAC_ALG="SHA256" |
||||
|
||||
} |
||||
|
||||
initializeOpenVPN () { |
||||
# Run setup questions first |
||||
installQuestions |
||||
|
||||
# Get the "public" interface from the default route |
||||
NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1) |
||||
|
||||
|
||||
# Find out if the machine uses nogroup or nobody for the permissionless group |
||||
if grep -qs "^nogroup:" /etc/group; then |
||||
NOGROUP=nogroup |
||||
else |
||||
NOGROUP=nobody |
||||
fi |
||||
|
||||
|
||||
# An old version of easy-rsa was available by default in some openvpn packages |
||||
if [[ -d /etc/openvpn/easy-rsa/ ]]; then |
||||
rm -rf /etc/openvpn/easy-rsa/ |
||||
fi |
||||
|
||||
# Install the latest version of easy-rsa from source |
||||
local version="3.0.6" |
||||
wget -O ~/EasyRSA-unix-v${version}.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v${version}/EasyRSA-unix-v${version}.tgz |
||||
tar xzf ~/EasyRSA-unix-v${version}.tgz -C ~/ |
||||
mv ~/EasyRSA-v${version}/ /etc/openvpn/ |
||||
mv /etc/openvpn/EasyRSA-v${version}/ /etc/openvpn/easy-rsa/ |
||||
chown -R root:root /etc/openvpn/easy-rsa/ |
||||
rm -f ~/EasyRSA-unix-v${version}.tgz |
||||
|
||||
|
||||
cd /etc/openvpn/easy-rsa/ |
||||
|
||||
echo "set_var EASYRSA_ALGO ec" > vars |
||||
echo "set_var EASYRSA_CURVE $CERT_CURVE" >> vars |
||||
|
||||
# Generate a random, alphanumeric identifier of 16 characters for CN and one for server name |
||||
SERVER_CN="cn_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" |
||||
SERVER_NAME="server_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" |
||||
echo "set_var EASYRSA_REQ_CN $SERVER_CN" >> vars |
||||
# Create the PKI, set up the CA, the DH params and the server certificate |
||||
./easyrsa init-pki |
||||
./easyrsa --batch build-ca nopass |
||||
|
||||
|
||||
./easyrsa build-server-full "$SERVER_NAME" nopass |
||||
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl |
||||
|
||||
openvpn --genkey --secret /etc/openvpn/tls-crypt.key |
||||
|
||||
# Move all the generated files |
||||
cp pki/ca.crt pki/private/ca.key "pki/issued/$SERVER_NAME.crt" "pki/private/$SERVER_NAME.key" /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn |
||||
|
||||
|
||||
|
||||
# Generate server.conf |
||||
echo "port $PORT" > /etc/openvpn/server.conf |
||||
if [[ "$IPV6_SUPPORT" = 'n' ]]; then |
||||
echo "proto $PROTOCOL" >> /etc/openvpn/server.conf |
||||
elif [[ "$IPV6_SUPPORT" = 'y' ]]; then |
||||
echo "proto ${PROTOCOL}6" >> /etc/openvpn/server.conf |
||||
fi |
||||
|
||||
echo "dev tun |
||||
user nobody |
||||
group $NOGROUP |
||||
persist-key |
||||
persist-tun |
||||
keepalive 10 120 |
||||
topology subnet |
||||
server 10.8.0.0 255.255.255.0 |
||||
ifconfig-pool-persist ipp.txt" >> /etc/openvpn/server.conf |
||||
|
||||
# DNS resolvers |
||||
echo 'push "dhcp-option DNS '${DNS1}'"' >> /etc/openvpn/server.conf |
||||
|
||||
if [[ "$DNS_ONLY" = 'y' ]]; then |
||||
echo '#push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf |
||||
else |
||||
echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf |
||||
fi |
||||
|
||||
# IPv6 network settings if needed |
||||
if [[ "$IPV6_SUPPORT" = 'y' ]]; then |
||||
echo 'server-ipv6 fd42:42:42:42::/112 |
||||
tun-ipv6 |
||||
push tun-ipv6 |
||||
push "route-ipv6 2000::/3" |
||||
push "redirect-gateway ipv6"' >> /etc/openvpn/server.conf |
||||
fi |
||||
|
||||
|
||||
|
||||
echo "dh none" >> /etc/openvpn/server.conf |
||||
echo "ecdh-curve $DH_CURVE" >> /etc/openvpn/server.conf |
||||
echo "tls-crypt tls-crypt.key 0" >> /etc/openvpn/server.conf |
||||
echo "crl-verify crl.pem |
||||
ca ca.crt |
||||
cert $SERVER_NAME.crt |
||||
key $SERVER_NAME.key |
||||
auth $HMAC_ALG |
||||
cipher $CIPHER |
||||
ncp-ciphers $CIPHER |
||||
tls-server |
||||
tls-version-min 1.2 |
||||
tls-cipher $CC_CIPHER |
||||
status /var/log/openvpn/status.log |
||||
verb 3" >> /etc/openvpn/server.conf |
||||
|
||||
|
||||
# Enable routing |
||||
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/20-openvpn.conf |
||||
if [[ "$IPV6_SUPPORT" = 'y' ]]; then |
||||
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/20-openvpn.conf |
||||
fi |
||||
# Avoid an unneeded reboot |
||||
sysctl --system |
||||
|
||||
# If SELinux is enabled and a custom port was selected, we need this |
||||
if hash sestatus 2>/dev/null; then |
||||
if sestatus | grep "Current mode" | grep -qs "enforcing"; then |
||||
if [[ "$PORT" != '1194' ]]; then |
||||
semanage port -a -t openvpn_port_t -p "$PROTOCOL" "$PORT" |
||||
fi |
||||
fi |
||||
fi |
||||
|
||||
|
||||
|
||||
|
||||
IP=$PUBLICIP |
||||
|
||||
# client-template.txt is created so we have a template to add further users later |
||||
echo "client" > /etc/openvpn/client-template.txt |
||||
if [[ "$PROTOCOL" = 'udp' ]]; then |
||||
echo "proto udp" >> /etc/openvpn/client-template.txt |
||||
elif [[ "$PROTOCOL" = 'tcp' ]]; then |
||||
echo "proto tcp-client" >> /etc/openvpn/client-template.txt |
||||
fi |
||||
echo "remote $IP $PORT |
||||
dev tun |
||||
resolv-retry infinite |
||||
nobind |
||||
persist-key |
||||
persist-tun |
||||
remote-cert-tls server |
||||
verify-x509-name $SERVER_NAME name |
||||
auth $HMAC_ALG |
||||
auth-nocache |
||||
cipher $CIPHER |
||||
tls-client |
||||
tls-version-min 1.2 |
||||
tls-cipher $CC_CIPHER |
||||
setenv opt block-outside-dns # Prevent Windows 10 DNS leak |
||||
verb 3" >> /etc/openvpn/client-template.txt |
||||
|
||||
} |
||||
|
||||
# Check for root, TUN, OS... |
||||
initialCheck |
||||
initializeOpenVPN |
@ -0,0 +1,75 @@ |
||||
#!/bin/bash |
||||
|
||||
if [ -z "$PUBLICIP" ]; then |
||||
echo 'No PUBLICIP, exiting...' |
||||
exit 1 |
||||
fi |
||||
|
||||
|
||||
mkdir -p /dev/net |
||||
if [ ! -e /dev/net/tun ]; then |
||||
mknod /dev/net/tun c 10 200 |
||||
fi |
||||
|
||||
if [ -z "$DNS_ONLY" ]; then |
||||
DNS_ONLY=n |
||||
fi |
||||
|
||||
if [ ! -e /etc/openvpn/server.conf ]; then |
||||
echo "Configuration file not found. Initializing..." |
||||
openvpn-initialize |
||||
fi |
||||
|
||||
OPENVPN_CONFIG_FILE=/etc/openvpn/server.conf |
||||
|
||||
if [ -z $DNS1 ]; then |
||||
echo "DNS1 env variable not set, setting as deafault Cloudflare's 1.1.1.1" |
||||
$DNS1 = '1.1.1.1' |
||||
sed -i -e 's/"dhcp-option DNS .*"/"dhcp-option DNS '${DNS1}'"/g' ${OPENVPN_CONFIG_FILE} |
||||
else |
||||
|
||||
if [[ $DNS1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then |
||||
echo "The DNS1 address is ${DNS1}" |
||||
sed -i -e 's/"dhcp-option DNS .*"/"dhcp-option DNS '${DNS1}'"/g' ${OPENVPN_CONFIG_FILE} |
||||
else |
||||
if echo "$DNS1" | grep -qP '^[a-z0-9](?!.*--)[a-z0-9-]{1,61}[a-z0-9]$' ; then |
||||
echo "DNS1 name of the container vaild" |
||||
|
||||
DNS1=$(host pihole | grep -oE "\b((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]?)\b") |
||||
|
||||
if [ ! -z $DNS1 ]; then |
||||
echo "The DNS1 container address is ${DNS1}" |
||||
sed -i -e 's/"dhcp-option DNS .*"/"dhcp-option DNS '${DNS1}'"/g' ${OPENVPN_CONFIG_FILE} |
||||
else |
||||
echo "Impossible to resolve the DNS1 container address, exiting..." |
||||
exit 1 |
||||
fi |
||||
else |
||||
echo "DNS1 name of the container not vaild, please try to not use spaces or special characters, exiting..." |
||||
exit 1 |
||||
fi |
||||
fi |
||||
fi |
||||
|
||||
if [[ "$DNS_ONLY" = 'y' ]]; then |
||||
sed -i 's/#push "redirect-gateway def1 bypass-dhcp"/push "redirect-gateway def1 bypass-dhcp"/g' ${OPENVPN_CONFIG_FILE} |
||||
else |
||||
sed -i 's/push "redirect-gateway def1 bypass-dhcp"/push "redirect-gateway def1 bypass-dhcp"/g' ${OPENVPN_CONFIG_FILE} |
||||
fi |
||||
|
||||
|
||||
# Get the \"public\" interface from the default route |
||||
export NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1) |
||||
|
||||
# Add iptable rules |
||||
if [[ "$DNS_ONLY" = 'y' ]]; then |
||||
add-openvpn-ipv4-dns-rules |
||||
else |
||||
add-openvpn-ipv4-rules |
||||
fi |
||||
|
||||
if [ '$IPV6_SUPPORT' = 'y' ]; then |
||||
add-openvpn-ipv6-rules |
||||
fi |
||||
|
||||
exec openvpn --config server.conf |
@ -0,0 +1,75 @@ |
||||
version: "3" |
||||
|
||||
services: |
||||
pihole: |
||||
container_name: pihole |
||||
image: pihole/pihole:latest |
||||
expose: |
||||
- "53/udp" |
||||
- "53/tcp" |
||||
- "80/tcp" |
||||
- "443/tcp" |
||||
volumes: |
||||
- '${LOCAL_STACK_DIR}/etc-pihole/:/etc/pihole/' |
||||
- '${LOCAL_STACK_DIR}/etc-dnsmasq.d/:/etc/dnsmasq.d/' |
||||
dns: |
||||
- 127.0.0.1 |
||||
- ${PHOLE_DNS1} |
||||
restart: unless-stopped |
||||
networks: |
||||
- piholenetwork |
||||
environment: |
||||
TZ: ${TZ} |
||||
WEBPASSWORD: ${PHOLE_WEBPASSWORD} |
||||
DNS1: ${PHOLE_DNS1} |
||||
DNS2: ${PHOLE_DNS2} |
||||
|
||||
openvpn-dns: |
||||
build: . |
||||
container_name: openvpn-dns |
||||
restart: unless-stopped |
||||
depends_on: |
||||
- pihole |
||||
volumes: |
||||
- ${LOCAL_STACK_DIR}/openvpn-dns/etc/openvpn:/etc/openvpn |
||||
- ${LOCAL_STACK_DIR}/openvpn-dns/root:/root |
||||
ports: |
||||
- "${ODNS_PORT}:${ODNS_PORT}/${ODNS_PROTOCOL}" |
||||
networks: |
||||
- piholenetwork |
||||
cap_add: |
||||
- NET_ADMIN |
||||
environment: |
||||
PUBLICIP: ${PUBLIC_IP} |
||||
PORT: ${ODNS_PORT} |
||||
PROTOCOL: ${ODNS_PROTOCOL} |
||||
IPV6_SUPPORT: ${ODNS_IPV6} |
||||
DNS_ONLY: ${ODNS_DNS_ONLY} |
||||
DNS1: ${ODNS_DNS1} # Add an IPv4 Address or a container name |
||||
|
||||
openvpn-general: |
||||
build: . |
||||
container_name: openvpn-general |
||||
restart: unless-stopped |
||||
depends_on: |
||||
- pihole |
||||
volumes: |
||||
- ${LOCAL_STACK_DIR}/openvpn-general/etc/openvpn:/etc/openvpn |
||||
- ${LOCAL_STACK_DIR}/openvpn-general/root:/root |
||||
ports: |
||||
- "${OGEN_PORT}:${OGEN_PORT}/${OGEN_PROTOCOL}" |
||||
networks: |
||||
- piholenetwork |
||||
cap_add: |
||||
- NET_ADMIN |
||||
environment: |
||||
PUBLICIP: ${PUBLIC_IP} |
||||
PORT: ${OGEN_PORT} |
||||
PROTOCOL: ${OGEN_PROTOCOL} |
||||
IPV6_SUPPORT: ${OGEN_IPV6} |
||||
DNS_ONLY: ${OGEN_DNS_ONLY} |
||||
DNS1: ${OGEN_DNS1} # Add an IPv4 Address or a container name |
||||
|
||||
networks: |
||||
piholenetwork: |
||||
driver: bridge |
Loading…
Reference in new issue