IPFW ipfw filter for tcp IPv6 on Freebsd 11

fwyKKCkQze2z

Member

Reaction score: 1
Messages: 45

Hi

I am using ipfw for firewalling on a FreeBSD 11 box. Unfortunately I cannot wrap my head around the fact that/why the following rule does not match when I initiate a TCP connection to 2a00:1450:4001:814::2003 (that is Google...):

Code:
ipfw add 340 set 5 count dst-ip6 2a00:1450:4001:814::2003 proto tcp ipver 6 setup
Looking at the rule after it is installed shows the following:

Code:
$ sudo ipfw show 340
00340   0     0 count tcp from any to 2a00:1450:4001:814::2003 ipver 6 setup
which looks reasonable to me.

But when I send a TCP SYN to 2a00:1450:4001:814::2003 the rule does not match.
But why?

The following rule (without the ipver 6), on the other hand, does match the same traffic:

Code:
ipfw add 341 set 5 count dst-ip6 2a00:1450:4001:814::2003 proto tcp setup
Code:
$ sudo ipfw show 340-341
00340   0     0 count tcp from any to 2a00:1450:4001:814::2003 ipver 6 setup
00341   1    84 count tcp from any to 2a00:1450:4001:814::2003 setup
I am wondering if I misinterpret the ipver keyword (the description in ipfw() is minimal, it just states "Matches IP packets whose IP version field is ver.") or if this is a bug?

BTW: I am trying to just use the "options" described in the man page section "RULE OPTIONS (MATCH PATTERNS)" because the man page states that this is the "new" suggested format.

Code:
The rule body has the following format:

       [proto from src to dst] [options]

     The first part (proto from    src to dst) is for backward compatibility with
     earlier versions of FreeBSD.  In modern FreeBSD any match pattern (in-
     cluding MAC headers, IP protocols,    addresses and ports) can be specified
     in    the options section.
 

Duffyx

Member

Reaction score: 34
Messages: 93

Hmmm, maybe try "IPv6" as ipver argument instead of just the "6". This is really a shot in the dark and might not help ^^.

EDIT: What I do know what should work is to rewrite the rule a bit to the following:
Code:
ipfw add 340 set 5 count ip6 dst-ip6 2a00:1450:4001:814::2003 proto tcp setup
 
OP
OP
F

fwyKKCkQze2z

Member

Reaction score: 1
Messages: 45

Thank you for following up. Unfortunately "IPv6" (various forms of capitalisation, etc.) does not seem to work either. The output of the show command says "ipver 0":

Code:
$ sudo ipfw show 340
00340 0 0 count tcp from any to 2a00:1450:4001:814::2003 ipver 0 setup
which makes me think that using just the "6" is closer to the intended usage :)

Thank you for the alternative notation too; I see that this is working (but then, not specifying "ipversion" at all also does work). But I still wonder and do not understand why the rule does not match when configured as shown above...
 

Duffyx

Member

Reaction score: 34
Messages: 93

Have you tried "ipversion" instead of "ipver"? I don't see any reference of "ipver" in ipfw().
 

roccobaroccoSC

Aspiring Daemon

Reaction score: 145
Messages: 600

Try like so:
Bash:
ipfw add 340 set 5 count tcp from any to 2a00:1450:4001:814::2003 setup
See:
Bash:
% sudo ipfw add 15 count log tcp from any to fe80::1 setup
00015 count log logamount 1000 tcp from any to fe80::1 setup
% telnet fe80::1%lo0 80                                                                                                                                                                                                                                                                                                             :(
Trying fe80::1...
telnet: connect to address fe80::1: Connection refused
telnet: Unable to connect to remote host
% sudo tail -n2 /var/log/security
Oct 13 15:27:54 ..... kernel: ipfw: 15 Count TCP [fe80::1]:32956 [fe80::1]:80 out via lo0
Oct 13 15:27:54 ..... kernel: ipfw: 15 Count TCP [fe80::1]:32956 [fe80::1]:80 in via lo0
 
OP
OP
F

fwyKKCkQze2z

Member

Reaction score: 1
Messages: 45

Dear roccobaroccoSC

Try like so:
Bash:
ipfw add 340 set 5 count tcp from any to 2a00:1450:4001:814::2003 setup
Thank you for replying and for your suggestion! It is true that the rule I have used to show the behaviour can be made work by using the/an IPv6 address. But my question is more about the intended use of the ipversion keyword in general. I think I can work around it in most (if not all?) use cases I have currently, but it bugs me that I do not understand how it is meant to work.
 

roccobaroccoSC

Aspiring Daemon

Reaction score: 145
Messages: 600

Thank you for replying and for your suggestion! It is true that the rule I have used to show the behaviour can be made work by using the/an IPv6 address. But my question is more about the intended use of the ipversion keyword in general. I think I can work around it in most (if not all?) use cases I have currently, but it bugs me that I do not understand how it is meant to work.
Oh, ok. Maybe you are asking too much of it then.
From my perspective (when I read the documentation), it's probably a simple field comparison in the IPFW code:
Code:
ipversion ver
             Matches IP packets whose IP version field is ver.
So what the code does is probably something like that:
C++:
if (ip_packet.ipversion == valueInIPFW) {
    // ...
    apply_actions(ip_packet);
}
Sorry, I am too lazy to take a look into the real code.

So if you want to use ipversion, then just take the generic rule and add the ipversion filter:

Code:
ipfw add 340 set 5 count tcp from any to any ipversion 6 setup
Update: I did some testing and the way I see it, ipversion match does NOT work (it's a bug).
With the following rule I don't get anything logged:
Code:
ipfw add 00015 count log ip from any to any ipversion 6
With this rule, logs can be seen:
Code:
ipfw add 00015 count log ip from any to me6
So, I think you understand it correctly. It simply does not work. If you want you could file a bug report.
 
OP
OP
F

fwyKKCkQze2z

Member

Reaction score: 1
Messages: 45

In short, preferred method to match ipv4 or ipv6 packets is as I showed above with ip4 and ip6 match directives.
Thank you very much for this update. I think I roughly understand what the BR says. One thing I do not understand is however, how the ipfw(8) man page can state

In modern FreeBSD any match pattern (including MAC headers, IP protocols, addresses and ports) can be specified in the options section.
I do not see any possibility to specify "IPv6 only" for a rule only using the options if it does not happen to use src-ip6 or dst-ip6 or ipv6-icmp.

Let's say, for the sake of an example (which is NOT working), to allow just TCP IPv6 connection setup:

Code:
ipfw -q add 340 set 5 allow proto tcp ipversion 6 setup
I have tried mac-type to no avail too:

Code:
ipfw -q add 345 set 5 count dst-ip6 2a00:1450:4001:814::2003 proto tcp mac-type ipv6 setup
Also: according to Wikipedia's IPv4 article the "version" field looks very much like (e.g. it's at the same offset) its IPv6 counterpart. This, to me, also suggests that it might not be working as intended or at least not how users would expect at first glance.

Don't get me wrong, I am not saying you are wrong or that I do not appreciate the effort you made. I just do not totally understand Andrey V. Elsukov (yet?).
 
Top