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
Hi folks,

I would like to write the following script (coming from this thread):
Just before my firewall is started (automatically) in the jail, i want to fetch the ip address(es) ot my tun0 (OpenVPN) connection/tunnel and add those ip addresses to the firewall rules (replacing the old ones preferably) and then start the firewall. I think this could be an easy script, but i'm not yet really familiar with scripting. Maybe someone can give me some help, point me in the right direction?

Thanks!

EDIT: I think i got the big part, using these examples.
Example 1
Example 2 (old)

The only thing now is to fetch the IP addresses and use them to add to the rules
 
Last edited:

Gonzalo

Senior Member
Joined
Nov 29, 2014
Messages
457
Hi Rilo,

So, you want to have a VPN service configured inside a jail with the Transmission client accessing to Internet via that service. I did the same with AirVPN. What service are you using?
For the configuration, in addition to DNS and local network addresses, all you need are the IPs supplied from your VPN service provider.

Regards.
 
Last edited:

Rilo Ravestein

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

I already got everything up and running smoothly, manually installed Transmission and OpenVPN in the same jail (so no plugin used, proud of myself :cool:).

However, i now allow local (VPN) subnet of 10.0.0.0/8 in my firewall rules, but i would realy like to just allow the IP that i'm connected to, tun0:
example: vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff

Since i do not know the ip range, my VPN provider does not provide that, i would like to write a script to check and apply the IP & rules before the firewall starts.
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
I do not use OpenVPN but scripting isn't too difficult if you have a clue what you really want to do. I'll offer some assistance but I will not be able to do anything on my machine except maybe some basic stuff.

The first step you need to take is to write down a listing of commands which you can run from within your jail to achieve the data you need and make the data work as intended. For example lets say you want to know the IP address of your jail, you would type
Code:
ifconfig | grep 'inet 192' | cut -d" " -f2

which would generate the result as follows:
Code:
root@Test2:/ # ifconfig | grep 'inet 192' | cut -d" " -f2
192.168.1.61
root@Test2:/ #


So that gets you the jails current IP address.

Once you figured out the series of manual steps, or have come as close as you can, then you can assemble a script and start testing it out.
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Steps:

flush previous firewall rules
get the 2 IP's of tun0
Code:
vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff

insert fixed rules
then use these two values to create firewall rules in my script, for example:
Code:
add 05000 allow ip from 10.4.13.37 to any
add 05002 allow ip from any to 10.4.13.37
add 05003 allow ip from 10.4.13.38 to any
add 05004 allow ip from any to 10.4.13.38

insert same more fixed rules

Just like in example 1, but then adding the functionality of getting the needed IP addresses first and use them for some rules.

EDIT: I'm actually not sure if i need to add both IP addresses, but i can deal with that later.
 
Last edited:

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
So what do you have to type to get the output of "vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff" ?

Here is something for you to try...
Code:
root@Test2:/ # echo "vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff" | cut -d" " -f4
10.4.13.38
root@Test2:/ # echo "vpn (tun0): inet 10.4.13.38 --> 10.4.13.37 netmask 0xffffffff" | cut -d" " -f6


As you can see all I did was feed the data you provided and cut out the sections you needed.
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Ok, cool. I see what you did, not that hard indeed.
Code:
ifconfig | grep 'vpn' | cut -d" " -f4

should do the trick to get the ip, right?

But now, how can i feed that into my script (as a variable?) and use it to create the rule?
Resulting in something like this:
Code:
add 05000 allow ip from {VARIABLE1} to any
 
Last edited:

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
I think i get it:
Code:
IP1="ifconfig | grep 'vpn' | cut -d" " -f4"
add 05000 allow ip from ${IP1} to any

Going to test some stuff when i get home :)

EDIT: Not sure if that will work, seeing all the " marks in the first line....
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
Teach a man to fish....

As I said, plan out the steps it takes to do it by hand and then create a script. Now if you can make the script run the way you really want it to (this can be a battle, trust me), you got it beat.
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Thanks so far, Joe. Really appreciate it. Will do some testing when i get home.

Feel like i could/should have figured it out myself, now that you make it look so easy :oops:
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
Use Google to help you, it helped me a lot when I was learning to write BSD scripts. Example: "freebsd script assign variable" or "freebsd script assign text variable". Remember, it's freebsd not freenas when you are playing on this level, sometimes though due to limitations of the smaller freenas distribution all things do not work as they would on a normal FreeBSD system, just keep that in mind. You can also check out the cut(1) command and get other examples off the internet you wouldn't have dreamed of.
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
I just can believe it was actually this easy!
Working script:
Code:
#!/bin/sh

fwcmd="/sbin/ipfw"
${fwcmd} -f flush

IP1="$(ifconfig | grep 'inet 10' | cut -d" " -f2)"
IP2="$(ifconfig | grep 'inet 10' | cut -d" " -f4)"

${fwcmd} add 01000 allow log udp from 192.168.2.0/24 to xxx.xxx.xxx dst-port 53 keep-state
${fwcmd} add 01002 allow log udp from 192.168.2.0/24 to 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 ${IP1} to any
${fwcmd} add 05002 allow ip from any to ${IP1}
${fwcmd} add 05004 allow ip from ${IP2} to any
${fwcmd} add 05006 allow ip from any to ${IP2}
${fwcmd} add 65534 deny ip from any to any
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
And have you been able to make the script run automatically as you intended? If so then I'd say you got it!

