How To: Set up a FTP Server in Linux

A mate of mine who shall remain nameless [cough]Shetboy[/cough] wanted to send me a 30MB file the other day, so at 30MB it’s not going to fit through email without splitting the file up and sending multiple emails with a section-per-mail, and we didn’t want to use dropsend either, so I ended up spending the best part of a day researching and setting up a FTP server on my box so he could just connect and upload the file. Here’s how I did it:

1.) Get yourself a FTP server

pro-FTPd seems to be the server of choice when I was researching, so I went with that and a copy of the docs (note that I’m not going to be using mysql for the user authentication, so I don’t need to get proftpd-mysql as well):

sudo apt-get install proftpd-basic proftpd-doc

When installing, it’ll pop up a window asking if you want a Standalone installation of FTPD, I did, and you probably do too, so just hit Next | Next | Finish or whatever to complete the installation.

2.) Get yourself a GUI to configure the server

This is optional, and you might just want to get elbow-deep in the config files, but I decided to use a GUI to configure most things, and then just tweak the resulting config file:

sudo apt-get install gadmin-tools

With that done (in Gnome, at least) you’ll have a set of GUI tools for configuring things, including proFTPd in your Applications | System Tools menu.

3.) Configure the FTP Server

This is the fun bit…

– Open GADMIN-PROFTPD and it’ll moan it doesn’t have a valid configuration file and ask you if you’d like to create a standard installation configuration, why yes, yes you would.
– As I’m not using mysql for authentication, and I don’t want to have to use real users of my system to connect, I’m going to use virtual users. To do so, just check the Enable virtual users checkbox.
– I don’t want my FTP running on the standard port (21), so I’ve moved the ftp service to run on port 2121
– I’m behind a router, so I need to tell proFTPd what my external IP is, for this guide, lets just say it’s Enter whatever your external IP is ( comes in useful here) and don’t forget to change the NAT Router setting to On to enable it.
– We’re going to be using additional ports (i.e. passive FTP), so we need to leave the range of 49152 to 65534 alone, and we’re going to port-forward these from our router to our internal server IP later.

You should end up with something looking pretty much like this (bar entering YOUR external IP, not just


4.) Set up your Virtual Users and Groups

If we want to use actual system users (i.e. user accounts which exist to log in to our machine) we can, but it’s a bit safer to use virtual users, and do you really want to create additional accounts on your machine when you don’t have to? Thought not. So to create our virtual users we use a script called ftpasswd which comes with proFTPd.

From the shell enter the following:

cd /etc/proftpd
sudo ftpasswd --passwd  --name ftpmonkey --home /home/ftpuploads --shell=/dev/null --uid=5000 --gid=5000


  • The ftpasswd tool creates your user and group files in your present working directory, if we move to where we want them to be created first, we don’t have to move them later.
  • The name field is the username you want to use to log in to your ftp server.
  • /home/ftpuploads is a directory I’ve created to store all the FTP files we’re going to serve, and is the location files will be uploaded to. You’ll need to create this directory, or another directory and then set them to be owned by the nobody group and user by using sudo chown nobody /home/ftpuploads and sudo chgrp nobody /etc/ftpuploads commands.
  • –shell=/dev/null disables any FTP users from starting their own shell session where they could potentially cause mischief.
  • –uid=xxxx and –gid=xxxx – A virtual user must have a UserID and GroupID. You don’t have to use 5000 for them, just any unused User and Group IDs will do – and I picked 5000 out of the air as they’re both free on my box.

After hitting enter you’ll be prompted for the user’s desired password and confirmation of the password, then a file called ftpd.passwd will be written in your current directory.

Next we need to create the group access file using ftpasswd again as follows:

sudo ftpasswd --group --name=ftpd --gid=5000 --member=ftpmonkey

The group name can be anything you want, and make sure you put the same gid value as you used when creating your user(s) above. If you’ve got multiple users you want to be able to connect to your FTP server, just add on additional –member=someuser –member=anotheruser switches when creating the group.

If you want to add additional users later on, just create a new user using ftpasswd as we’ve done above but specify a different, unique UID for the user, then edit the file and tack on the users you’ve just created. For example, you’d modify the file so that:




