Register for the iXsystems Community to get an ad-free experience and exclusive discounts in our eBay Store.

Help needed writing a script

Status
Not open for further replies.

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
I use ipfw and OpenVPN in a jail, so far everything works fine. Just want to automate some stuff. This jail it the only place i need to access the outside world (except for the occasional FreeNAS update), and only through the VPN tunnel.
Seems like the OpenVPN script hooks is the best and easiest way to go.
 

cdgonzalez

Junior Member
Joined
Dec 19, 2014
Messages
21
Just to chime in, I've also had no issues using OpenVPN inside a jail with functioning ipfw rules. Also like Rilo I still need to build some custom scripting to have a functioning kill switch to ensure traffic only travels via the tunnel. So keep working on it and keep publishing your work :)
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
I will, but it takes time. As you can see, i'm still learning a lot here
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
I will, but it takes time. As you can see, i'm still learning a lot here
It certainly does take time with the intracacies between how different software reacts and now you need to figure out some good hook from OpenVPN which you could utilize.

I agree with you saying you can establish the firewall with known default rules and then once OpenVPN notifies you the connection has been made that you would trigger your script. One thing to note is I'd also run a script to validate the IP address's periodically just in case OpenVPN doesn't make that trigger. As I mentioned before, a CRON job run lets say every 1 minute or maybe you would prefer 5 seconds would kick off a script to check the status of the OpenVPN. I actually think you could create just a script that runs every 5 seconds, checks for the IP address and if it doesn't exist, sve the value as 0.0.0.0 and exit. Once your script returns an IP address then compare it to the previous IP address, if it's different then run the rules, if its the same then exit. I actually like this one better because it's not linked directly to OpenVPN and is completely self-reliant. Sorry to toss this at you but...
 

jgreco

Resident Grinch
Moderator
Joined
May 29, 2011
Messages
13,174
ime openvpn's hooks are totally reliable
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
ime openvpn's hooks are totally reliable
That is very good to know.

@Rilo Ravestein
Is there a reason in your script why you look for the subnet mask first vice the IP address? Just curious. Again, I don't use OpenVPN so I don't know if there is a reason to check subnet mask first.
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
Here is a cleaner script, put a few minutes into it and tested it, seems to work fine. You just need to go down to line 75 and add in your default rules set (which could be incorporated into the set_rules routine if I knew what those values were). You should be able to run this via CRON periodically for now while you're playing around with the OpenVPN hooks.

Code:
#!/bin/sh

export SUBNET_MASK=""
export IP_ADDR=""


# Main Routines
###########
write_file ()
{
# Write the IP Address to Firewall_IP.log
echo "${IP_ADDR}" > /mnt/media/Firewall_IP.log
}

