Ftp server inside container sending localhost ip for pasv to remote clients

Don’t know if that has something to do with incus.

I’m running sftpgo inside a container and the wget client in a script can’t reach 127.0.0.1:50045 for pasv. Thats clear so far. I’ve forwared 50000-50100 to the container. (and 21) But wget means it should use the local ip. A filezilla client detect it and used the fqdn instead and it works. But wget not.

Any idea. A problem in sftpgo??

Tnx

Rüdiger

How are you doing the forwarding? Through a proxy device?

If so, then indeed the default proxy device (without either proxy_protocol or nat) will make it look like a connection is coming from localhost, which in a protocol using multiple connections like FTP can be an issue as the address returned to the remote client would be wrong.

If you can use nat=true on your device, that’d probably be the easiest way out of this as I don’t think there’s any FTP server which supports the haproxy proxy_protocol header stuff (though I may be wrong there).

Hi, thanks for your reply.

The sftpgo application has a webgui, what is reachable via a caddy reverse proxy. And the needed ftp ports are forwarded as followed. The range 50000-50100 is needed for pasv.
How to and what changed when enabling nat?

user@incus:~$ incus config device show void-sftp 
ftp-2021to2021:
  connect: tcp:127.0.0.1:2021
  listen: tcp:0.0.0.0:2021
  type: proxy
ftp-22000-22500:
  connect: tcp:127.0.0.1:22000-22500
  listen: tcp:0.0.0.0:22000-22500
  type: proxy
ftp-50000-50100:
  connect: tcp:127.0.0.1:50000-50100
  listen: tcp:0.0.0.0:50000-50100
  type: proxy
sftp-2022to2022:
  connect: tcp:127.0.0.1:2022
  listen: tcp:0.0.0.0:2022
  type: proxy

Basically three steps:

  • Edit the instance and set ipv4.address on its network interface (usually eth0), you can set it to the current value see in incus list. This will ensure the address can’t change again which is a requirement for NAT.
  • Edit the instance config and set nat: true on all of the proxy devices
  • Restart the instance

Thanks. I will try it now, but I sometimes have difficulties putting the command together. Sometimes it’s easier to edit things in config files than to know in which order which commands have to be given.

Sometimes it would be helpful to give an example in the documentation, to explain what is needed here.
For expl. Is remote the ip and network eth0 …?

incus network set [<remote>:]<network> <key>=<value>... [flags]

That seems not correct:

+----------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
| void-sftp      | RUNNING | 10.217.37.85 (eth0)  | fd42:de68:bf1a:f128:216:3eff:fef0:d36e (eth0) | CONTAINER | 1         |
+----------------+---------+----------------------+-----------------------------------------------+-----------+-----------+
:~$ incus config device set void-sftp eth0 ipv4.address=10.217.37.85
Error: Device from profile(s) cannot be modified for individual instance. Override device or modify profile instead

Your eth0 device was inherited from a profile, so you’re going to want incus config device override void-sftp eth0 ipv4.address=10.217.37.85 instead.

OK, and that will not break other instances network, and i could do this if needed with other instances in the same way?

Yep

I have removed the proxy device and added new with:

incus config device add void-sftp ftp-50000-50100 proxy listen=tcp:213.109.xxx.xx:50000-50100 connect=tcp:10.217.37.85:50000-50100 nat=true

But the ftp connection failed. The 213… is my servers ext. ip. Seems difficult…

eth0:
  ipv4.address: 10.217.37.85
  name: eth0
  network: incusbr0
  type: nic
ftp-2021to2021:
  connect: tcp:127.0.0.1:2021
  listen: tcp:0.0.0.0:2021
  type: proxy
ftp-50000-50100:
  connect: tcp:10.217.37.85:50000-50100
  listen: tcp:213.109.xxx.xx:50000-50100
  nat: "true"
  type: proxy
sftp-2022to2022:
  connect: tcp:127.0.0.1:2022
  listen: tcp:0.0.0.0:2022
  type: proxy

By the way. These are the messages from the client filezilla… I’m asuming that means the client cannot reach via port 500xx the server…?!

The settings from sftpgo for ftp:


FTP server

Status: "Started"
Address: ":2021"
TLS: "Disabled"
Passive port range: "50000-50100"

Filezilla:

Status:	Verbinde mit 213.109.xxx.xx:2021...
Status:	Verbindung hergestellt, warte auf Willkommensnachricht...
Status:	Unverschlüsseltes FTP ist unsicher. Bitte wechseln Sie zu FTP über TLS.
Status:	Angemeldet
Status:	Empfange Verzeichnisinhalt...
Status:	Vom Server gesendete Adresse für den Passiv-Modus ist nicht routingfähig. Benutze stattdessen die Serveradresse.
Befehl:	MLSD
Antwort:	425 data connection security requirements not met
Fehler:	Verzeichnisinhalt konnte nicht empfangen werden

When I last tried this (setup FTP in an instance, use a reverse-proxy), I had to use nf_conntrack_ftp the kernel module.

OK, it seems it works now. My problem was, that the ftp server was sending the localhost ip for pasv mode to the client, where clients like filezilla are able to detekt this and switch to the public address. But in my ftp scripts with wget that won’t work.
The idea to use a nat hasn’t work at the first attempt. I’m not sure, if i had setup the nat correctly to be honest. I’ve posted the output above, maybe @stgraber, u could say if that was correct.

In the meantime i found a solution to force the ftp server so send the public ip as a pasv destination. And i removed the natted proxy an used the one without…

This is the SFTPGO config with the exportvariables… If someone is interessted. (running on VoidLinux)
(Last export line…)
https://sftpgo.com/

Thanks for help and support…

#!/bin/sh
exec 2>&1

export SFTPGO_FTPD__BINDINGS__0__PORT=2021
export SFTPGO_HTTPD__TEMPLATES_PATH=/usr/share/sftpgo/templates
export SFTPGO_HTTPD__STATIC_FILES_PATH=/usr/share/sftpgo/static
export SFTPGO_DATA_PROVIDER__DRIVER=sqlite
export SFTPGO_DATA_PROVIDER__NAME=/var/lib/sftpgo/sftpgo.db
export SFTPGO_SFTPD__HOST_KEYS=/var/lib/sftpgo/id_rsa,/var/lib/sftpgo/id_ecdsa,/var/lib/sftpgo/id_ed25519
export SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP=213.109.x.y

[ -r ./conf ] && . ./conf

exec sftpgo serve


1 Like