tftp-hpa – BSD derived TFTP Server

tftp-hpa – BSD derived TFTP Server

Last Updated on 2019-02-22 by Sture

Description

tftp-hpa is portable, BSD derived tftp server. It supports advanced options such as blksize, blksize2, tsize, timeout, and utimeout. It also supported rule-based security options.

Requirements

The following application(s) must be installed, configured and running before tftp-hpa is installed:

  • None

Preparation for Installation

Start PuTTY on a Windows PC, Terminal on a Mac or similar terminal application on a Linux PC.

In this example Terminal on a Mac is used.

Open a remote SSH session to the server with:

Mac:~ user$ ssh user@192.168.1.4 [enter]
N.B.: Replace user@192.168.1.4 with User ID and IP Address on Your server!
[user@server ~]$

Enable superuser privileges with:

[user@server ~]$ sudo -s [enter]
Password: <-- passwd [enter]
[root@server /usr/home/user]#

N.B.: Enter user password, not the root password!

Installation

Search for tftp in the remote package repositories with:

[root@server /usr/home/user]# pkg search tftp  [enter]
atftp-0.7_3                    Advanced tftp server and client
nagios-check_tftp-1.0.1        Nagios plugin to check tftp servers
p5-TFTP-1.0                    TFTP client in Perl as described in RFC783
py27-tftpy-0.6.2               Pure Python TFTP Implementation
tftp-hpa-5.2                   Advanced tftp server
tftpgrab-0.2                   TFTP stream extractor
utftpd-0.2.4_2                 secure tftpd server with fine grained access and revision control
[root@server /usr/home/user]##

In this example, tftp-hpa will be installed.

Install port tftp-hpa with;

[root@server /usr/home/user]# pkg install tftp-hpa [enter]
Updating FreeBSD repository catalogue...
FreeBSD repository is up-to-date.
All repositories are up-to-date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	tftp-hpa: 5.2

Number of packages to be installed: 1

38 KiB to be downloaded.

Proceed with this action? [y/N]: y [enter]
Fetching tftp-hpa-5.2.txz: 100%   38 KiB  39.3kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing tftp-hpa-5.2...
[1/1] Extracting tftp-hpa-5.2: 100%
[root@server /usr/home/user]#

Configuration

packet filter (pf)

Access to the tftpd service must be enabled in the packet filter (pf) configuration file.

Start editing file /etc/pf.conf with:

[root@server /usr/home/user]# ee /etc/pf.conf [enter]

…and add port information to enable access to the TFTP service from clients on the local network as in this example:

...
# Ports:
#  53 TCP UDP   Domain Name System (DNS)
#  67 TCP UDP	Bootstrap Protocol (BOOTP) server
#  69 TCP UDP   Trivial File Transfer Protocol (TFTP)
# 123 TCP       Network Time Protocol
...
tcp_pass="{ 53,  67, 69, 123 }"
udp_pass="{ 53,  67, 69, }"
...
# Pass specified tcp traffic in to this server from LAN clients
pass in on $lan_if proto tcp from $lan_if:network to $lan_if port $tcp_pass

# Pass specified udp  traffic in to this server from LAN clients
pass in on $lan_if proto udp from $lan_if:network to $lan_if port $udp_pass

# Pass SSH traffic from LAN clients (for Admin)
pass in on $lan_if proto tcp from $lan_if:network to $lan_if port ssh
...

Check /etc/pf.conf for errors, but do not load ruleset with:

[root@server /usr/home/user]# pfctl -vvnf /etc/pf.conf [enter]

…and then reload /etc/pf.conf with:

[root@server /usr/home/user]# service pf reload [enter]
Reloading pf rules.
[root@server /usr/home/user]#

/tftpboot Directory

List current ZFS pool information with:

[root@server /usr/home/user]# zpool list [enter]
NAME    SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
zroot  5,44T   254G  5,19T         -     2%     4%  1.00x  ONLINE  -
[root@server /usr/home/user]#

In this example, zroot pool was found.

Creates a dataset where the tftpboot files will be stored with:

