#!/bin/bash
# ovpnctl v4 debian 11 by @tommytnt

# make sure that the script running as root
if [[ $EUID -ne 0 ]]; then
	echo "error: this script must be run as root" 1>&2
	exit 1
fi

# script config
servername="hellvpn"
serverpath="/etc/openvpn/server/$servername" #ovpn server path
rsadir="rsa" #rsa directory name (placed in server dir)
outdir="ovpnkeys" #output dir path (placed in server dir)
tls="1" #1 - enable tls, 0 - disable.tls

# client config
function clientconf {
echo "client
dev tun
proto udp
remote server.com 8888
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-128-CBC
auth SHA512
verb 3" > $serverpath/$outdir/compiled/$keyname.ovpn
if [[ $tls == "1" ]] && [ -f $serverpath/ta.key ]; then
	echo "key-direction 1" >> $serverpath/$outdir/compiled/$keyname.ovpn
fi
echo "remote-cert-tls server
auth-user-pass
auth-nocache
keepalive 10 120" >> $serverpath/$outdir/compiled/$keyname.ovpn
}

# server config
function serverconf {
echo -e "# general
mode server
port 8888
proto udp
dev tun
topology subnet

# security
ca $serverpath/ca.crt
cert $serverpath/server.crt
key $serverpath/server.key
dh $serverpath/dh.pem" > $serverpath/$servername.conf
if [[ $tls == "1" ]]; then
	echo "tls-auth $serverpath/ta.key 0" >> $serverpath/$servername.conf
fi
echo "cipher AES-128-CBC
data-ciphers AES-128-CBC
auth SHA512
persist-key
persist-tun
#crl-verify $serverpath/crl.pem

# networking
server 172.17.2.0 255.255.255.0
ifconfig-pool-persist $serverpath/ipp.txt
keepalive 10 120
client-to-client

# client routes
#push 'redirect-gateway def1 bypass-dhcp'
#push 'dhcp-option DNS 8.8.8.8'
#push 'dhcp-option DNS 8.8.4.4'
#push 'route 178.63.151.224 255.255.255.255'     #2ip.ru
#push 'route 195.201.201.32 255.255.255.255'     #2ip.ru

# logging
status /var/log/ovpn-$servername-status.log
log /var/log/ovpn-$servername.log
verb 3" >> $serverpath/$servername.conf

# put rsa config
echo 'set_var EASYRSA_REQ_COUNTRY "UA"
set_var EASYRSA_REQ_PROVINCE "KO"
set_var EASYRSA_REQ_CITY "Kyiv"
set_var EASYRSA_REQ_ORG "ITCORP"
set_var EASYRSA_REQ_EMAIL "@tommytnt"
set_var EASYRSA_REQ_OU "IT"
set_var EASYRSA_ALGO "CORPIT"
set_var EASYRSA_REQ_CN "server.com"
set_var EASYRSA_DIGEST "sha512"' > $serverpath/$rsadir/vars

ln -s $serverpath/$servername.conf /etc/openvpn/server/$servername.conf
systemctl enable openvpn-server@$servername
systemctl start openvpn-server@$servername
}

function servergen {
	cd $serverpath/$rsadir
	./easyrsa init-pki
	( echo -en "\n" ) | ./easyrsa gen-req server nopass
	( echo -en "\n" ) | ./easyrsa build-ca nopass
	( echo -en "yes\n" ) | ./easyrsa sign-req server server
	./easyrsa gen-dh
	openvpn --genkey secret ta.key
	cp -f pki/ca.crt $serverpath/
	cp -f pki/dh.pem $serverpath/
	cp -f pki/issued/server.crt $serverpath/
	cp -f pki/private/server.key $serverpath/
	cp -f ta.key $serverpath/
}

function check {
	if ! [ -f $serverpath/ca.crt ]; then
		echo "error: ca.crt not found"
		exit 1
	fi
	if [[ $tls == "1" ]] && ! [ -f $serverpath/ta.key ]; then
		echo "error: tls key not found"
		exit 1
	fi
	if [ -f $serverpath/$rsadir/pki/issued/$keyname.crt ]; then
		read -p "error: the key already exists, may I just compile it? (y/n) " nogen
		if ! [[ $nogen = "y" ]] ; then
			exit 1
		else
			clientconf
			clientcomp
		fi
	fi
}

function clientgen {
	# create output dir
	mkdir -p $serverpath/$outdir/orig/$keyname/
	mkdir -p $serverpath/$outdir/compiled/
	cd $serverpath/$rsadir

	# generate key
	( echo -en "\n" ) | ./easyrsa gen-req $keyname nopass
	( echo -en "yes\n" ) | ./easyrsa sign-req client $keyname

	# copy keys to ouptut dir
	cp -f $serverpath/$rsadir/pki/ca.crt $serverpath/$outdir/orig/$keyname/
	cp -f $serverpath/$rsadir/pki/issued/$keyname.crt $serverpath/$outdir/orig/$keyname/
	cp -f $serverpath/$rsadir/pki/private/$keyname.key $serverpath/$outdir/orig/$keyname/
	if [[ $tls == "1" ]]; then
		cp -f $serverpath/$rsadir/ta.key $serverpath/$outdir/orig/$keyname/
	fi

	# set permissions
	chmod -R 777 $serverpath/$outdir/orig/$keyname/
}

function clientcomp {
	# create output dir
	mkdir -p $serverpath/$outdir/compiled/

	echo "<ca>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	cat $serverpath/$rsadir/pki/ca.crt >> $serverpath/$outdir/compiled/$keyname.ovpn
	echo "</ca>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	echo "<cert>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	cat $serverpath/$rsadir/pki/issued/$keyname.crt >> $serverpath/$outdir/compiled/$keyname.ovpn
	echo "</cert>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	echo "<key>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	cat $serverpath/$rsadir/pki/private/$keyname.key >> $serverpath/$outdir/compiled/$keyname.ovpn
	echo "</key>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	if [[ $tls == "1" ]] ; then
		echo "<tls-auth>" >> $serverpath/$outdir/compiled/$keyname.ovpn
		cat $serverpath/$rsadir/ta.key >> $serverpath/$outdir/compiled/$keyname.ovpn
		echo "</tls-auth>" >> $serverpath/$outdir/compiled/$keyname.ovpn
	fi
	exit 1
}

function revoke {
	cd $serverpath/$rsadir
	./easyrsa revoke keyrev
	./easyrsa gen-crl
	cp -f $serverpath/$rsadir/pki/crl.pem $serverpath/
	sed -i 's/#crl-verify/crl-verify/g' $serverpath/$servername.conf
	exit 1
}

### [> script start <] ###

# determinate what to do
if [[ $1 ]]; then
	if [[ $1 == "-init" ]]; then
		# install openvpn and create path
		sudo apt-get install -fy openvpn
		mkdir -p $serverpath
		make-cadir $serverpath/$rsadir
		serverconf
		servergen
		exit 1
	elif [[ $1 == "-gen" ]] && [[ $2 ]]; then
		keyname=$2
	elif [[ $1 == "-revoke" ]] && [[ $2 ]]; then
		keyrev=$2
		revoke
	fi
else
	echo "ovpnctl v4 debian 11 by @tommytnt"
	echo "	./ovpnctl.sh -init		- create server"
	echo "	./ovpnctl.sh -gen client1	- create key 'client1'"
	echo "	./ovpnctl.sh -revoke client1	- revoke keys 'client1'"
fi

check
clientgen
clientconf
clientcomp