Advertisement
RamSet

RoadWarrior With Pi-hole

Sep 4th, 2019
634
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.77 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) Local isolated DNS (When OpenVPN and Pi-hole are on this device)"
  203.     echo "   2) Current system resolvers (When Pi-hole is on a different device)"
  204.     echo "   3) 1.1.1.1"
  205.     echo "   4) Google"
  206.     echo "   5) OpenDNS"
  207.     echo "   6) Verisign"
  208.     read -p "DNS [1-6]: " -e -i 1 DNS
  209.     echo
  210.     echo "Finally, tell me your name for the client certificate."
  211.     echo "Please, use one word only, no special characters."
  212.     read -p "Client name: " -e -i client CLIENT
  213.     echo
  214.     echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now."
  215.     read -n1 -r -p "Press any key to continue..."
  216.     if [[ "$OS" = 'debian' ]]; then
  217.         apt-get update
  218.         apt-get install openvpn iptables openssl ca-certificates -y
  219.     else
  220.         # Else, the distro is CentOS
  221.         yum install epel-release -y
  222.         yum install openvpn iptables openssl ca-certificates -y
  223.     fi
  224.     # Get easy-rsa
  225.     EASYRSAURL='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz'
  226.     wget -O ~/easyrsa.tgz "$EASYRSAURL" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$EASYRSAURL"
  227.     tar xzf ~/easyrsa.tgz -C ~/
  228.     mv ~/EasyRSA-3.0.5/ /etc/openvpn/
  229.     mv /etc/openvpn/EasyRSA-3.0.5/ /etc/openvpn/easy-rsa/
  230.     chown -R root:root /etc/openvpn/easy-rsa/
  231.     rm -f ~/easyrsa.tgz
  232.     cd /etc/openvpn/easy-rsa/
  233.     # Create the PKI, set up the CA and the server and client certificates
  234.     ./easyrsa init-pki
  235.     ./easyrsa --batch build-ca nopass
  236.     EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass
  237.     EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass
  238.     EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  239.     # Move the stuff we need
  240.     cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn
  241.     # CRL is read with each client connection, when OpenVPN is dropped to nobody
  242.     chown nobody:$GROUPNAME /etc/openvpn/crl.pem
  243.     # Generate key for tls-auth
  244.     openvpn --genkey --secret /etc/openvpn/ta.key
  245.     # Create the DH parameters file using the predefined ffdhe2048 group
  246.     echo '-----BEGIN DH PARAMETERS-----
  247. MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
  248. +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
  249. 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
  250. YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
  251. 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
  252. ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
  253. -----END DH PARAMETERS-----' > /etc/openvpn/dh.pem
  254.     # Generate server.conf
  255.     echo "port $PORT
  256. proto $PROTOCOL
  257. dev tun
  258. sndbuf 0
  259. rcvbuf 0
  260. ca ca.crt
  261. cert server.crt
  262. key server.key
  263. dh dh.pem
  264. auth SHA512
  265. tls-auth ta.key 0
  266. topology subnet
  267. server 10.8.0.0 255.255.255.0
  268. ifconfig-pool-persist ipp.txt" > /etc/openvpn/server.conf
  269.     echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
  270.     # DNS
  271.     case $DNS in
  272.         1)
  273.         echo 'push "dhcp-option DNS 10.8.0.1"' >> /etc/openvpn/server.conf
  274.         ;;
  275.         2)
  276.         # Locate the proper resolv.conf
  277.         # Needed for systems running systemd-resolved
  278.         if grep -q "127.0.0.53" "/etc/resolv.conf"; then
  279.             RESOLVCONF='/run/systemd/resolve/resolv.conf'
  280.         else
  281.             RESOLVCONF='/etc/resolv.conf'
  282.         fi
  283.         # Obtain the resolvers from resolv.conf and use them for OpenVPN
  284.         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
  285.             echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
  286.         done
  287.         ;;
  288.         3)
  289.         echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server.conf
  290.         echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server.conf
  291.         ;;
  292.         4)
  293.         echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
  294.         echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
  295.         ;;
  296.         5)
  297.         echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
  298.         echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
  299.         ;;
  300.         6)
  301.         echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server.conf
  302.         echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server.conf
  303.         ;;
  304.     esac
  305.     echo "keepalive 10 120
  306. cipher AES-256-CBC
  307. user nobody
  308. group $GROUPNAME
  309. persist-key
  310. persist-tun
  311. status openvpn-status.log
  312. verb 3
  313. crl-verify crl.pem" >> /etc/openvpn/server.conf
  314.     # Enable net.ipv4.ip_forward for the system
  315.     echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/30-openvpn-forward.conf
  316.     # Enable without waiting for a reboot or service restart
  317.     echo 1 > /proc/sys/net/ipv4/ip_forward
  318.     if pgrep firewalld; then
  319.         # Using both permanent and not permanent rules to avoid a firewalld
  320.         # reload.
  321.         # We don't use --add-service=openvpn because that would only work with
  322.         # the default port and protocol.
  323.         firewall-cmd --zone=public --add-port=$PORT/$PROTOCOL
  324.         firewall-cmd --zone=trusted --add-source=10.8.0.0/24
  325.         firewall-cmd --permanent --zone=public --add-port=$PORT/$PROTOCOL
  326.         firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
  327.         # Set NAT for the VPN subnet
  328.         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
  329.         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
  330.     else
  331.         # Needed to use rc.local with some systemd distros
  332.         if [[ "$OS" = 'debian' && ! -e $RCLOCAL ]]; then
  333.             echo '#!/bin/sh -e
  334. exit 0' > $RCLOCAL
  335.         fi
  336.         chmod +x $RCLOCAL
  337.         # Set NAT for the VPN subnet
  338.         iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP
  339.         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
  340.         if iptables -L -n | grep -qE '^(REJECT|DROP)'; then
  341.             # If iptables has at least one REJECT rule, we asume this is needed.
  342.             # Not the best approach but I can't think of other and this shouldn't
  343.             # cause problems.
  344.             iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT
  345.             iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
  346.             iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
  347.             sed -i "1 a\iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT" $RCLOCAL
  348.             sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
  349.             sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
  350.         fi
  351.     fi
  352.     # If SELinux is enabled and a custom port was selected, we need this
  353.     if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then
  354.         # Install semanage if not already present
  355.         if ! hash semanage 2>/dev/null; then
  356.             yum install policycoreutils-python -y
  357.         fi
  358.         semanage port -a -t openvpn_port_t -p $PROTOCOL $PORT
  359.     fi
  360.     # And finally, restart OpenVPN
  361.     systemctl restart openvpn@server.service
  362.     if [[ "$OS" = 'centos' ]]; then
  363.         systemctl enable openvpn@server.service
  364.     fi
  365.     # If the server is behind a NAT, use the correct IP address
  366.     if [[ "$PUBLICIP" != "" ]]; then
  367.         IP=$PUBLICIP
  368.     fi
  369.     # client-common.txt is created so we have a template to add further users later
  370.     echo "client
  371. dev tun
  372. proto $PROTOCOL
  373. sndbuf 0
  374. rcvbuf 0
  375. remote $IP $PORT
  376. resolv-retry infinite
  377. nobind
  378. persist-key
  379. persist-tun
  380. remote-cert-tls server
  381. auth SHA512
  382. cipher AES-256-CBC
  383. setenv opt block-outside-dns
  384. key-direction 1
  385. verb 3" > /etc/openvpn/client-common.txt
  386.     # Generates the custom client.ovpn
  387.     newclient "$CLIENT"
  388.     echo
  389.     echo "Finished!"
  390.     echo
  391.     echo "Your client configuration is available at:" ~/"$CLIENT.ovpn"
  392.     echo "If you want to add more clients, you simply need to run this script again!"
  393. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement