No Nonsense FTP/TFTP Server
uftpd is a UNIX daemon with sane built-in defaults. It just works.
Features
- FTP and/or TFTP
- No complex configuration file
- Runs from standard UNIX inetd, or standalone
- Uses
ftpuser's$HOME, from/etc/passwd, or custom path - Uses
ftp/tcpandtftp/udpfrom/etc/services, or custom ports - Privilege separation, drops root privileges having bound to ports
- Possible to use symlinks outside of the FTP home directory
- Possible to have group writable FTP home directory
Usage
uftpd [-hnsv] [-l LEVEL] [-o OPTS] [PATH]
-h Show this help text
-l LEVEL Set log level: none, err, notice (default), info, debug
-n Run in foreground, do not detach from controlling terminal
-o OPT Options:
ftp=PORT
tftp=PORT
pasv_addr=ADDR
writable
-s Use syslog, even if running in foreground, default w/o -n
-v Show program version
The optional 'PATH' defaults to the $HOME of the /etc/passwd user 'ftp'
Bug report address: https://github.com/troglobit/uftpd/issues
To start uftpd in the background as an FTP/TFTP server:
$ uftpd
If the ftp user does not exist on your system, uftpd defaults to
serve files from the /srv/ftp directory. To serve another directory,
simply append that directory to the argument list.
Use sudo, or set CAP_NET_BIND_SERVICE capabilities, on uftpd to
allow regular users to start uftpd on privileged (standard) ports,
i.e. < 1024:
$ sudo setcap cap_net_bind_service+ep uftpd
To change port on either FTP or TFTP, use:
$ uftpd -o ftp=PORT,tftp=PORT
Set PORT to zero (0) to disable either service.
New sessions are dropped by default if uftpd detects the FTP root is writable. To allow writable FTP root:
$ uftpd -o writable PATH
Since v2.11 uftpd logs a lot more events by default. Set up your syslogd to redirect
LOG_FTPto a separate log file, or reduce the log level of uftpd using-l errorto only log errors and higher.
Running from inetd
Rarely used services like FTP/TFTP are good candidates to run from the
Internet super server, inetd. On Debian and Ubuntu based distributions
we recommend openbsd-inetd.
Use the following two lines in /etc/inetd.conf, notice how in.ftpd
and in.tftpd are symlinks to the uftpd binary:
ftp stream tcp nowait root /usr/sbin/in.ftpd
tftp dgram udp wait root /usr/sbin/in.tftpd
Remember to activate your changes to inetd by reloading the service or
sending SIGHUP to it. Another inetd server may use different syntax.
Like the inetd that comes built-in to Finit, in /etc/finit.conf:
inetd ftp/tcp nowait /usr/sbin/in.ftpd -- The uftpd FTP server
inetd tftp/udp wait /usr/sbin/in.tftpd -- The uftpd TFTP server
Caveat
uftpd is primarily not targeted at secure installations, it is targeted at users in need of a simple FTP/TFTP server.
uftpd allows symlinks outside the FTP root, as well as a group writable FTP home directory — user-friendly features that potentially can cause security breaches, but also very useful for people who just want their FTP server to work. A lot of care has been taken, however, to lock down and secure uftpd by default.
Build & Install
Debian/Ubuntu
$ curl -sS https://deb.troglobit.com/pubkey.gpg | sudo apt-key add -
$ echo "deb [arch=amd64] https://deb.troglobit.com/debian stable main" | sudo tee /etc/apt/sources.list.d/troglobit.list
$ sudo apt-get update && sudo apt-get install uftpd
Building from Source
uftpd depends on two other projects to build from source, libuEv
and lite. See their respective README for details, there should be
no real surprises, both use the familiar configure, make, make install.
To find the two libraries uftpd depends on pkg-config. The package
name for your Linux distribution varies, on Debian/Ubuntu systems:
$ sudo apt install pkg-config
...
uftpd, as well as its dependencies, can be built as .deb packages on
Debian or Ubuntu based distributions. Install the packaging tools, and
the -dev packages of the dependencies, then run
$ sudo apt install devscripts debhelper lintian po-debconf
$ ./autogen.sh # Only needed if using GIT sources
$ ./configure
...
$ make package
...
Note, dpkg-shlibdeps looks the dependencies up in the installed .deb
packages, so libuev-dev and libite-dev must come from apt -- a
libuEv or libite installed from source under /usr/local is not enough.
The .deb package takes care of setting up /etc/inetd.conf, create an
ftp user and an /srv/ftp home directory with write permissions for
all members of the users group.
If you are using a different Linux or UNIX distribution, check the
output from ./configure --help, followed by make all install.
For instance, building on Alpine Linux:
$ PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure \
--prefix=/usr --localstatedir=/var --sysconfdir=/etc
Provided the library dependencies were installed in /usr/local/. This
PKG_CONFIG_LIBDIR trick may be needed on other GNU/Linux, or UNIX,
distributions as well.
Origin & References
uftpd was originally based on FtpServer by Xu Wang, but is now a complete rewrite with TFTP support by Joachim Wiberg, maintained at GitHub.
Copyright (C) 2014-2026 Joachim Wiberg <troglobit@gmail.com> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Contributing to uftpd
We welcome any and all help in the form of bug reports, fixes, patches for new features -- preferably as GitHub pull requests. Other methods are of course also possible: emailing the maintainer a patch or even a raw file, or simply emailing a feature request or an alert of a problem. For email questions/requests/alerts there is always the risk of memory exhaustion on the part of the maintainer(s), so use GitHub :)
If you are unsure of what to do, or how to implement an idea or bugfix,
open an issue with "[RFC: Unsure if this is a bug ... ?", or similar,
so we can discuss it. Talking about the code first is the best way to
get started before submitting a pull request.
Either way, when sending an email, patch, or pull request, start by stating the version the change is made against, what it does, and why.
Please take care to ensure you follow the project coding style and the commit message format. If you follow these recommendations you help the maintainer(s) and make it easier for them to include your code.
Coding Style
Tip: Always submit code that follows the style of surrounding code!
First of all, lines are allowed to be longer than 72 characters these days. In fact, there exist no enforced maximum, but keeping it around 100 chars is OK.
The coding style itself is strictly Linux KNF.
Commit Messages
Commit messages exist to track why a change was made. Try to be as clear and concise as possible in your commit messages, and always, be proud of your work and set up a proper GIT identity for your commits:
git config --global user.name "Jane Doe"
git config --global user.email jane.doe@example.com
Example commit message from the Pro Git online book, notice
how git commit -s is used to automatically add a Signed-off-by:
Brief, but clear and concise summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as
the subject of an email and the rest of the text as the body. The
blank line separating the ummary from the body is critical (unless
you omit the body entirely); tools like rebase can get confused if
you run the two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here
Signed-off-by: Jane Doe <jane.doe@example.com>
Making a Release
Maintainers: the steps for cutting a release, including updating both
ChangeLog.md and debian/changelog, are in CHECKLIST.md.
Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery
- Personal attacks
- Trolling or insulting/derogatory comments
- Public or private harassment
- Publishing other's private information, such as physical or electronic addresses, without explicit permission
- Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the Contributor Covenant, version 1.2.0.
Security Policy
Supported Versions
uftpd is a small project, as such we have no possibility to support older versions. The only supported version is the latest released on GitHub:
https://github.com/troglobit/uftpd/releases
Reporting a Vulnerability
Contact the project's main author and owner to report and discuss vulnerabilities.