DaemonForums  

Go Back   DaemonForums > OpenBSD > OpenBSD Security

OpenBSD Security Functionally paranoid!

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 10th October 2013
bsd_matt bsd_matt is offline
Port Guard
 
Join Date: Oct 2013
Posts: 12
Thanked 0 Times in 0 Posts
Default pf = Perfectly Frustrating? =)

I am working at a web-host. I have pf setup (using rdr-to) to redirect internet IP's to the local LAN. The problem is that the local boxes see my Internet addy as the source and not the clients internet addy. Traffic is still getting routed correctly, but my SQL logs all show access from _myIP_ and not the real IP.

i.e. My internet IP range = 1.1.1.1 : 1.1.1.200
gateway = 1.1.1.1
www mapped to: 1.1.1.3
mysql = 1.1.1.4
ftp = 1.1.1.5
...etc.

When a client hits our web-server or sql box the logs on these boxes show "connection from 1.1.1.3" (which is the mapping from pf.conf for that 'service')
I want it to show: "connection from 123.54.22.244" or the clients actual IP

I have been mucking around with the pf.conf rules changing rdr-to into nat-to (and others...) but nothing 'fixes' it.

History: We have an old OpenBSD4.8 box that is currently running as our firewall/gateway. It does this behaviour as desired. I only see this issue on a new OBSDv5.3 that we are trying to migrate to.

Help... please!
Reply With Quote
  #2   (View Single Post)  
Old 10th October 2013
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 3,719
Thanked 214 Times in 189 Posts
Default

Hello, and welcome!

Without seeing your PF configuration, based on your problem description I'm going to assume you have NAT configured to translate on the inward facing network. If so, that is the cause of the trouble.

A typical network configuration is to translate only traffic on the outward facing network. See this line from the example configuration in the PF User's Guide:
match out on egress inet from !(egress:network) to any nat-to (egress:0)
The "match" command is not a pass or a block. It is used when you want set specific filtering options to apply to later rules.

The "egress" group contains the NICs assigned to the default route -- also known as the gateway route -- that should be the NICs connecting to your ISPs, or, NICs that route traffic to routers that connect to your ISPs.

Note that the traffic to be NATted comes from all non-egress networks that transit this router. They can go to any address, and will be translated to the first address assigned to the applicable egress NIC.

Note that there is no translation on any of the inner, non-egress network(s).
Reply With Quote
  #3   (View Single Post)  
Old 10th October 2013
bsd_matt bsd_matt is offline
Port Guard
 
Join Date: Oct 2013
Posts: 12
Thanked 0 Times in 0 Posts
Default Thanks...

Thank-you for your reply. I have tried what you input but it's not working. I am working on sanitizing my pf.conf and I will post it here.

Thanks again for you reply..
Reply With Quote
  #4   (View Single Post)  
Old 11th October 2013
bsd_matt bsd_matt is offline
Port Guard
 
Join Date: Oct 2013
Posts: 12
Thanked 0 Times in 0 Posts
Default

After much delay, here is my pf.conf.
Code:
#####################################################
##   Available range:  a.b.c.d.66 -> a.b.c.d.126   ##
#####################################################
# Public IP Addresses #

main_ext_ip     =       "a.b.c.d.66"	
routing_ip      =       "a.b.c.d.65"
sync_pub_ip	=	"a.b.c.d.100"
screen_pub_ip	=	"a.b.c.d.101"

# Important Internal IP Addresses #
netfs           =       "192.168.0.152"
localscreen     =       "192.168.0.221"

# Other Variables#
ext_if="em0"  	#WAN
int_if="em1"	#LAN

set loginterface em0
set loginterface em1

table <binat> {\
	$localscreen\
        $netfs\
        }

