Linux/tftp-hpa: Difference between revisions

From Omnia
Jump to navigation Jump to search
No edit summary
 
(21 intermediate revisions by the same user not shown)
Line 5: Line 5:
Website:
Website:
  https://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git/
  https://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git/
My version with some community patches applied:
https://github.com/kiloforce/tftp-hpa.git


== Install ==
== Install ==
Tested on;
* Ubuntu 20
* Ubuntu 22
* Ubuntu 24


=== Dependencies ===
=== Dependencies ===


All dependencies:
All dependencies:
  apt install tftp xinetd gcc make autoconf build-essential
  sudo apt install xinetd gcc make autoconf build-essential


Get the client for testing:
Get the client for testing:
  apt install tftp
  sudo apt install tftp
# or use the tftp-hpa client version being installed


Get xinetd wrapper
Get xinetd wrapper
  apt install xinetd
  sudo apt install xinetd


=== Source ===
=== Source ===
Line 33: Line 42:


Home folder
Home folder
  mkdir /tftp
  sudo mkdir /tftp
# note: will do this next step after creating tftp user below...
# sudo chown tftp:tftp /tftp


=== xinetd ===
=== xinetd ===
Line 45: Line 56:
         wait            = yes
         wait            = yes
         user            = root
         user            = root
        #group          = tftp
         port            = 69
         port            = 69
         server          = /opt/tftp-hpa/sbin/in.tftpd
         server          = /opt/tftp-hpa/sbin/in.tftpd
         server_args    = -vvv --create --user tftp  --secure /tftp  --map-file /etc/tftpd.map  --refuse blksize
         server_args    = --verbose  --verbose --verbose --user tftp  --secure /tftp  --map-file /etc/tftpd.map  --refuse blksize
         #server_args    = -vvv -s /tftp -m /etc/tftpd.map -r blksize
        #    Use --create only if you need upload permission
         #server_args    = --verbose -u tftp -s /tftp -r blksize
         # server_args    = --verbose  --verbose  --verbose  --create  --user tftp  --secure /tftp --map-file /etc/tftpd.map --refuse blksize
        #    Short parameter version:
         # server_args    = -vvv -c -u tftp -s /tftp -m /etc/tftpd.map -r blksize
        flags          = IPv4
         disable        = no
         disable        = no
}
}
</pre>
</pre>


  adduser tftp
Other parameters of interest:
  --umask umask, -U umask  # umask for newly created files
--timeout timeout, -t timeout  # in seconds default is 900 (15 minutes)
 
=== tftp user ===
 
sudo adduser tftp
# no password
 
sudo usermod -d /tftp -s /usr/sbin/nologin tftp
 
# /etc/password
tftp:x:1011:1011:TFTP User:/tftp:/usr/sbin/nologin
# or
tftp:x:1011:1011:,,,:/tftp:/usr/sbin/nologin
 
# /etc/shadow
tftp:!:20121:0:99999:7:::


  tftp:x:1001:1001:TFTP User:/tftp:
  sudo chown tftp:tftp /tftp


chown tftp:tftp /tftp
=== Map File ===


/etc/tftpd.map:
/etc/tftpd.map:
Line 65: Line 95:
# Convert backslashes to slashes
# Convert backslashes to slashes
rg \\ /
rg \\ /
# Reject Put requests
Pa .
# Reject IPv6 requests
6a .
</pre>
</pre>


=== Service ===
=== Service ===


  service xinetd stop
  sudo service xinetd stop
  service xinetd start
  sudo service xinetd start
#
sudo service xinetd restart
#
sudo service xinetd status
 
# or
 
sudo systemctl stop xinetd
sudo systemctl start xinetd
#
sudo systemctl restart xinetd
#
sudo systemctl status xinetd
 
=== Upload folder ===
 
Dangerous, but possible if the --create option is added above.  Doesn't appear to be a way to limit to a specific folder, so would be best to have a limited tftp upload server, seperate from regular tftp server usage.
 
sudo mkdir /tftp/upload
sudo chmod 775 /tftp/upload
sudo chown tftp:tftp /tftp/upload
 
<s>sudo chmod 777 /tftp/upload</s>
 
echo "test" > test.txt
# tftp tftp.server.com
tftp localhost
/opt/tftp-hpa/bin/tftp localhost  # doesn't seem to like ipv6, so force to ipv4 with:
/opt/tftp-hpa/bin/tftp 127.0.0.1
  put test.txt upload/test.txt
  # Sent 6 bytes in 0.1 seconds


== More Complete Map File ==
== More Complete Map File ==
Line 126: Line 193:


