vineri, 24 noiembrie 2017

Perfect Installer Secured OpenVPN 2.3.3 - 2.4.4 - from source

Hi there, inspired from source - https://github.com/Angristan/OpenVPN-install
Tested on Centos 7.x and working fine here a script, put the name openvpn-installer.sh

Before runing this script save your firewall rules and reapply after running this and append new rules need to openvpn.

openvpn-installer.sh

#!/bin/bash
# v3
# OPENVPN (also suported clients <= 2.3.3)
# PORT:  1149 tcp/udp
# CIPHER: AES-128-CBC
# CERTIFICATE: RSA
# RSA_SIZE: 4096
# CERT_HASH: sha384
# DH_TYPE: DH
# DH_SIZE: 4096
# CC_ENC: TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
# TLS_SIG: tls-auth
# HMAC_AUTH: SHA384
# COMPRESSION: lz0

#Detect root user
if [[ "$EUID" -ne 0 ]]; then
echo "Sorry, you need to run this as root"
exit 1
fi

#Detect TUN
if [[ ! -e /dev/net/tun ]]; then
echo "TUN is not available"
exit 2
fi

#Detect CENTOS
if [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then
        OS=centos
        IPTABLES='/etc/sysconfig/iptables'
        SYSCTL='/etc/sysctl.conf'
else
        echo "Looks like you aren't running this installer on CentOS system"
        exit 4
fi

# Detect Server IP.
IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -o -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
if [[ "$IP" = "" ]]; then
        IP=$(wget -qO- ipv4.icanhazip.com)
fi
# Detect Network Interface
NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)

#echo $IP
#echo $NIC

if [[ -e /etc/openvpn/server3.conf ]]; then
while :
do
clear
echo ""
echo "Looks like OpenVPN is already installed"
echo ""
echo "What do you want to do?"
echo "   1) Exit"
read -p "Select an option [1]: " option
case $option in
1) exit;;
esac
done
else
clear
echo "Welcome to the secure OpenVPN installer"
echo ""
# OpenVPN setup
echo ""
echo "Port for OpenVPN"
PORT="1194"
#Default UDP 1194
#echo $PORT
echo ""
echo "What protocol for OpenVPN?"
echo "   1) UDP (recommended)"
PROTOCOL="1"
#echo $PROTOCOL
echo ""
echo "DNS to use with the VPN?"
echo "   1) Google (Anycast: worldwide)"
DNS="1"
#echo $DNS
echo ""
echo "Choose which compression algorithm you want to use:"
echo "   1) LZ0 (use for OpenVPN 2.3 compatibility)"
COMPRESSION="lzo"
#echo $COMPRESSION
echo ""
echo "The encryption in OpenVPN."
echo "Only use AES-CBC for OpenVPN 2.3 compatibilty"
echo "   1) AES-128-CBC"
CIPHER="cipher AES-128-CBC"
#echo $CIPHER
echo ""
echo "Kind of certificate to use"
echo "RSA for OpenVPN 2.3 compatibilty"
echo "   1) RSA"
CERT_TYPE="1"
#echo $CERT_TYPE
echo ""
echo "Choose which RSA key size you want to use:"
echo "   1) 4096 bits"
RSA_SIZE="4096"
#echo $RSA_SIZE
echo ""
echo "Choose which hash algorithm you want to use for the certificate:"
echo "   1) SHA-384 (recommended)"
CERT_HASH="sha384"
#echo $CERT_HASH
echo ""
echo "Choose what kind of Diffie-Hellman key you want to use."
echo "Use DH for OpenVPN 2.3 compatibilty"
echo "   1) DH"
DH_TYPE="1"
#echo $DH_TYPE
echo""
echo "Choose which DH key size you want to use"
echo "   1) 4096 bits"
DH_SIZE="4096"
#echo $DH_SIZE
echo ""
echo "Choose which cipher you want to use for the control channel:"
    echo "   1) ECDHE-RSA-AES-256-GCM-SHA384 (recommended)"
CC_ENC="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
#echo $CC_ENC
echo ""
echo "Do you want to use tls-crypt or tls-auth?"
echo "They both encrypt and authenticate all control channel packets with a key."
echo "tls-crypt is more advanced and secure than tls-auth, but it's an OpenVPN 2.4 feature."
echo "   1) tls-auth (use only for OpenVPN 2.3 client compatibility)"
TLS_SIG="1"
#echo $TLS_SIG
echo""
echo "Choose which message digest algorithm you want to use for the data channel packets"
echo "and the tls-auth/tls-crypt control channel packets:"
echo "   2) SHA-384 (recommended)"
HMAC_AUTH="SHA384"
#echo $HMAC_AUTH
echo ""
echo "Finally, 1 client certificate and configuration will be add by default: firstuser"
CLIENT="firstuser"
#echo $CLIENT
echo ""
echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now"
read -n1 -r -p "Press any key to continue..."

if [[ "$OS" = 'centos' ]]; then
yum install epel-release -y
        yum --enablerepo=epel -y install openvpn
yum --enablerepo=epel -y install htop
        yum install iptables iptables-services openssl wget ca-certificates curl mlocate net-tools policycoreutils-python redhat-lsb-core -y
# Install iptables service
if [[ ! -e /etc/systemd/system/iptables.service ]]; then
    mkdir /etc/iptables
iptables-save > /etc/sysconfig/iptables
echo "#!/bin/sh
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT" > /etc/iptables/flush-iptables.sh
chmod +x /etc/iptables/flush-iptables.sh
echo "[Unit]
Description=Packet Filtering Framework
DefaultDependencies=no
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/sysconfig/iptables
ExecReload=/sbin/iptables-restore /etc/sysconfig/iptables
ExecStop=/etc/iptables/flush-iptables.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/iptables.service
systemctl daemon-reload
systemctl enable iptables.service
# Disable firewalld to allow iptables to start upon reboot
systemctl disable firewalld
fi

fi

#To remember we use tls-auth when generating a new client conf
echo $TLS_SIG > /etc/openvpn/TLS_SIG

# 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
# Get easy-rsa
cd ~/
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.3/EasyRSA-3.0.3.tgz
    tar -xzvf EasyRSA-3.0.3.tgz
    mv /root/EasyRSA-3.0.3 /root/easy-rsa
    mv /root/easy-rsa /etc/openvpn/easy-rsa
chown -R root:root /etc/openvpn/easy-rsa/
rm -rf EasyRSA-3.0.3.tgz
    rm -rf easy-rsa
cd /etc/openvpn/easy-rsa/

if [[ $CERT_TYPE == "1" ]]; then
echo "set_var EASYRSA_KEY_SIZE $RSA_SIZE" > vars
fi
echo 'set_var EASYRSA_DIGEST "'$CERT_HASH'"' >> vars
# Create the PKI, set up the CA, the DH params and the server + client certificates
/etc/openvpn/easy-rsa/easyrsa init-pki
/etc/openvpn/easy-rsa/easyrsa --batch build-ca nopass
openssl dhparam -out dhv3.pem $DH_SIZE
/etc/openvpn/easy-rsa/easyrsa build-server-full server nopass
EASYRSA_CRL_DAYS=3650 /etc/openvpn/easy-rsa/easyrsa gen-crl
if [[ $TLS_SIG == "1" ]]; then
openvpn --genkey --secret /etc/openvpn/tls-auth.key
fi
# Move all the generated files
cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/easy-rsa/pki/private/ca.key /etc/openvpn/easy-rsa/pki/issued/server.crt /etc/openvpn/easy-rsa/pki/private/server.key /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn
if [[ $DH_TYPE == "1" ]]; then
    cp /etc/openvpn/easy-rsa/dhv3.pem /etc/openvpn
fi
# Make cert revocation list readable for non-root
chmod 644 /etc/openvpn/crl.pem

# Generate server3.conf
echo "port $PORT" > /etc/openvpn/server3.conf
if [[ "$PROTOCOL" = '1' ]]; then
echo "proto udp" >> /etc/openvpn/server3.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/server3.conf
# DNS resolvers
#Google
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server3.conf
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server3.conf
echo 'push "redirect-gateway def1 bypass-dhcp" '>> /etc/openvpn/server3.conf
echo "crl-verify crl.pem
ca ca.crt
cert server.crt
key server.key" >> /etc/openvpn/server3.conf
if [[ $TLS_SIG == "1" ]]; then
echo "tls-auth tls-auth.key 0" >> /etc/openvpn/server3.conf
fi
if [[ $DH_TYPE == "1" ]]; then
echo "dh dhv3.pem" >> /etc/openvpn/server3.conf
fi
echo "auth $HMAC_AUTH
$CIPHER
ncp-disable
tls-server
tls-version-min 1.2
tls-cipher $CC_ENC" >> /etc/openvpn/server3.conf

if [[  $COMPRESSION == "lzo"  ]]; then
echo "compress $COMPRESSION" >> /etc/openvpn/server3.conf
fi

echo "status openvpn3.log
verb 3" >> /etc/openvpn/server3.conf

# Enable net.ipv4.ip_forward for the system
sed -i '/\<net.ipv4.ip_forward\>/c\net.ipv4.ip_forward=1' $SYSCTL
if ! grep -q "\<net.ipv4.ip_forward\>" $SYSCTL; then
echo 'net.ipv4.ip_forward=1' >> $SYSCTL
fi
# Avoid an unneeded reboot
echo 1 > /proc/sys/net/ipv4/ip_forward
# Set NAT for the VPN subnet
iptables -I INPUT -p udp --dport $PORT -j ACCEPT
iptables -t nat -A POSTROUTING -o $NIC -s 10.8.0.0/24 -j MASQUERADE
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Save persitent iptables rules
iptables-save > $IPTABLES

