# problem with pf and redirect to internal interface



## alc99vol (Mar 11, 2013)

Hello!

Could you please help me configure PF? I have a problem in redirecting ssh traffic to an internal interface, here are the rules from my pf.conf:

```
allowed_ports = { 22 } 
scrub in all 
rdr log on $if_ext inet proto tcp from any to ($if_ext) port $allowed_ports -> $if_int:0 
.... 
block in all 
pass in quick on $if_ext inet proto tcp from any to $if_int:0 port $allowed_ports flags S/SA keep state
```
I've tried to use tcpdump for debugging, as a result I saw ssh packages with S flag coming into the external interface ($if_ext), and didn't see any traffic coming into the internal interface ($if_int).


----------



## Jeque (Mar 11, 2013)

I think you need one more rule:

```
pass in quick on $if_ext inet proto tcp from any to $if_ext port $allowed_ports flags S/SA keep state
```


----------



## Beeblebrox (Mar 11, 2013)

It' probably a matter of personal preference, but I prefer to "allow all" on the $int_if and control everything on the $ext_if. No point in duplicating rules and "checking everything twice" unless you have a specific reason to do so. Therefore, if you replace

```
block in all
```
with below, it will allow free traffic flow on $int_if (right now you are blocking all inbound on $int_if. This will apply blocking on $ext_if only.

```
block in log on $ext_if
```
You probably also have allowed all out traffic:

```
pass out
```
And if you want to block any outgoing, again do it on $ext_if (block it there). This blocks dhcp offers from going out the $ext_if:

```
block out quick on $ext_if inet proto { tcp udp } from ($ext_if) port { 67, 68 } to any
```
That takes care of the $int_if.

This only re-directs traffic to $int_if:

```
rdr log on $if_ext inet proto tcp from any to ($if_ext) port $allowed_ports -> $if_int:0
```
Now you have to allow it to pass in on $ext_if:

```
pass in quick on [color="Red"]$if_ext[/color] inet proto tcp from any to $if_int:0 port $allowed_ports
```
"S/SA keep state" is unnecessary - they are default behavior for PF.

You could also do this in a single command if you have defined "pass out" on $ext_if:

```
rdr log [color="Red"]pass[/color] on $if_ext inet proto tcp from any to ($if_ext) port $allowed_ports -> $if_int:0
```


----------



## alc99vol (Mar 12, 2013)

Jeque, Beeblebrox - thanks for your answers, but yet I didn't solve the problem.
Finally, I've changed my pf.conf like this:

```
scrub in all
rdr on msk0 inet proto tcp from any to (msk0) port 22 -> vr0:0
pass in
pass out
```
And that changed nothing. Also, I have to tell:
- `ifconfig` shows that both interfaces are active
- sysctl net.inet.ip.forwarding: 1  ; gateway_enable="YES" in rc.conf
In fact, I don't even know what else should I check


----------



## J65nko (Mar 12, 2013)

Adapt the pf.conf in http://forums.freebsd.org/showpost.php?p=212022&postcount=4 to your specific situation. Then use the tcpdump(1) debugging tips in that same post to check what is going on.


----------



## Beeblebrox (Mar 13, 2013)

> (msk0) port 22 -> vr0:0


What is the internal IP of the machine prviding the SSL service? This just passes the traffic to the "internal net" assuming that the traffic magically knows where to go from there.

If SSL is served from the same machine that pf is working on, it's all wrong. If the SSL server is another machine in the internal network, place its IP there:

```
svc_ssl="192.168.1.100"

rdr on msk0 inet proto tcp from any to (msk0) port 22 -> $srv_ssl
```
pf is way smarter than you think in figuring out the routes (once you give it the correct information)


----------



## alc99vol (Mar 13, 2013)

J65nko: as I said before, [CMD=""]tcpdump[/CMD] shows incomming ssh packages with S flag on external interface and shows nothing on internal interface. 
Beeblebrox: I can be wrong, but I think that 

```
(msk0) port 22 -> vr0:0
```
sends traffic to internal interface and not to internal net. And [CMD=""]pfctl -sa[/CMD] shows that vr0:0 was successfully translated to 192.168.1.1 (actual address of the internal interface).


----------



## J65nko (Mar 14, 2013)

alc99vol said:
			
		

> J65nko: as I said before, [CMD=""]tcpdump[/CMD] shows incomming ssh packages with S flag on external interface and shows nothing on internal interface.


 I know that, you wrote that in your first post 

As we cannot debug it this remotely, I offered you a method to debug this redirection by referring you to another post, where another forum user is having a similar issue.

BTW As explained in http://www.openbsd.org/faq/pf/rdr.html#reflect, redirection on the external interface does not work when the connection is initiated from the internal LAN.


----------



## Beeblebrox (Mar 14, 2013)

What is the *IP* of the machine providing the SSL service, and what is the IP of the internal NIC? If those two IP's are not the same (which they probably are not) your ruleset will not work.


----------



## alc99vol (Mar 14, 2013)

Beeblebrox: sorry, I've read your message inattentively and didn't notice:


> If SSL is served from the same machine that pf is working on, it's all wrong.



Surely, this could be the answer, but I don't understand what is wrong with this. 
In my configuration, I have two interfaces. The external gets it's settings via DHCP, the internal has manually assigned address 192.168.1.1 and 5 aliases (192.168.1.2 and so on). The idea was to redirect traffic from external interface to 192.168.1.1, because I don't want to use dinamically assigned ip address explicitly anywhere in my config files. 

There is a paragraf in pf manual, saying that it's impossible to use redirect, defined for the internal interface, from local network. I guess, I understand why. But I use redirect, defined from the external interface, and I test it from the external network also. And I didn't find any restrictions about using local address as a destination for redirect.


----------



## Beeblebrox (Mar 14, 2013)

Please tell us what you are trying to do with the host running pf so that we can stop guessing about solutions. For example, my host is behind a firewall (adsl modem) and passes trivial traffic to and from internal network which consists of PXE booted clients.

Where will SSL client connect from and on which machine is the SSL client running?


----------



## alc99vol (Mar 17, 2013)

Beeblebrox: please, see the scheme in attachment. Here is my configuration:
sshd_config:

```
ListenAddress 192.168.1.1
```
And - I really don't want to add 
	
	



```
ListenAddress 192.168.2.240
```
 I want to use redirect, if it is possible, because 192.168.2.240 is assigned dynamically and can be changed. 

pf.conf:

```
scrub in all

rdr pass  on msk0 inet proto tcp from any to 192.168.2.240 port 22 -> vr0:0

pass in keep state
pass out keep state
```
rc.conf:

```
hald_enable="YES"
dbus_enable="YES"
sshd_enable="YES"
pf_enable="YES"
pf_rules="etc/pf.conf"
pflog_enable="YES"
syslogd_flags="-b 192.168.1.1"
hostname="krakatau.iok1"
gateway_enable="YES"
ifconfig_msk0="DHCP"
ifconfig_vr0="192.168.1.1/24"
ifconfig_vr0_alias0="192.168.1.2/32"
ifconfig_vr0_alias1="192.168.1.3/32"
ifconfig_vr0_alias2="192.168.1.4/32"

jail_jail_web1_rootdir="/var/jail/jail_web1"
jail_jail_web1_hostname="web1.iok1"
jail_jail_web1_ip="192.168.1.2"
jail_jail_web1_devfs_enable="YES"
jail_jail_web1_defs_ruleset="devfsrules_jail"
#... and so on for each jail
```


----------



## alc99vol (Mar 17, 2013)

And, here is the result of `pfctl -sa` command:

```
TRANSLATION RULES:
rdr pass on msk0 inet proto tcp from any to 192.168.2.240 port = ssh -> 192.168.1.1

FILTER RULES:
scrub in all fragment reassemble
pass in all flags S/SA keep state
pass out all flags S/SA keep state
...
```


----------



## Beeblebrox (Mar 18, 2013)

It should be working fine - I see no error in the setup.

Are you sure ssh is running on port 22? The fact that workstation2 connects may not necessarily mean the port is 22. Sometimes ssh port is changed as a security measure?


----------



## alc99vol (Mar 18, 2013)

Beeblebrox: yes, I forgot to tell, I use 22 port for ssh everywhere.sshd is running and listens to 22 port. Here is `sockstat -4` output:

```
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root     sshd       2358  3  tcp4   192.168.1.1:22        *:*
root     sendmail   1958  3  tcp4   192.168.1.4:25        *:*
root     syslogd    1899  6  udp4   192.168.1.4:514       *:*
root     sendmail   1819  3  tcp4   192.168.1.3:25        *:*
root     sshd       1816  3  tcp4   192.168.1.3:22        *:*
root     syslogd    1765  6  udp4   192.168.1.3:514       *:*
root     sendmail   1676  3  tcp4   192.168.1.2:25        *:*
root     sshd       1673  3  tcp4   192.168.1.2:22        *:*
root     syslogd    1618  8  udp4   192.168.1.2:514       *:*
root     sendmail   1470  3  tcp4   127.0.0.1:25          *:*
root     syslogd    1365  6  udp4   192.168.1.1:514       *:*
```
here is `tcpdump -nvvvi msk0 tcp and port 22` output:

```
23:13:16.302819 IP (tos 0x0, ttl 128, id 26011, offset 0, flags [DF], proto TCP
(6), length 52)
    192.168.2.53.61247 > 192.168.2.240.22: Flags [S], cksum 0xf71e (correct), seq 502383674, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
23:13:19.310348 IP (tos 0x0, ttl 128, id 26042, offset 0, flags [DF], proto TCP
(6), length 52)
    192.168.2.53.61247 > 192.168.2.240.22: Flags [S], cksum 0xf71e (correct), seq 502383674, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
23:13:25.311402 IP (tos 0x0, ttl 128, id 26103, offset 0, flags [DF], proto TCP
(6), length 48)
    192.168.2.53.61247 > 192.168.2.240.22: Flags [S], cksum 0x0b28 (correct), seq 502383674, win 8192, options [mss 1460,nop,nop,sackOK], length 0
```
And `tcpdump -nvvvi vr0 tcp and port 22` gives nothing.

How else can I debug this? Could it be hardware problem, or, maybe, some kernel options?
I have no ideas about what else can I do


----------



## Beeblebrox (Mar 19, 2013)

Try redirecting the http traffic to your http jail and see if workstation1 can access the web server from 192.168.2.240:

```
rdr on msk0 inet proto tcp from any to (msk0) port 80 -> 192.168.1.2
```


----------

