tftp part 1 – running it as non-root

I was trying to get the components of my PXE build server working; ie: http and tftp.

  • xinetd and tftpd installed on Centos 7 (on a pi.)
  • tftp client installed on Centos 7.
  • Both with firewalld and selinux enforcing.

I stumbled over a few things in the process, and have reposted that information in three parts:

Previously published as a single post.

Not running tftpd as non-root.

The ‘user’ field in the xinetd configuration for tftp must be set to root.

It doesn’t do what you want it to do. Or rather it does, but at the expense of tftp not working.

Create an account, switch out user=root in /etc/xinetd.d/tftp, and you’ll get:

in.tftpd[2120]: cannot set groups for user nobody

Which is confusing, because you thought you told xinetd to run it as a specific account .. and not ‘nobody.’

  • That’s not what that configuration entry is for. The xinetd config user field determines what account xinetd spawns the daemon as.
  • The parameters on the daemon determine what account it will do the tftp as.
  • Don’t specify parameters for the daemon and it’ll always try and use nobody.
  • If it isn’t running as root, it cannot switch to the nobody account.

If xinetd is told to run tftpd as non-root, and tftpd is told (by omission) to fork internally to the nobody account, it doesn’t work. A road well trodden.

in.tftpd[2120]: cannot set groups for user nobody

The daemon doesn’t handle this, it just fails to work.

Running tftpd as non-root. Sort of.

The ‘correct’ way to do it is as follows (xinetd configuration:)

	user			= root
	server_args		= -u user -s /some/path

By default the xinetd spawned process persists for 15 minutes afterwards (change this with –timeout in server_args) and so you can see it runs as root.

When an actual tftp session kicks off, it forks, and then does this (from strace output)

[pid 3503] setgroups32(1, [10069]) = 0
[pid 3503] chroot(".") = 0
[pid 3503] setregid32(10069, 10069) = 0
[pid 3503] setreuid32(10069, 10069) = 0

Which, without reading up on syscalls, I take to mean that it switches uid and gid.

I’m running selinux enforcing. Which you should be doing as well. That provides an alternative way to assure containment.

I spent a long time googling and trying to find a way to make that work nicely (ie: so your TFTP listener isn’t sitting there running as root) and I think it’s a non starter.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s