Hi people...

I wonder if anyone can see what is up with these firewall rules.

We have two external IP ranges from our ISP.  We're trying to migrate from 
IPCop to OpenBSD so we can use the extra range, using a CARPed cluster of two 
3.8 machines.  Initially we just want to get a single Windows web server 
running behind it.

                        
          ---------- isp router  ----------
        |                                 |
        |                                 |
      ipcop                      ---------------------
                                |                     |
                             openbsd1             openbsd2
                                |                     |
                                 ---------------------
                                          |
                                          |
     webserv1                         webserv2


This morning we set the default route of the web server to send traffic 
through the new firewalls, and I a



##########################
#       INTERFACES       #
##########################

ext_if           = "vr0"
dmz_if           = "em0"
int_if           = "em1"
pfsync_phys_if   = "em1"
pfsync_secure_if = "enc0"
all_if           = "{ vr0, em0, em1 }"
# can't antispoof on em1 because enc0 (created by ipsec) shares an IP range
# not critical as this is on the internal interface anyway
antispoof_if     = "{ vr0, em0 }"


##########################
# ADDRESSES AND SERVICES #
##########################

### External

table <public> persist { a.b.c.d/28, e.f.g.h/28 }

### DMZ

dmz_ad="10.0.0.0/16"
dmz_tcp_services_out = "{ http, https, ftp, ntp, domain, 5999 }" 
  # 5999 is cvsup (FreeBSD)
dmz_udp_services_out = "{ ntp, domain }"

## webserv1
webserv1_ext_ad = "x.x.x.x"
webserv1_dmz_ad = "10.0.0.12"

gr8_ext_ad = "x.x.x.x"
gr8_dmz_ad = "10.0.0.13"

codeweavers_secure_ext_ad = "x.x.x.x"
codeweavers_secure_dmz_ad = "10.0.0.14"

dealersystem_ext_ad = "x.x.x.x"
dealersystem_dmz_ad = "10.0.0.15"

easidrive_ext_ad = "x.x.x.x"
easidrive_dmz_ad = "10.0.0.21"

## webserv2 (cluster)
# primary dmz address is "physical address", others are CARPED
webserv2_ext_ad = "x.x.x.x"
webserv2_dmz_primary_ad = "{ 10.0.1.1, 10.0.1.2 }"
webserv2_dmz_ad = "{ 10.0.100.1, 10.0.101.1 }"

# applies to all webservers
webserver_tcp_services = "{ http, https, ssh }"
webserv1_extra_tcp_services = "{ smtp, 3389 }"

## database servers
magneto_dmz_ad = "10.0.2.1"
mystique_dmz_ad = "10.0.2.2"
dbserv_ext_ad = "x.x.x.x"
dbserv_tcp_services = "{ 2222, 2223 }"


# Internal

table <internal> persist { 192.168.136.0/24, 192.168.0.0/24 }

intranet_ext_ad = "x.x.x.x"

jigsawfirewall_ad = "192.168.136.251"
jigsawfirewall_tcp_services_in = "{ smtp }"

# include both firewalls here to save maintaining separate
# scripts for each server
# note: these are the IPs used over the internal interface
firewall_ad = "{ 192.168.136.253, 192.168.136.252,
                 192.168.254.254, 192.168.254.253 }"

# Spam

table <spammers> persist


############
# DEFAULTS #
############

# dont filter on loopback:
set skip on lo0 


#############
# SCRUBBING #
#############

# clean all packets:
#   - random-id: helps prevent OS identification and NAT host counting
#   - reassemble tcp: used with fragment reassemble for NAT
#   - fragment reassemble: makes sure packet fragments are reassembled before 
#     sending through the network
scrub all reassemble tcp
scrub in all fragment reassemble
scrub out all random-id



###################
# NAT/REDIRECTION #
###################

### DMZ

nat on $ext_if inet proto { tcp, udp, icmp } \
  from $webserv1_dmz_ad -> $webserv1_ext_ad

nat on $ext_if inet proto { tcp, udp, icmp } \
  from $webserv2_dmz_primary_ad -> $webserv2_ext_ad

