< blog / >

FTP Passive mode on a Scaleway Web Server: making it work

This is not a tutorial on how to setup a FTP server. It’s mostly dedicated to people struggling to make FTP Passive mode work on Scaleway instances.
If you need a detailed tutorial head over to How To Forge and check out their « The Perfect Server » tutorials – there’s at least one for your needs.

Wait, don’t you Kube all the things?

Here at kiss my, we are huge fans of Kubernetes.

When I say huge fans, it’s an understatement. We host almost everything – our internal apps, GitLab instance, QA and staging websites, even this website and the WordPress instance powering this blog – on Kubernetes.

And when I say Kubernetes, I’m not talking about AKS or some other managed Kubernetes solution: I’m talking bare-metal HA clusters built with kubeadm, homemade Rook + Ceph storage…

This takes us a lot of time but also allows us to deep dive into Kubernetes, and even manage our client’s clusters. For instance, AbracadaRoom and all the services backing its booking system are hosted on one of these clusters. This makes our client’s expenses 1/10th of what it would be using one of the 3 leading cloud providers (AWS, Google Cloud, Azure) while allowing us to scale appropriately.

But let’s face it, sometimes Kubernetes is not the right solution. For instance when you need to host more « basic » websites for a client – say a few WordPress sites – and this client needs everything a WordPress user can expect.

Like easy FTP access (have you tried to forward passive FTP traffic through a Load Balancer and inside a Kubernetes cluster? A PITA is what it is), installing or removing plugins (which can be made when deploying Docker containers, but it’s far from trivial).

For this kind of need, I always go for a simpler, but still very powerful and efficient solution: ISPConfig.

ISPConfig 3 is a web hosting control panel that allows you to configure the following services through a web browser: Apache or Nginx web server, Postfix mail server, Courier or Dovecot IMAP/POP3 server, MySQL, BIND or MyDNS nameserver, PureFTPd, SpamAssassin, ClamAV, and many more.

Till Brehm

It’s kind of a CPanel solution but cheaper (it’s Free and Open Source), easier to use, and as a bonus, Till Brehm – lead developer and creator of ISPConfig – created a bunch of crystal-clear tutorials about building a full-fledged Web server from a Linux box (thanks so much Till).

In short: ISPConfig is easy to install, setting up a Web server (Web, Database, Email, FTP, SSH, DNS…) is a breeze with ISPConfig and How To Forge tutorials, and in less than half a day you end up with a server ready to host production websites.

The « But »

This title you won’t mistype.

But, this morning here I was with my brand new Scaleway instance, having everything setup to transfer a WordPress site from a dying VPS to this shiny new instance.

The website is up, database imported, DNS migrated, Let’s Encrypt certs created, but the FTP refuses to work.

Everything seems to be fine until FileZilla reaches the MLSD – which is not LSD for Machines but a standardized equivalent of the LIST command. At this point, FileZilla hangs until a timeout occurs.

Let’s go through what I did to fix this, so hopefully you won’t smash your head against the wall like I did.

Understanding FTP transfer modes (and why FTP Passive mode is better)

There are many, so many, too many articles about the difference between Active and Passive mode for me to add another one. Let’s just say that:

  • Active connection will depend on the client while Passive will depend on the server (overly simplified);
  • Active is older and as a Web developer I like younger (overly stupid statement);
  • Most clients will try to switch to FTP Passive mode if no mode is requested so it’s best if it works properly (this one I keep).

Passive is better when you are lazy.

Some guy who did not get it

OK, so now that we know we’d rather make FTP Passive mode work instead of teaching our clients how to configure their FTP software for Active mode, let’s dive into the main subject: Making it work on a Scaleway instance!

While the following steps are specific to Scaleway AND pure-ftpd, it shouldn’t be too hard to adapt it to another hosting provider or another FTP software. Feel free to reach out if you need help doing so.

Let’s get to it and make this FTP passive mode work!

Last things first: check the ip_local_port_range of your instance

