Re: pf state tracking and tos/dscp

2013-05-23 Thread Stuart Henderson
The TOS class isn't (and can't be) used to match packets to the state. Once you 
have created state from a packet with one TOS class, other packets with the 
same src/dest ip/port match this state even if the class is different. (It has 
to be this way - say you are natting - you wouldn't want a different source 
port if some packets  happen to use different TOS).

PF states include two queue names - one for normal traffic, one for "high 
prioroty" traffic: empty TCP ACKs and packets with TOS 'lowdelay' (0x10). So 
perhaps you would get somewhere by using 'match in from $work871 tos 0xB8 set 
tos lowdelay' to re-mark the incoming packets as 'lowdelay' and using e.g. 'set 
queue (vpn, vpn-fast)'.

Otherwise, if you don't need NAT, disabling state tracking for these packets 
might be an option.

Adam Gensler  wrote:

>Hi all,
>
>I've been playing with pf for a number of months now and I've come
>across a situation that I'm having trouble finding a solution for.
>Specifically I'm working with the following topology:
>
>Internet --- OpenBSD box --- Cisco router --- other devices
>
>The Cisco router (a small 800 series router) is sitting behind an
>OpenBSD box (version 5.1). This Cisco router has an IPsec tunnel
>connected to another router out on the Internet. So, all the OpenBSD
>box sees is a bunch of encrypted frames (udp port 4500). That's all
>fine and dandy, that works well, no problems there.
>
>However, some of the devices behind the Cisco router are setting the
>tos/dscp bits on their packets. I would like to be able to prioritize
>those packets in pf for altq handling. So, I've created the following
>rules:
>
>local_nets = "{ 172.28.1.0/24, 172.28.10.0/24, 172.28.11.0/24 }"
>work871 = "172.28.1.3"
>pass in quick inet proto udp from $work871 tos 0xB8 tag VOIP-RTP
>pass in quick inet proto udp from $work871 tos 0x60 tag VOIP-SIG
>pass in quick inet proto { tcp, udp } from $local_nets
>
>The idea here being that ingress traffic from 172.28.1.3, with the
>various tos values will be tagged with a specific tag. On the egress
>side I match on that tag and then apply it to a queue. That isn't
>working though.  It seems that PF creates a state entry first for the
>overall ipsec tunnel using the third rule. After that state gets
>established all subsequent packets do not evaluate the rules, even if
>those packets have different tos values. This leaves me to believe that
>pf isn't creating a state entry tuple that contains the tos value.
>
>I've confirmed the TOS bits are being carried through to the IP header
>of the IPSEC packets. Here's a tcpdump of the incoming packets from my
>LAN interface (vr0):
>
>tcpdump: listening on vr0, link-type EN10MB (Ethernet), capture size
>65535 bytes
>21:37:39.464357 IP (tos 0xc0, ttl 255, id 848, offset 0, flags [none],
>proto UDP (17), length 144)
>172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap:
>ESP(spi=0x32284280,seq=0x12e), length 116
>21:37:39.483350 IP (tos 0xc0, ttl 255, id 1707, offset 0, flags [none],
>proto UDP (17), length 29)
>   172.28.1.3.4500 > 64.102.7.50.4500: isakmp-nat-keep-alive
>21:37:42.365389 IP (tos 0x0, ttl 255, id 849, offset 0, flags [none],
>proto UDP (17), length 152)
>172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap:
>ESP(spi=0x32284280,seq=0x12f), length 124
>21:37:45.465724 IP (tos 0xc0, ttl 255, id 850, offset 0, flags [none],
>proto UDP (17), length 144)
>172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap:
>ESP(spi=0x32284280,seq=0x130), length 116
>21:37:47.370081 IP (tos 0x0, ttl 255, id 851, offset 0, flags [none],
>proto UDP (17), length 152)
>172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap:
>ESP(spi=0x32284280,seq=0x131), length 124
>21:37:49.256302 IP (tos 0x60, ttl 255, id 852, offset 0, flags [none],
>proto UDP (17), length 120)
>172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap:
>ESP(spi=0x32284280,seq=0x132), length 92
>
>From this it's clear that the last packet has "tos 0x60" set. However,
>if I look at this particular rule, it doesn't have any matches or state
>entries:
>
>pass in quick inet proto udp from 172.28.1.3 to any tos 0x60 keep state
>tag VOIP-SIG
>[ Evaluations: 34Packets: 0 Bytes: 0   States:
>0 ]
> [ Inserted: uid 0 pid 13666 State Creations: 0 ]
>
>Instead, there's a state entry logged for this traffic under the third
>rule:
>
>all udp 1.1.1.1:4500 <- 172.28.1.3:4500   MULTIPLE:MULTIPLE
>age 00:15:50, expires in 00:00:57, 394:196 pkts, 52356:39176 bytes,
>rule 37
>
>Based on the above, it seems like the state entries don't include the
>tos information making it impossible to properly classify traffic that
>is encrypted with ipsec. The only way to differentiate various traffic
>streams contained within the tunnel is via tos/dscp. This is fairly
>common practice in the Enterprise routing space. I'd love to be able to
>do the same thing here.
>
>Am I missing something obvious? I've tested OpenBSD 5.1 and (for what
>its worth) FreeBSD 9.0 and also pfsense 2.1beta1, I see the same
>behavior on all of them.
>
>Thanks in

