How to set up a temporary DHCP and FTP server

Back to homepage

Sometimes it's useful to be able to quickly draw up a DHCP server serving on one interface to give an address to some embedded device you are poking around with. Most DHCP server tutorials focus on permanent setups, that are controlled by init.d or SystemD - which is too much work to set up and then remove for my use. This tutorial shows you how to set up a DHCP and FTP server running in a shell, that can be easily turned off when not necesary and leaves no garbage in the system config files.


You can use dhcpd(8) to run a DHCP server. Create a local config file for the subnet declarations. This one also contains an empty declaration to prevent the server from running in a regular network. My file looks like this:

# No DHCP in the usual network
subnet netmask { }

# temporary DHCP 
subnet netmask {

Then, add a static IP address on the interface the server will be running on. Start dhcpd(8) with -d and -cf options to prevent it from forking to background and make it read the local file instead of system wide /etc/dhcpd.conf .

The script below takes care of starting dhcpd(8). It traps SIGINT and cleans up the IP address assignment, so that you can stop the server with ^C

# Temporary DHCP server script
# 2019
# 3-clause BSD licence

dhcpflags="-4 -d -cf dhcpd.conf"

function quit(){
    echo -e "\nCleaning up"
    ip a del $serverip dev $iface

trap quit INT
echo "Setting a static address"
ip a add $serverip dev $iface
echo "Starting the server"
dhcpd $dhcpflags $iface

Note that this script has to be run as root, since the server needs root priviledges. Remember to change the config file as well if you change the serverip variable


I was looking for an FTP daemon suitable for this, and neither ftpd nor vsFTPd seemed suitable. bftpd is a nice little server. Its not installed by default on most systems, but available in most repositories.

bftpd runs in inetd mode by default. Pass the -D option, to prevent if from forking, and pass the config file with the -c option. There aren't many other command line options.

This one is simple enough to not need a script, run it like this:

bfptd -D -c btfpd.conf

My config file looks like this:

global {
    HELLO_STRING="FTP at %i ready!"
    QUIT_MSG="Catch you on the flip side!"
user ftp {
user anonymous {
user root {

There are a couple things to note about bftpd and this config file

  1. RATIO must be set to "none", otherwise the server will not let you download unless you upload files to it (pretty oldschool)
  2. The ROOTDIR value needs to be a hardcoded path, bftpd won't accept "." or other relative path. This is a minor inconveinience, I guess that it could be automated with sed and a startup script but this is good enough.
  3. Take caution, because if the above path is wrong, bftpd will start serving your / directory
  4. It listens only on IPv4
  5. BIND_TO_ADDR accepts only one IPv4 address, or "any", in the latter case it binds to the first available address

This setup works with busybox' ftpget pretty well. You can test whether the server works correctly like this:

$ ftp localhost
ftp: Trying ...
Connected to localhost.
220 FTP at ready!
Name (localhost:xxxxxx): anonymous
331 Password please.
230 User logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
150 BINARY data connection established.
-rw-r--r--   1 0        0        7 Jun  3 19:22 test.txt
226 Directory list has been submitted.
ftp> quit
221 Catch you on the flip side!

Its worth to run that check, from my experience bftpd is pretty picky about its options.

Back to homepage