If I understand keep state option within a rule correctly, if a packet
explicitly matches a rule that allows traffic to flow through, the
return packet will also be allowed, without any specific rules applied
to the return packet. Correct me if I am wrong.
The network that we have, has three interfaces on a PowerEdge 1850.
"uname -a" from the machine:
OpenBSD donner.silverspringnet.com 3.9 GENERIC.MP#660 i386
* Interface ext_if, is of course the external interface and has public
IP address on it, within a /29 subnet.
* Interface dmz_if, also has a public IP address on it, within a /26 subnet.
* Interface int_if, is the internal interface, with /22 CIDR block.
Below is the pf.conf from the machine. Public IP address are masked.
Note: The following pf.conf works and caters my need, but I want to
understand the pf rule set much more clearly, especially keep state
option on a given rule set irrespective of tcp or udp or icmp.
Question is, without the explicit pass out rule (last rule on Internet
access lists) on ext_if, I cannot get DMZ network to access to DNS
anywhere (rule number 4) on DMZ pass in access lists, but I can get the
first rule on DMZ working fine without any problems What am I missing here?.
As I understand the working of the rule set that I have written, again
please correct me if I wrong, the rule matching/allowing the inbound on
DMZ, again should have an outbound rule set allowing on Internet, is
this correct, then is this what keep state does? I thought having keep
state on a single rule on a specific interface, without any further
rules on any other interface than necessary will do the trick.
Same thing with packets traversing intranet and DMZ interface, without
specific pass out rule on DMZ (last 2 rules on DMZ interface), I cannot
get the packets, from different subnets to talk, even though I have pass
all on intranet interface.
Initially, on the pass out rules outbound on DMZ interface, I had all
the tables, except intranet, expecting that it is allowed, as per the
rules on intranet interface, but I was able to connect from all the
network mentioned in the pass out rule, except for intranet, adding that
table i.e. intranet table to the egress rule set on DMZ did the trick.
Can somebody explain what I am missing here? If you want me to be more
clear, please let me know.
table <INTERNET> const { E.E.E.E/29 }
table <DMZ> const { D.D.D.D/26 }
table <INTRANET> const { 10.200/22 }
table <S2929> const { 10.201/22 }
table <DIALER> const { 10.202/22 }
table <RAVPN> const { 10.206/22 }
table <PROD_GW> persist { \
10.202/22, \
G.G.G/24, \
H1.H1.H1.H1, \
H2.H2.H2.H2, \
H3.H3.H3.H3, \
H4.H4.H4.H4, \
H5.H5.H5.H5, \
H6.H6.H6.H6, \
H7.H7.H7.H7 }
table <UIQ_SERVERS> persist { \
D1.D1.D1.D1, \
D2.D2.D2.D2, \
D3.D3.D3.D3, \
D4.D4.D4.D4, \
D5.D5.D5.D5, \
D6.D6.D6.D6, \
D7.D7.D7.D7, \
D8.D8.D8.D8, \
D9.D9.D9.D9, \
DA.DA.DA.DA, \
DB.DB.DB.DB }
table <UIQ_DB> persist { \
10.200.1.161, \
10.200.1.162, \
10.200.1.214, \
10.200.1.218, \
10.200.1.222, \
10.200.1.243 }
table <KEYSTONE_DB> persist { \
10.200.1.59, \
10.200.1.60, \
10.200.1.61, \
10.200.1.62 }
table <POWERSTREAM_GATEWAYS> persist { \
B1.B1.B1.B1, \
B2.B2.B2.B2, \
B3.B3.B3.B3 }
table <UIQ_POWERSTREAM> persist { C1.C1.C1.C1, C2.C2.C2.C2 }
table <MAIL_SERVERS> persist { MS1.MS1.MS1.MS1, MS2.MS2.MS2.MS2 }
table <DNS_SERVERS> persist { DS1.DS1.DS1.DS1, DS2.DS2.DS2.DS2 }
table <BAD_SMTP> persist
table <BAD_HTTPS> persist
ext_if = "em0" # Internet interface
dmz_if = "em1" # DMZ interface
int_if = "dc0" # Intranet interface
lo_if = "lo0" # Loopback interface
nat_proto = "{ tcp, udp, icmp }"
keystone_uiq_ports = "{ 3101, 3102, 3103 }"
uiq_ports = "{ 3001, 3002, 3003, 3011 }"
uiq_dmz_ports = "{ 22, 3001, 3002 }"
uiq_http_ports = "{ 80, 443, 8080 }"
NTP_SERVER = "NT1.NT1.NT1.NT1"
ICMP_HOST = "IH1.IH1.IH1.IH1"
CITRIX = "CT1.CT1.CT1.CT1"
SPRY = "SP1.SP1.SP1.SP!"
WHISTLER = "10.200.1.253"
set block-policy drop
set debug urgent
set limit frags 2500
set loginterface $ext_if
set optimization normal
set require-order yes
set skip on $lo_if
set timeout { interval 7, frag 20 }
set timeout { tcp.first 5, tcp.finwait 10, tcp.closing 10 }
set timeout { adaptive.start 5000, adaptive.end 20000 }
scrub in on { $ext_if $dmz_if $int_if } all min-ttl 15 max-mss 1518
scrub in on { $ext_if $dmz_if $int_if } all no-df
scrub on { $ext_if $dmz_if $int_if } reassemble tcp
scrub in on { $ext_if $dmz_if $int_if } all random-id
scrub out on { $ext_if $dmz_if $int_if } all
scrub out on { $ext_if $dmz_if $int_if } all random-id
nat on $ext_if inet proto $nat_proto from <INTRANET> -> ($ext_if) port
1024:*
block in log all
block in quick on $ext_if from <BAD_SMTP>
block in quick on $ext_if from <BAD_HTTPS>
antispoof log quick for { $ext_if $dmz_if $int_if }
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Internet access lists
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
pass in quick on $ext_if inet proto tcp from $SPRY to <DMZ> flags S/SA \
keep state
pass in quick on $ext_if inet proto tcp from any to <MAIL_SERVERS> port
= smtp \
flags S/SA keep state (max-src-conn-rate 5/10, overload <BAD_SMTP>
flush)
pass in quick on $ext_if inet proto tcp from any to <UIQ_SERVERS> \
port $uiq_http_ports flags S/SA keep state
pass in quick on $ext_if inet proto tcp from any to $CITRIX port = https
flags S/SA keep state (max-src-conn-rate 3/10, overload <BAD_HTTPS>
flush)
pass in quick on $ext_if inet proto udp from any to <DNS_SERVERS> \
port = domain keep state
pass in quick on $ext_if inet proto icmp from any to $ICMP_HOST
icmp-type 8 code 0 keep state
pass in quick on $ext_if inet proto { udp, icmp } from $SPRY to <DMZ>
keep state
-----------------------------------------------------------------------
pass out quick on $ext_if inet proto tcp from { <DMZ>, ($ext_if) } to
any flags S/SA keep state
pass out quick on $ext_if inet proto { udp, icmp } from { <DMZ>,
($ext_if) } to any keep state
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
DMZ access lists
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
pass in quick on $dmz_if inet proto tcp from <UIQ_SERVERS> to <UIQ_DB> \
port = 1521 flags S/SA keep state
pass in quick on $dmz_if inet proto tcp from $ICMP_HOST to $WHISTLER \
port = ssh flags S/SA keep state
pass in quick on $dmz_if inet proto tcp from <MAIL_SERVERS> to any port
= smtp flags S/SA keep state
pass in quick on $dmz_if inet proto udp from <DNS_SERVERS> to any \
port = domain keep state
pass in quick on $dmz_if inet proto udp from <DMZ> to any port = domain
keep state
pass in quick on $dmz_if inet proto udp from $NTP_SERVER to any port =
ntp keep state
pass in quick on $dmz_if inet proto icmp from <DMZ> to { <INTERNET>, \
($dmz_if) } icmp-type 8 keep state
--------------------------------------------------------------------
pass out quick on $dmz_if inet proto tcp from { <INTRANET>, <DIALER>,
<RAVPN>, <SSN2929>, ($dmz_if) } to <DMZ> flags S/SA keep state
pass out quick on $dmz_if inet proto { udp, icmp } from { <INTRANET>, \
<DIALER>, <RAVPN>, <SSN2929>, ($dmz_if) } to <DMZ> keep state
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Intranet access lists
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
pass in quick on $int_if inet proto tcp all flags S/SA keep state
pass in quick on $int_if inet proto { udp, icmp } all keep state
========================================================================
Thanks
Prabhu