[root@server /usr/home/user]# zfs create -o compression=lz4 -o mountpoint=/tftpboot zroot/tftpboot [enter]
[root@server /usr/home/user]#
[root@server /usr/home/user]# chown tftpd:tftpd /tftpboot [enter]
[root@server /usr/home/user]#
[root@server /usr/home/user]# chmod u=rwx,g=rx,o= /tftpboot [enter]
[root@server /usr/home/user]#

tftpd User

Create a separate user tftpd with group tftpd, no login shell and the home directory set to /nonexistent for running tftpd with:

Add a separate user group tftpd for running the tftpd service with:

[root@server /usr/home/user]# pw groupadd tftpd  [enter]
[root@server /usr/home/user]#

Add a separate user tftpd in group tftpd, no login shell and the home directory set to /nonexistent for running the tftpd service with:

[root@server /usr/home/user]# pw useradd tftpd -c tftp_manager -d /nonexistent -g tftpd -s /usr/sbin/nologin [enter]
[root@server /usr/home/user]#
[root@server /usr/home/user]# vipw [enter]
...
tftpd:*:4004:4003::0:0:tftp_manager:/nonexistent:/usr/sbin/nologin
...
[root@server /usr/home/user]#

Enable tftpd Service

List installed tftpd services with:

[root@server /usr/home/user]# service -r | grep tftpd [enter]
/usr/local/etc/rc.d/tftpd
[root@server /usr/home/user]#

Find the rcvar for /etc/rc.conf with:

[root@server /usr/home/user]# /usr/local/etc/rc.d/tftpd rcvar [enter]
# tftpd
#
tftpd_enable="NO"
#   (default: "")

[root@server /usr/home/user]#

To start tftpd at system boot, add information to /etc/rc.conf with this commands:

[root@server /usr/home/user]# echo '' >> /etc/rc.conf; echo '# tftpd-hpa' >> /etc/rc.conf; echo 'tftpd_enable="YES"' >> /etc/rc.conf; echo 'tftpd_flags="--ipv4 --secure --create --user tftpd --umask 027 --permissive --address 0.0.0.0:69 /tftpboot"' >> /etc/rc.conf [enter]
[root@server /usr/home/user]#

Optional: Add –blocksize 1468 to the tftpd_flags may improve the performance on some systems.

Display full list of tftpd options with:

[root@server /usr/home/user]# man in.tftpd [enter]

Start

Manually start tftpd with:

[root@server /usr/home/user]# service tftpd start [enter]
Starting tftpd.
[root@server /usr/home/user]#

Verify and Test

Check whether the tftpd service daemon is running:

[root@server /usr/home/user]# ps -x | grep tftp | grep -v grep [enter]
 2970  -  Is       0:00,00 /usr/local/libexec/in.tftpd --ipv4 --secure --create --user tftpd --umask 027 --permissive --address 0.0.0.0:69 /tftpboot -P /var/run/tftpd.pid -l
[root@server /usr/home/user]#

You should now have an operational TFTP server. Since your FreeBSD system also has a TFTP client, you can test that the server is running.

First, tftp to the address of your TFTP server as a regular user. Here, we will use the tftp client from the same computer, that is the TFTP server.

Connect to the TFTP service on the local host with:

[root@server /usr/home/user]# tftp localhost [enter]

If the server responds, your prompt will change to:

tftp>

If you type ?, you’ll get a list of command that the tftp client supports:

tftp> ? [enter]
Commands may be abbreviated.  Commands are:

connect 	connect to remote tftp
mode    	set file transfer mode
put     	send file
get     	receive file
quit    	exit tftp
verbose 	toggle verbose mode
status  	show current status
binary  	set mode to octet
ascii   	set mode to netascii
rexmt   	set per-packet retransmission timeout[-]
timeout 	set total retransmission timeout
trace   	enable 'debug packet'[-]
debug   	enable verbose output
blocksize	set blocksize[*]
blocksize2	set blocksize as a power of 2[**]
rollover	rollover after 64K packets[**]
options 	enable or disable RFC2347 style options
help    	print help information
packetdrop	artificial packetloss feature
?       	print help information

