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.
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)
- 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).
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
I often use custom ports between
42000 so I decided I would use a range of 1000 ports from
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:
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
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
I didn’t find any documentation about this, so I’m not sure about this behavior, only that
ForcePassiveIP never worked unless specified in a file of the same name in
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
You can find the external IP either:
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
pure-ftpd-mysql in my case):
systemctl restart pure-ftpd-mysql
ncftp (or another tool)
➜ ncftp -u USERNAME -p PASSWORD kayak.mydomain.com NcFTP 3.2.6 (Dec 04, 2016) by Mike Gleason (http://www.NcFTP.com/contact/). 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 kayak.mydomain.com. ncftp / > passive passive on ncftp / > passive passive off ncftp / >
Yes, it works!
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!
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.