Note: You may need to add write permissions to ftpd.passwd and ftpd.conf via sudo chmod 644 ./ftpd.passwd and sudo chmod 644 ./ if you want to manually edit them.

Finally, don’t forget to add in your new users as allowed to login to the FTP server from the proftpd.conf file by finding the section at the bottom that looks like (angle brackets changed to square brackets in the below text to avoid HTML woes):

[Limit LOGIN]
  AllowUser ftpmonkey

and changing it to something like:

[Limit LOGIN]
  AllowUser ftpmonkey
  AllowUser someuser
  AllowUser anotheruser

5.) Tweak the config

We used GADMIN-PROFTPD to create our initial configuration (which is stored in /etc/proftpd/proftpd.conf), now we’re going to tweak it a little to use our created passwd and group files. To do this, add in the following lines to the top of your proftpd.conf file (making sure you don’t have the same directives twice! i.e. if there’s another AuthUserFile directive somewhere, remove it etc.):

DenyFilter			\*.*/
# Use this to jail all users in their homes 
DefaultRoot			~
ServerType standalone
DefaultServer on
Umask 022 022
# Authentication using AuthUserFile
AuthUserFile                    /etc/proftpd/ftpd.passwd
# AuthOrder to use mod_auth_file.c only, no local user allowed
AuthOrder                       mod_auth_file.c

Once you’ve done this, strip out the Anonymous section from the bottom of the file – we don’t want anonymous logins, and GADMIN-PROFTPD uses a cludgy, incorrect way to try to add in users as anonymous users anyway.

You should end up with a file looking something like the one here.

6.) Test it locally

Stop and then start the FTP server so it’s running with our new config by using:

sudo /etc/init.d/proftpd restart

Try connecting to your server in Firefox on ftp://localhost:2121 – if you’ve followed the steps correctly you should be able to log in. If not, have a look to see if you’ve missed any steps, and maybe do a little additional reading on Virtual Users, Authentication, and has a proFTPd setup guide which I found halfway through writing this one!

7.) Open it up to the world

