3
\$\begingroup\$

I've made this script above for GRE Tunnels and I'd like to know how I can improve it.

Also, at the bottom, you'll see "Do you want to forward more ports." I want an easier method of asking this and inputting the info. The method I have right now is lone and not neat.

I want to be able to input ports separated by commas as a user, and I want the iptables commands (below) to be run for each of the ports they input, separated by commas.

#!/bin/bash -e
clear
echo "Kaveen's GRE Tunnel script"
echo ""
echo "This script requires an external package to be installed on your system called SSHPass, This allows this script to remote login to your customer's/secondary box"
echo ""
echo "If you are unsure of the packages that are going to be installed, just check the script itself using a text editor"
echo ""
apt-get update
sleep 1
apt-get install sshpass
sleep 1
echo "Repositories updated and SSHPass installed"
sleep 1
read -p "Your Filtered IP:" fillip
if ip route get $fillip &>/dev/null; then
    echo "$fillip IP Validation Passed"
else
    echo "$fillip IP Validation failed"
    echo "Valid IP Ranges are from 0.0.0.0 - 255.255.255.255"
    exit
fi
read -p "Customers main IP:" cusip
if ip route get $cusip &>/dev/null; then
    echo "$cusip IP Validation Passed"
else
    echo "$cusip IP Validation failed"
    echo "Valid IP Ranges are from 0.0.0.0 - 255.255.255.255"
    echo "Program exiting"
    exit
fi
read -p "Your secondary IP:" secip
if ip route get $secip &>/dev/null; then
    echo "$secip IP Validation Passed"
else
    echo "$secip IP Validation Failed"
    echo "Valid IP Ranges are from 0.0.0.0 - 255.255.255.255"
    echo "Program exiting"
    exit
fi
read -p "Port you wish to forward:" port
if [[ $port -gt 0 && $port -lt 65535 ]]; then
    echo "Port $port is probably OK"
else
    echo "$port Port validation failed"
    echo "Valid port ranges are 0-65535"
    echo "Program exiting"
    exit
fi
echo ""
echo "IP Area completed"
echo "Moving on to remote host info. PLEASE NOTE: Remote hosts SSH Port must be 22 for this script to work"
echo "Filtered IP: $fillip"
echo "Customer IP: $cusip"
echo "Secondary IP: $secip"
echo "Port: $port"
read -p "^^ Is all the above information correct? (y/n) ^^" answer
if [[ $answer =~ ^[Yy]$ ]]
then
    echo Confirmed, Continuing setup
else
    echo Unconfirmed, Exitting application
    exit
fi
sleep 2
clear
read -p "IP of remote host to make tunnel with" remotehost
if ip route get $remotehost &>/dev/null; then
    echo "Checking remote host.."
    echo "Remote host confirmed"
else
    echo "Remote host is not valid! Please recheck the IP and restart the script!..."
    echo "Exiting application"
    exit
fi
read -p "Login user on the remote host" user
sleep 1
read -s -p "Password for $user@$remotehost:" sshpass
sleep 1
read -p "Continue setup at $user@$remotehost with password $sshpass? (y/n)" answer2
if [[ $answer2 =~ ^[Yy]$ ]]
then
    echo "Confirmed, continuing setup"
    sleep 1
else
    echo "Unconfirmed! Cancelling setup and exiting program"
    exit
fi
sleep 2
clear
echo "Starting IPIP Tunnel Creation"
sleep 1
echo "Enabling IP Forwarding"
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
echo "Enabled IP Forwarding"
sleep 1
echo "Creating local tunnel"
iptunnel add ipip1 mode ipip local $secip remote $cusip ttl 255
ip addr add 192.168.168.1/30 dev ipip1
ip link set ipip1 up
echo "Created local tunnel"
echo "Setting up remote tunnel"
sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost iptunnel add ipip1 mode ipip local $cusip remote $secip ttl 255
sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost ip addr add 192.168.168.
sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost ip link set ipip1 up
echo "Created remote tunnel"
echo "Testing <> Connection"
((count = 100))
while [[ $count -ne 0 ]] ; do
    ping -c 1 192.168.168.2               
    rc=$?
    if [[ $rc -eq 0 ]] ; then
        ((count = 1))
    fi
    ((count = count - 1))
done

if [[ $rc -eq 0 ]] ; then
    echo "Connection test worked. Continuing"
else
    echo "Connection failed. Exitting application"
    exit
