IPFW+NAT+FreeBSD7.3 please help to solve problem

Hi. I`m a newby to FreeBSD and i`ve got some problems while configuring my gateway.

I want to share my public lan (ed1 - 10.1.0.0/16) to anyone in my private lan (ed0 - 192.168.1.0/24).
I compiled and installed kernel with following options:

Code:
options         IPFIREWALL
options         IPFIREWALL_VERBOSE
options         IPFIREWALL_VERBOSE_LIMIT=50
options         IPFIREWALL_NAT
options         LIBALIAS
options         ROUTETABLES=2
options         DUMMYNET
options         HZ="1000"

/etc/rc.conf has following lines:

Code:
gateway_enable="YES"
ifconfig_ed0="inet 192.168.1.1 netmask 255.255.255.0"
ifconfig_ed1="inet 10.1.201.200 netmask 255.255.0.0"
defaultrouter="10.1.254.254"
firewall_enable="YES"
firewall_type="/etc/firewall"

/etc/firewall:

Code:
add 1000 allow ip from 10.1.201.200 to any out xmit ed1
add 1010 allow ip from any to 10.1.201.200 in recv ed1

add 1040 allow ip from any to any via ed0

add 1050 deny ip from any to 192.168.0.0/16 in recv ed1
add 1060 deny ip from 192.168.0.0/16 to any in recv ed1
add 1070 deny ip from any to 172.16.0.0/12 in recv ed1
add 1080 deny ip from 172.16.0.0/12 to any in recv ed1
add 1090 deny ip from any to 10.0.0.0/8 in recv ed1
add 10100 deny ip from 10.0.0.0/8 to any in recv ed1
add 10110 deny ip from any to 169.254.0.0/16 in recv ed1
add 10120 deny ip from 169.254.0.0/16 to any in recv ed1

nat 1 config if ed1 log deny_in same_ports reset

add 10130 nat 1 tcp from any to any out xmit ed1 limit src-addr 20
add 10140 nat 1 ip from any to any out xmit ed1

add 10150 nat 1 ip from any to any in recv ed1

add 65534 deny all from any to any

I can ping both pc`s in both lans - 192.168.1.0/24 and 10.1.0.0/16 from FreeBSD.
When I try to use it as gateway (I sing in gateway: 192.168.1.1 and some ip in my windows pc) time limits out. The problem is in /etc/firewall but I don`t know how work it out.

Plese help.
 
Try this ruleset:
Code:
add 1040 allow ip from any to any via ed0

add 1050 deny ip from any to 192.168.0.0/16 in recv ed1
add 1060 deny ip from 192.168.0.0/16 to any in recv ed1
add 1070 deny ip from any to 172.16.0.0/12 in recv ed1
add 1080 deny ip from 172.16.0.0/12 to any in recv ed1
add 10110 deny ip from any to 169.254.0.0/16 in recv ed1
add 10120 deny ip from 169.254.0.0/16 to any in recv ed1

nat 1 config if ed1 log deny_in same_ports reset

add 10130 nat 1 tcp from any to any out xmit ed1 limit src-addr 20
add 10131 allow tcp from any to any out xmit ed1

add 10140 nat 1 ip from any to any via ed1
add 10150 allow ip from any to any via ed1

add 65534 deny all from any to any

Beware of limit statement on nat rules. The last time I been trying put limits on nat, I got kernel panics. There is one semi-related PR about that problem:
http://www.freebsd.org/cgi/query-pr.cgi?pr=144187
I would not recomended to use limit on nat...

If you are using latest FreeBSD 8.1 you should be aware about problems with sysctl "one_pass" directive - it do not works anymore (it is broken). So why there is a need for 10131 and 10150.
 
terminus said:
Try this ruleset:
Code:
add 1040 allow ip from any to any via ed0

add 1050 deny ip from any to 192.168.0.0/16 in recv ed1
add 1060 deny ip from 192.168.0.0/16 to any in recv ed1
add 1070 deny ip from any to 172.16.0.0/12 in recv ed1
add 1080 deny ip from 172.16.0.0/12 to any in recv ed1
add 10110 deny ip from any to 169.254.0.0/16 in recv ed1
add 10120 deny ip from 169.254.0.0/16 to any in recv ed1

nat 1 config if ed1 log deny_in same_ports reset

add 10130 nat 1 tcp from any to any out xmit ed1 limit src-addr 20
add 10131 allow tcp from any to any out xmit ed1

add 10140 nat 1 ip from any to any via ed1
add 10150 allow ip from any to any via ed1

add 65534 deny all from any to any

Beware of limit statement on nat rules. The last time I been trying put limits on nat, I got kernel panics. There is one semi-related PR about that problem:
http://www.freebsd.org/cgi/query-pr.cgi?pr=144187
I would not recomended to use limit on nat...

If you are using latest FreeBSD 8.1 you should be aware about problems with sysctl "one_pass" directive - it do not works anymore (it is broken). So why there is a need for 10131 and 10150.

thanks! it works! i had to remove also rule 1070 and 1080 because provider use two mirrored nets to provide such services as online TV, radio, ftp and so on. So when i query some address for example "www.some.net" it gets ip 172.16.x.x. but when i query "some.net" it gets ip 10.1.y.y In both cases i get the same look-like content.


Now i will try to share tun0 too. :)
 
I had to change rules 1070 and 1080 to allow because provider has DNS server 10.1.0.5. This server can redirect query to 10.1.0.0/16 or 172.16.0.0/16 networks, so i had to change rules to allow.
Now i`m trying to solve new problem. I also use tun0 (PTP VPN internet connection, MPPE-128,MSCHAPv2). I also want to share it. I use pptp-client, and it works fine only in FreeBSD i`m configuring.

I tried to add rules to /etc/firewall:

Code:
nat 2 config if tun0 log deny_in same_ports reset
add 20140 nat 2 ip from any to any out recv tun0
add 20140 allow ip from any to any out recv tun0
add 20150 nat 2 ip from any to any in xmit tun0
add 20160 allow ip from any to any via tun0

but when FreeBSD starts ppp has not established connection to VPN server nor it has not created tun0 interface, so there is no tun0 and firewall says:
Code:
Line xx: unknown interface name tun0

But when i sign this rules manually after system is loaded and connection was established everything works all right.

Please advise how to load firewall (or firewall rules) after tun0 created.
 
You can cut second part of you ipfw ruleset (where nat 2 and related rules are defined), put it in new rc.d script stored in /usr/local/etc/rc.d/, and configure it to start just after pptpclient.

I do not know how pptpclient works - may be there already is some kind of if-up/if-down scripts just like one in MPD? Anyway rc.d script will solve you problems.

Here is an example of simple rc.d script. You will need to customize it - adjust line "REQUIRE: PPTPCLIENT" to correspond to name of pptpclient rc.d script (I assume that ptpclient rc.d script have line "PROVIDE: PPTPCLIENT").

Code:
#!/bin/sh
# PROVIDE: SECOND-NAT
# REQUIRE: PPTPCLIENT
# BEFORE: DAEMON
#
# put second-nat_enable="YES" in /etc/rc.conf
#

. /etc/rc.subr

name="second-nat"
rcvar=`set_rcvar`

load_rc_config $name

[ -z "$second-nat_enable" ] && second-nat_enable="NO"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

second-nat_start()
{

ipfw nat 2 config if tun0 log deny_in same_ports reset
ipfw add 20140 nat 2 ip from any to any out recv tun0
ipfw add 20140 allow ip from any to any out recv tun0
ipfw add 20150 nat 2 ip from any to any in xmit tun0
ipfw add 20160 allow ip from any to any via tun0

}

second-nat_stop()
{

ipfw delete 20140
ipfw delete 20140
ipfw delete 20150
ipfw delete 20160
ipfw nat 2 delete

}
run_rc_command "$1"

Save it as /usr/local/etc/rc.d/second-nat and do not forget to make it executable using chmod.
 
I did all as you said:

created /usr/local/etc/rc.d/second-nat

chmod 777 /usr/local/etc/rc.d/second-nat

added
Code:
second-nat_enable="YES"
to rc.conf but it still not working - it said while booting second-nat not found.

So i had to edit /etc/rc.local and add line:
Code:
sh /usr/local/etc/rc.d/second-nat start

and to remove
Code:
second-nat_enable="YES"
from rc.conf and after reboot script started fine. I must forgot - I commented some lines in script:

Code:
#!/bin/sh
# PROVIDE: SECOND-NAT
# REQUIRE: PPTPCLIENT
# BEFORE: DAEMON
#
# put second-nat_enable="YES" in /etc/rc.conf
#

. /etc/rc.subr

name="second-nat"
#rcvar=`set_rcvar`
#load_rc_config $name
#[ -z "$second-nat_enable" ] && second-nat_enable="NO"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

second-nat_start()
{

ipfw nat 2 config if tun0 log deny_in same_ports reset
ipfw add 20140 nat 2 ip from any to any out recv tun0
ipfw add 20140 allow ip from any to any out recv tun0
ipfw add 20150 nat 2 ip from any to any in xmit tun0
ipfw add 20160 allow ip from any to any via tun0

}

second-nat_stop()
{

ipfw delete 20140
ipfw delete 20140
ipfw delete 20150
ipfw delete 20160
ipfw nat 2 delete

}
run_rc_command "$1"

Now it works. Script starts before enter login appears, after ppp and firewall started. But it still writ
Code:
ing Starting local daemons:ipfw: tun0: cannot get interface address
than loads all rules and everything works! tun0 is shared to anyone in 192.168.1.0/24.

Why is it so? I guess, if I add that rules to /etc/firewall , ipfw gets an error and stop loading other rules that follow down, but script just addes rules to ipfw table?

Thank you anyway!
 
Back
Top