If you can connect from inside your local network, and you want users to be able to access the FTP server from anywhere, we need to do a bit of port-forwarding to allow the server to be accessed from the outside world. Port forwarding is a big topic, and I’m not going to cover it in depth here – if you need help try, but what we’re going to do is forward port 2121 to the local IP of our FTP server (in my case the FTP server’s just running on my laptop at local IP, and then port forward the range of ports 49152 to 65534 for our actual FTP traffic.

I tried doing this initially with the DD-WRT firmware on my router, but the router config had got a bit mangled and wouldn’t work properly. As I’d been meaning to move to the Tomato firmware anyway, I just threw that on the router and things started working properly in no-time, so just be aware that your router and not your FTP configuration can be the weak link when things aren’t working sometimes.


With that done, try accessing your FTP server through a web browser with: ftp://YOUR-EXTERNAL-IP:2121

If you get a login box then your port-forwards are fine. If you can’t login you need to stop the FTP server and go look at the Virtual Users part again then restart the FTP server. If you can access and login, but can’t upload or download, you need to look at your ftpuploads directory and maybe change the permissions on them (try sudo chgrp 5000 /home/ftpuploads -R, for example).

Last thing, try using FileZilla or something to upload some files to your FTP server – if it works, you’ve done it. Congrats!

Oh, and the mate who wanted to FTP me a 30MB file? He’d misread the file size – it was actually 3MB… ls -alh ftw!

Final note: If you’re running DD-WRT on your router, and want to change to the Tomato firmware, don’t forget to telnet into the router and get the password hash first!

How To: Easily Convert FLAC audio to MP3s in Linux

I grabbed a bunch of FLAC files the other day, and as nice as they sound, I don’t think ~30-40MB per track is acceptable, so I did a bit of research and stumbled across this great post on LinuxTutorialBlog.

Turns out there’s a dead simple GUI based tool called SoundConverter – which really is as simple as pointing it at a directory and configuring your transcoding preferences (mp3, ogg, file-naming etc). A swift sudo apt-get install soundcoverter and a couple of clicks later and the job’s done.


If you really want a bash method, there’s a bunch of scripts and links in tfa, such as this one by Octavio Ruiz :

# Copyright 2008 Octavio Ruiz
# Distributed under the terms of the GNU General Public License v3
# $Header: $
# Yet Another FLAC to MP3 script
# Author:
# Octavio Ruiz (Ta^3) <>
# Modification/Fixage:
# r3dux
# Thanks:
# Those comments at:
# WebPage:
# This program is distributed in the hope that it will be useful,
# See the GNU General Public License for more details.
LAME_OPTS="-V 0 -q 0 --vbr-new"
id3v2=$(which id3v2)
files=( `find . -type f -name '*flac'` )
for N_files in ${!files[@]}
vars=( `metaflac --no-utf8-convert --export-tags-to=- "${files[${N_files}]}"` )
for N_vars in ${!vars[@]}
    export "$(echo "${vars[${N_vars}]%=*}" | tr [:upper:] [:lower:])=${vars[${N_vars}]#*=}"
flac -dc "${files[${N_files}]}" |\
    lame ${LAME_OPTS} --ignore-tag-errors --add-id3v2 \
        ${artist:+--ta} ${artist} \
        ${tracknumber:+--tn} ${tracknumber} \
        ${title:+--tt} ${title} \
        ${album:+--tl} ${album} \
        ${date:+--ty} ${date} \
        ${genre:+--tg} ${genre} \
        ${comment:+--tc} ${comment} \
        - "${files[${N_files}]/\.flac/.mp3}"
    [[ -x ${id3v2} ]] && ${id3v2} \
        ${artist:+--artist} ${artist} \
        ${tracknumber:+--track} ${tracknumber} \
        ${title:+--song} ${title} \
        ${album:+--album} ${album} \
        ${date:+--year} ${date} \
        ${genre:+--genre} ${genre} \
        ${comment:+--comment} ${comment} \

I’ve modded the LAME_OPTS line in the above script to use the -q 0 switch in lame (so it uses the highest quality algorithm it can), and changed the order of when the ${LAME_OPTS) options are passed to lame, which results in them actually being honoured. Which is nice. Should you have any specific encoding goals, you can always browse through the lame switches and mod it to your hearts content.

Sweet like chocolate =D

Note: To run the above script, just copy & paste into a file, maybe or something, then chmod +x to make it executable and run it on a folder like MyFolderOfFLACFiles.

How To: Make VirtualBox Use Your Router’s DHCP to get an IP Address in Linux

Update: The method below for getting a virtualbox IP from your DHCP works (in linux) – but it turns out there’s an easier way (kindly pointed out by Mike in the comments below). You can just change your VirtualBox network settings from NAT to Bridged Adapter and point it at eth0/wlan0 or whichever connection is being used for networking. Then, optionally, you can configure the MAC address of the bridged adapter and set your router to assign a specific IP to a specific bridged adapter. Also, the built-in Bridged Adapter method works to deploy solutions from XNA Game Studio to my Xbox 360, so I’m rapt! Thanks, Mike!

VirtualBox Bridged Adapter Settings

Note: The below bit is for linux only, the above method should work on any host OS!

VirtualBox is an awesome bit of kit and I <3 it long time ten-dorrah. But by default when your virtual copy of Windows/Linux/Solaris/Whatever grabs an IP address, it does so through NAT, and at version 3.0.4, this means it gives us a default Category A network address (i.e. 10.x.y.z).

It’s a working cat-A address, as in it’s fully functional and can talk to the Internet and all that, but sometimes life is a lot easier if you have an IP in the same range as the DHCP pool your router is dishing out. For example, my lappy is internally, my Wii might be, the NAS .103 etc, so I want my virtualboxen to take addresses like .104, .105 and such.

I’m doing this to bridge my wireless connection on wlan0, if you’re bridging an ethernet connection substitute eth0 or whatever connection as necessary.

Also, to perform the bridging using this method, you’ll need some tools (feel free to sudo apt-get install NAME-OF-TOOL as necessary):
– 1.) uml-utilities
– 2.) parprouted
– 3.) bcrelay