if iptables -L -n | grep -qE 'REJECT|DROP'; then
# If iptables has at least one REJECT rule, we asume this is needed.
if [[ "$PROTOCOL" = '1' ]]; then
iptables -I INPUT -p udp --dport $PORT -j ACCEPT
fi
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
if [[ "$PROTOCOL" = '1' ]]; then
sed -i "1 a\iptables -I INPUT -p udp --dport $PORT -j ACCEPT" $RCLOCAL
fi
sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
fi
# 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 isn't available in CentOS 6 by default
if ! hash semanage 2>/dev/null; then
yum install policycoreutils-python -y
fi
if [[ "$PROTOCOL" = '1' ]]; then
semanage port -a -t openvpn_port_t -p udp $PORT
fi
fi
fi
fi
# And finally, restart OpenVPN
if [[ "$OS" = 'centos' ]];  then
    #Workaround to avoid rewriting the entire script for Arch
sed -i 's|/etc/openvpn/server|/etc/openvpn|' /usr/lib/systemd/system/openvpn-server@.service
sed -i 's|%i.conf|server3.conf|' /usr/lib/systemd/system/openvpn-server@.service
systemctl daemon-reload
systemctl restart openvpn-server@openvpn.service
systemctl enable openvpn-server@openvpn.service
else
systemctl restart openvpn@server.service
systemctl enable openvpn@server.service
fi
# Try to detect a NATed connection and ask about it to potential LowEndSpirit/Scaleway users
EXTERNALIP=$(wget -qO- ipv4.icanhazip.com)
#echo $EXTERNALIP

# client-template.txt is created so we have a template to add further users later
echo "client" > /etc/openvpn/client-template.txt
if [[ "$PROTOCOL" = '1' ]]; then
echo "proto udp" >> /etc/openvpn/client-template.txt
fi
echo "remote $IP $PORT
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth $HMAC_AUTH
auth-nocache
$CIPHER
tls-client
tls-version-min 1.2
tls-cipher $CC_ENC" >> /etc/openvpn/client-template.txt

if [[ $COMPRESSION == "lzo"  ]]; then
echo "compress $COMPRESSION" >> /etc/openvpn/client-template.txt
fi

echo "setenv opt block-outside-dns
verb 3" >> /etc/openvpn/client-template.txt

echo ""
echo "Finished!"
echo ""
fi
exit 0;

To create users use:

createuser.sh

#!/bin/bash
#
# Generates the custom client.ovpn
homeDir="/root"
#echo $2 > /root/parola
cd /etc/openvpn/easy-rsa/
./easyrsa build-client-full $1 nopass
#</root/parola
cp /etc/openvpn/client-template.txt $homeDir/$1.v3.ovpn
echo "<ca>" >> $homeDir/$1.v3.ovpn
cat /etc/openvpn/easy-rsa/pki/ca.crt >> $homeDir/$1.v3.ovpn
echo "</ca>" >> $homeDir/$1.v3.ovpn
echo "<cert>" >> $homeDir/$1.v3.ovpn
cat /etc/openvpn/easy-rsa/pki/issued/$1.crt >> $homeDir/$1.v3.ovpn
echo "</cert>" >> $homeDir/$1.v3.ovpn
echo "<key>" >> $homeDir/$1.v3.ovpn
cat /etc/openvpn/easy-rsa/pki/private/$1.key >> $homeDir/$1.v3.ovpn
echo "</key>" >> $homeDir/$1.v3.ovpn
#We verify if we used tls-crypt or tls-auth during the installation
TLS_SIG=$(cat /etc/openvpn/TLS_SIG)
if [[ $TLS_SIG == "1" ]]; then
echo "key-direction 1" >> $homeDir/$1.v3.ovpn
echo "<tls-auth>" >> $homeDir/$1.v3.ovpn
cat /etc/openvpn/tls-auth.key >> $homeDir/$1.v3.ovpn
echo "</tls-auth>" >> $homeDir/$1.v3.ovpn
fi
echo ""
echo "Client $CLIENT added, certs available at $homeDir/$1.v3.ovpn"
exit

Put script in /root
And use it like EX: ./createuser.sh user

To revoke user do like this:
In console  give command

tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '

to find out numbers of certificates,

results will looks like

1
2
3

use

tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "2"p

to associate number 2 ( at the end of command bettwen "" - "2"p ) with the user which u want to revoke

U find out which one u need... and in console

cd /etc/openvpn/easy-rsa/
./easyrsa --batch revoke user
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
rm -rf pki/reqs/user.req
rm -rf pki/private/user.key
rm -rf pki/issued/user.crt
rm -rf /etc/openvpn/crl.pem
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
chmod 644 /etc/openvpn/crl.pem

Thats it