This was unfortunately the last thing I checked, but as you need the right values for the next steps, I’m doing you a favor by starting with this. You’re welcome.

If you’re already struggling with your FTP server, this might be where all your troubles come from.
Not all ports are available to open on Scaleway instances. There’s actually a range that you can use.

For example here is mine on this instance:

cat /proc/sys/net/ipv4/ip_local_port_range

32768	60999

There it is. We can use ports in the range 32768:60999.
I often use custom ports between 40000 and 42000 so I decided I would use a range of 1000 ports from 44000 to 45000 just to be safe.

Configure your Security Group to allow traffic for port 21 and your passive port range

In case you customize your Security Groups – I don’t as I prefer using either ufw on my basic servers, or firewalld on my Kubernetes nodes – you’ll need to open these ports.

Here’s my Security Group which allows basically everything:

Permissive is the next security

Scaleway doesn’t allow yet to open a port range so if you can avoid editing manually all your ports and keep the default ACCEPT rule, you’ll save a lot of time. Do use a firewall though, accepting all traffic on both your Security Group and your instance is really a very bad idea.

Configure the firewall

This is pretty easy on Ubuntu using UFW, and not much harder on other flavors.

# allow FTP port
ufw allow 21

# allow incoming/outgoing traffic on TCP range
ufw allow 44000:45000/tcp

# reload UFW so the rule is actually applied
ufw reload

That’s it.

Configure pure-ftpd to use the right external IP and FTP passive mode port range

Be careful when doing so: when using pure-ftpd configuration files (usually in /etc/pure-ftpd/conf), pure-ftpd won’t use the configuration values in /etc/pure-ftpd/pure-ftpd.conf .
I didn’t find any documentation about this, so I’m not sure about this behavior, only that PassivePortRange or ForcePassiveIP never worked unless specified in a file of the same name in /etc/pure-ftpd/conf/ .

Find the instance public IP

Scaleway has a networking specificity that makes the internal network IP show up in some instances.
So just to be safe, you need to add the external IP address in /etc/pure-ftpd/conf/ForcePassiveIP.

You can find the external IP either:

  • Using ip addr show
  • Or from the Scaleway console in the instances listing page or in the instance details page

Set the public IP as passive IP

Now you can set it:

# replace with your actual public IP
echo "123.456.789.101" > /etc/pure-ftpd/conf/ForcePassiveIP

Set the FTP passive mode range port

Again that’s quite easy:

echo "44000 45000" > /etc/pure-ftpd/conf/PassivePortRange

Apply configuration

Simply restart pure-ftpd (or pure-ftpd-mysql in my case):

systemctl restart pure-ftpd-mysql

Testing with ncftp (or another tool)

➜ ncftp -u USERNAME -p PASSWORD   
NcFTP 3.2.6 (Dec 04, 2016) by Mike Gleason (
Connecting to XXX.YYY.ZZZ.52...                                                                                                                              
--------- Welcome to Pure-FTPd [privsep] [TLS] ----------
You are user number 1 of 50 allowed.
Local time is now 16:55. Server port: 21.
This is a private system - No anonymous login
IPv6 connections are also welcome on this server.
You will be disconnected after 15 minutes of inactivity.
Logging in...                                                                                                                                               
OK. Current restricted directory is /
Logged in to                                                                                                                            
ncftp / > passive
passive                        on
ncftp / > passive
passive                        off
ncftp / > 

Yes, it works!

People acting stupid while typing on keyboard

Now we can give our client their access and let them break their WordPress freely 🙂

Thanks for reading through this post. Hope it helped you at least a bit. Feel free to drop a line if you spotted an issue or want to talk about it!

Special thanks

I’ll never thank enough Till Brehm for his tutorials. He’s the reason why I broke so many servers but eventually started building stuff that works to host my websites at first, then friends’ websites, and finally my clients’ production apps.

Special thanks to the people building Flameshot, the most amazing screenshot tool for Linux. Try it out, it’s wonderful, and of course, free and open source.