openvpn-docker/entrypoint.sh

213 lines
4.3 KiB
Bash
Raw Normal View History

2024-08-24 21:05:07 +02:00
#!/usr/bin/env bash
set -euo pipefail
## CONSTANTS ##
readonly DATA_DIR="/etc/openvpn-data"
readonly EASYRSA_DIR="${DATA_DIR}/easyrsa"
readonly DATA_SERVER_DIR="${DATA_DIR}/server"
readonly DATA_CLIENT_DIR="${DATA_DIR}/client"
## HANDLE EXIT SIGNALS ##
trap trap_exit EXIT SIGINT SIGTERM
trap_exit(){
if [[ "${openvpn_pid:+x}" ]]; then
kill -- $openvpn_pid 2> /dev/null || true
q=0
while proc_running $openvpn_pid; do
q=$(( q + 1 ))
snore 1
if [[ "$q" -ge 15 ]]; then
log_warn "Sending kill to OpenVPN"
kill -s KILL -- $openvpn_pid 2> /dev/null || true
break
fi
done
fi
exit 0
}
#
# LIB: Efficient sleep (does not create a new process).
#
snore(){
local IFS
[[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:)
read ${1:+-t "$1"} -u $_snore_fd || true
}
#
# HELPER: Check whether given pid is running.
#
# @param $1 Process ID.
#
# @exit 0: Process is running
# 1: Process is not running.
#
proc_running(){
# try reading state
local state_path="/proc/$1/stat"
[[ ! -f "$state_path" ]] && return 1
local state=$(cat "$state_path" | cut -d ' ' -f3)
# parse state
case "$state" in
R|S|D|Z|W|W|P|I) return 0;;
*) return 1;;
esac
}
#
# HELPER: Initialize iptables rules.
#
iptables_init(){
/sbin/iptables -t nat -I POSTROUTING -s 192.168.35.0/24 ! -d 192.168.35.0/24 -j MASQUERADE
/sbin/iptables -I INPUT -i tun0 -j ACCEPT
/sbin/iptables -I INPUT -p udp --dport 1194 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 1194 -j ACCEPT
/sbin/iptables -I FORWARD -s 192.168.35.0/24 -j ACCEPT
/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
}
#
# HELPER: Set up easyrsa.
#
easyrsa_init(){
## MAYBE CREATE VARS FILE ##
if [[ ! -f "${EASYRSA_DIR}/vars" ]]; then
touch "${EASYRSA_DIR}/vars"
fi
}
#
# HELPER: Set up server keys.
#
easyrsa_server_keys_create(){
## IGNORE IF EXISTING ##
[[ -d "${EASYRSA_DIR}/pki" ]] && return 0
## SET UP CA AND SERVER KEYS (EASYRSA) ##
local prev_pwd="$PWD" && cd "$EASYRSA_DIR"
# new pki
/usr/bin/easyrsa --batch init-pki
2024-08-27 20:45:04 +02:00
chmod 755 pki
2024-08-24 21:05:07 +02:00
# create ca
/usr/bin/easyrsa --batch --days=7300 build-ca nopass
# generate server keys
/usr/bin/easyrsa --batch --days=7300 build-server-full server nopass
# generate crl
/usr/bin/easyrsa --batch --days=7300 gen-crl
chown nobody:nobody pki/crl.pem
# restore pwd
cd "$prev_pwd"
# create symlinks
ln -s ${EASYRSA_DIR}/pki/{ca.crt,private/ca.key,issued/server.crt,private/server.key,crl.pem} "${DATA_SERVER_DIR}"
## OTHER KEYS ##
2024-08-27 20:17:53 +02:00
# dh parameters from `IETF RFC 7919`
echo "-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----" > "${DATA_SERVER_DIR}/dh2048.pem"
2024-08-24 21:05:07 +02:00
# tls-crypt key
openvpn --genkey secret "${DATA_SERVER_DIR}/tls-crypt.key"
}
#
# HELPER: Set up openvpn server config file.
#
openvpn_config_init(){
## IGNORE IF EXISTING ##
[[ -f "${DATA_SERVER_DIR}/server.conf" ]] && return 0
## WRITE SERVER CONFIG ##
echo "port 1194
proto udp
server 192.168.35.0 255.255.255.0
dev tun
user nobody
group nogroup
topology subnet
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
crl-verify crl.pem
tls-crypt tls-crypt.key
auth SHA512
client-config-dir ${DATA_CLIENT_DIR}
ifconfig-pool-persist ipp.txt
2024-08-24 22:08:57 +02:00
keepalive 300 1500
2024-08-24 21:05:07 +02:00
persist-key
persist-tun
push \"dhcp-option DNS 1.1.1.1\"
push \"dhcp-option DNS 1.0.0.1\"
push \"redirect-gateway def1 bypass-dhcp\"
push \"block-outside-dns\"
verb 3" > "${DATA_SERVER_DIR}/server.conf"
}
## SET UP USED DIRECTORIES ##
mkdir -p "$DATA_DIR"
mkdir -p "$EASYRSA_DIR"
mkdir -p "$DATA_SERVER_DIR"
mkdir -p "$DATA_CLIENT_DIR"
## SET UP TUN DEVICE ##
mkdir -p /dev/net
[[ ! -c /dev/net/tun ]] && mknod /dev/net/tun c 10 200
## SET UP FW AND ROUTING ##
iptables_init
## INITIALIZE CONFIG ##
# set up easyrsa
easyrsa_init
# server keys
easyrsa_server_keys_create
# server config
openvpn_config_init
## RUN OPENVPN SERVER ##
/usr/sbin/openvpn --cd "${DATA_SERVER_DIR}" --config "${DATA_SERVER_DIR}/server.conf" & openvpn_pid=$!
wait $openvpn_pid