Re: pf state tracking and tos/dscp

2013-05-22 Thread Alexey E. Suslikov
Adam Gensler  kristenandadam.net> writes:

> local_nets = "{ 172.28.1.0/24, 172.28.10.0/24, 172.28.11.0/24 }"
> work871 = "172.28.1.3"
> pass in quick inet proto udp from $work871 tos 0xB8 tag VOIP-RTP
> pass in quick inet proto udp from $work871 tos 0x60 tag VOIP-SIG
> pass in quick inet proto { tcp, udp } from $local_nets

Another possible thing I see, is a tunnel originating side.

Since tos rules you have are unidirectional (in terms of match),
they will create state if only first packet comes from $work871.

However, first packet coming from other side will match another
rule and create state, so all subsequent tunnel's packets will
not hit tos rules.



Re: pf state tracking and tos/dscp

2013-05-22 Thread Alexey E. Suslikov
Adam Gensler  kristenandadam.net> writes:

> all udp 1.1.1.1:4500 <- 172.28.1.3:4500   MULTIPLE:MULTIPLE
>   age 00:15:50, expires in 00:00:57, 394:196 pkts, 52356:39176 bytes, rule 37

put "pass all tos " higher in your ruleset and see if it matches.



pf state tracking and tos/dscp

2013-05-22 Thread Adam Gensler
Hi all,

I've been playing with pf for a number of months now and I've come across a 
situation that I'm having trouble finding a solution for. Specifically I'm 
working with the following topology:

Internet --- OpenBSD box --- Cisco router --- other devices

The Cisco router (a small 800 series router) is sitting behind an OpenBSD box 
(version 5.1). This Cisco router has an IPsec tunnel connected to another 
router out on the Internet. So, all the OpenBSD box sees is a bunch of 
encrypted frames (udp port 4500). That's all fine and dandy, that works well, 
no problems there.

However, some of the devices behind the Cisco router are setting the tos/dscp 
bits on their packets. I would like to be able to prioritize those packets in 
pf for altq handling. So, I've created the following rules:

local_nets = "{ 172.28.1.0/24, 172.28.10.0/24, 172.28.11.0/24 }"
work871 = "172.28.1.3"
pass in quick inet proto udp from $work871 tos 0xB8 tag VOIP-RTP
pass in quick inet proto udp from $work871 tos 0x60 tag VOIP-SIG
pass in quick inet proto { tcp, udp } from $local_nets

The idea here being that ingress traffic from 172.28.1.3, with the various tos 
values will be tagged with a specific tag. On the egress side I match on that 
tag and then apply it to a queue. That isn't working though.  It seems that PF 
creates a state entry first for the overall ipsec tunnel using the third rule. 
After that state gets established all subsequent packets do not evaluate the 
rules, even if those packets have different tos values. This leaves me to 
believe that pf isn't creating a state entry tuple that contains the tos value.

I've confirmed the TOS bits are being carried through to the IP header of the 
IPSEC packets. Here's a tcpdump of the incoming packets from my LAN interface 
(vr0):

tcpdump: listening on vr0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:37:39.464357 IP (tos 0xc0, ttl 255, id 848, offset 0, flags [none], proto 
UDP (17), length 144)
   172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x12e), 
length 116
21:37:39.483350 IP (tos 0xc0, ttl 255, id 1707, offset 0, flags [none], proto 
UDP (17), length 29)
   172.28.1.3.4500 > 64.102.7.50.4500: isakmp-nat-keep-alive
21:37:42.365389 IP (tos 0x0, ttl 255, id 849, offset 0, flags [none], proto UDP 
(17), length 152)
   172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x12f), 
length 124
21:37:45.465724 IP (tos 0xc0, ttl 255, id 850, offset 0, flags [none], proto 
UDP (17), length 144)
   172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x130), 
length 116
21:37:47.370081 IP (tos 0x0, ttl 255, id 851, offset 0, flags [none], proto UDP 
(17), length 152)
   172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x131), 
length 124
21:37:49.256302 IP (tos 0x60, ttl 255, id 852, offset 0, flags [none], proto 
UDP (17), length 120)
   172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x132), 
length 92

>From this it's clear that the last packet has "tos 0x60" set. However, if I 
>look at this particular rule, it doesn't have any matches or state entries:

pass in quick inet proto udp from 172.28.1.3 to any tos 0x60 keep state tag 
VOIP-SIG
 [ Evaluations: 34Packets: 0 Bytes: 0   States: 0 ]
 [ Inserted: uid 0 pid 13666 State Creations: 0 ]

Instead, there's a state entry logged for this traffic under the third rule:

all udp 1.1.1.1:4500 <- 172.28.1.3:4500   MULTIPLE:MULTIPLE
  age 00:15:50, expires in 00:00:57, 394:196 pkts, 52356:39176 bytes, rule 37

Based on the above, it seems like the state entries don't include the tos 
information making it impossible to properly classify traffic that is encrypted 
with ipsec. The only way to differentiate various traffic streams contained 
within the tunnel is via tos/dscp. This is fairly common practice in the 
Enterprise routing space. I'd love to be able to do the same thing here.

Am I missing something obvious? I've tested OpenBSD 5.1 and (for what its 
worth) FreeBSD 9.0 and also pfsense 2.1beta1, I see the same behavior on all of 
them.

Thanks in advance,
Adam