Now, with that lot installed, run the following commands (provided here in bash script form):

# To use this script you will need the following utilities installed:
# 1.) uml-utilities 2.) parprouted  3.) bcrelay
# sudo apt-get install 'em
# Enable IP forwarding
sudo sysctl net.ipv4.ip_forward=1
# Create a TAP as your current logged in user (replace with -u YOUR-USER-NAME if you want...)
sudo tunctl -u $USER
# Tell tap0 to respond to ARP (Address Resolution Protocal) packets 
sudo sysctl net.ipv4.conf.tap0.proxy_arp=1
# Give your TAP (tap0) an IP address and enable it (make sure the IP address is OUTSIDE the DHCP range on your router)
sudo ip addr add dev tap0
sudo ip link set tap0 up
# Run parprouted and make it add routes automatically for wlan0 and tap0 as needed
# Make the command "parprouted -d wlan0 tap0" to display routes added and additional info. No sudo necc. for this one.
parprouted wlan0 tap0
# Use bcrelay on your net connection and TAP to "rewrite the layer-2 header and forward broadcast messages between network interfaces"
# The "-d" in this instance MAKES bcrelay work as a daemon. Need to sudo this or it doesn't work.
sudo bcrelay -d -i tap0 -o wlan0

Now, fire up VirtualBox and for your machine of choice change the network selection from NAT to tap0 as shown:


Then boot up your virtual machine and check the IP:


Great. Super. Smashing. =D

Note: The entire reason I wanted to grab an IP from the router was so my virtual copy of XP could be on the same network as my XBox 360, so I could deploy games to it through XNA Studio 3.1, however XNA Studio is very fussy about timing when it comes to registering the 360, and although it can see the 360 using the bridge, and it tries to connect, it times out before it can fully establish a connection. I guess I’ll have to go with an IP routes method of bridging if I want it to work for that purpose, but as yet I haven’t quite figured it all out. Will keep trying when I have time, or if you know a way, feel free to call me technically incompetent and sling a solution in the comments! Cheers!

How To: Fix CUPS PDF Printing in Linux

CUPS, the Common Unix Printing System, is b0rked in the standard Jaunty 9.04 release. Which is less than ideal when you want to print directly to PDF.

You can use “Print to File” and change from PostScript to PDF, and this will work, but I just wanted to use the PDF virtual printer, so did a bit of research and fixed it. Turns out cups is fine, but the AppArmour profile for cupsd was busted, so all we need to do is to tell AppArmour to just moan about cups-pdf instead of shutting it down due to the wonky profile.

From the console enter the following.

r3dux@r3dux-laptop:~$ sudo aa-complain
Please enter the program to switch to complain mode: cupsd
Setting /etc/apparmor.d/usr.sbin.cupsd to complain mode.
r3dux@r3dux-laptop:~$ sudo /etc/init.d/cups restart
* Restarting Common Unix Printing System: cupsd
[ OK ]

FiXX0r3d. Or smth.

Source (defunct as of 12/2013):

P.S. You can also fix the problem by disabling the AppArmour profile instead of putting the profile for cupsd to complain mode, full details given at source page above.

How To: Force Word 2003 to Repeat Table Headings Across Pages

Occasionally Word 2003 will refuse to play ball when you ask it to repeat table headings across pages, that is, each new page that a table’s on gets the table heading so the reader knows what’s what in the columns. But sometimes no matter what actions you perform that should do the trick – it just doesn’t happen. Here’s how to skull-fuck force it into doing what you’re damned well telling it to do:

  • Tried selecting the top row, then Right click | Table Properties | Row tab followed by checking the box labled Repeat as header row at the top of each page? Not having it?
  • Tried selecting Text Wrapping to None from the Table tab of Table Properties? No dice?
  • Tried un-marking the Properties | Repeat as header box then hitting [OK] then getting the table properties up again and re-selecting the box followed by [OK]? Still being a dick?
  • Then click somewhere in the table and go to Table | Heading Rows Repeat in the menu. Sorted!