#!/bin/bash # # .---. . . # | | | # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-' # ' ' --' --' -' - -' ' ' -' -' -' ' - --' # # Freedom in the Cloud # # VPN functions # https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-debian-8 # https://jamielinux.com/blog/force-all-network-traffic-through-openvpn-using-iptables/ # http://www.farrellf.com/projects/software/2016-05-04_Running_a_VPN_Server_with_OpenVPN_and_Stunnel/index_.php # # License # ======= # # Copyright (C) 2014-2017 Bob Mottram # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . VARIANTS='full full-vim' IN_DEFAULT_INSTALL=0 SHOW_ON_ABOUT=0 OPENVPN_SERVER_NAME="server" OPENVPN_KEY_FILENAME='client.ovpn' VPN_COUNTRY_CODE="US" VPN_AREA="Apparent Free Speech Zone" VPN_LOCATION="Freedomville" VPN_ORGANISATION="Freedombone" VPN_UNIT="Freedombone Unit" STUNNEL_PORT=3439 VPN_TLS_PORT=553 vpn_variables=(MY_EMAIL_ADDRESS DEFAULT_DOMAIN_NAME MY_USERNAME VPN_COUNTRY_CODE VPN_AREA VPN_LOCATION VPN_ORGANISATION VPN_UNIT VPN_TLS_PORT) function logging_on_vpn { echo -n '' } function logging_off_vpn { echo -n '' } function install_interactive_vpn { VPN_DETAILS_COMPLETE= while [ ! $VPN_DETAILS_COMPLETE ] do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Configuration" \ --title $"VPN Configuration" \ --form $"\nPlease enter your VPN details. Changing the port to 443 will help defend against censorship but will prevent other web apps from running." 12 65 1 \ $"TLS port:" 1 1 "$(grep 'VPN_TLS_PORT' temp.cfg | awk -F '=' '{print $2}')" 1 12 4 4 \ 2> $data sel=$? case $sel in 1) exit 1;; 255) exit 1;; esac tlsport=$(cat $data | sed -n 1p) if [ ${#tlsport} -gt 1 ]; then if [[ "$tlsport" != *' '* && "$tlsport" != *'.'* ]]; then VPN_TLS_PORT="$tlsport" VPN_DETAILS_COMPLETE="yes" write_config_param "VPN_TLS_PORT" "$VPN_TLS_PORT" fi fi done APP_INSTALLED=1 } function vpn_change_tls_port { EXISTING_VPN_TLS_PORT=$VPN_TLS_PORT data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"VPN Configuration" \ --backtitle $"Freedombone Control Panel" \ --inputbox $'Change TLS port' 10 50 $VPN_TLS_PORT 2>$data sel=$? case $sel in 0) tlsport=$(<$data) if [ ${#tlsport} -gt 0 ]; then if [[ "$tlsport" != "$EXISTING_VPN_TLS_PORT" ]]; then clear VPN_TLS_PORT=$tlsport write_config_param "VPN_TLS_PORT" "$VPN_TLS_PORT" sed -i "s|accept =.*|accept = $VPN_TLS_PORT|g" /etc/stunnel/stunnel.conf sed -i "s|accept =.*|accept = $VPN_TLS_PORT|g" /etc/stunnel/stunnel-client.conf for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /home/$USERNAME/stunnel-client.conf ]; then cp /etc/stunnel/stunnel-client.conf /home/$USERNAME/stunnel-client.conf chown $USERNAME:$USERNAME /home/$USERNAME/stunnel-client.conf fi done if [ $VPN_TLS_PORT -eq 443 ]; then systemctl stop nginx systemctl disable nginx else systemctl enable nginx systemctl restart nginx fi systemctl restart stunnel dialog --title $"VPN Configuration" \ --msgbox $"TLS port changed to $VPN_TLS_PORT" 6 60 fi fi ;; esac } function vpn_regenerate_client_keys { data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Regenerate VPN keys for a user" \ --backtitle $"Freedombone Control Panel" \ --inputbox $'username' 10 50 2>$data sel=$? case $sel in 0) USERNAME=$(<$data) if [ ${#USERNAME} -gt 0 ]; then if [ -d /home/$USERNAME ]; then clear create_user_vpn_key $USERNAME dialog --title $"Regenerate VPN keys for a user" \ --msgbox $"VPN keys were regenerated for $USERNAME" 6 60 fi fi ;; esac } function configure_interactive_vpn { read_config_param VPN_TLS_PORT while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"VPN Configuration" \ --radiolist $"Choose an operation:" 13 70 3 \ 1 $"Change TLS port (currently $VPN_TLS_PORT)" off \ 2 $"Regenerate keys for a user" off \ 3 $"Exit" on 2> $data sel=$? case $sel in 1) return;; 255) return;; esac case $(cat $data) in 1) vpn_change_tls_port;; 2) vpn_regenerate_client_keys;; 3) break;; esac done } function reconfigure_vpn { echo -n '' } function upgrade_vpn { echo -n '' } function backup_local_vpn { for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /home/$USERNAME/$OPENVPN_KEY_FILENAME ]; then cp /home/$USERNAME/$OPENVPN_KEY_FILENAME /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} fi done function_check backup_directory_to_usb backup_directory_to_usb /etc/openvpn/easy-rsa/keys vpn } function restore_local_vpn { temp_restore_dir=/root/tempvpn restore_directory_from_usb $temp_restore_dir vpn if [ -d ${temp_restore_dir} ]; then cp -r ${temp_restore_dir}/* /etc/openvpn/easy-rsa/keys rm -rf ${temp_restore_dir} for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} ]; then cp /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} /home/$USERNAME/$OPENVPN_KEY_FILENAME chown $USERNAME:$USERNAME /home/$USERNAME/$OPENVPN_KEY_FILENAME fi done fi } function backup_remote_vpn { for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /home/$USERNAME/$OPENVPN_KEY_FILENAME ]; then cp /home/$USERNAME/$OPENVPN_KEY_FILENAME /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} fi done function_check backup_directory_to_friend backup_directory_to_friend /etc/openvpn/easy-rsa/keys vpn } function restore_remote_vpn { temp_restore_dir=/root/tempvpn restore_directory_from_friend $temp_restore_dir vpn if [ -d ${temp_restore_dir} ]; then cp -r ${temp_restore_dir}/* /etc/openvpn/easy-rsa/keys rm -rf ${temp_restore_dir} for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} ]; then cp /etc/openvpn/easy-rsa/keys/${USERNAME}_${OPENVPN_KEY_FILENAME} /home/$USERNAME/$OPENVPN_KEY_FILENAME chown $USERNAME:$USERNAME /home/$USERNAME/$OPENVPN_KEY_FILENAME fi done fi } function remove_vpn { systemctl stop stunnel systemctl disable stunnel rm /etc/systemd/system/stunnel.service systemctl stop openvpn if [ $VPN_TLS_PORT -ne 443 ]; then firewall_remove VPN-TLS $VPN_TLS_PORT fi apt-get -yq remove --purge fastd openvpn easy-rsa apt-get -yq remove stunnel4 if [ -d /etc/openvpn ]; then rm -rf /etc/openvpn fi firewall_disable_vpn echo 0 > /proc/sys/net/ipv4/ip_forward sed -i 's|net.ipv4.ip_forward=.*|net.ipv4.ip_forward=0|g' /etc/sysctl.conf remove_completion_param install_vpn # remove any client keys for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [ -f /home/$USERNAME/$OPENVPN_KEY_FILENAME ]; then shred -zu /home/$USERNAME/$OPENVPN_KEY_FILENAME fi rm /home/$USERNAME/stunnel* done userdel -f vpn groupdel -f vpn if [ -d /etc/stunnel ]; then rm -rf /etc/stunnel fi } function create_user_vpn_key { username=$1 if [ ! -d /home/$username ]; then return fi echo $"Creating VPN key for $username" cd /etc/openvpn/easy-rsa if [ -f /etc/openvpn/easy-rsa/keys/$username.crt ]; then rm /etc/openvpn/easy-rsa/keys/$username.crt fi if [ -f /etc/openvpn/easy-rsa/keys/$username.key ]; then rm /etc/openvpn/easy-rsa/keys/$username.key fi if [ -f /etc/openvpn/easy-rsa/keys/$username.csr ]; then rm /etc/openvpn/easy-rsa/keys/$username.csr fi sed -i 's| --interact||g' build-key ./build-key "$username" if [ ! -f /etc/openvpn/easy-rsa/keys/$username.crt ]; then echo $'VPN user cert not generated' exit 783528 fi user_cert=$(cat /etc/openvpn/easy-rsa/keys/$username.crt) if [ ${#user_cert} -lt 10 ]; then cat /etc/openvpn/easy-rsa/keys/$username.crt echo $'User cert generation failed' exit 634659 fi if [ ! -f /etc/openvpn/easy-rsa/keys/$username.key ]; then echo $'VPN user key not generated' exit 682523 fi user_key=$(cat /etc/openvpn/easy-rsa/keys/$username.key) if [ ${#user_key} -lt 10 ]; then cat /etc/openvpn/easy-rsa/keys/$username.key echo $'User key generation failed' exit 285838 fi user_vpn_cert_file=/home/$username/$OPENVPN_KEY_FILENAME if [ ! -f /usr/share/doc/openvpn/examples/sample-config-files/client.conf ]; then echo $'No VPN client template found' exit 429823 fi cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf $user_vpn_cert_file sed -i "s|remote .*|remote $DEFAULT_DOMAIN_NAME $STUNNEL_PORT|g" $user_vpn_cert_file sed -i 's|;user .*|user nobody|g' $user_vpn_cert_file sed -i 's|;group .*|group nobody|g' $user_vpn_cert_file sed -i 's|ca ca.crt|;ca ca.crt|g' $user_vpn_cert_file sed -i 's|cert client.crt|;cert client.crt|g' $user_vpn_cert_file sed -i 's|key client.key|;key client.key|g' $user_vpn_cert_file sed -i 's|tls-auth ta.key|;tls-auth ta.key|g' $user_vpn_cert_file sed -i 's|;proto tcp|proto tcp|g' $user_vpn_cert_file sed -i 's|proto udp|;proto udp|g' $user_vpn_cert_file echo '' >> $user_vpn_cert_file cat /etc/openvpn/ca.crt >> $user_vpn_cert_file echo '' >> $user_vpn_cert_file echo '' >> $user_vpn_cert_file cat /etc/openvpn/easy-rsa/keys/$username.crt >> $user_vpn_cert_file echo '' >> $user_vpn_cert_file echo '' >> $user_vpn_cert_file cat /etc/openvpn/easy-rsa/keys/$username.key >> $user_vpn_cert_file echo '' >> $user_vpn_cert_file chown $username:$username $user_vpn_cert_file # keep a backup cp $user_vpn_cert_file /etc/openvpn/easy-rsa/keys/$username.ovpn #rm /etc/openvpn/easy-rsa/keys/$username.crt #rm /etc/openvpn/easy-rsa/keys/$username.csr shred -zu /etc/openvpn/easy-rsa/keys/$username.key echo $"VPN key created at $user_vpn_cert_file" } function add_user_vpn { new_username="$1" new_user_password="$2" create_user_vpn_key $new_username if [ -f /etc/stunnel/stunnel.pem ]; then cp /etc/stunnel/stunnel.pem /home/$new_username/stunnel.pem chown $new_username:$new_username /home/$new_username/stunnel.pem fi if [ -f /etc/stunnel/stunnel.p12 ]; then cp /etc/stunnel/stunnel.p12 /home/$new_username/stunnel.p12 chown $new_username:$new_username /home/$new_username/stunnel.p12 fi cp /etc/stunnel/stunnel-client.conf /home/$new_username/stunnel-client.conf chown $new_username:$new_username /home/$new_username/stunnel-client.conf } function remove_user_vpn { new_username="$1" } function install_stunnel { apt-get -yq install stunnel4 cd /etc/stunnel openssl req -x509 -nodes -days 3650 -sha256 \ -subj "/O=$VPN_ORGANISATION/OU=$VPN_UNIT/C=$VPN_COUNTRY_CODE/ST=$VPN_AREA/L=$VPN_LOCATION/CN=$HOSTNAME" \ -newkey rsa:2048 -keyout key.pem \ -out cert.pem if [ ! -f key.pem ]; then echo $'stunnel key not created' exit 793530 fi if [ ! -f cert.pem ]; then echo $'stunnel cert not created' exit 204587 fi chmod 400 key.pem chmod 640 cert.pem cat key.pem cert.pem >> stunnel.pem chmod 640 stunnel.pem openssl pkcs12 -export -out stunnel.p12 -inkey key.pem -in cert.pem -passout pass: if [ ! -f stunnel.p12 ]; then echo $'stunnel pkcs12 not created' exit 639353 fi chmod 640 stunnel.p12 echo 'chroot = /var/lib/stunnel4' > stunnel.conf echo 'pid = /stunnel4.pid' >> stunnel.conf echo 'setuid = stunnel4' >> stunnel.conf echo 'setgid = stunnel4' >> stunnel.conf echo 'socket = l:TCP_NODELAY=1' >> stunnel.conf echo 'socket = r:TCP_NODELAY=1' >> stunnel.conf echo 'cert = /etc/stunnel/stunnel.pem' >> stunnel.conf echo '[openvpn]' >> stunnel.conf echo "accept = $VPN_TLS_PORT" >> stunnel.conf echo 'connect = localhost:1194' >> stunnel.conf echo 'cert = /etc/stunnel/stunnel.pem' >> stunnel.conf sed -i 's|ENABLED=.*|ENABLED=1|g' /etc/default/stunnel4 echo '[openvpn]' > stunnel-client.conf echo 'client = yes' >> stunnel-client.conf echo "accept = $STUNNEL_PORT" >> stunnel-client.conf echo "connect = $DEFAULT_DOMAIN_NAME:$VPN_TLS_PORT" >> stunnel-client.conf echo 'cert = /etc/stunnel/stunnel.pem' >> stunnel-client.conf echo '[Unit]' > /etc/systemd/system/stunnel.service echo 'Description=SSL tunnel for network daemons' >> /etc/systemd/system/stunnel.service echo 'Documentation=man:stunnel https://www.stunnel.org/docs.html' >> /etc/systemd/system/stunnel.service echo 'DefaultDependencies=no' >> /etc/systemd/system/stunnel.service echo 'After=network.target' >> /etc/systemd/system/stunnel.service echo 'After=syslog.target' >> /etc/systemd/system/stunnel.service echo '' >> /etc/systemd/system/stunnel.service echo '[Install]' >> /etc/systemd/system/stunnel.service echo 'WantedBy=multi-user.target' >> /etc/systemd/system/stunnel.service echo 'Alias=stunnel.target' >> /etc/systemd/system/stunnel.service echo '' >> /etc/systemd/system/stunnel.service echo '[Service]' >> /etc/systemd/system/stunnel.service echo 'Type=forking' >> /etc/systemd/system/stunnel.service echo 'RuntimeDirectory=stunnel' >> /etc/systemd/system/stunnel.service echo 'EnvironmentFile=-/etc/stunnel/stunnel.conf' >> /etc/systemd/system/stunnel.service echo 'ExecStart=/usr/bin/stunnel /etc/stunnel/stunnel.conf' >> /etc/systemd/system/stunnel.service echo 'ExecStop=/usr/bin/killall -9 stunnel' >> /etc/systemd/system/stunnel.service echo 'RemainAfterExit=yes' >> /etc/systemd/system/stunnel.service if [ $VPN_TLS_PORT -eq 443 ]; then systemctl stop nginx systemctl disable nginx else systemctl enable nginx systemctl restart nginx fi systemctl enable stunnel systemctl daemon-reload systemctl start stunnel cp /etc/stunnel/stunnel.pem /home/$MY_USERNAME/stunnel.pem cp /etc/stunnel/stunnel.p12 /home/$MY_USERNAME/stunnel.p12 cp /etc/stunnel/stunnel-client.conf /home/$MY_USERNAME/stunnel-client.conf chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/stunnel* } function install_vpn { apt-get -yq install fastd openvpn easy-rsa if [ ! -f /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz ]; then echo $'Example openvpn server config not found' exit 783953 fi groupadd vpn useradd -r -s /bin/false -g vpn vpn # server configuration gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf sed -i "s|;push \"redirect-gateway|push \"redirect-gateway|g" /etc/openvpn/server.conf sed -i 's|;push "dhcp-option|push "dhcp-option|g' /etc/openvpn/server.conf sed -i 's|;user no.*|user vpn|g' /etc/openvpn/server.conf sed -i 's|;group no.*|group vpn|g' /etc/openvpn/server.conf sed -i 's|;max-clients.*|max-clients 2|g' /etc/openvpn/server.conf sed -i 's|;proto tcp|proto tcp|g' /etc/openvpn/server.conf sed -i 's|proto udp|;proto udp|g' /etc/openvpn/server.conf sed -i 's|explicit-exit-notify.*|explicit-exit-notify 0|g' /etc/openvpn/server.conf sed -i 's|tls-auth|;tls-auth|g' /etc/openvpn/server.conf echo 1 > /proc/sys/net/ipv4/ip_forward sed -i 's|# net.ipv4.ip_forward|net.ipv4.ip_forward|g' /etc/sysctl.conf sed -i 's|#net.ipv4.ip_forward|net.ipv4.ip_forward|g' /etc/sysctl.conf sed -i 's|net.ipv4.ip_forward.*|net.ipv4.ip_forward=1|g' /etc/sysctl.conf cp -r /usr/share/easy-rsa/ /etc/openvpn if [ ! -d /etc/openvpn/easy-rsa/keys ]; then mkdir /etc/openvpn/easy-rsa/keys fi # keys configuration sed -i "s|export KEY_COUNTRY.*|export KEY_COUNTRY=\"US\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_PROVINCE.*|export KEY_PROVINCE=\"TX\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_CITY.*|export KEY_CITY=\"Dallas\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_ORG.*|export KEY_ORG=\"$PROJECT_NAME\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_EMAIL.*|export KEY_EMAIL=\"$MY_EMAIL_ADDRESS\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_OU=.*|export KEY_OU=\"MoonUnit\"|g" /etc/openvpn/easy-rsa/vars sed -i "s|export KEY_NAME.*|export KEY_NAME=\"$OPENVPN_SERVER_NAME\"|g" /etc/openvpn/easy-rsa/vars # generate host keys if [ ! -f /etc/openvpn/dh2048.pem ]; then openssl dhparam -out /etc/openvpn/dh2048.pem 2048 fi cd /etc/openvpn/easy-rsa . ./vars ./clean-all vpn_openssl_version='1.0.0' if [ ! -f openssl-${vpn_openssl_version}.cnf ]; then echo $"openssl-${vpn_openssl_version}.cnf was not found" exit 7392353 fi cp openssl-${vpn_openssl_version}.cnf openssl.cnf if [ -f /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.crt ]; then rm /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.crt fi if [ -f /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.key ]; then rm /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.key fi if [ -f /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.csr ]; then rm /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.csr fi sed -i 's| --interact||g' build-key-server sed -i 's| --interact||g' build-ca ./build-ca ./build-key-server $OPENVPN_SERVER_NAME if [ ! -f /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.crt ]; then echo $'OpenVPN crt not found' exit 7823352 fi server_cert=$(cat /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.crt) if [ ${#server_cert} -lt 10 ]; then cat /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.crt echo $'Server cert generation failed' exit 3284682 fi if [ ! -f /etc/openvpn/easy-rsa/keys/${OPENVPN_SERVER_NAME}.key ]; then echo $'OpenVPN key not found' exit 6839436 fi if [ ! -f /etc/openvpn/easy-rsa/keys/ca.key ]; then echo $'OpenVPN ca not found' exit 7935203 fi cp /etc/openvpn/easy-rsa/keys/{$OPENVPN_SERVER_NAME.crt,$OPENVPN_SERVER_NAME.key,ca.crt} /etc/openvpn create_user_vpn_key $MY_USERNAME firewall_enable_vpn if [ $VPN_TLS_PORT -ne 443 ]; then firewall_add VPN-TLS $VPN_TLS_PORT tcp fi systemctl start openvpn install_stunnel APP_INSTALLED=1 } # NOTE: deliberately there is no "exit 0"