nat on $ext_if inet proto { tcp, udp, icmp } \
  from { $magneto_dmz_ad, $mystique_dmz_ad } -> $dbserv_ext_ad

## webserv1

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $webserv1_ext_ad port { http, https, ssh, smtp, 3389 } \
           -> $webserv1_dmz_ad

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $codeweavers_secure_ext_ad port { http, https } \
           -> $codeweavers_secure_dmz_ad 

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $dealersystem_ext_ad port { http, https } \
           -> $dealersystem_dmz_ad

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $gr8_ext_ad port { http, https } \
           -> $gr8_dmz_ad 

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $easidrive_ext_ad port { http, https } \
           -> $easidrive_dmz_ad 

## webserv2 (load balancing)

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $webserv2_ext_ad port http -> $webserv2_dmz_ad port http \
  round-robin sticky-address
rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $webserv2_ext_ad port https -> $webserv2_dmz_ad port https \
  round-robin sticky-address
rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $webserv2_ext_ad port ssh -> $webserv2_dmz_ad port ssh \
  round-robin sticky-address

rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $dbserv_ext_ad port 2222 -> $magneto_dmz_ad port ssh
rdr on { $ext_if, $int_if } inet proto tcp \
  from any to $dbserv_ext_ad port 2223 -> $mystique_dmz_ad port ssh


# Internal

nat on $ext_if proto { tcp, udp, icmp } \
  from <internal> -> $intranet_ext_ad

rdr on $ext_if proto { tcp, udp, icmp } \
  from any to $intranet_ext_ad -> $jigsawfirewall_ad


# Spam

rdr pass on $ext_if inet proto tcp \
  from <spammers> to port smtp -> 127.0.0.1 port spamd


# FTP proxy

rdr on $dmz_if proto tcp \
  from $dmz_ad to any port ftp -> localhost port 8021
rdr on $int_if proto tcp \
  from <internal> to any port ftp -> localhost port 8021


#############
# FILTERING #
#############

#default policy:
block log
antispoof log quick for $antispoof_if
# pass out anything we've deemed safe to leave the opposite interface
pass out quick inet tagged SANITISED modulate state


# --- pfsync (ipsec virtual interface)

# just allow anything, nothing unpleasant is going to pass over the interface
pass quick on $pfsync_secure_if


# --- external

# fuzz any 'nmap' attempt 
# (see http://monkey.org/openbsd/archive/misc/0208/msg00877.html)
block in log quick on $ext_if inet proto tcp from any to any flags FUP/FUP
block in log quick on $ext_if inet proto tcp from any to any flags SF/SFRA
block in log quick on $ext_if inet proto tcp from any to any flags /SFRA

# to intranet
pass in on $ext_if inet proto tcp \
  from any to $jigsawfirewall_ad port $jigsawfirewall_tcp_services_in \
  synproxy state tag SANITISED

pass in on $ext_if inet proto tcp \
  from any to 192.168.0.1 port smtp \
  synproxy state tag SANITISED

# to web servers
pass in on $ext_if inet proto tcp \
  from any to $webserv1_dmz_ad port $webserver_tcp_services \
  synproxy state tag SANITISED
pass in on $ext_if inet proto tcp \
  from any to $webserv1_dmz_ad port $webserv1_extra_tcp_services \
  synproxy state tag SANITISED

# webserv1 ssl
pass in on $ext_if inet proto tcp \
  from any to $codeweavers_secure_dmz_ad port { http, https } \
  synproxy state tag SANITISED
pass in on $ext_if inet proto tcp \
  from any to $dealersystem_dmz_ad port { http, https } \
  synproxy state tag SANITISED
pass in on $ext_if inet proto tcp \
  from any to $gr8_dmz_ad port { http, https } \
  synproxy state tag SANITISED
pass in on $ext_if inet proto tcp \
  from any to $easidrive_dmz_ad port { http, https } \
  synproxy state tag SANITISED

# webserv2
pass in on $ext_if inet proto tcp \
  from any to $webserv2_dmz_ad port $webserver_tcp_services \
  synproxy state tag SANITISED