So, does the IP address change periodically and if so, how do you plan to detect the change, or is this basically a static IP until you have to reboot the jail?
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Yes, it runs automatically. But it seems like the VPN tunnel takes a few seconds to come up, so it doesn't add the four lines if the firewall starts before it is completely up. I experimented a bit in rc.conf with netwait_enable, netwait_ip and netwait_if, but no luck. Now i'm going to alter the script above to wait a few seconds if IP1 and/or IP2 returns empty and then try again for x times.

Your 2nd question would be another thing. To frequently poll if the ip address has changed. So far i have not had another IP address, even after reconnecting, but it seems like a fun challenge to figure out how to do this. Would be hard to test however, if the ip doesn't change. Maybe create some dummy text file for that......

But first things first :cool:
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
Got it working. It loops until the VPN is up and then adds the rules.
Code:
#!/bin/sh

fwcmd="/sbin/ipfw"
${fwcmd} -f flush

IP2="$(ifconfig | grep 'inet 10' | cut -d" " -f4)"
until [ $IP2 != "" ]
do
    IP2=$(ifconfig | grep 'inet 10' | cut -d" " -f4)
    sleep 3
done

IP1="$(ifconfig | grep 'inet 10' | cut -d" " -f2)"

${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 ${IP1} to any
${fwcmd} add 05002 allow ip from any to ${IP1}
${fwcmd} add 05004 allow ip from ${IP2} to any
${fwcmd} add 05006 allow ip from any to ${IP2}
${fwcmd} add 65534 deny ip from any to any


Now trying to limit the retries to 5 (in lines 7, 8 & 11), but no luck so far. I seem to do everything excactly the same as in the examples i look up
Code:
#!/bin/sh

fwcmd="/sbin/ipfw"
${fwcmd} -f flush

IP2="$(ifconfig | grep 'inet 10' | cut -d" " -f4)"
n=0
until [ $IP2 != "" ] || [ $n -ge 5 ]
do
    IP2=$(ifconfig | grep 'inet 10' | cut -d" " -f4)
    n=$[$n+1]
    sleep 3
done

IP1="$(ifconfig | grep 'inet 10' | cut -d" " -f2)"

${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 ${IP1} to any
${fwcmd} add 05002 allow ip from any to ${IP1}
${fwcmd} add 05004 allow ip from ${IP2} to any
${fwcmd} add 05006 allow ip from any to ${IP2}
${fwcmd} add 65534 deny ip from any to any


Keep getting this:
Code:
root@vpn:/ # /etc/rc.d/ipfw restart
net.inet.ip.fw.enable: 1 -> 0
net.inet6.ip6.fw.enable: 1 -> 0
Flushed all rules.
[: !=: unexpected operator
[: !=: unexpected operator
[: $[0+1]: bad number
[: !=: unexpected operator
[: $[$[0+1]+1]: bad number
[: !=: unexpected operator
[: $[$[$[0+1]+1]+1]: bad number
[: !=: unexpected operator
[: $[$[$[$[0+1]+1]+1]+1]: bad number
^C
root@vpn:/ #
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
Line 11, try "let n=n+1".
 

Rilo Ravestein

Neophyte Sage
Joined
Mar 6, 2014
Messages
685
That worked :)
Don't yet know why, though...
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
In the google searches include the word "bash". Bash can be very finicky. Glad it worked.

EDIT: It worked because you were using the $ which is a string operation, not number operator, well something like that. It gives me a headache thinking about it at times.

One suggestion for making it automatically check to see if the IP address has changed...

Add this at line 16:
1) Check for existence of file named "old_address.txt".
2) If exist read the file and compare to the current IP1 and IP2 values.
3) If the values are the same then exit.
4) If the values are different then append the IP1 and IP2 values to the "old_address.txt" file and add a date/time stamp to the data.
5) Run the firewall rules.

The problem with this is you would need two script files, one to run at the very beginning to set the firewall rules no matter what and the second to check things haven't changed. The difference between the two scripts would be the first four steps I listed would actually just append the IP1 and IP2 and time stamp to the data and then rune the firewall rules. The way around that would be to create a file that only existed in RAM and went away once you stopped the jail, then when you restart the jail you would check for the file, if it doesn't exist you would force the firewall rules to be applied.

Why do something like this? So the rules are applied only when needed. I'm not sure how the firewall reacts if it's in the middle of something and you apply the rules, will it cause an error in your data transmission (probably not) but I try to see all the possible issues and plan ahead.
 

jgreco

Resident Grinch
Moderator
Joined
May 29, 2011
Messages
13,190
I just can believe it was actually this easy!
Shell scripting is coolawesome but doing it well takes lots of patience.

I recently posted a one-liner in the staff area that gives the current stable 9.3 version available for download. UNIX has always been awesome for stacking commands and processing text. Accessing a web page and parsing data out of it can be easy!

My script to display the age of the update in days was less elegant and took several lines, mostly 'cuz, well, ya know, lazy. But it did actually parse the file modification time provided by the web server... easily done in shell script :smile:
 

joeschmuck

Old Man
Moderator
Joined
May 28, 2011
Messages
8,949
What amazes me about scripting is how complex a single line could become. When I started learning scripting for BASH I asked some question on how to do something for which I thought was fairly simple but I hadn't figured out the exact context. I was given a few very complex single line answers which got me pointed in the right direction. Trying to break apart and understand what the hell those lines meant were very difficult. Awk for instance confused me but it's actually a very handy tool if you know how to use it. I still have no clue but Google comes to the rescue if I need to use it.

My script to display the age of the update in days was less elegant and took several lines, mostly 'cuz, well, ya know, lazy. But it did actually parse the file modification time provided by the web server... easily done in shell script :)
Too bad they haven't implement it yet, assuming it will work under Xenforo.
 
Status
Not open for further replies.
Top