diff --git a/openvpn-install.sh b/openvpn-install.sh index e945d59..0b2a575 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -58,6 +58,14 @@ newclient () { echo "" >> ~/$1.ovpn } +cdr2mask () +{ + # Number of args to shift, 255..255, first non-255 byte, zeroes + set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 + [ $1 -gt 1 ] && shift $1 || shift + echo ${1-0}.${2-0}.${3-0}.${4-0} +} + # Try to get our IP from the system and fallback to the Internet. # I do this to make the script compatible with NATed servers (lowendspirit.com) # and to avoid getting an IPv6. @@ -130,24 +138,24 @@ if [[ -e /etc/openvpn/server.conf ]]; then if [[ "$REMOVE" = 'y' ]]; then PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2) PROTOCOL=$(grep '^proto ' /etc/openvpn/server.conf | cut -d " " -f 2) - IP=$(grep 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to ' $RCLOCAL | cut -d " " -f 11) + IP=$(grep 'iptables -t nat -A POSTROUTING -s $SUBNET -j SNAT --to ' $RCLOCAL | cut -d " " -f 11) if pgrep firewalld; then # Using both permanent and not permanent rules to avoid a firewalld reload. firewall-cmd --zone=public --remove-port=$PORT/$PROTOCOL - firewall-cmd --zone=trusted --remove-source=10.8.0.0/24 + firewall-cmd --zone=trusted --remove-source=$SUBNET firewall-cmd --permanent --zone=public --remove-port=$PORT/$PROTOCOL - firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24 + firewall-cmd --permanent --zone=trusted --remove-source=$SUBNET fi if iptables -L -n | grep -qE 'REJECT|DROP|ACCEPT'; then iptables -D INPUT -p $PROTOCOL --dport $PORT -j ACCEPT - iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT + iptables -D FORWARD -s $SUBNET -j ACCEPT iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT sed -i "/iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT/d" $RCLOCAL - sed -i "/iptables -I FORWARD -s 10.8.0.0\/24 -j ACCEPT/d" $RCLOCAL + sed -i "/iptables -I FORWARD -s $SUBNET -j ACCEPT/d" $RCLOCAL sed -i "/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT/d" $RCLOCAL fi - iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -j SNAT --to $IP - sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 -j SNAT --to /d' $RCLOCAL + iptables -t nat -D POSTROUTING -s $SUBNET -j SNAT --to $IP + sed -i '/iptables -t nat -A POSTROUTING -s $SUBNET -j SNAT --to /d' $RCLOCAL if hash sestatus 2>/dev/null; then if sestatus | grep "Current mode" | grep -qs "enforcing"; then if [[ "$PORT" != '1194' || "$PROTOCOL" = 'tcp' ]]; then @@ -201,6 +209,9 @@ else echo "What port do you want OpenVPN listening to?" read -p "Port: " -e -i 1194 PORT echo "" + echo "What subnet do you want to use for OpenVPN internal network?" + read -p "IP/prefix length: " -e -i "10.8.0.0/24" SUBNET + echo "" echo "Which DNS do you want to use with the VPN?" echo " 1) Current system resolvers" echo " 2) Google" @@ -261,7 +272,7 @@ key server.key dh dh.pem tls-auth ta.key 0 topology subnet -server 10.8.0.0 255.255.255.0 +server ${SUBNET%/*} `cdr2mask ${SUBNET##*/}` ifconfig-pool-persist ipp.txt" > /etc/openvpn/server.conf echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf # DNS @@ -316,26 +327,26 @@ exit 0' > $RCLOCAL fi chmod +x $RCLOCAL # Set NAT for the VPN subnet - iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to $IP - sed -i "1 a\iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to $IP" $RCLOCAL + iptables -t nat -A POSTROUTING -s $SUBNET -j SNAT --to $IP + sed -i "1 a\iptables -t nat -A POSTROUTING -s $SUBNET -j SNAT --to $IP" $RCLOCAL if pgrep firewalld; then # We don't use --add-service=openvpn because that would only work with # the default port. Using both permanent and not permanent rules to # avoid a firewalld reload. firewall-cmd --zone=public --add-port=$PORT/$PROTOCOL - firewall-cmd --zone=trusted --add-source=10.8.0.0/24 + firewall-cmd --zone=trusted --add-source=$SUBNET firewall-cmd --permanent --zone=public --add-port=$PORT/$PROTOCOL - firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24 + firewall-cmd --permanent --zone=trusted --add-source=$SUBNET fi if iptables -L -n | grep -qE 'REJECT|DROP'; then # If iptables has at least one REJECT rule, we asume this is needed. # Not the best approach but I can't think of other and this shouldn't # cause problems. iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT - iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT + iptables -I FORWARD -s $SUBNET -j ACCEPT iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT sed -i "1 a\iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT" $RCLOCAL - sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL + sed -i "1 a\iptables -I FORWARD -s $SUBNET -j ACCEPT" $RCLOCAL sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL fi # If SELinux is enabled and a custom port was selected, we need this @@ -375,7 +386,7 @@ exit 0' > $RCLOCAL echo "" echo "If your server is NATed (e.g. LowEndSpirit), I need to know the external IP" echo "If that's not the case, just ignore this and leave the next field blank" - read -p "External IP: " -e USEREXTERNALIP + read -p "External IP: " -e -i $EXTERNALIP USEREXTERNALIP if [[ "$USEREXTERNALIP" != "" ]]; then IP=$USEREXTERNALIP fi