ipfw with nat - allowing by MAC address

eksffa at freebsdbrasil.com.br eksffa at freebsdbrasil.com.br
Thu Apr 26 02:16:25 UTC 2007


Ok, I got home (when I have some time) and tried exactly your rule set.
The main deal why it worked on my example and not your approach is:

- once packets get dropped (denied) on layer2, it will never reach upper
layers

Thus, NO OTHER action besides deny will avoid the packet getting into
ip_input or ip_output.

This is crystal-clear on man page, on PACKET FLOW session, and yes,
sometimes we just ignore the man pages, this si why I found very strange
when I tried your setup and it showed the exact behavior you described (as
I didnt expect).

What was happening:

When you skipped packets on layer2 to somewhere-else, it was ONLY skipped
for layer2. Since the packet was still in the network stack, when it
hitted upper layers (ip_input or ip_output) the rule MATCHED the packet.
In  your set, the DIVERT rule matched the packet, and it obviously got
diverted.

What I did to find it out was:

tail -f /var/log/security | grep 1203

Among other "debug funs", using the ruleset present in the body of this
message.

So, we can be sure that SKIPTO, ALLOW or anything else on Layer2 will
NEVER avoid a packet getting filtered on upper layers.

So, what we needed? A way to identify packets the we dont want to divert.
Which packets we dont want to divert? That ones that, while were flowing
on Layer, DID NOT match the ruleset comparing MAC address. We need to
point the finger and say:

- Hey, you dont have the allowed MAC address, so you wont get diverted

Or we could finger:

- Hey, you have the allowed MAC, so you will be diverted.

Doesnt matter for the system, matters for who is making the rulesets. But
how to do this?

My approach was tagging the ones that did not have the allowed MAC.

Please, read rule 501.

Its action is skipto. Why? Because I was lazy and did not want to rewrite
it as a "count" rule, because in fact, it does NOTHING to the current
ruleset. It skips to somewhere were there is no layer2 rules. So it skips
to nowhere and the packet reaches the "allow from any to any" while on
layer2 flow. Meaning, it only tags. That is enough.

Later, on rule 203 and 205 (selective divert) we only divert the packets
that was not tagged (the allowed MAC). Please note that rule 501 is about
the internal interface. If we make a mistake and do it for all interfaces,
our own (as "our own" pleas read: "the firewall, "me") packets will get
tagged 1. This is not what we want.

Please keep reading:

---------------------------------------------------------------------

# MY TESTING RULESET

my_mac="00:17:31:df:bc:ab/48"
my_net="10.69.0.0/16"
ife="vr0" # external if
ifi="xl0" #internal

/sbin/sysctl net.link.ether.ipfw=1

ipfw -f f

ipfw add 300 skipto 1200 ip from any to any { MAC any $my_mac or MAC
$my_mac any } layer2 // try lubomir_s approach
#ipfw add 301 skipto 1200 ip from any to any MAC $my_mac any layer2 // not
needed since lubomir_s approach worked fine
#ipfw add 500 deny all from any to any layer2
ipfw add 501 skipto 1400 tag 1 log logamount 0 ip from any to any layer2
via $ifi // skipto only on L2 and tag for further ch
ipfw add 1200 count log all from any to any layer2 // somebody passed here
- check the logs
ipfw add 1203 divert 8668 log logamount 0 ip from $my_net to any out via
$ife not tagged 1
ipfw add 1205 divert 8668 log logamount 0 ip from any to me in via $ife
not tagged 1
ipfw add 1240 count log logamount 0 all from any to any diverted not
layer2 // lets see whos got here diverted
ipfw add 1250 queue 1 ip from any to any src-port 80 via $ife not layer2
ipfw add 1251 queue 1 ip from any to any dst-port 80 via $ife not layer2
ipfw add 1300 queue 2 ip from any to any not src-port 80 via $ife not layer2
ipfw add 1398 count log logamount 0 all from any to any diverted not
layer2 // lets see whos got here diverted - since one_pa
ipfw add 1399 count log logamount 0 all from any to any not diverted not
layer2 // lets see whos got here undiverted
ipfw add 1440 allow ip from any to any

ipfw queue 1 config weight 10 mask src-ip 0x000000ff pipe 1
ipfw queue 2 config weight 2 mask src-ip 0x000000ff pipe 1
ipfw pipe 1 config bw 4Mbit/s queue 30

---------------------------------------------------------------------

Maybe the better and more clear (to read and understand) approach would be:

- tag on laye2 packets with the ALLOWED MAC
- on upper layers, only divert packets tagged 1
- be sure no other rule will tag packets with tag 1
- be sure ng_tag wont tag packets with tag 1

Anything else on FreeBSD besides ipfw and netgraph are able to tag
packets? Probably not right now. Maybe a geom class one day (hehe, just
kidding..). PF tags are not compatible with ipfw/netgraph ones so, no
special attention is required.

Hope I could help you better this turn.




> OK, so let's get started. Here's my ruleset -
>
> 00300   131732   19262748 skipto 1200 ip from any to any { MAC any
> 00:19:d2:36:b8:48 or MAC 00:19:d2:36:b8:48 any } layer2
> 00500     4723    1941536 skipto 1400 ip from any to any layer2
> 01203    68479    8449298 divert 8668 ip from 192.168.1.0/24 to any out
> via
> fxp0
> 01205    71215   16745674 divert 8668 ip from any to me in via fxp0
> *01250   410160  534966441 queue 1 ip from any to any src-port 80 via fxp0
> *01251   143290   14139299 queue 1 ip from any to any dst-port 80 via fxp0
> *01300  2711668 1462734503 queue 2 ip from any to any not src-port 80 via
> fxp0
> 01400 12581325 6691776490 allow ip from any to any
>
> I've marked the dummynet rules with an asterisk. I'm using Patrick's
> ruleset
> - since I'm only allowing internet access for a single machine I've
> combined
> his first two rules into one. My internal network is 192.168.1.0/24 and my
> external iface is fxp0. What I'm experiencing right now as I'm using this
> set is this - I have internet on this machine I desired /OK/ and on all
> others with ip 192.168.1.X /not OK, obviously :)/ regardless of MAC. For
> me,
> the rules that concern layer2 don't do what they're supposed to and thusly
> the traffic reaches rule 1203 and 1205 and onward. Interestingly enough
> traffic does hit the first and second rule. Here's my uname -
>
> FreeBSD bogoqho.com 6.1-RELEASE FreeBSD 6.1-RELEASE #1: Sun Apr  8
> 10:54:10
> EEST
> 2007     tldstyl3 at bogoqho.com:/usr/src/sys/i386/compile/bogoqho  i386
>
> And my sysctl -
>
> bogoqho# sysctl -a | egrep "one_pass\|ether"
> bogoqho#
>
> which as you can see returns nothing using the command you instructed me
> to
> use.
>
> If there's anything that would help you - just say the word... Let's
> brainstorm :)
>
> --
> mEsS wItH tHe bEsT
> dIE liKe tHe rESt
> _______________________________________________
> freebsd-ipfw at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
> To unsubscribe, send any mail to "freebsd-ipfw-unsubscribe at freebsd.org"
>




More information about the freebsd-ipfw mailing list