Followed the info at http://grimwell.wikispaces.com/tftpd, paying particular attention to "rinse and repeat" in order to get the selinux policies in place. After a few attempts it all started working - uploading, and creation of new files.

In short:

  • make sure you have audit installed in centos otherwise SELinux may not log anything!
  • make sure your xinetd.d/tftpd has -c -v -s /tftpboot in the server args line
  • make sure that the directory tftp will be writing to has 777 permissions
  • do a tftp localhost and try to put a file in the directory
  • touch a file in the directoy, chmod 666 it, and then via tftp localhost, try and overwrite the file
  • do grep tftp /var/log/audit/audit.log | audit2allow -m tftpwrite to create a selinux policy. Make sure that the policy includes write and create lines. If not, try writing and creating again to generate alerts in the audit log and try again.
  • create an installable policy using grep tftp /var/log/audit/audit.log | audit2allow -M tftpwrite then install it using semodule -i tftpwrite.pp
  • service xinetd reload and try using tftp.

Splendid. Hope others find this useful!


I found another, better solution to this problem. I couldn't believe that the people who wrote the selinux policy files didn't think that people would need tftp uploads so I did some digging. I couldn't find anything on the internet that isn't already referenced here but by searching the selinux policy I was able to find another security context already on the system for tftp writes. Changing the context of /tftpboot fixed the problem.

# sesearch -a | grep tftpdir  |grep tftpd_
   allow tftpd_t tftpdir_t : file { read getattr }; 
   allow tftpd_t tftpdir_t : dir { read getattr search }; 
   allow tftpd_t tftpdir_t : lnk_file { read getattr }; 
   allow tftpd_t tftpdir_rw_t : file { ioctl read write create getattr setattr lock append unlink link rename }; 
   allow tftpd_t tftpdir_rw_t : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir }; 
   allow tftpd_t tftpdir_rw_t : lnk_file { read create getattr setattr unlink link rename }; 
# ls -Z /tftpboot/ -a
drwxrwxrwx  root root system_u:object_r:tftpdir_t      .
drwxr-xr-x  root root system_u:object_r:root_t         ..
# chcon -t tftpdir_rw_t /tftpboot
# ls -Z /tftpboot/ -a
drwxrwxrwx  root root system_u:object_r:tftpdir_rw_t   .
drwxr-xr-x  root root system_u:object_r:root_t         ..

Are you starting tftpd with the -s option? Some clients may be expecting this, e.g. uploading a file called foo to /foo is really intended for /tftpboot/foo on the server. Adding -s /tftpboot essentially tells the server to do a "chroot" to that directory.

Try running tftpd manually, e.g. not via xinetd, and see what the output is. You can also try running it with strace to see exactly which files it is attempting to open and which systems calls it is making.

Double check /etc/hosts.allow and /etc/hosts.deny to make sure traffic is being allowed into the server.

With respect to SELinux, depending on how your system is configured it may be logging to /var/log/audit/audit.log if you have enabled auditd. See section 5 of this page.