I am trying to get my app functioning properly in Docker, but am having trouble with it.

The app connects to a remote FTP server with PASV mode, and PUTs a file. Pretty simple and works fine without docker. Neither the FTP server nor the client are behind any NAT; but the client becomes NAT'd because I am using Docker bridged networking. (Using default bridge config http://pastie.org/10954592)

If I look at tshark on the FTP server when running the client app, it exchanges a lot of packets, so it is "connecting" to the server, but the app isn't receiving anything back. This makes me assume that when the the FTP server attempts to respond on that empirical port, it isn't being routed back to the Docker container from the host OS.

So, hopefully to summarize, is there any good way to have these pasv ports forwarded properly to the docker bridge? Constraint: I do not have control of the FTP server in production, so I can not simply hardcode a list of pasv ports for iptables.

Thanks for any ideas!

  • 1
    Are you sure the client 1/ is using PASV (or EPSV) 2/ isn't firewalled in addition to being nated? Because with PASV, the client doesn't send its own IP informations, and there's no connection from server to client, only client to server. But the data connection will be from any random port to any port (the one the server asked). So this data connection has to be allowed: either no firewall, or better with using the modules nf_conntrack_ftp / nf_nat_ftp and some related (pun intended) iptables rules.
    – A.B
    Nov 21 '16 at 0:53

PASV FTP works fine inside Docker containers.

It gets harder using Docker Swarm, but is possible with a single replica or in deploy mode:global with port mapping using mode:host.

Because PASV mode is stateful, subsequent requests need to be routed to the same node in the cluster.

Example stack using host mode

    image: vendor/vsftpd
      - { target: 20,    published: 20, mode: host }
      - { target: 21,    published: 21, mode: host }
      - { target: 21100, published: 21100, mode: host }
      - { target: 21101, published: 21101, mode: host }
      - { target: 21102, published: 21102, mode: host }
      mode: global

I've tested your scenario and it worked without issues on my side.

root@testapp-ftp-6b66556854-fdgvs:/# ftp -p   
Connected to
220 Welcome to XXX FTP K8s service.
Name ( testuser
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (172,21,131,137,39,115).
150 Here comes the directory listing.
drwxrwxrwx    2 ftp      ftp             0 Jul 24 08:25 FTP
226 Directory send OK.

Could you share your connection string? Maybe you missed to switch to passive mode.

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.