You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
5.2 KiB
214 lines
5.2 KiB
#!/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/ || exit
|
|
|
|
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
|
|
ecdh-curve $DH_CURVE
|
|
tls-crypt tls-crypt.key 0
|
|
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
|
|
|