Skip to content

Instantly share code, notes, and snippets.

@tjumyk
Last active June 20, 2024 11:10
Show Gist options
  • Save tjumyk/fe1d515f31326cd37bdeff02d6ccd9e5 to your computer and use it in GitHub Desktop.
Save tjumyk/fe1d515f31326cd37bdeff02d6ccd9e5 to your computer and use it in GitHub Desktop.
Setup OpenVPN on Ubuntu 22.04 LTS
#!/bin/bash
set -e
SERVER_PORT="8194"
WORK_DIR="$HOME/openvpn"
EASYRSA_VERSION="3.1.7"
EASYRSA_DIR="$WORK_DIR/EasyRSA-$EASYRSA_VERSION"
CLIENT_CONFIGS_DIR="$WORK_DIR/client-configs"
printf "Please make sure the firewall rule for public port $SERVER_PORT has been set!\n"
printf "Server Public IP: "
read SERVER_IP
printf "Client Name: "
read FIRST_CLIENT_NAME
###############################
# Install Packages
###############################
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y openvpn
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"
if [ ! -f "EasyRSA-$EASYRSA_VERSION.tgz" ] ; then
wget "https://github.com/OpenVPN/easy-rsa/releases/download/$EASYRSA_VERSION/EasyRSA-$EASYRSA_VERSION.tgz"
fi
tar xf "EasyRSA-$EASYRSA_VERSION.tgz"
###############################
# PKI Configuration
###############################
cd "$EASYRSA_DIR"
cp vars.example vars
cat <<EOF >> vars
set_var EASYRSA_REQ_COUNTRY "HK"
set_var EASYRSA_REQ_PROVINCE "HK"
set_var EASYRSA_REQ_CITY "HK"
set_var EASYRSA_REQ_ORG "KMNet"
set_var EASYRSA_REQ_EMAIL "root@km.net"
set_var EASYRSA_REQ_OU "Net"
EOF
./easyrsa init-pki
./easyrsa build-ca nopass
###############################
# Server Configuration
###############################
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey --secret pki/ta.key
sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt pki/ta.key pki/dh.pem /etc/openvpn/
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/
sudo sed -i "s/^port 1194/port $SERVER_PORT/g" /etc/openvpn/server.conf
sudo sed -i 's/dh2048\.pem/dh\.pem/g' /etc/openvpn/server.conf
cat <<EOF | sudo tee -a /etc/openvpn/server.conf
auth SHA256
user nobody
group nogroup
duplicate-cn
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
management localhost 7505
EOF
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
INTERFACE=$(ip route | grep default | sed 's/dev\s*/|/' | cut -d'|' -f2 | cut -d' ' -f1)
sudo mv /etc/ufw/before.rules before.rules.old
cat <<EOF | sudo tee /etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to wlp11s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/24 -o $INTERFACE -j MASQUERADE
COMMIT
# END OPENVPN RULES
EOF
sudo cat before.rules.old | sudo tee -a /etc/ufw/before.rules
sudo sed -i 's/^DEFAULT_FORWARD_POLICY/#DEFAULT_FORWARD_POLICY/g' /etc/default/ufw
echo 'DEFAULT_FORWARD_POLICY="ACCEPT"' | sudo tee -a /etc/default/ufw
sudo ufw allow $SERVER_PORT/udp
sudo ufw allow OpenSSH
sudo ufw disable
sudo ufw enable
sudo systemctl start openvpn@server
sudo systemctl status openvpn@server
sudo systemctl enable openvpn@server
###############################
# Clients Configuration
###############################
mkdir "$CLIENT_CONFIGS_DIR"
chmod -R 700 "$CLIENT_CONFIGS_DIR"
cd "$CLIENT_CONFIGS_DIR"
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf "base.conf"
sed -i "s/^remote /;remote /g" "base.conf"
sed -i 's/^;user /user /g' "base.conf"
sed -i 's/^;group /group /g' "base.conf"
sed -i 's/^ca /;ca /g' "base.conf"
sed -i 's/^cert /;cert /g' "base.conf"
sed -i 's/^key /;key /g' "base.conf"
sed -i 's/^tls-auth /;tls-auth /g' "base.conf"
cat <<EOF >> "base.conf"
remote $SERVER_IP $SERVER_PORT
auth SHA256
key-direction 1
EOF
cp base.conf base_linux.conf
cat <<EOF >>base_linux.conf
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
EOF
cat <<EOF >> "make_config.sh"
#!/bin/bash
# First argument: Client identifier
KEY_DIR=$CLIENT_CONFIGS_DIR/keys
OUTPUT_DIR=$CLIENT_CONFIGS_DIR/files
BASE_CONFIG=$CLIENT_CONFIGS_DIR/base.conf
BASE_LINUX_CONFIG=$CLIENT_CONFIGS_DIR/base_linux.conf
cat \${BASE_CONFIG} \\
<(echo -e '<ca>') \\
\${KEY_DIR}/ca.crt \\
<(echo -e '</ca>\n<cert>') \\
\${KEY_DIR}/\${1}.crt \\
<(echo -e '</cert>\n<key>') \\
\${KEY_DIR}/\${1}.key \\
<(echo -e '</key>\n<tls-auth>') \\
\${KEY_DIR}/ta.key \\
<(echo -e '</tls-auth>') \\
> \${OUTPUT_DIR}/\${1}.ovpn
cat \${BASE_LINUX_CONFIG} \\
<(echo -e '<ca>') \\
\${KEY_DIR}/ca.crt \\
<(echo -e '</ca>\n<cert>') \\
\${KEY_DIR}/\${1}.crt \\
<(echo -e '</cert>\n<key>') \\
\${KEY_DIR}/\${1}.key \\
<(echo -e '</key>\n<tls-auth>') \\
\${KEY_DIR}/ta.key \\
<(echo -e '</tls-auth>') \\
> \${OUTPUT_DIR}/\${1}_linux.ovpn
EOF
chmod u+x "make_config.sh"
mkdir -p "$CLIENT_CONFIGS_DIR/keys"
mkdir -p "$CLIENT_CONFIGS_DIR/files"
ln -s "$EASYRSA_DIR/pki/ca.crt" "$CLIENT_CONFIGS_DIR/keys"
ln -s "$EASYRSA_DIR/pki/ta.key" "$CLIENT_CONFIGS_DIR/keys"
cd "$EASYRSA_DIR"
./easyrsa gen-req "$FIRST_CLIENT_NAME" nopass
ln -s "$EASYRSA_DIR/pki/private/$FIRST_CLIENT_NAME.key" "$CLIENT_CONFIGS_DIR/keys"
./easyrsa sign-req client "$FIRST_CLIENT_NAME"
ln -s "$EASYRSA_DIR/pki/issued/$FIRST_CLIENT_NAME.crt" "$CLIENT_CONFIGS_DIR/keys"
cd "$CLIENT_CONFIGS_DIR"
./make_config.sh "$FIRST_CLIENT_NAME"
echo "All finished. Client config files are at $CLIENT_CONFIGS_DIR/files/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment