Advertisement
RamSet

Open VPN Road Warrior

Dec 6th, 2018
1,516
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 14.48 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3.  
  4. # Detect Debian users running the script with "sh" instead of bash
  5. if readlink /proc/$$/exe | grep -q "dash"; then
  6.     echo "This script needs to be run with bash, not sh"
  7.     exit
  8. fi
  9.  
  10. if [[ "$EUID" -ne 0 ]]; then
  11.     echo "Sorry, you need to run this as root"
  12.     exit
  13. fi
  14.  
  15. if [[ ! -e /dev/net/tun ]]; then
  16.     echo "The TUN device is not available
  17. You need to enable TUN before running this script"
  18.     exit
  19. fi
  20.  
  21. if [[ -e /etc/debian_version ]]; then
  22.     OS=debian
  23.     GROUPNAME=nogroup
  24.     RCLOCAL='/etc/rc.local'
  25. elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then
  26.     OS=centos
  27.     GROUPNAME=nobody
  28.     RCLOCAL='/etc/rc.d/rc.local'
  29. else
  30.     echo "Looks like you aren't running this installer on Debian, Ubuntu or CentOS"
  31.     exit
  32. fi
  33.  
  34. newclient () {
  35.     # Generates the custom client.ovpn
  36.     cp /etc/openvpn/client-common.txt ~/$1.ovpn
  37.     echo "<ca>" >> ~/$1.ovpn
  38.     cat /etc/openvpn/easy-rsa/pki/ca.crt >> ~/$1.ovpn
  39.     echo "</ca>" >> ~/$1.ovpn
  40.     echo "<cert>" >> ~/$1.ovpn
  41.     sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/easy-rsa/pki/issued/$1.crt >> ~/$1.ovpn
  42.     echo "</cert>" >> ~/$1.ovpn
  43.     echo "<key>" >> ~/$1.ovpn
  44.     cat /etc/openvpn/easy-rsa/pki/private/$1.key >> ~/$1.ovpn
  45.     echo "</key>" >> ~/$1.ovpn
  46.     echo "<tls-auth>" >> ~/$1.ovpn
  47.     sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/ta.key >> ~/$1.ovpn
  48.     echo "</tls-auth>" >> ~/$1.ovpn
  49. }
  50.  
  51. if [[ -e /etc/openvpn/server.conf ]]; then
  52.     while :
  53.     do
  54.     clear
  55.         echo "Looks like OpenVPN is already installed."
  56.         echo
  57.         echo "What do you want to do?"
  58.         echo "   1) Add a new user"
  59.         echo "   2) Revoke an existing user"
  60.         echo "   3) Remove OpenVPN"
  61.         echo "   4) Exit"
  62.         read -p "Select an option [1-4]: " option
  63.         case $option in
  64.             1)
  65.             echo
  66.             echo "Tell me a name for the client certificate."
  67.             echo "Please, use one word only, no special characters."
  68.             read -p "Client name: " -e CLIENT
  69.             cd /etc/openvpn/easy-rsa/
  70.             EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass
  71.             # Generates the custom client.ovpn
  72.             newclient "$CLIENT"
  73.             echo
  74.             echo "Client $CLIENT added, configuration is available at:" ~/"$CLIENT.ovpn"
  75.             exit
  76.             ;;
  77.             2)
  78.             # This option could be documented a bit better and maybe even be simplified
  79.             # ...but what can I say, I want some sleep too
  80.             NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
  81.             if [[ "$NUMBEROFCLIENTS" = '0' ]]; then
  82.                 echo
  83.                 echo "You have no existing clients!"
  84.                 exit
  85.             fi
  86.             echo
  87.             echo "Select the existing client certificate you want to revoke:"
  88.             tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
  89.             if [[ "$NUMBEROFCLIENTS" = '1' ]]; then
  90.                 read -p "Select one client [1]: " CLIENTNUMBER
  91.             else
  92.                 read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
  93.             fi
  94.             CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
  95.             echo
  96.             read -p "Do you really want to revoke access for client $CLIENT? [y/N]: " -e REVOKE
  97.             if [[ "$REVOKE" = 'y' || "$REVOKE" = 'Y' ]]; then
  98.                 cd /etc/openvpn/easy-rsa/
  99.                 ./easyrsa --batch revoke $CLIENT
  100.                 EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  101.                 rm -f pki/reqs/$CLIENT.req
  102.                 rm -f pki/private/$CLIENT.key
  103.                 rm -f pki/issued/$CLIENT.crt
  104.                 rm -f /etc/openvpn/crl.pem
  105.                 cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
  106.                 # CRL is read with each client connection, when OpenVPN is dropped to nobody
  107.                 chown nobody:$GROUPNAME /etc/openvpn/crl.pem
  108.                 echo
  109.                 echo "Certificate for client $CLIENT revoked!"
  110.             else
  111.                 echo
  112.                 echo "Certificate revocation for client $CLIENT aborted!"
  113.             fi
  114.             exit
  115.             ;;
  116.             3)
  117.             echo
  118.             read -p "Do you really want to remove OpenVPN? [y/N]: " -e REMOVE
  119.             if [[ "$REMOVE" = 'y' || "$REMOVE" = 'Y' ]]; then
  120.                 PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
  121.                 PROTOCOL=$(grep '^proto ' /etc/openvpn/server.conf | cut -d " " -f 2)
  122.                 if pgrep firewalld; then
  123.                     IP=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24 -j SNAT --to ' | cut -d " " -f 10)
  124.                     # Using both permanent and not permanent rules to avoid a firewalld reload.
  125.                     firewall-cmd --zone=public --remove-port=$PORT/$PROTOCOL
  126.                     firewall-cmd --zone=trusted --remove-source=10.8.0.0/24
  127.                     firewall-cmd --permanent --zone=public --remove-port=$PORT/$PROTOCOL
  128.                     firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24
  129.                     firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  130.                     firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  131.                 else
  132.                     IP=$(grep 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to ' $RCLOCAL | cut -d " " -f 14)
  133.                     iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  134.                     sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 ! -d 10.8.0.0\/24 -j SNAT --to /d' $RCLOCAL
  135.                     if iptables -L -n | grep -qE '^ACCEPT'; then
  136.                         iptables -D INPUT -p $PROTOCOL --dport $PORT -j ACCEPT
  137.                         iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT
  138.                         iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
  139.                         sed -i "/iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT/d" $RCLOCAL
  140.                         sed -i "/iptables -I FORWARD -s 10.8.0.0\/24 -j ACCEPT/d" $RCLOCAL
  141.                         sed -i "/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT/d" $RCLOCAL
  142.                     fi
  143.                 fi
  144.                 if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then
  145.                     semanage port -d -t openvpn_port_t -p $PROTOCOL $PORT
  146.                 fi
  147.                 if [[ "$OS" = 'debian' ]]; then
  148.                     apt-get remove --purge -y openvpn
  149.                 else
  150.                     yum remove openvpn -y
  151.                 fi
  152.                 rm -rf /etc/openvpn
  153.                 rm -f /etc/sysctl.d/30-openvpn-forward.conf
  154.                 echo
  155.                 echo "OpenVPN removed!"
  156.             else
  157.                 echo
  158.                 echo "Removal aborted!"
  159.             fi
  160.             exit
  161.             ;;
  162.             4) exit;;
  163.         esac
  164.     done
  165. else
  166.     clear
  167.     echo 'Welcome to this OpenVPN "road warrior" installer!'
  168.     echo
  169.     # OpenVPN setup and first user creation
  170.     echo "I need to ask you a few questions before starting the setup."
  171.     echo "You can leave the default options and just press enter if you are ok with them."
  172.     echo
  173.     echo "First, provide the IPv4 address of the network interface you want OpenVPN"
  174.     echo "listening to."
  175.     # Autodetect IP address and pre-fill for the user
  176.     IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
  177.     read -p "IP address: " -e -i $IP IP
  178.     # If $IP is a private IP address, the server must be behind NAT
  179.     if echo "$IP" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
  180.         echo
  181.         echo "This server is behind NAT. What is the public IPv4 address or hostname?"
  182.         read -p "Public IP address / hostname: " -e PUBLICIP
  183.     fi
  184.     echo
  185.     echo "Which protocol do you want for OpenVPN connections?"
  186.     echo "   1) UDP (recommended)"
  187.     echo "   2) TCP"
  188.     read -p "Protocol [1-2]: " -e -i 1 PROTOCOL
  189.     case $PROTOCOL in
  190.         1)
  191.         PROTOCOL=udp
  192.         ;;
  193.         2)
  194.         PROTOCOL=tcp
  195.         ;;
  196.     esac
  197.     echo
  198.     echo "What port do you want OpenVPN listening to?"
  199.     read -p "Port: " -e -i 1194 PORT
  200.     echo
  201.     echo "Which DNS do you want to use with the VPN?"
  202.     echo "   1) Current system resolvers"
  203.     echo "   2) 1.1.1.1"
  204.     echo "   3) Google"
  205.     echo "   4) OpenDNS"
  206.     echo "   5) Verisign"
  207.     read -p "DNS [1-5]: " -e -i 1 DNS
  208.     echo
  209.     echo "Finally, tell me your name for the client certificate."
  210.     echo "Please, use one word only, no special characters."
  211.     read -p "Client name: " -e -i client CLIENT
  212.     echo
  213.     echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now."
  214.     read -n1 -r -p "Press any key to continue..."
  215.     if [[ "$OS" = 'debian' ]]; then
  216.         apt-get update
  217.         apt-get install openvpn iptables openssl ca-certificates -y
  218.     else
  219.         # Else, the distro is CentOS
  220.         yum install epel-release -y
  221.         yum install openvpn iptables openssl ca-certificates -y
  222.     fi
  223.     # Get easy-rsa
  224.     EASYRSAURL='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz'
  225.     wget -O ~/easyrsa.tgz "$EASYRSAURL" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$EASYRSAURL"
  226.     tar xzf ~/easyrsa.tgz -C ~/
  227.     mv ~/EasyRSA-3.0.5/ /etc/openvpn/
  228.     mv /etc/openvpn/EasyRSA-3.0.5/ /etc/openvpn/easy-rsa/
  229.     chown -R root:root /etc/openvpn/easy-rsa/
  230.     rm -f ~/easyrsa.tgz
  231.     cd /etc/openvpn/easy-rsa/
  232.     # Create the PKI, set up the CA and the server and client certificates
  233.     ./easyrsa init-pki
  234.     ./easyrsa --batch build-ca nopass
  235.     EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass
  236.     EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass
  237.     EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  238.     # Move the stuff we need
  239.     cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn
  240.     # CRL is read with each client connection, when OpenVPN is dropped to nobody
  241.     chown nobody:$GROUPNAME /etc/openvpn/crl.pem
  242.     # Generate key for tls-auth
  243.     openvpn --genkey --secret /etc/openvpn/ta.key
  244.     # Create the DH parameters file using the predefined ffdhe2048 group
  245.     echo '-----BEGIN DH PARAMETERS-----
  246. MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
  247. +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
  248. 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
  249. YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
  250. 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
  251. ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
  252. -----END DH PARAMETERS-----' > /etc/openvpn/dh.pem
  253.     # Generate server.conf
  254.     echo "port $PORT
  255. proto $PROTOCOL
  256. dev tun
  257. sndbuf 0
  258. rcvbuf 0
  259. ca ca.crt
  260. cert server.crt
  261. key server.key
  262. dh dh.pem
  263. auth SHA512
  264. tls-auth ta.key 0
  265. topology subnet
  266. server 10.8.0.0 255.255.255.0
  267. ifconfig-pool-persist ipp.txt" > /etc/openvpn/server.conf
  268.     echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
  269.     # DNS
  270.     case $DNS in
  271.         1)
  272.         # Locate the proper resolv.conf
  273.         # Needed for systems running systemd-resolved
  274.         if grep -q "127.0.0.53" "/etc/resolv.conf"; then
  275.             RESOLVCONF='/run/systemd/resolve/resolv.conf'
  276.         else
  277.             RESOLVCONF='/etc/resolv.conf'
  278.         fi
  279.         # Obtain the resolvers from resolv.conf and use them for OpenVPN
  280.         grep -v '#' $RESOLVCONF | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do
  281.             echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
  282.         done
  283.         ;;
  284.         2)
  285.         echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server.conf
  286.         echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server.conf
  287.         ;;
  288.         3)
  289.         echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
  290.         echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
  291.         ;;
  292.         4)
  293.         echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
  294.         echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
  295.         ;;
  296.         5)
  297.         echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server.conf
  298.         echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server.conf
  299.         ;;
  300.     esac
  301.     echo "keepalive 10 120
  302. cipher AES-256-CBC
  303. user nobody
  304. group $GROUPNAME
  305. persist-key
  306. persist-tun
  307. status openvpn-status.log
  308. verb 3
  309. crl-verify crl.pem" >> /etc/openvpn/server.conf
  310.     # Enable net.ipv4.ip_forward for the system
  311.     echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/30-openvpn-forward.conf
  312.     # Enable without waiting for a reboot or service restart
  313.     echo 1 > /proc/sys/net/ipv4/ip_forward
  314.     if pgrep firewalld; then
  315.         # Using both permanent and not permanent rules to avoid a firewalld
  316.         # reload.
  317.         # We don't use --add-service=openvpn because that would only work with
  318.         # the default port and protocol.
  319.         firewall-cmd --zone=public --add-port=$PORT/$PROTOCOL
  320.         firewall-cmd --zone=trusted --add-source=10.8.0.0/24
  321.         firewall-cmd --permanent --zone=public --add-port=$PORT/$PROTOCOL
  322.         firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
  323.         # Set NAT for the VPN subnet
  324.         firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  325.         firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  326.     else
  327.         # Needed to use rc.local with some systemd distros
  328.         if [[ "$OS" = 'debian' && ! -e $RCLOCAL ]]; then
  329.             echo '#!/bin/sh -e
  330. exit 0' > $RCLOCAL
  331.         fi
  332.         chmod +x $RCLOCAL
  333.         # Set NAT for the VPN subnet
  334.         iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  335.         sed -i "1 a\iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP" $RCLOCAL
  336.         if iptables -L -n | grep -qE '^(REJECT|DROP)'; then
  337.             # If iptables has at least one REJECT rule, we asume this is needed.
  338.             # Not the best approach but I can't think of other and this shouldn't
  339.             # cause problems.
  340.             iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT
  341.             iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
  342.             iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
  343.             sed -i "1 a\iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT" $RCLOCAL
  344.             sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
  345.             sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
  346.         fi
  347.     fi
  348.     # If SELinux is enabled and a custom port was selected, we need this
  349.     if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then
  350.         # Install semanage if not already present
  351.         if ! hash semanage 2>/dev/null; then
  352.             yum install policycoreutils-python -y
  353.         fi
  354.         semanage port -a -t openvpn_port_t -p $PROTOCOL $PORT
  355.     fi
  356.     # And finally, restart OpenVPN
  357.     systemctl restart openvpn@server.service
  358.     if [[ "$OS" = 'centos' ]]; then
  359.         systemctl enable openvpn@server.service
  360.     fi
  361.     # If the server is behind a NAT, use the correct IP address
  362.     if [[ "$PUBLICIP" != "" ]]; then
  363.         IP=$PUBLICIP
  364.     fi
  365.     # client-common.txt is created so we have a template to add further users later
  366.     echo "client
  367. dev tun
  368. proto $PROTOCOL
  369. sndbuf 0
  370. rcvbuf 0
  371. remote $IP $PORT
  372. resolv-retry infinite
  373. nobind
  374. persist-key
  375. persist-tun
  376. remote-cert-tls server
  377. auth SHA512
  378. cipher AES-256-CBC
  379. setenv opt block-outside-dns
  380. key-direction 1
  381. verb 3" > /etc/openvpn/client-common.txt
  382.     # Generates the custom client.ovpn
  383.     newclient "$CLIENT"
  384.     echo
  385.     echo "Finished!"
  386.     echo
  387.     echo "Your client configuration is available at:" ~/"$CLIENT.ovpn"
  388.     echo "If you want to add more clients, you simply need to run this script again!"
  389. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement