holepunch/bash/install-openvpn.sh

156 lines
4.9 KiB
Bash

#!/bin/bash
IP=$(curl -s https://ifconfig.me)
PORT=443
PROTOCOL=tcp
# Get the "public" interface from the default route
NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)
# Install OpenVPN
apt-get install -y openvpn wget curl
# Install the latest version of easy-rsa from source
wget -O ~/easy-rsa.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.2/EasyRSA-3.1.2.tgz
mkdir -p /etc/openvpn/easy-rsa
tar xzf ~/easy-rsa.tgz --strip-components=1 --no-same-owner --directory /etc/openvpn/easy-rsa
rm -f ~/easy-rsa.tgz
cd /etc/openvpn/easy-rsa/ || return
echo "set_var EASYRSA_ALGO ec" >/etc/openvpn/easy-rsa/pki/vars
echo "set_var EASYRSA_CURVE prime256v1" >>/etc/openvpn/easy-rsa/pki/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)"
# Create the PKI, set up the CA, the DH params and the server certificate
./easyrsa init-pki
./easyrsa --batch --req-cn="$SERVER_CN" build-ca nopass
./easyrsa --batch 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
# Make cert revocation list readable for non-root
chmod 644 /etc/openvpn/crl.pem
# Generate server.conf
echo "port $PORT" >/etc/openvpn/server.conf
echo "proto $PROTOCOL" >>/etc/openvpn/server.conf
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
echo 'push "dhcp-option DNS 80.67.169.40"' >>/etc/openvpn/server.conf
echo 'push "dhcp-option DNS 80.67.169.12"' >>/etc/openvpn/server.conf
echo "push \"redirect-gateway def1 bypass-dhcp\"
dh none
ecdh-curve prime256v1
tls-crypt tls-crypt.key
crl-verify crl.pem
ca ca.crt
cert $SERVER_NAME.crt
key $SERVER_NAME.key
auth SHA256
cipher AES-128-GCM
ncp-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
client-config-dir /etc/openvpn/ccd
status /var/log/openvpn/status.log
verb 3" >>/etc/openvpn/server.conf
# Create client-config-dir dir
mkdir -p /etc/openvpn/ccd
# Create log dir
mkdir -p /var/log/openvpn
# Enable routing
echo 'net.ipv4.ip_forward=1' >/etc/sysctl.d/99-openvpn.conf
# Apply sysctl rules
sysctl --system
# Don't modify package-provided service
cp /lib/systemd/system/openvpn\@.service /etc/systemd/system/openvpn\@.service
# Workaround to fix OpenVPN service on OpenVZ
sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn\@.service
# Another workaround to keep using /etc/openvpn/
sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn\@.service
systemctl daemon-reload
systemctl enable openvpn@server
systemctl restart openvpn@server
# Add iptables rules in two scripts
mkdir -p /opt/holepunch-openvpn-iptables
# Script to add rules
echo "#!/bin/sh
iptables -t nat -I POSTROUTING 1 -s 10.8.0.0/24 -o $NIC -j MASQUERADE
iptables -I INPUT 1 -i tun0 -j ACCEPT
iptables -I FORWARD 1 -i $NIC -o tun0 -j ACCEPT
iptables -I FORWARD 1 -i tun0 -o $NIC -j ACCEPT
iptables -I INPUT 1 -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/opt/holepunch-openvpn-iptables/add-openvpn-rules.sh
# Script to remove rules
echo "#!/bin/sh
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE
iptables -D INPUT -i tun0 -j ACCEPT
iptables -D FORWARD -i $NIC -o tun0 -j ACCEPT
iptables -D FORWARD -i tun0 -o $NIC -j ACCEPT
iptables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/opt/holepunch-openvpn-iptables/remove-openvpn-rules.sh
chmod +x /opt/holepunch-openvpn-iptables/add-openvpn-rules.sh
chmod +x /opt/holepunch-openvpn-iptables/remove-openvpn-rules.sh
# Handle the rules via a systemd script
echo "[Unit]
Description=iptables rules for OpenVPN
Before=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/holepunch-openvpn-iptables/add-openvpn-rules.sh
ExecStop=/opt/holepunch-openvpn-iptables/remove-openvpn-rules.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target" >/etc/systemd/system/holepunch-openvpn-iptables.service
# Enable service and apply rules
systemctl daemon-reload
systemctl enable holepunch-openvpn-iptables
systemctl start holepunch-openvpn-iptables
# Generate a template for client
echo "client
proto tcp-client
remote $IP $PORT
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name $SERVER_NAME name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3" >>/etc/openvpn/client-template.txt