Skip to content

Instantly share code, notes, and snippets.

@Mwni
Last active September 8, 2024 16:19
Show Gist options
  • Save Mwni/fb8e762d61ab493c4d42eca1acd0b900 to your computer and use it in GitHub Desktop.
Save Mwni/fb8e762d61ab493c4d42eca1acd0b900 to your computer and use it in GitHub Desktop.
Bash script for creating OpenVPN servers along with multiple client configurations. Certificates and keys are inlined without passwords.
if ! [ -x "$(command -v openvpn)" ]; then
echo "openvpn is not installed on this machine"
echo "cannot continue"
exit
fi
read -p "project name (lowercase): " -r project
make_client() {
./easyrsa build-client-full $1 nopass &>/dev/null
config_file="$1.conf"
echo "client" >> $config_file
echo "tls-client" >> $config_file
echo "remote $2 $3" >> $config_file
echo "proto udp" >> $config_file
echo "dev tun" >> $config_file
echo "resolv-retry infinite" >> $config_file
echo "nobind" >> $config_file
echo "pull" >> $config_file
echo "user nobody" >> $config_file
echo "group nogroup" >> $config_file
echo "persist-key" >> $config_file
echo "persist-tun" >> $config_file
echo "auth SHA512" >> $config_file
echo "key-direction 1" >> $config_file
echo "remote-cert-tls server" >> $config_file
echo "comp-lzo adaptive" >> $config_file
echo "verb 3" >> $config_file
echo "" >> $config_file
echo "<ca>" >> $config_file
cat pki/ca.crt >> $config_file
echo "</ca>" >> $config_file
echo "" >> $config_file
echo "<cert>" >> $config_file
cat pki/issued/$1.crt >> $config_file
echo "</cert>" >> $config_file
echo "" >> $config_file
echo "<key>" >> $config_file
cat pki/private/$1.key >> $config_file
echo "</key>" >> $config_file
echo "" >> $config_file
echo "<tls-crypt>" >> $config_file
cat ta.key >> $config_file
echo "</tls-crypt>" >> $config_file
}
if [ ! -d "$project" ]; then
echo "downloading easy-rsa..."
wget https://github.com/OpenVPN/easy-rsa/archive/3.0.1.tar.gz &>/dev/null
tar xzf 3.0.1.tar.gz &>/dev/null
cp -r easy-rsa-3.0.1/easyrsa3 $project
rm -rf easy-rsa-3.0.1 3.0.1.tar.gz
cd $project
echo "initializing pki..."
echo "set_var EASYRSA_BATCH \"yes\"" >> vars
echo "set_var EASYRSA_REQ_CN \"$project\"" >> vars
echo "set_var EASYRSA_NO_PASS 1" >> vars
echo "set_var EASYRSA_ALGO \"ec\"" >> vars
echo "set_var EASYRSA_DIGEST \"sha512\"" >> vars
./easyrsa init-pki nopass &>/dev/null
./easyrsa build-ca nopass &>/dev/null
./easyrsa build-server-full $project nopass &>/dev/null
openvpn --genkey secret ta.key
mkdir server
read -p "server domain: " -r domain
read -p "server port: " -r port
read -p "server vpn ip: " -r gateway
echo "creating server config..."
echo $domain > domain.txt
echo $port > port.txt
echo $gateway > gateway.txt
config_file="server/$project.conf"
gateway_base="${gateway%.*}"
mkdir server/$project.ccd
echo "tls-server" >> $config_file
echo "port $port" >> $config_file
echo "server $gateway 255.255.255.0 nopool" >> $config_file
echo "ifconfig-pool $gateway_base.100 $gateway_base.200" >> $config_file
echo "topology subnet" >> $config_file
echo "proto udp" >> $config_file
echo "dev tun" >> $config_file
echo "duplicate-cn" >> $config_file
echo "client-to-client" >> $config_file
echo "keepalive 10 120" >> $config_file
echo "user nobody" >> $config_file
echo "group nogroup" >> $config_file
echo "persist-key" >> $config_file
echo "persist-tun" >> $config_file
echo "auth SHA512" >> $config_file
echo "dh none" >> $config_file
echo "key-direction 0" >> $config_file
echo "comp-lzo adaptive" >> $config_file
echo "client-config-dir $project.ccd" >> $config_file
echo "status /var/log/openvpn/$project-status.log" >> $config_file
echo "log /var/log/openvpn/$project.log" >> $config_file
echo "log-append /var/log/openvpn/$project.log" >> $config_file
echo "verb 3" >> $config_file
echo "explicit-exit-notify 1" >> $config_file
echo "" >> $config_file
echo "<ca>" >> $config_file
cat pki/ca.crt >> $config_file
echo "</ca>" >> $config_file
echo "" >> $config_file
echo "<cert>" >> $config_file
cat pki/issued/$project.crt >> $config_file
echo "</cert>" >> $config_file
echo "" >> $config_file
echo "<key>" >> $config_file
cat pki/private/$project.key >> $config_file
echo "</key>" >> $config_file
echo "" >> $config_file
echo "<tls-crypt>" >> $config_file
cat ta.key >> $config_file
echo "</tls-crypt>" >> $config_file
echo "creating generic client config..."
make_client "client" $domain $port
cd ..
fi
cd $project
domain="$(cat domain.txt)"
port="$(cat port.txt)"
gateway="$(cat gateway.txt)"
gateway_base="${gateway%.*}"
print_configs() {
echo "these configs have been created so far:"
echo "- server@$project"
echo "- client@$project[$gateway_base.100-$gateway_base.200]"
for file in *.conf; do
if [ "$(basename "$file")" = "client.conf" ]; then
continue
fi
name="${file%.conf}"
ccd="$(cat server/$project.ccd/$name)"
ip="${ccd:14}"
ip="${ip%% *}"
echo "- $name@$project[$ip]"
done
}
while : ; do
print_configs
read -p "create additional client (y/n)? " choice
if [ "$choice" = "y" ]; then
read -p "client name (lowercase): " -r name
read -p "client last ip digit ($gateway_base.?): " -r ip
echo "creating $name config..."
make_client $name $domain $port
echo "ifconfig-push $gateway_base.$ip 255.255.255.0" > "server/$project.ccd/$name"
else
break
fi
done
read -p "install server config now (y/n)? " choice
if [ "$choice" = "y" ]; then
echo "installing server config..."
cp -r server/* /etc/openvpn/server/
systemctl restart openvpn-server@$project &>/dev/null
systemctl enable openvpn-server@$project &>/dev/null
echo "server config installed, started and symlinked"
fi
read -p "create zip file with all configs (y/n)? " choice
if [ "$choice" = "y" ]; then
mkdir zip
cp -r server/ zip/
echo "### OpenVPN Setup ###" >> zip/readme.txt
echo "" >> zip/readme.txt
echo "using domain: $domain" >> zip/readme.txt
echo "using port: $port" >> zip/readme.txt
echo "" >> zip/readme.txt
echo "/server" >> zip/readme.txt
echo " contains all files for server" >> zip/readme.txt
echo " contents should be copied into /etc/openvpn/" >> zip/readme.txt
echo "" >> zip/readme.txt
echo "client@$project.ovpn" >> zip/readme.txt
echo " random ip: $gateway_base.100 - $gateway_base.200" >> zip/readme.txt
echo " generic client file" >> zip/readme.txt
echo " can be used by multiple different users" >> zip/readme.txt
echo "" >> zip/readme.txt
for file in *.conf; do
if [ "$(basename "$file")" = "client.conf" ]; then
continue
fi
name="${file%.conf}"
ccd="$(cat server/$project.ccd/$name)"
ip="${ccd:14}"
ip="${ip%% *}"
echo "$name@$project.ovpn" >> zip/readme.txt
echo " ip: $ip" >> zip/readme.txt
echo " single use only" >> zip/readme.txt
echo "" >> zip/readme.txt
cp $file zip/$name@$project.ovpn
done
cp client.conf zip/client@$project.ovpn
apt install zip &>/dev/null
cd zip
zip -r ../../$project-vpn.zip * &>/dev/null
cd ..
rm -rf zip
echo "$project-vpn.zip created in current directory"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment