I have recently tried to set up jails on one of my FreeBSD servers, and I’m running into strange errors while trying to download FreeBSD packages via FTP.

I have these rules in the PF firewall to allow the download of packages on the host machine, where they work fine:

ext_if = "bge0"

# Allow downloads
pass out log on $ext_if proto tcp to any port {20, 21, 22, 80, 443}

# Special exception for FTP.
pass out log on $ext_if proto tcp to any port > 49151 keep state

But when I try to install packages from inside the Jail, the FTP connection just times out.
The error message I get is this:

%pkg_add -vr bash
[snipped FTP connection setup]
>>> CWD pub/FreeBSD/ports/amd64/packages-8.1-release/Latest
<<< 250 CWD command successful.
>>> MODE S
<<< 200 MODE S accepted.
>>> TYPE I
<<< 200 Type set to I.
binding data socket
>>> PORT 82,103,140,25,229,3
<<< 200 PORT command successful.
initiating transfer
>>> RETR bash.tbz
<<< 425 Can't build data connection: Operation timed out.
Error: Unable to get ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/packages-8.1-release/Latest/bash.tbz: Can't open data connection
pkg_add: unable to fetch 'ftp://ftp.freebsd.org/pub/FreeBSD/ports/amd64/packages-8.1-release/Latest/bash.tbz' by URL
pkg_add: 1 package addition(s) failed

Is there some sort of connection I’m missing? I wish I could just configure pkg_add to use HTTP instead of FTP (I have no idea why FreeBSD still uses that sorry excuse for a protocol), but it seems FTP is needed to operate FreeBSDs package system, and I have no idea how to make it work with the firewall. Any suggestions will be welcome :)

  • You can use setenv PACKAGEROOT http://ftp7.us.freebsd.org if you want to fetch the packages via HTTP (assuming you're using pkg_add -r {package_name} . FTP is better at file transfers, therefor FreeBSD uses it. – Chris S Aug 2 '10 at 15:55
  • Thanks, that works – as for FTP being better at file transfers, I haven’t heard of anything that would make it measurably better than HTTP when doing transfers in the megabyte range… – mikl Aug 2 '10 at 17:09

By default FTP uses so called 'Active' mode for data transfer which is not very firewall friendly. In this mode FTP server connects to IP:port specified in PORT command sent by client ( in your case).

Simplest way to fix this is to switch from 'Active' to 'Passive' FTP transfer mode. In case of 'pkg_add', which uses fetch(1) for file retrieval, it is done by setting environment variable FTP_PASSIVE_MODE.

  • Ah, that’s a neat trick, thanks. Where is the best place to set such a variable globally (as to avoid having it in .bashrc, .cshrc, etc. for all admin users)? – mikl Aug 4 '10 at 21:21
  • 1
    Use /etc/profile for 'sh' and 'bash' or /etc/csh.cshrc and /etc/csh.login for 'csh'. Also, environment can be set through /etc/login.conf. BTW, I've just found that 'default' class in default /etc/login.conf already has FTP_PASSIVE_MODE set. – AlexD Aug 5 '10 at 3:36

You can try to use ftp-proxy(8) with anchor "ftp-proxy/*"

For more info see here http://www.openbsd.org/faq/pf/ftp.html

  • Yeah, I read about this option, but I considered it to be too much of a hassle. I don’t need any more strange services to keep track of :) – mikl Aug 4 '10 at 21:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.