# allow the firewall iteself to make requests
pass out on $ext_if inet proto { tcp, udp, icmp } \
  from ($ext_if) to any modulate state
## - NTP
#pass out log on $ext_if inet proto { tcp, udp } \
#  from ($ext_if) to any port { ntp } keep state
## - DNS
#pass out on $ext_if inet proto { tcp, udp } \
#  from ($ext_if) to any port { domain } keep state

# allow FTP traffic
pass in on $ext_if inet proto tcp \
  from any to <public> port > 49151 keep state
pass out on $ext_if inet proto { tcp } \
  from ($ext_if) to any port { ftp } keep state

# WORMS: block known worms explicitly so we don't log the packets
# Sasser
block in quick on $ext_if proto tcp to port { 445, 5554, 9996 }
# Blaster
block in quick on $ext_if proto tcp to port 135
# God Message
block in quick on $ext_if proto tcp to port 139
# Messenger spam bug
block in quick on $ext_if proto udp to port 135
block in quick on $ext_if proto udp to port 1025 >< 1032


# --- internal

# allow firewall to reach the internal network
pass out on $int_if inet proto { tcp, udp, icmp } \
  from ($int_if) to <internal> keep state

# allow traffic from internal network to anywhere
pass in on $int_if inet proto { tcp, udp, icmp } modulate state tag SANITISED

# don't need to let this out of the internal network
block in on $int_if inet proto igmp

# allow SSH traffic from internal to firewall itself
# TODO: not needed because we're allowing internal full access?
# ...maybe look at restricting internal access to DMZ?
pass in on $int_if inet proto tcp \
  from <internal> to ($int_if) port ssh keep state

# allow SSH, ISAKMP, ICMP traffic between firewalls over internal interface
pass out on $int_if inet proto tcp \
  from ($int_if) to $firewall_ad \
  port ssh keep state
pass in on $int_if inet proto tcp \
  from $firewall_ad to ($int_if) \
  port ssh keep state
pass out on $int_if inet proto { tcp, udp } \
  from ($int_if) to $firewall_ad \
  port isakmp keep state
pass in on $int_if inet proto { tcp, udp } \
  from $firewall_ad to ($int_if) \
  port isakmp keep state
pass out on $int_if inet proto icmp \
  from ($int_if) to $firewall_ad keep state
pass out on $int_if inet proto icmp \
  from $firewall_ad to ($int_if) keep state

# allow encrypted traffic (ipsec tunnel for pfsync)
pass in on $int_if inet proto esp from any to ($int_if)
pass out on $int_if inet proto esp from ($int_if) to any


# --- dmz

# allow firewall to reach the DMZ servers
pass out on $dmz_if inet proto { tcp, udp, icmp } \
  from ($dmz_if) to $dmz_ad keep state

# allow traffic from the DMZ to selected services, but
# not to the internal network
pass in on $dmz_if inet proto tcp \
  from $dmz_ad to any port $dmz_tcp_services_out modulate state tag SANITISED
pass in on $dmz_if inet proto udp \
  from $dmz_ad to any port $dmz_udp_services_out keep state tag SANITISED
pass in on $dmz_if proto icmp \
  from $dmz_ad to any keep state tag SANITISED

# allow access to FTP proxy
# don't ask me why we need the second rule but we do!
# it was deduced from the pflog output
pass in on $dmz_if inet proto tcp \
  from $dmz_ad to localhost port { 8021 } keep state
pass in on $dmz_if inet proto tcp \
  from $dmz_ad to <public> keep state

# TODO: configure NTP server in the DMZ and remove NTP access here
pass in on $dmz_if inet proto { tcp, udp } \
  to port ntp modulate state tag SANITISED

# don't allow connections to internal initiated from the DMZ
block in log on $dmz_if from $dmz_ad to <internal>

# block netbios traffic from the DMZ
block in on $dmz_if proto { tcp, udp } \
  from any to any port { netbios-ns, netbios-dgm, netbios-ssn }


# --- CARP

pass on $all_if inet proto carp keep state

Reply via email to