[-] : You shouldn't use these ones anymore.
[*] : RFC2347 options support required.
[**] : Non-standard RFC2347 option.
tftp>

Exit the tftp client with:

tftp> q [enter]
[root@server /usr/home/user]#

2 Replies to “tftp-hpa – BSD derived TFTP Server”

  1. Thank you for this document, has help me setup TFTP-hpa for use with a Raspberry Pi 4B with 8 gigs of dram memory. I want to network boot and needed a trivial file transfer program to work over Wi-Fi. I was able to follow step by step.
    I think that the “chown tftpd:tftpd /tftpboot” command needed to come after the “group add” and the “user add” commands.
    I used this August 7, 2016 tftp setup as a comparison for your command sequences.
    [https://forum.netgate.com/topic/99884/pfsense-2-3-tftp-server/7](TFTP server setup example on pfsense 2.3).

  2. ps. I was using GhostBSD.org desktop 21.01.20 updated version, that uses OpenRC not systemd. The service command changes to rc-service, yet most everything else is the same.
    my version of verifying that “tftpd” was running did not have the correct output:

    root@localhost:~ # ps -x | grep tftp | grep -v grep
    88361 – Is 0:00.00 /usr/local/libexec/in.tftpd -P /var/run/tftpd.pid -l
    root@localhost:~ # rc-service -v tftpd restart
    * Caching service dependencies … [ ok ]
    * Executing: /libexec/rc/sh/openrc-run.sh /libexec/rc/sh/openrc-run.sh /usr/local/etc/init.d/tftpd stop
    * Stopping tftpd …
    * Will stop /usr/local/libexec/in.tftpd
    * Will stop PID 88361
    * Will stop processes of `/usr/local/libexec/in.tftpd’
    * Sending signal 15 to PID 88361 … [ ok ]
    * Executing: /libexec/rc/sh/openrc-run.sh /libexec/rc/sh/openrc-run.sh /usr/local/etc/init.d/tftpd start
    * Starting tftpd …
    * start-stop-daemon: fopen `/var/run/tftpd.pid’: No such file or directory
    * Detaching to start `/usr/local/libexec/in.tftpd’ … [ ok ]
    root@localhost:~ # ps -x | grep tftp | grep -v grep
    3126 – Ss 0:00.00 /usr/local/libexec/in.tftpd -P /var/run/tftpd.pid -l
    root@localhost:~ # ps -x | grep tftp
    3126 – Is 0:00.00 /usr/local/libexec/in.tftpd -P /var/run/tftpd.pid -l
    so will perform more checking and verifying to find out why.

    pss. I also used Digital Ocean document to clarify setting up pf.conf
    [https://www.digitalocean.com/community/tutorials/how-to-configure-packet-filter-pf-on-freebsd-12-1](pf on FreeBSD 12.1)

    #file /etc/pf.con
    lan_if=’wlan0′
    icmp_types = “{ echoreq }”
    # Ports:
    # 53 TCP UDP Domain Name System (DNS)
    # 67 TCP UDP Bootstrap Protocol (BOOTP) server
    # 69 TCP UDP Trivial File Transfer Protocol (TFTP)
    # 123 TCP Network Time Protocol
    tcp_pass=”{ 53, 67, 69, 123 }”
    udp_pass=”{ 53, 67, 69 }”

    # Pass specified tcp traffic in to this server from LAN clients
    pass in on $lan_if proto tcp from $lan_if:network to $lan_if port $tcp_pass

    # Pass specified udp traffic in to this server from LAN clients
    pass in on $lan_if proto udp from $lan_if:network to $lan_if port $udp_pass

    # Pass SSH traffic from LAN clients (for Admin)
    pass in on $lan_if proto tcp from $lan_if:network to $lan_if port ssh

    pass in on $lan_if proto tcp to port { 22 }
    pass inet proto icmp icmp-type $icmp_types

    [https://rackn.com/rebar/]( Rebar and provision)
    [https://www.youtube.com/watch?v=S_I6xua0q-Y](Youtube video on Rebar 3.8 Workflow)
    [https://starkandwayne.com/blog/rackn-hd-bosh/](PXE provisioning CoreOS on bare metal)

Leave a Reply