ref: https://stackoverflow.com/questions/68982596/multiple-definition-error-while-compiling-tftp-hpa
ref: https://stackoverflow.com/questions/68982596/multiple-definition-error-while-compiling-tftp-hpa
=== cannot set groups for user nobody ===
Problem:
* If you have the xinet user set to tftp (or nobody) you get the following error in the logs:
<pre>
in.tftpd[2120]: cannot set groups for user nobody
</pre>
Solution:
* xinet user must be set to root :-(  BUT, you pass in the server_args "-u USER" to run as another user.
ref: https://blog.thewatertower.org/2019/05/01/tftp-part-1-running-it-as-non-root/


== keywords ==
== keywords ==


tftp tftpd tftp-hpa
tftp tftpd tftp-hpa

Latest revision as of 02:55, 2 February 2025

tftp-hpa

Note: Code hasn't been updated since 2015!

Website:

https://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git/

My version with some community patches applied:

https://github.com/kiloforce/tftp-hpa.git

Install

Tested on;

  • Ubuntu 20
  • Ubuntu 22
  • Ubuntu 24

Dependencies

All dependencies:

sudo apt install xinetd gcc make autoconf build-essential

Get the client for testing:

sudo apt install tftp
# or use the tftp-hpa client version being installed

Get xinetd wrapper

sudo apt install xinetd

Source

mkdir ~/.src ; cd ~/.src
# git clone https://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git
git clone https://github.com/kiloforce/tftp-hpa.git  # - added patch to fix compile issue
cd tftp-hpa
bash autogen.sh
# ./configure
./configure --prefix=/opt/tftp-hpa
make clean
make
sudo make install

Home folder

sudo mkdir /tftp
# note: will do this next step after creating tftp user below...
# sudo chown tftp:tftp /tftp

xinetd

/etc/xinetd.d/tftp:

service tftp
{
        socket_type     = dgram
        protocol        = udp
        wait            = yes
        user            = root
        port            = 69
        server          = /opt/tftp-hpa/sbin/in.tftpd
        server_args     = --verbose  --verbose  --verbose  --user tftp  --secure /tftp  --map-file /etc/tftpd.map  --refuse blksize
        #    Use --create only if you need upload permission
        # server_args     = --verbose  --verbose  --verbose  --create  --user tftp  --secure /tftp  --map-file /etc/tftpd.map  --refuse blksize
        #    Short parameter version:
        # server_args     = -vvv -c -u tftp -s /tftp -m /etc/tftpd.map -r blksize
        flags           = IPv4
        disable         = no
}

Other parameters of interest:

--umask umask, -U umask  # umask for newly created files
--timeout timeout, -t timeout  # in seconds default is 900 (15 minutes)

tftp user

sudo adduser tftp
# no password
sudo usermod -d /tftp -s /usr/sbin/nologin tftp
# /etc/password
tftp:x:1011:1011:TFTP User:/tftp:/usr/sbin/nologin
# or
tftp:x:1011:1011:,,,:/tftp:/usr/sbin/nologin
# /etc/shadow
tftp:!:20121:0:99999:7:::
sudo chown tftp:tftp /tftp

Map File

/etc/tftpd.map:

# Convert backslashes to slashes
rg \\ /

# Reject Put requests
Pa .

# Reject IPv6 requests
6a .

Service

sudo service xinetd stop
sudo service xinetd start
#
sudo service xinetd restart
#
sudo service xinetd status
# or
sudo systemctl stop xinetd
sudo systemctl start xinetd
#
sudo systemctl restart xinetd
#
sudo systemctl status xinetd

Upload folder

Dangerous, but possible if the --create option is added above. Doesn't appear to be a way to limit to a specific folder, so would be best to have a limited tftp upload server, seperate from regular tftp server usage.

sudo mkdir /tftp/upload
sudo chmod 775 /tftp/upload
sudo chown tftp:tftp /tftp/upload
sudo chmod 777 /tftp/upload
echo "test" > test.txt
# tftp tftp.server.com
tftp localhost
/opt/tftp-hpa/bin/tftp localhost   # doesn't seem to like ipv6, so force to ipv4 with:
/opt/tftp-hpa/bin/tftp 127.0.0.1
  put test.txt upload/test.txt
  # Sent 6 bytes in 0.1 seconds

More Complete Map File

#
# Rule file for the -m (remapping option)
#
# This file has three fields: operation, regex, remapping
#
# The operation is a combination of the following letters:
#
# r - rewrite the matched string with the remapping pattern
# i - case-insensitive matching
# g - repeat until no match (used with "r")
# e - exit (with success) if we match this pattern, do not process
#     subsequent rules
# s - start over from the first rule if we match this pattern
# a - abort (refuse the request) if we match this rule
# G - this rule applies to TFTP GET requests only
# P - this rule applies to TFTP PUT requests only
#
# The regex is a regular expression in the style of egrep(1).
#
# The remapping is a pattern, all characters are verbatim except \
# \0 copies the full string that matched the regex
# \1..\9 copies the 9 first (..) expressions in the regex
# \\ is an escaped \
# See http://linux.die.net/man/8/tftpd for more info.
#
# "#" begins a comment, unless \-escaped
#
ri    ^[a-z]:            # Remove "drive letters"
rg    \\        /        # Convert backslashes to slashes
rg    ([A-Z])   \L\1     # Convert uppercase to lowercase
rg    \#        @        # Convert hash marks to @ signs
rg    /../      /..no../ # Convert /../ to /..no../
e    ^ok/                # These are always ok
r    ^[^/]      /\0      # Convert non-absolute files
a    \.pvt$              # Reject requests for private files

ref: https://github.com/jumanjihouse/docker-tftp-hpa/blob/master/src/mapfile

Issue

compile issue - multiple definition of toplevel

Issue:

/usr/bin/ld: main.o:/root/.src/tftp-hpa/tftp/main.c:98: multiple definition of `toplevel'; tftp.o:/root/.src/tftp-hpa/tftp/tftp.c:51: first defined here

Fix:

ref: https://stackoverflow.com/questions/68982596/multiple-definition-error-while-compiling-tftp-hpa

cannot set groups for user nobody

Problem:

  • If you have the xinet user set to tftp (or nobody) you get the following error in the logs:
in.tftpd[2120]: cannot set groups for user nobody

Solution:

  • xinet user must be set to root :-( BUT, you pass in the server_args "-u USER" to run as another user.

ref: https://blog.thewatertower.org/2019/05/01/tftp-part-1-running-it-as-non-root/

keywords

tftp tftpd tftp-hpa