# pf and ftp-proxy



## jdratlif (Dec 29, 2010)

I was hoping to get some help on my pf rules. Most of them seem to work perfectly, but I cannot get my rdr rules to work. They seem to be ignored.

I want to use ftp-proxy to allow ftp connections from behind the pf firewall. My test setup is a virtualbox FreeBSD install. My simple pf.conf:


```
set skip on lo0

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on em0 proto tcp from (em0) to any port 21 -> 127.0.0.1 port 8021

block log all

pass in quick inet proto tcp from any to any port { 8022, ssh }
pass out quick inet proto { tcp, udp } from any to any port domain

anchor "ftp-proxy/*"
pass out log inet proto tcp from 127.0.0.1 to any port ftp
```

em0 is the external NIC. There is no internal network in this test setup. Not sure if/why that would make a difference.

The results:


```
ftp -a ftp.freebsd.org
Trying 204.152.184.73...
ftp: connect to address 204.152.184.73: Operation not permitted
Trying 87.51.34.132...
ftp: connect to address 87.51.34.132: Operation not permitted
Trying 149.20.64.73...
ftp: connect to address 149.20.64.73: Operation not permitted
Trying 2001:4f8:0:2::e...
ftp: connect to address 2001:4f8:0:2::e: No route to host
Trying 2001:6c8:2:600::132...
ftp: connect: No route to host
ftp>
```


```
sudo tcpdump -n -e -ttt -i pflog0
Password:
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 96 bytes
00:00:00.000000 rule 0/0(match): block out on em0: 192.168.5.7.28869 > 204.152.184.73.21: [|tcp]
00:00:00.000516 rule 0/0(match): block out on em0: 192.168.5.7.63577 > 87.51.34.132.21: [|tcp]
00:00:00.000186 rule 0/0(match): block out on em0: 192.168.5.7.11177 > 149.20.64.73.21:  tcp 40 [bad hdr length 0 - too short, < 20]
00:00:14.489828 rule 0/0(match): block in on em0: 192.168.5.3.2190 > 192.168.5.15.2190: UDP, length 153
```

Install is FreeBSD 8.1 x86. Custom kernel to add altq.

I also want to setup squid as a web proxy, but I was starting with this.

Thanks for any ideas.

em0 = 192.168.5.7
That's the external IP on my real local network NAT'd behind a Netgear router.


----------



## SirDice (Dec 29, 2010)

You don't need ftp-proxy to allow outgoing FTP sessions. Just make sure you use passive FTP.


----------



## jdratlif (Dec 29, 2010)

I realize I could open a giant port range, or allow all outgoing connections, but that's not what I want.

I want to allow only the following outgoing services
ssh, http(s), imap(s), smtp(s), pop3(s), domain
and ftp

I paired my ruleset down to focus on ftp. I thought the point of ftp-proxy was to add dynamic rules to allow for both passive and active ftp in both directions. Is this not the case?


----------



## SirDice (Dec 29, 2010)

You can only use passive FTP from that server. You are behind a modem/router that also does NAT. Even if you make it work on the FreeBSD box the modem/router's NAT will cause problems.


----------



## jdratlif (Dec 29, 2010)

If I allow all outgoing traffic in pf, ftp works fine, so I do not think the external NAT will do any interference. My problem is not the external NAT, but whether ftp-proxy can be configured as a redirect on the external interface.


```
set skip on lo0

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on em0 proto tcp from (em0) to any port 21 -> 127.0.0.1 port 8021

block log all

pass in inet proto tcp from any to any port { 8022, ssh }
#pass out inet proto { tcp, udp } from any to any port domain
pass out on em0 from (em0) to any

pass out log inet proto tcp from 127.0.0.1 to any port ftp
anchor "ftp-proxy/*"
```

Make this one change to my previous ruleset and ftp traffic works fine. It works because all outgoing traffic is allowed. I do not wish to allow all outgoing traffic. I want to limit it to a small, well defined set.


```
ftp -a ftp.freebsd.org
Trying 204.152.184.73...
Connected to ftp.freebsd.org.
220 Welcome to freebsd.isc.org.
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||61977|).
150 Here comes the directory listing.
drwxrwxr-x    3 110      1002          512 Oct 23  2006 pub
226 Directory send OK.
ftp>
```

With this ruleset, ftp traffic works just like it should. Can we adjust the ruleset to allow a more restrictive outgoing policy?


----------



## jdratlif (Dec 29, 2010)

I've been reading many threads on this and related issues; they all give the same advice: you need to open the outgoing port range. ftp-proxy appears to work only with NAT redirects. So it won't work on the external interface.

I'm not really happy with that answer, so I'll keep looking. If anyone has any suggestions, I would very much appreciate it.


----------



## SirDice (Dec 30, 2010)

jdratlif said:
			
		

> If I allow all outgoing traffic in pf, ftp works fine, so I do not think the external NAT will do any interference.


Try setting up an active FTP transfer. You'll quickly see the interference caused by NAT. 

Active FTP works because the client opens a port and tells the server to connect to it. That port will need to be forwarded on both the modem/router's NAT _and_ on the FreeBSD's NAT. The last can be dealt with using ftp-proxy, the modem/router's NAT however cannot.


----------



## kpa (Dec 30, 2010)

He is talking about a set up where outgoing connections are restricted by destination port to known ports. In that kind of set up you do need an ftp proxy even for passive mode connections because the data connection will be made to previously unknown high numbered port(s).

I don't think you can redirect an outgoing connection initiated on the machine that acts as the proxy to the ftp-proxy, at least not with pf afaik.


----------

