DaemonForums  

Go Back   DaemonForums > OpenBSD > OpenBSD Security

OpenBSD Security Functionally paranoid!

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default NAT source address translation

Hello,

Could anyone help me please?

I'm trying to connect from 192.168.0.3 to 192.168.0.1:8080 and send that to 192.168.1.2:80 as if it were coming from 192.168.1.1.

Pretty silly but I don't know how. I've tried the following:

Code:
int_if1 = 192.168.0.1 #re0
int_if2 = 192.168.1.1 #re1
client = 192.168.0.3
server = 192.168.1.2

pass in on $int_if1 inet proto tcp from $client to $int_if1 port 8080 rdr-to $server port 80
pass out on $int_if1 inet proto tcp to $server port 80 received-on $int_if1 nat-to $int_if2
Code:
test# tcpdump -n -i re0 port 8080
tcpdump: listening on re0, link-type EN10MB
18:15:39.895350 192.168.0.3.44971 > 192.168.0.1.8080: S 4258345521:4258345521(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 3319586456 0> (DF)
18:15:40.156961 192.168.0.3.47237 > 192.168.0.1.8080: S 1293923870:1293923870(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 786111235 0> (DF)
18:15:45.892088 192.168.0.3.44971 > 192.168.0.1.8080: S 4258345521:4258345521(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 3319586468 0> (DF)
18:15:46.152135 192.168.0.3.47237 > 192.168.0.1.8080: S 1293923870:1293923870(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 786111247 0> (DF)
Code:
test# tcpdump -n -i re1 port 80  
tcpdump: listening on re1, link-type EN10MB
18:18:11.386568 192.168.0.3.7444 > 192.168.1.2.80: S 1435489758:1435489758(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 2917288379 0>
18:18:11.649978 192.168.0.3.21710 > 192.168.1.2.80: S 500167953:500167953(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 459285197 0>
18:18:17.378744 192.168.0.3.7444 > 192.168.1.2.80: S 1435489758:1435489758(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 2917288391 0>
18:18:17.648712 192.168.0.3.21710 > 192.168.1.2.80: S 500167953:500167953(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 459285209 0>

Last edited by junk; 4 Weeks Ago at 01:31 PM.
Reply With Quote
  #2   (View Single Post)  
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

Hello, and a belated welcome!

I'm going to guess that the inbound pass establishes state, so the outbound traffic is not tested. You could check to see if this is what is happening by either changing the outbound rule to a match rule, or adding no state to your inbound pass rule.
Reply With Quote
  #3   (View Single Post)  
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

I've tested both, here's the output:

Code:
pass in on $int_if1 inet proto tcp from $client to $int_if1 port 8080 rdr-to $server port 80 no state
pass out on $int_if1 inet proto tcp to $server port 80 received-on $int_if1 nat-to $int_if2

test# pfctl -nf /etc/pf.conf
/etc/pf.conf:1: nat-to and rdr-to require keep state
/etc/pf.conf:1: skipping rule due to errors
/etc/pf.conf:1: rule expands to no valid combination
Code:
pass in on $int_if1 inet proto tcp from $client to $int_if1 port 8080 rdr-to $server port 80
match out on $int_if1 inet proto tcp to $server port 80 nat-to $int_if2

test# tcpdump -n -i re1 port 80
tcpdump: listening on rl1, link-type EN10MB
00:48:26.814606 192.168.0.3.32836 > 192.168.1.2.80: S 2731610042:2731610042(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 2862910124 0>
00:48:27.086607 192.168.0.3.5015 > 192.168.1.2.80: S 3391433507:3391433507(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 3308540081 0>
00:48:31.621346 192.168.0.3.16056 > 192.168.1.2.80: S 1418429462:1418429462(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 1283736596 0>
00:48:31.875904 192.168.0.3.20977 > 192.168.1.2.80: S 840544532:840544532(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 1452155539 0>
Reply With Quote
  #4   (View Single Post)  
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

Code:
/etc/pf.conf:1: nat-to and rdr-to require keep state
Oh, yes, of course.

I'll have to experiment, and see if I can come up with a solution.
Reply With Quote
  #5   (View Single Post)  
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

I've spent at least six hours trying to make it work before starting this thread. Read the pf user's guide on Traffic Redirection (Port Forwarding), the pf.conf man page, i've taken a look at Peter Hansteen's tutorials, also tried the fwbuilder interface to see the fw compilation results:

Code:
# Rule  0 (NAT)
match in on re0 proto tcp from 192.168.0.3 to 192.168.0.1 port 8080 rdr-to 192.168.1.2 port 80
match out on re0 proto tcp from 192.168.0.3 to 192.168.1.2 port 80 nat-to (re1)
I've got this in the kernel config:

Code:
test# sysctl |grep net.inet.ip
net.inet.ip.forwarding=1
net.inet.ip.redirect=1
I guess it has to be studied more in depth, i wouldn't want to waste your time... I just thought it was something simple to configure.

Last edited by junk; 4 Weeks Ago at 01:35 PM.
Reply With Quote
  #6   (View Single Post)  
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

I've been using NAT with PF since 2004. This problem is interesting to me.

I should have some time on Friday to pursue it.
Reply With Quote
  #7   (View Single Post)  
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

I have recreated the problem. It is the redirection which causes the NAT translation issue.

If there is no redirection, NAT works as expected. For example, having the client reach out directly to the server on port 80. The PF User's guide has a section on combining nat-to and rdr-to in the Redirection chapter.

https://www.openbsd.org/faq/pf/rdr.html#rdrnat
Reply With Quote
  #8   (View Single Post)  
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

Hi jggimi,

The example from that section, that's what i've been basing mine on. You say the issue has to do with the redirection, do you mean the rdr-to rule should be excluded?

Code:
pass in on 192.168.0.1 inet proto tcp from 192.168.0.3 to 192.168.1.2 port 80 nat-to 192.168.1.1
Code:
test# tcpdump -n -i re0 port 80
tcpdump: listening on re0, link-type EN10MB
16:00:56.201078 192.168.0.3.39157 > 192.168.1.2.80: S 1831632233:1831632233(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 396746662 0> (DF)
16:00:56.461130 192.168.0.3.40049 > 192.168.1.2.80: S 2135530915:2135530915(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 1695820090 0> (DF)
Code:
test# tcpdump -n -i re1 port 80
tcpdump: listening on re1, link-type EN10MB
16:00:56.201134 192.168.1.1.64573 > 192.168.1.2.80: S 1831632233:1831632233(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 396746662 0>
16:00:56.201721 192.168.1.2.80 > 192.168.1.1.64573: S 3651808616:3651808616(0) ack 1831632234 win 5792 <mss 1460,sackOK,timestamp 6019177 396746662,nop,wscale 7> (DF)
16:00:56.201782 192.168.1.1.64573 > 192.168.1.2.80: R 1831632234:1831632234(0) win 0 (DF)
16:00:56.461183 192.168.1.1.63859 > 192.168.1.2.80: S 2135530915:2135530915(0) win 16384 <mss 1440,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 1695820090 0>
16:00:56.461661 192.168.1.2.80 > 192.168.1.1.63859: S 3653687898:3653687898(0) ack 2135530916 win 5792 <mss 1460,sackOK,timestamp 6019229 1695820090,nop,wscale 7> (DF)
16:00:56.461717 192.168.1.1.63859 > 192.168.1.2.80: R 2135530916:2135530916(0) win 0 (DF)
The source address is now translated but the reply from the server doesn't reach the client.

Last edited by junk; 4 Weeks Ago at 09:30 PM.
Reply With Quote
  #9   (View Single Post)  
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

The rdr-to in the FAQ is distinctly different from your initial test in one key way: the rdr-to and nat-to are both on the same interface. This is used on an internal network as part of a redirection/reflection solution.

I think what your seeing is related to this restriction discussion in the Redirection and Reflection section of the FAQ, where I've highlighted:
Quote:
Adding a second redirection rule for the internal interface does not have the desired effect either. When the local client connects to the external address of the firewall, the initial packet of the TCP handshake reaches the firewall through the internal interface. The redirection rule does apply and the destination address gets replaced with that of the internal server. The packet gets forwarded back through the internal interface and reaches the internal server. But the source address has not been translated, and still contains the local client's address, so the server sends its replies directly to the client. The firewall never sees the reply and has no chance to properly reverse the translation. The client receives a reply from a source it never expected and drops it. The TCP handshake then fails and no connection can be established.
If you outline what the operational problem is that you're trying to solve, perhaps an alternative solution can be devised.

Last edited by jggimi; 4 Weeks Ago at 03:23 PM. Reason: clarity
Reply With Quote
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

pf user guide's example:

Code:
pass in on $int_if proto tcp from $int_net to egress port 80 rdr-to $server
pass out on $int_if proto tcp to $server port 80 received-on $int_if nat-to $int_if
My initial rules:

Code:
pass in on $int_if1 inet proto tcp from $client to $int_if1 port 8080 rdr-to $server port 80
pass out on $int_if1 inet proto tcp to $server port 80 received-on $int_if1 nat-to $int_if2
The only difference i see is that, apart from the port translation, in my case int_if2 is not a gateway and that the nat-to address is not the internal interface, but i doesn't make sense that you nat-to from $int_if unless $server is in the same subnet as $int_if, does it?

This would be closer to what they say in pf's faq:

Code:
int_if1 = 192.168.0.1
int_if2 = 192.168.1.1
client = 192.168.0.3
server = 192.168.1.2

pass in on $int_if1 proto tcp from $client to $int_if2 port 80 rdr-to $server
pass out on $int_if1 proto tcp to $server port 80 received-on $int_if1 nat-to $int_if1
Code:
test# tcpdump -n -i re0 port 80
tcpdump: listening on re0, link-type EN10MB
19:42:08.928850 192.168.0.3.48966 > 192.168.1.1.80: S 1766645:1766645(0) win 16384 <mss 1460,nop,nop,sackOK,nop,wscale 6,nop,nop,timestamp 56749928 0> (DF)
19:42:08.928944 192.168.1.1.80 > 192.168.0.3.48966: R 0:0(0) ack 1766646 win 0

test# tcpdump -n -i re1 port 80
tcpdump: listening on re1, link-type EN10MB
[none]
The pass out rule never matches? it's not even performing the rdr-to?

Quote:
destination address gets replaced with that of the internal server. The packet gets forwarded back through the internal interface and reaches the internal server. But the source address has not been translated, and still contains the local client's address,
That's what happens when you rdr-to from 192.168.0.1 to 192.168.1.2 (post #1).

Quote:
If you outline what the operational problem is that you're trying to solve, perhaps an alternative solution can be devised.
I've got computers attached to a switch (192.168.0.x) and phones connecting to a wifi AP (192.168.1.x). i have them on two different subnets because i read somewhere it's better that way. I'd like to access the AP's config from a desktop.

Last edited by junk; 4 Weeks Ago at 09:52 PM.
Reply With Quote
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

Quote:
I'd like to access the AP's config from a desktop.
Do you require NAT between these subnets?
Reply With Quote
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

I don't know, i can ping 192.168.1.1 from 192.168.0.3 but not 192.168.1.2.

Last edited by junk; 4 Weeks Ago at 01:46 PM.
Reply With Quote
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

Hmm, if the VOIP AP is filtering access, you may be able to provision it to accept connections from the workstation. If not, I can think of two other ways which might accomplish this; ssh(1) port forwarding, or a Layer 7 TCP relay with relayd(8).
Reply With Quote
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

The more I think about this ... I think PF should work as a NAT solution, if you are able to eliminate the redirect. Just have the client connect directly to the server. PF will translate the sending address and port, and keep track of the stateful session.
Reply With Quote
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

I tried another access point and was able to access it directly 192.168.0.3 ->
192.168.1.3 so the problem must be related to the previous access point... hahah! i can't believe it! I'm so sorry. Thanks anyway!...

Last edited by junk; 4 Weeks Ago at 01:48 PM.
Reply With Quote
Old 4 Weeks Ago
jggimi's Avatar
jggimi jggimi is offline
More noise than signal
 
Join Date: May 2008
Location: USA
Posts: 6,631
Default

I'm glad you got the operational problem resolved.
Reply With Quote
Old 4 Weeks Ago
junk's Avatar
junk junk is offline
New User
 
Join Date: Jun 2018
Posts: 10
Default

This also works now:

Code:
int_if1 = 192.168.0.1
int_if2 = 192.168.1.1
client = 192.168.0.3
server2 = 192.168.1.3

pass in on $int_if1 inet proto tcp from $client to $int_if1 port 8080 rdr-to $server2 port 80
pass out on $int_if1 inet proto tcp to $server2 port 80 received-on $int_if1 nat-to $int_if1 #(or even $int_if2)
Code:
test# tshark -t ad -r re0.dump
1 2019-06-22 17:27:32.222346     192.168.0.3 → 192.168.0.1     TCP 34249 8080 34249 → 8080 [SYN] Seq=0 Win=16384 Len=0 MSS=1460 SACK_PERM=1 WS=64 TSval=1574527048 TSecr=0
2 2019-06-22 17:27:32.228595     192.168.0.1 → 192.168.0.3     TCP 8080 34249 8080 → 34249 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1440 SACK_PERM=1 TSval=48477 TSecr=1574527048 WS=2
3 2019-06-22 17:27:32.228741     192.168.0.3 → 192.168.0.1     TCP 34249 8080 34249 → 8080 [ACK] Seq=1 Ack=1 Win=16384 Len=0 TSval=1574527048 TSecr=48477
4 2019-06-22 17:27:32.229366     192.168.0.3 → 192.168.0.1     HTTP 34249 8080 GET / HTTP/1.1 [Packet size limited during capture]
5 2019-06-22 17:27:32.232756     192.168.0.1 → 192.168.0.3     TCP 8080 34249 8080 → 34249 [ACK] Seq=1 Ack=383 Win=6864 Len=0 TSval=48478 TSecr=1574527048
6 2019-06-22 17:27:32.238640     192.168.0.1 → 192.168.0.3     HTTP 8080 34249 HTTP/1.0 302 Redirect [Packet size limited during capture]
...
Code:
test# tshark -t ad -r re1.dump
1 2019-06-22 17:27:32.222418     192.168.0.3 → 192.168.1.3     TCP 34249 80 34249 → 80 [SYN] Seq=0 Win=16384 Len=0 MSS=1440 SACK_PERM=1 WS=64 TSval=1574527048 TSecr=0
2 2019-06-22 17:27:32.228550     192.168.1.3 → 192.168.0.3     TCP 80 34249 80 → 34249 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 SACK_PERM=1 TSval=48477 TSecr=1574527048 WS=2
3 2019-06-22 17:27:32.228794     192.168.0.3 → 192.168.1.3     TCP 34249 80 34249 → 80 [ACK] Seq=1 Ack=1 Win=16384 Len=0 TSval=1574527048 TSecr=48477
4 2019-06-22 17:27:32.229408     192.168.0.3 → 192.168.1.3     HTTP 34249 80 GET / HTTP/1.1 [Packet size limited during capture]
5 2019-06-22 17:27:32.232710     192.168.1.3 → 192.168.0.3     TCP 80 34249 80 → 34249 [ACK] Seq=1 Ack=383 Win=6864 Len=0 TSval=48478 TSecr=1574527048
6 2019-06-22 17:27:32.238592     192.168.1.3 → 192.168.0.3     HTTP 80 34249 HTTP/1.0 302 Redirect [Packet size limited during capture]
...
But the source address is not being translated??

Last edited by junk; 4 Weeks Ago at 04:30 PM.
Reply With Quote
Reply

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
network address translation azdps OpenBSD Security 12 1st October 2016 10:36 PM
PF and NAT: Specify SRC IP Address? jasonvp FreeBSD Security 5 25th November 2015 08:04 PM
Other Open-source typeface “Hack” brings design to source code J65nko News 1 31st August 2015 03:06 PM
MAC address to IP rex FreeBSD General 9 11th November 2008 07:06 PM
Asking about IPv6 address berlowin Off-Topic 2 9th July 2008 02:39 AM


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


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