###########
quit ()
{
exit 0
}
###########
check_ip ()
{
# Lets see what the current values are:
  SUBNET_MASK="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f4)"

if [ "$SUBNET_MASK" != "" ]
then
# SUBNET_MASK is not NUL
  IP_ADDR="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f2)"
  set_rules
else
# SUBNET_MASK is NUL
  IP_ADDR=""
  set_default_rules
  write_file
fi
}
###########
set_rules ()
{
# Compare previous values to current values

TEMP="$(cat /mnt/media/Firewall_IP.log)"
if [ "$TEMP" != "$IP_ADDR" ]
then
echo "New IP Address"

# Flush the current rules
  fwcmd="/sbin/ipfw"
  ${fwcmd} -f flush

# Set New OpenVPN Rules
  ${fwcmd} add 01000 allow log udp from 192.168.2.0/24 to xxx.xxx.xxx.xxx dst-port 53 keep-state
  ${fwcmd} add 01002 allow log udp from 192.168.2.0/24 to xxx.xxx.xxx.xxx dst-port 53 keep-state
  ${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
  ${fwcmd} add 02000 allow ip from 192.168.2.0/24 to xxx.xxx.xxx.xxx keep-state
  ${fwcmd} add 04000 allow ip from 127.0.0.1 to any
  ${fwcmd} add 05000 allow ip from "${IP_ADDR}" to any
  ${fwcmd} add 05002 allow ip from any to "${IP_ADDR}"
  ${fwcmd} add 05004 allow ip from "${SUBNET_MASK}" to any
  ${fwcmd} add 05006 allow ip from any to "${SUBNET_MASK}"
  ${fwcmd} add 65534 deny ip from any to any
write_file
else
echo Same IP Address, No change required
fi
}
###########
set_default_rules ()
{
# Flush the current rules
  fwcmd="/sbin/ipfw"
  ${fwcmd} -f flush

# Enter your default setup for when there is no VPN tunnel.
}

# Main Program

check_ip
exit

 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Is there a reason in your script why you look for the subnet mask first vice the IP address? Just curious. Again, I don't use OpenVPN so I don't know if there is a reason to check subnet mask first.
I'm not checking for any subnet mask. The VPN tunnel looks something like this:
Code:
vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff
I am getting the two IP addresses.
 
Last edited:

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Here is a cleaner script, put a few minutes into it and tested it, seems to work fine. You just need to go down to line 75 and add in your default rules set (which could be incorporated into the set_rules routine if I knew what those values were). You should be able to run this via CRON periodically for now while you're playing around with the OpenVPN hooks.

Code:
 #!/bin/sh
...
Thanks Joe! Since i will be evaluating the two IP addresses of the tunnel (see my previous comment), i've altered the script a little.
Code:
#!/bin/sh

export IP_ADDR_1=""
export IP_ADDR_2=""

# Main Routines
###########
write_file ()
{
# Write the IP Address to Firewall_IP.log
echo "${IP_ADDR_1}" > /mnt/media/Firewall_IP.log
echo "${IP_ADDR_2}" >> /mnt/media/Firewall_IP.log
}

###########
quit ()
{
exit 0
}

###########
check_ip ()
{
# Lets see what the current values are:
  IP_ADDR_1="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f2)"
  IP_ADDR_2="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f4)"
if [ "$IP_ADDR_1" != "" ] && [ "$IP_ADDR_2" != "" ]
then
# IP_ADDR_1 & IP_ADDR_2 are not NUL
  IP_ADDR_1="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f2)"
  IP_ADDR_2="$(/sbin/ifconfig | grep 'inet 10' | cut -d" " -f4)"
  set_rules
else
# IP_ADDR_1 and/or IP_ADDR_2 is NUL
  IP_ADDR_1=""
  IP_ADDR_2=""
  set_default_rules
  write_file
fi
}

###########
set_rules ()
{
# Compare previous values to current values
TEMP="$(cat /mnt/media/Firewall_IP.log)"
if [ "sed -n 1p ${TEMP}" != "$IP_ADDR_1" ] || [ "sed -n 2p ${TEMP}" != "$IP_ADDR_2" ]
then
echo "New IP Address"
# Flush the current rules
  fwcmd="/sbin/ipfw"
  ${fwcmd} -f flush
# Set New OpenVPN Rules
  ${fwcmd} add 01000 allow log udp from 192.168.2.0/24 to xxx.xxx.xxx.xxx dst-port 53 keep-state #DNS IP 1
  ${fwcmd} add 01002 allow log udp from 192.168.2.0/24 to xxx.xxx.xxx.xxx dst-port 53 keep-state #DNS IP 1
  ${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
  ${fwcmd} add 02000 allow ip from 192.168.2.0/24 to xxx.xxx.xxx.xxx keep-state #VPN IP
  ${fwcmd} add 04000 allow ip from 127.0.0.1 to any
  ${fwcmd} add 05000 allow ip from "${IP_ADDR_1}" to any
  ${fwcmd} add 05002 allow ip from any to "${IP_ADDR_1}"
  ${fwcmd} add 05004 allow ip from "${IP_ADDR_2}" to any
  ${fwcmd} add 05006 allow ip from any to "${IP_ADDR_2}"
  ${fwcmd} add 65534 deny ip from any to any
write_file
else
echo Same IP Address, No change required
fi
}

###########
set_default_rules ()
{
# Flush the current rules
  fwcmd="/sbin/ipfw"
  ${fwcmd} -f flush

# Default setup for when there is no VPN tunnel.
  ${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
  ${fwcmd} add 02000 allow ip from 192.168.2.0/24 to xxx.xxx.xxx.xxx keep-state
  ${fwcmd} add 04000 allow ip from 127.0.0.1 to any
  ${fwcmd} add 65534 deny ip from any to any
}

# Main Program
check_ip
exit

Can't test right now, since i'm at work.
  • I think i could lose lines 30,31, 35 & 36.
  • I am not sure yet if if line 47 works correctly. I want to test IP_ADDR_1 against line 1 of the IP.log and IP_ADDR_2 against line 2.
  • Default rules are almost the same, only without the DNS lines (first two) and the VPN lines (5000*)
  • I will tighten things up even more in lines 100* later, since the DNSs only needs to be accessed from this jail, not my complete subnet (home network) and only 1 IP (my laptop) needs acces to the jail. Also need to add a line to open a port. In fact, i've done i bit of reading on ipfw, and it seems there is a lot of room for improvement in these rules. However, this is all outside of the scope of this thread
I will check things out tonight when return from work and my wife has gone to work :)
 
Last edited:

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
Yes, you can drop lines 30 and 31 because you already have those in lines 25 and 26. As for lines 35 and 36, you "should" be able to get rid of those two lines as well.

I do find it easier to work use these small subroutines because you can make a change in one section knowing it shouldn't affect something else.

I forgot that you put up the line with two ip addresses in it, since my system returned the subnet mask that is why I went with those labels. Oh yes, please change the script to fit your needs, it's an example that I think looks very promising.
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
@titan_rw
I'm glad you can write scripts but how does your specific posting help to OP? I wouldn't mind you taking a look at the scripts here and adding your two cents to try an make it either more streamlined or understandable. I don't mind learning as well.
 

titan_rw

Neophyte Sage
Joined
Sep 1, 2012
Messages
591
I'm sorry, I was simply pointing out that a tricky as it is in FreeBSD to write shell scripts it's infinitely easier / better than windows.

I'll try to unclutter the OP's thread.
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
I'm sorry, I was simply pointing out that a tricky as it is in FreeBSD to write shell scripts it's infinitely easier / better than windows.

I'll try to unclutter the OP's thread.
No problem. I was hoping you might see some changes to be made because I'm not very good at programming so having someone else look at it could be a benefit.
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Hi there,

After some tweaking, i now got a working script for cron. The firewall loads the default (more restricting) rules on startup, only allowing the local subnet and the IP of the VPN server. This script also clears the IP logfile. After that, the cron script runs, to check if one of the IP addresses of the tunnel has changed. If not, the script exits. If there is a change, it checks if any of the two IP addresses is null. If so, it sets the restricting default rules. If not, it uses the "normal" rules, allowing the IP addresses of the tunnel.

Rules loaded on firewall (ifpw) startup:
Code:
#!/bin/sh

# Set rules command prefix
fwcmd="/sbin/ipfw"

# Flush out the list before we begin.
${fwcmd} -f flush

${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
${fwcmd} add 02000 allow ip from 192.168.2.0/24 to xxx.xxx.xxx.xxx keep-state
${fwcmd} add 04000 allow ip from 127.0.0.1 to any
${fwcmd} add 65534 deny ip from any to any
echo "" > /mnt/media/Firewall_IP.log


script for cron job:
Code:
#!/bin/sh

export IP_ADDR_1=""
export IP_ADDR_2=""

# Main Routines
###########
write_file ()
{
    # Write the IP Address to Firewall_IP.log
    echo "${IP_ADDR_1}" > /mnt/media/Firewall_IP.log
    echo "${IP_ADDR_2}" >> /mnt/media/Firewall_IP.log
    quit
}

###########
quit ()
{
    exit 0
}

###########
check_ip ()
{
    # Lets see what the current values are:
    IP_ADDR_1="$(/sbin/ifconfig | grep 'inet 10.' | cut -d" " -f2)"
    IP_ADDR_2="$(/sbin/ifconfig | grep 'inet 10.' | cut -d" " -f4)"
    # Lets see what the previous values are:
    TEMP1="$(sed '1q;d' /mnt/media/Firewall_IP.log)"
    TEMP2="$(sed '2q;d' /mnt/media/Firewall_IP.log)"
    # Lets compare
    if [ "${TEMP1}" = "$IP_ADDR_1" ] && [ "${TEMP2}" = "$IP_ADDR_2" ]
        then
            # IP has not changed
            echo No change required
            quit
        else
            # IP has changed
              set_rules
    fi
}

###########
set_rules ()
{
    # This function is only called if one of the IP addresses has changed
    if [ "$IP_ADDR_1" != "" ] && [ "$IP_ADDR_2" != "" ]
        then
            echo "New IP Address"
            # Flush the current rules
            fwcmd="/sbin/ipfw"
            ${fwcmd} -f flush
            # Set New OpenVPN Rules
            ${fwcmd} add 01000 allow log udp from 192.168.2.0/24 to 37.235.1.174 dst-port 53 keep-state #DNS IP 1
            ${fwcmd} add 01002 allow log udp from 192.168.2.0/24 to 37.235.1.177 dst-port 53 keep-state #DNS IP 2
            ${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
            ${fwcmd} add 02000 allow ip from 192.168.2.0/24 to ##. ###. ###. ### keep-state #VPN IP
            ${fwcmd} add 04000 allow ip from 127.0.0.1 to any
            ${fwcmd} add 05000 allow ip from "${IP_ADDR_1}" to any
            ${fwcmd} add 05002 allow ip from any to "${IP_ADDR_1}"
            ${fwcmd} add 05004 allow ip from "${IP_ADDR_2}" to any
            ${fwcmd} add 05006 allow ip from any to "${IP_ADDR_2}"
            ${fwcmd} add 65534 deny ip from any to any
            write_file
        else
            echo No IP Address found, Change to default rules
            set_default_rules
            write_file
    fi
}

###########
set_default_rules ()
{
    # Flush the current rules
    fwcmd="/sbin/ipfw"
    ${fwcmd} -f flush
    # Default setup for when there is no VPN tunnel.
    ${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
    ${fwcmd} add 02000 allow ip from 192.168.2.0/24 to ##. ###. ###. ### keep-state
    ${fwcmd} add 04000 allow ip from 127.0.0.1 to any
    ${fwcmd} add 65534 deny ip from any to any
}

# Main Program
check_ip
exit


I'm pretty shure i covered all possible scenarios now (please correct me if i'm wrong). I think i will let this script run every minute until i find the time to write a script that uses the OpenVPN hooks.
 
Last edited:

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,947
Hope it all works fine.
 

denist

Member
Joined
Jan 28, 2013
Messages
188
i am having issue with ipfw and if it is even starting.,

i used the cronjob and script for ipfw_rules

used /etc/rc.d/ipfw start to start it

comes up with this.

00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 deny ip from any to ::1
00500 deny ip from ::1 to any
00600 allow ipv6-icmp from :: to ff02::/16
00700 allow ipv6-icmp from fe80::/10 to fe80::/10
00800 allow ipv6-icmp from fe80::/10 to ff02::/16
00900 allow ipv6-icmp from any to any ip6 icmp6types 1
01000 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136
Line 4: bad command `fwcmd="/sbin/ipfw"'
Firewall rules loaded.

then i try the ping www.google.com.au with openvpn on or off still pings..

this is what i used for the script and cron.

#!/bin/sh

# Set rules command prefix
fwcmd="/sbin/ipfw"

# Flush out the list before we begin.
${fwcmd} -f flush

${fwcmd} add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
${fwcmd} add 02000 allow ip from 192.168.2.0/24 to xxx.xxx.xxx.xxx keep-state
${fwcmd} add 04000 allow ip from 127.0.0.1 to any
${fwcmd} add 65534 deny ip from any to any
echo "" > /sabnzbd/scripts/Firewall_IP.log

this is the rules.

dont know whats happening

do i have to change the device i put tun0 but as you see above its says loO

so not sure..

thanx
 

denist

Member
Joined
Jan 28, 2013
Messages
188
anyone know what the cmd is for checking what the adapters are....

there is this firewall rules

ipfw -f flush

ipfw -q add 00010 allow ip from any to any via tun0

ipfw -q add 00101 allow ip from me to 10.0.0.0/24 via epair0b uid transmission
ipfw -q add 00102 allow ip from 10.0.0.0/24 to me via epair0b uid transmission
ipfw -q add 00103 deny ip from any to any via epair0b uid transmission

ipfw -q add 65535 allow all from any to any

but not sure if my adapter is epairob

so im lost with ipfw.

notr sure how to tell if its running or using the rules

i got openvpn working fine via the script and boots fine.. its just the ipfw or kill switch
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Have you changed all the ip addresses to match your needs? Local network, VPN remote server IP, local VPN IP, DNS servers, etc. Why do you want to check the adapter? VPN is tun# and you should only allow traffic through tun#.
 

UF8FF

Member
Joined
Jan 16, 2016
Messages
29
Before I screw it up I figured I'd ask:

If I'm using 192.168.1.1 as my router address, DHCP range being 192.168.1.2-1.200 and then my Jails are using 192.168.1.201-225, will my firewall rules want to look thusly?

Code:
#!/bin/sh
# Set rules command prefix
fwcmd="/sbin/ipfw"
# Flush out the list before we begin.
${fwcmd} -f flush
${fwcmd} add 01006 allow ip from 192.168.1.0/24 to 192.168.1.0/24 keep-state
${fwcmd} add 02000 allow ip from 192.168.1.0/24 to 192.168.1.202 keep-state #this being the IP of the transmission Jail, NOT my my actual server which is 1.16
${fwcmd} add 04000 allow ip from 127.0.0.1 to any
${fwcmd} add 65534 deny ip from any to any
echo "" > /mnt/media/Firewall_IP.log
 
Status
Not open for further replies.
Top