table   <rfc1918> const \
        { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

##===================================================
##	Block stuff
##===================================================

block in log on $ext_if
block in log quick on $ext_if from <rfc1918> to any
block out log quick on $ext_if from <rfc1918> to any
pass out log

# ==================================================================================
########  Allow ICMP ping     ####Ping test to make sure we can get to host
pass in inet proto icmp from any to any icmp-type $icmp_types modulate state
### Note: it does work for $sync_pub_ip but not $screen_pub_ip ???   #  <- THIS IS A CLUE!?!
# ==================================================================================


pass log on $ext_if from $netfs      	to any binat-to $sync_pub_ip
pass log on $ext_if from $localscreen   to any binat-to $screen_pub_ip

match out log inet from ! $ext_if to any nat-to $ext_if

pass in log on $ext_if proto { tcp, udp } from any to $sync_pub_ip port { 873 ftp ftp-data 22 21 } rdr-to $netfs
match in log on $ext_if to $screen_pub_ip
pass in log on $ext_if:0 proto { tcp, udp } to $screen_pub_ip port { 81 82 3306 3312 } nat-to $localscreen
pass out log on $ext_if from $localscreen nat-to $screen_pub_ip
match out log on $ext_if from $localscreen to any nat-to $screen_pub_ip
-------------------------------------------------------------------------------
match in log on $ext_if proto { tcp, udp } from any to $screen_pub_ip:0 port { 81 82 3306 3312 52530 } rdr-to $localscreen
match out log on $ext_if from $screen_pub_ip:0 to $localscreen nat-to $ext_if
pass out log on $ext_if from $int_if:network to any
pass in log on $ext_if from $screen_pub_ip:0 nat-to $localscreen
I would really love to hear any suggestions that you might have.

EDIT: If anybody could give me some hints about paring this down, and/or optimizing the layout and code I would be greatful. I am trying to make this thing very efficient too but I know I have a lot of things that are redundant.

Last edited by ocicat; 11th October 2013 at 09:09 PM. Reason: Please use [code] & [/code] tags when posting text file contents.
Reply With Quote
  #5   (View Single Post)  
Old 11th October 2013
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 3,719
Thanked 214 Times in 189 Posts
Default

Though this is but a pair of excerpts from your configuration -- thank you.

One thing to note, if you use match rules to apply options like nat-to, the match rules need to appear before any applicable block or pass rules. And then, with any subsequent matching rule, the prior match settings will also apply, so that a nat-to option need only be used once. From your excerpt, it appears the match rules were thrown in without that understanding.

Additionally, you are using standard NAT translation on your inward network, and that is causing the issue with external addresses being translated. Specifically, this line, the last in the configuration, is the root cause of the problem:
Code:
pass in log on $ext_if from $screen_pub_ip:0 nat-to $localscreen
Other than that, I note that you are combining bidirectional NAT and standard NAT for the same platforms. There is no need. And, the rules are out of order, as your binat-to rules appear before your general nat-to.

Remember: the last matching rule applies.

I've never used bidirectional NAT myself, but I have done some light reading on the subject. When bidirectional NAT is combined with standard NAT, it is possible to misconfigure. Michael Lucas, in his second edition of Absolute OpenBSD, recommends these sort of rules shown below for combining your main NAT with bidirectional NAT. I've adapted his recommended rules to the macros and redacted addresses you used in your configuration excerpt.

Note that Michael uses pass, rather than match, because he does not have multiple followon rules that require the nat-to option. (That's the value of match. Use it once to set an option that you would otherwise have to apply to multiple rules.)

But with a match for nat-to and then a subsequent pass, or with a pass that includes nat-to, the order of rules is critical. The last matching rule applies.
Code:
main_ext_ip = "a.b.c.d.66"
screen_pub_ip = "a.b.c.d.101"
localscreen = "192.168.0.221"

int_if = "em1"

pass out log on egress from $int_if:network to any nat-to $main_ext_ip
pass on $int_if from $localscreen to any binat-to $screen_pub_ip
The first rule applies the general translation, the subsequent rule applies the specific translation. Michael writes that these rules produce unambigous address translations. Only the one specific server uses the dedicated external address, and all other hosts use the main address.

Last edited by jggimi; 11th October 2013 at 10:24 PM. Reason: typos, clarity
Reply With Quote
  #6   (View Single Post)  
Old 11th October 2013
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 3,157
Thanked 182 Times in 149 Posts
Default

As stated in pf.conf(5) pf uses a last matching rule wins strategy :

Code:
     For each packet processed by the packet filter, the filter rules are
     evaluated in sequential order, from first to last.  For block and pass,
     the last matching rule decides what action is taken; if no rule matches
     the packet, the default action is to pass the packet.  For match, rules
     are evaluated every time they match; the pass/block state of a packet
     remains unchanged.
To circumvent this strategy you have to use quick:
Code:
    quick   If a packet matches a rule which has the quick option set, this
            rule is considered the last matching rule, and evaluation of
            subsequent rules is skipped.
Code:
   match
           The packet is matched.  This mechanism is used to provide fine
           grained filtering without altering the block/pass state of a
           packet.  match rules differ from block and pass rules in that
           parameters are set every time a packet matches the rule, not only
           on the last matching rule.  For the following parameters, this
           means that the parameter effectively becomes ``sticky'' until
           explicitly overridden:nat-to, binat-to, rdr-to, queue, rtable, and
           scrub.

With this in mind, and because I don't quite understand what you are trying to accomplish, the following effort to re-organize and clean up the rule set may thus not work at all :
Code:
DEBUG = log

# --- NAT
match out $DEBUG inet from ! $ext_if to any nat-to $ext_if
match out $DEBUG on $ext_if from $screen_pub_ip:0 to $localscreen nat-to $ext_if

pass   in $DEBUG on $ext_if:0 proto { tcp, udp } to $screen_pub_ip port { 81 82 3306 3312 } nat-to $localscreen
pass  out $DEBUG on $ext_if                      from $localscreen nat-to $screen_pub_ip
match out $DEBUG on $ext_if                      from $localscreen to any nat-to $screen_pub_ip
pass  in  $DEBUG  on $ext_if                     from $screen_pub_ip:0 nat-to $localscreen

# --- BINAT
pass    $DEBUG on $ext_if from $netfs             to any binat-to $sync_pub_ip
pass    $DEBUG on $ext_if from $localscreen       to any binat-to $screen_pub_ip

# --- RDR
pass  in $DEBUG on $ext_if proto { tcp, udp } from any to $sync_pub_ip     port { 873 ftp ftp-data 22 21 } rdr-to $netfs
match in $DEBUG on $ext_if proto { tcp, udp } from any to $screen_pub_ip:0 port { 81 82 3306 3312 52530 } rdr-to $localscreen

# --- Block RFC 1918 non publicly routable addresses 
block  in $DEBUG quick on $ext_if from <rfc1918> to any
block out $DEBUG quick on $ext_if from <rfc1918> to any

# ==================================================================================
########  Allow ICMP ping     ####Ping test to make sure we can get to host
pass in quick inet proto icmp from any to any icmp-type $icmp_types
### Note: it does work for $sync_pub_ip but not $screen_pub_ip ???   #  <- THIS IS A CLUE!?!
# ==================================================================================

match in $DEBUG on $ext_if to $screen_pub_ip
-------------------------------------------------------------------------------
pass out $DEBUG on $ext_if from $int_if:network to any

# --- Default policy
block log all
# ---------------------------
You can see I defined a variable DEBUG that allows you to easily flip logging on or off.
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
  #7   (View Single Post)  
Old 16th October 2013
bsd_matt bsd_matt is offline
Port Guard
 
Join Date: Oct 2013
Posts: 12
Thanked 0 Times in 0 Posts
Default

Thanks for your help folks. I have had a buch of fires popup here (Windows boxes misbehaving!) so I haven't even had the chance to test out your suggestions.

I really can't express how grateful I am for your assistance though.

Thanks.
Reply With Quote
Reply

Tags
openbsd 5.3 pf

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
OpenBSD installation goes perfectly passthejoe OpenBSD Installation and Upgrading 4 16th November 2012 02:40 AM
OBSD 4.9 Frustrating kernel panic on boot edwebdev OpenBSD General 1 16th July 2011 09:37 PM


All times are GMT. The time now is 08:01 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick