#!/bin/bash

set -e

OPENVPN_DIR="/etc/openvpn/server"
EASYRSA_DIR="/etc/openvpn/easy-rsa"
CLIENT_DIR="/root/clients"

function check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "Run as root"
        exit 1
    fi
}

function detect_nic() {
    NIC=$(ip route get 1 | awk '{print $5;exit}')
}

function detect_ip() {
    PUBLIC_IP=$(curl -s https://api.ipify.org)
}

function install_packages() {

apt update

apt install -y \
openvpn \
easy-rsa \
iptables \
curl \
ca-certificates \
iproute2

}

function enable_forwarding() {

cat <<EOF > /etc/sysctl.d/99-openvpn.conf
net.ipv4.ip_forward=1
EOF

sysctl --system

}

function setup_easyrsa() {

rm -rf $EASYRSA_DIR
mkdir -p $EASYRSA_DIR

cp -r /usr/share/easy-rsa/* $EASYRSA_DIR/

cd $EASYRSA_DIR

./easyrsa init-pki
EASYRSA_BATCH=1 ./easyrsa build-ca nopass
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass
./easyrsa gen-crl

}

function create_server_config() {

mkdir -p $OPENVPN_DIR

cat <<EOF > $OPENVPN_DIR/server.conf
port 1194
proto udp
dev tun

user nobody
group nogroup

persist-key
persist-tun

topology subnet
server 10.8.0.0 255.255.255.0

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"

keepalive 10 120

cipher AES-256-GCM
auth SHA256

tls-server
tls-version-min 1.2

ca ca.crt
cert server.crt
key server.key
dh none
ecdh-curve prime256v1

crl-verify crl.pem

status /var/log/openvpn-status.log
verb 3
EOF

}

function copy_certificates() {

cp $EASYRSA_DIR/pki/ca.crt $OPENVPN_DIR/
cp $EASYRSA_DIR/pki/issued/server.crt $OPENVPN_DIR/
cp $EASYRSA_DIR/pki/private/server.key $OPENVPN_DIR/
cp $EASYRSA_DIR/pki/crl.pem $OPENVPN_DIR/

}

function configure_firewall() {

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE
iptables -A INPUT -p udp --dport 1194 -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT

}

function start_openvpn() {

systemctl daemon-reload
systemctl enable openvpn-server@server
systemctl restart openvpn-server@server

}

function generate_client() {

read -p "Client name: " CLIENT

cd $EASYRSA_DIR

EASYRSA_BATCH=1 ./easyrsa build-client-full $CLIENT nopass

mkdir -p $CLIENT_DIR

cat <<EOF > $CLIENT_DIR/$CLIENT.ovpn
client
dev tun
proto udp
remote $PUBLIC_IP 1194

resolv-retry infinite
nobind
persist-key
persist-tun

remote-cert-tls server

cipher AES-256-GCM
auth SHA256

verb 3
EOF

cat <<EOF >> $CLIENT_DIR/$CLIENT.ovpn
<ca>
$(cat $EASYRSA_DIR/pki/ca.crt)
</ca>

<cert>
$(sed -ne '/BEGIN CERTIFICATE/,$p' $EASYRSA_DIR/pki/issued/$CLIENT.crt)
</cert>

<key>
$(cat $EASYRSA_DIR/pki/private/$CLIENT.key)
</key>
EOF

echo
echo "Client created:"
echo "$CLIENT_DIR/$CLIENT.ovpn"

}

function revoke_client() {

cd $EASYRSA_DIR

echo
echo "Existing clients:"
grep "^V" pki/index.txt | cut -d '=' -f2

read -p "Client to revoke: " CLIENT

./easyrsa revoke $CLIENT
./easyrsa gen-crl

cp pki/crl.pem $OPENVPN_DIR/crl.pem

rm -f $CLIENT_DIR/$CLIENT.ovpn

echo "Client revoked"

}

function list_clients() {

echo
echo "Active clients:"
grep "^V" $EASYRSA_DIR/pki/index.txt | cut -d '=' -f2
echo

}

function remove_openvpn() {

systemctl stop openvpn-server@server
systemctl disable openvpn-server@server

apt remove --purge -y openvpn easy-rsa

rm -rf /etc/openvpn
rm -rf $CLIENT_DIR

echo "OpenVPN removed"

}

function install_openvpn() {

detect_nic
detect_ip

install_packages
enable_forwarding
setup_easyrsa
create_server_config
copy_certificates
configure_firewall
start_openvpn

mkdir -p $CLIENT_DIR

echo
echo "OpenVPN installed successfully"
echo

}

function menu() {

echo
echo "======================"
echo " OpenVPN Manager"
echo "======================"
echo
echo "1) Install OpenVPN"
echo "2) Add Client"
echo "3) Revoke Client"
echo "4) List Clients"
echo "5) Remove OpenVPN"
echo "6) Exit"
echo

read -p "Select option: " OPTION

case $OPTION in

1) install_openvpn ;;
2) generate_client ;;
3) revoke_client ;;
4) list_clients ;;
5) remove_openvpn ;;
6) exit ;;
*) echo "Invalid option" ;;

esac

}

check_root

while true
do
menu
done
