I'm trying to put together a firewall for our DMZ and internal network. For
some reason, a server in the DMZ can only hit the external DNS server if it
has keep state on the DMZ interface. Basically the following (relvant
extract) blocks access:
ext_if = "vr0"
dmz_if = "em0"
dmz_tcp_services_out = "{ http, https, ftp, ntp, domain }"
dmz_tcp_services_in = "{ http, https, ssh }"
dmz_udp_services_in = "{ ntp }"
dmz_udp_services_out = "{ domain }"
webserv2_dmz_ad = "{ 10.0.0.4 }"
webserv2_ext_ad= "..."
tcp_opts = "modulate state" # gave up on synproxy state
udp_opts = "keep state"
icmp_opts = "keep state"
nat_proto = "{ tcp, udp, icmp }"
scrub all reassemble tcp
scrub in all fragment reassemble
scrub out all random-id
nat on $ext_if proto $nat_proto \
from $webserv2_dmz_ad -> $webserv2_ext_ad
rdr on { $ext_if, $int_if } proto tcp \
from any to $webserv2_ext_ad port www -> $webserv2_dmz_ad port www
block in log (all) all
block out log (all) all
antispoof log quick for $antispoof_if
pass out on $ext_if proto tcp \
from any to any $tcp_opts
pass out on $ext_if proto udp \
from any to any $udp_opts
pass out on $ext_if inet proto icmp \
from any to any $icmp_opts
pass in on $dmz_if proto tcp \
from $dmz_ad to any port $dmz_tcp_services_out #$tcp_opts
pass in on $dmz_if proto udp \
from $dmz_ad to any port $dmz_udp_services_out #$udp_opts
pass in on $dmz_if proto icmp \
from $dmz_ad to any #$udp_opts
Call dig with this setup and it times out; uncomment the options
(modulate/keep) state and you get a DNS result. I was under the impression
that the state should be created as the packets leave $ext_if, so why is it
necessary to put a state option in the DMZ interface rules?
Hope someone can clear this up
Thanks
Ashley
--
"If you do it the stupid way, you will have to do it again"
- Gregory Chudnovsky