fi
echo "Connection test succeeded"
sleep 1
echo "Adding Network Address Translation entries"
iptables -t nat -A POSTROUTING -s 192.168.168.0/30 -j SNAT --to-source $fillip
echo "NAT entries added"
sleep 1
echo "Forwarding ports"
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port -j DNAT --to-destination 192.168.168.2:$port
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "Ports forwarded"
echo "Tunnel setup done!"
sleep 2
echo "Generating IPTunnel and IPTables reset script for local host"
cat << \EOF > reset.sh
#!/bin/sh -e
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptunnel del ipip1
EOF
chmod +x reset.sh
echo "Generated IPTunnel and IPTables reset script for local host"
sleep 1
echo "Generating reset script on remote machine"
sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost cat << \EOF > reset.sh
#!/bin/sh -e
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptunnel del ipip1
EOF
sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost chmod +x reset.sh
echo "Generated reset script on remove machine"
sleep 1
read -p "Would you like to document the changes this script has made in a separate file? (y/n)" changes
if [[ $changes =~ ^[Yy]$ ]]
then
    echo "Confirmed, documenting changes"
    cat << \EOF > changes.txt
    iptunnel add ipip1 mode ipip local $secip remote $cusip ttl 255
    ip addr add 192.168.168.1/30 dev ipip1
    ip link set ipip1 up
    sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost iptunnel add ipip1 mode ipip local $cusip remote $secip ttl 255
    sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost ip addr add 192.168.168.
    sshpass -p$sshpass ssh -o StrictHostKeyChecking=no $user@$remotehost ip link set ipip1 up
    iptables -t nat -A POSTROUTING -s 192.168.168.0/30 -j SNAT --to-source $fillip
    iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port -j DNAT --to-destination 192.168.168.2:$port
    iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
EOF
else
    echo "Denied, Continuing"
fi
sleep 2
read -p "Ok, do you want to forward any final ports? (y/n)" douwanna
if [[ $douwanna =~ ^[Yy]$ ]]
then
    echo "Ok, starting port forwarding wizard. Press ctrl+c at anytime to finish up everything and exit wizard! Enjoy your IPIP Tunnel!"
    sleep 1
    read -p "First port to forward" port1
    read -p "Another port to forward" port2
    read -p "Another port to forward" port3
    read -p "Another port to forward" port4
    read -p "Another port to forward" port5
    echo "Ok, forwarding those ports"
else
    echo "Denied, Exiting script, your IPIP tunnel is complete!"
fi
if [[ $port1 $port2 $port3 $port4 $port5 -gt 0 && $port -lt 65535 ]]; then
    echo "Port $port is probably OK"
else
    echo "$port Port validation failed"
    echo "Valid port ranges are 0-65535"
    echo "Program exiting"
    exit
fi
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port1 -j DNAT --to-destination 192.168.168.2:$port1
sleep 1
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port1 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "forwarded port $port1"
sleep 1
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port2 -j DNAT --to-destination 192.168.168.2:$port2
sleep 1
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port2 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "forwarded port $port2"
sleep 1
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port3 -j DNAT --to-destination 192.168.168.2:$port3
sleep 1
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port3 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "forwarded port $port3"
sleep 1
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port4 -j DNAT --to-destination 192.168.168.2:$port4
sleep 1
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port4 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "Forwarded port $port4"
sleep 1
sleep 1
iptables -t nat -A PREROUTING -p tcp -d $fillip -- dport $port5 -j DNAT --to-destination 192.168.168.2:$port5
sleep 1
iptables -A FORWARDING -p tcp -d 192.168.168.2 --dport $port5 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
echo "Forwarded port $port5"
echo "All ports $port1 $port2 $port3 $port4 $port5 forwarded, exitting application"
exit
\$\endgroup\$
1
  • \$\begingroup\$ Does any one else have any other suggestions? \$\endgroup\$
    – Kaveen K
    Aug 16, 2015 at 20:15

1 Answer 1

2
\$\begingroup\$

Nitpicks

Why do you keep calling sleep? As far as I can tell, it only pauses execution and isn't needed here. It's rather annoying to have to wait when the code executes.

You should also add some blanks lines into this code, as well as some comments. By adding blank lines and comments you can improve the clarity, and readability of your code.

I'm also noticing a few inconsistencies with your echo calls. For example, in many places, you use quotes, "", to echo a message, like this:

echo "Program exiting"

And in other places, you call echo without quotes, like this:

echo Confirmed, Continuing setup

I'd recommend that you choose a style rather than mixing two.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you, I will implement those changes. I call sleep so it doesnt spam the user all at once with a bunch of stuff. I will fix the echo calls, I admit it was a bit lazy on my part, Haha, Do you have a solution for the other problem i mentioned above in the thread? \$\endgroup\$
    – Kaveen K
    Aug 13, 2015 at 1:57
  • \$\begingroup\$ @KaveenK Just don't change the code in your post body. Since I'm not a Bash guru, I'm not quite sure how to solve that issue. If the answer did help, you can click the check mark to accept it. \$\endgroup\$ Aug 13, 2015 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.