Setting up a TFTP server in Debian/Ubuntu

I’ve needed to setup a TFTP server for various reasons in the past. Most recently, I needed it in order to upload files (OS images, VPN clients, etc.) to Cisco routers, switches and ASA Firewalls. So this blog is for the sole purpose of setting up a TFTP server.

I need to stress and emphasis the security issues that TFTP servers have. There is no logon credentials, the protocol is all in plain text, and there is no file security for any files supplied by the TFTP server. So make sure that you are only putting files on this server that are considered “compromisable”. If you’re going to be backing up files on this server (running configs, especially), then you should do everything in your power to limit access to this machine by use of firewall rules. For large networks, I would recommend using a product like CatTools.

Alright, so lets see here. First off you’re going to need to install some software.

steve @ steve-G75VX ~ :) ##   sudo apt-get update
[sudo] password for steve:
Fetched 916 kB in 8s (112 kB/s)                                                                                                                                                                                                            
Reading package lists... Done
steve @ steve-G75VX ~ :) ##   sudo apt-get install xinetd tftpd tftp
Reading package lists... Done
Building dependency tree      
Reading state information... Done
xinetd is already the newest version.
tftp is already the newest version.
tftpd is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 38 not upgraded.
steve @ steve-G75VX ~ :) ##

Now that we have our software installed, we need to configure our TFTP daemon to run.

Start by creating a new file and paste in this info:

steve @ steve-G75VX ~ :) ##   sudo nano /etc/xinetd.d/tftp
service tftp
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = nobody
server          = /usr/sbin/in.tftpd
server_args     = /tftp
disable         = no
steve @ steve-G75VX ~ :) ##

Things to remember here are that you’re specifying the default port of 69/udp and that the user “nobody” is going to be the user of the files.

Now that we have that done, we can create our directory and set permissions:

steve @ steve-G75VX ~ :) ##   sudo mkdir /tftp
steve @ steve-G75VX ~ :) ##   sudo chmod -R 777 /tftp
steve @ steve-G75VX ~ :) ##   sudo chown -R nobody /tftp

All that’s left is that we need to start the service!

steve @ steve-G75VX ~ :) ##   sudo service xinetd restart


steve @ steve-G75VX ~ :) ##   sudo /etc/init.d/xinetd restart

Just test to make sure that the service is running:

steve @ steve-G75VX ~ :) ##   ps aux | grep xinet
root      7049  0.0  0.0  15024   456 ?        Ss   Oct22   0:00 /usr/sbin/xinetd -pidfile /run/ -stayalive -inetd_compat -inetd_ipv6
steve    16301  0.0  0.0  15188  1984 pts/3    S+   17:25   0:00 grep --color=auto xinet
steve @ steve-G75VX ~ :) ##  
steve @ steve-G75VX ~ :) ##   ports | grep 69
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
udp        0      0    *                           -              
steve @ steve-G75VX ~ :) ##

And we’re done!

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Debian Backups, the Command Line Way…

I’ve been wanting to write a blog on this for a long time since I’ve actually had this backup method running in my environment for years. It’s super easy to setup and, while thank god I’ve never had to recover from a backup, I have been able to go back and recover individual files from my backups. What you’ll need from an environment setup is at least one Linux box that you need backed up, and at least one NAS or other file storage server that has an SSH server. I perform all my backups to online disk storage that is based on FreeNAS. There are plenty of NAS environment, and I’m not saying FreeNAS is the best or the worst, but I like it and it works for me. It works extremely well with Linux, Windows and Mac OS X.

There are two parts to this:

  • 1. manual backups
  • 2. automated backups

  • Let’s start with the manual backups, because once we have the manual backups performed, then we can easily turn that into a script and run it in CRON.

    First, we need to specify the directories we don’t want to backup in a file that is accessible to root. Let’s list the directories in “/” first.

    steve @ steve-G75VX ~ :) ##   ll /
    total 18M
    drwxr-xr-x  25 root   root 4.0K Oct 22 14:54 ./
    drwxr-xr-x  25 root   root 4.0K Oct 22 14:54 ../
    drwxr-xr-x   2 root   root 4.0K Aug 14 02:03 bin/
    drwxr-xr-x   4 root   root 3.0K Oct  3 11:39 boot/
    drwxrwxr-x   2 root   root 4.0K May 21 11:52 cdrom/
    -rw-------   1 root   root  18M Oct  3 11:40 core
    drwxr-xr-x  24 root   root 4.8K Oct 31 12:38 dev/
    drwxr-xr-x 148 root   root  12K Oct 27 20:37 etc/
    drwxr-xr-x   3 root   root 4.0K May 21 11:53 home/
    lrwxrwxrwx   1 root   root   33 Aug 14 02:06 initrd.img -> boot/initrd.img-3.19.0-25-generic
    lrwxrwxrwx   1 root   root   33 Jul 10 08:56 initrd.img.old -> boot/initrd.img-3.19.0-22-generic
    drwxr-xr-x  26 root   root 4.0K Oct 13 13:41 lib/
    drwxr-xr-x   2 root   root 4.0K May 21 12:41 lib32/
    drwxr-xr-x   2 root   root 4.0K Apr 22  2015 lib64/
    drwx------   2 root   root  16K May 21 11:47 lost+found/
    drwxr-xr-x   3 root   root 4.0K May 21 12:01 media/
    drwxr-xr-x   2 root   root 4.0K Apr 17  2015 mnt/
    drwxr-xr-x   6 root   root 4.0K Oct 20 11:28 opt/
    dr-xr-xr-x 283 root   root    0 Oct 21 20:30 proc/
    drwx------   4 root   root 4.0K Oct 27 16:57 root/
    drwxr-xr-x  30 root   root 1.1K Oct 27 20:50 run/
    drwxr-xr-x   2 root   root  12K Aug 14 02:03 sbin/
    drwxr-xr-x   2 root   root 4.0K Apr 22  2015 srv/
    dr-xr-xr-x  13 root   root    0 Oct 22 14:55 sys/
    drwxrwxrwx   2 nobody root 4.0K Oct 22 17:55 tftp/
    drwxrwxrwt  18 root   root 4.0K Nov  1 15:17 tmp/
    drwxr-xr-x  11 root   root 4.0K May 21 12:41 usr/
    drwxr-xr-x  13 root   root 4.0K Apr 22  2015 var/
    lrwxrwxrwx   1 root   root   30 Aug 14 02:06 vmlinuz -> boot/vmlinuz-3.19.0-25-generic
    lrwxrwxrwx   1 root   root   30 Jul 10 08:56 vmlinuz.old -> boot/vmlinuz-3.19.0-22-generic

    So, based on this, we’ll exclude like this:

    steve @ steve-G75VX ~ :) ##   sudo mkdir /backups
    [sudo] password for steve:
    steve @ steve-G75VX ~ :) ##   sudo touch /backups/exclude.list
    steve @ steve-G75VX ~ :) ##   sudo nano /backups/exclude.list
    steve @ steve-G75VX ~ :) ##  


    (Ctrl+x to quit, then y to save)

    Now that we have our directory and exclude list setup, now we need to make sure RSYNC is installed on our system.

    steve @ steve-G75VX ~ :) ##   sudo apt-get update
    Fetched 1,743 kB in 21s (79.7 kB/s)
    Reading package lists... Done
    steve @ steve-G75VX ~ :) ##   sudo apt-get install rsync
    Reading package lists... Done
    Building dependency tree      
    Reading state information... Done
    rsync is already the newest version.
    0 upgraded, 0 newly installed, 0 to remove and 38 not upgraded.
    steve @ steve-G75VX ~ :) ##

    Now that we have RSYNC installed and our backup exclusions defined, lets get our backups started.

    First, edit your .bashrc file in your home directory and add this line:

    alias backupall='sudo rsync -athvz --delete / steve@

    “What does all this do?” you might ask… well, it’s quite simple really.

    First, we create an alias for your shell named, “backupall”, because we’ll be performing full system backups from here.

    Next, we call “rsync” to run as root, and ask it to run with the switches -a, -t, -h, -v and -z.

  • -a = run in archive mode, which equals -rlptgoD (no -H,-A,-X)
  • -t = makes sure to preserve modification times on your files
  • -h = ensures that output numbers in a human-readable format
  • -v = trun verbosely.
  • -z = makes sure that file data is compressed during the transfer
  • And lastly, the “–delete” means, “This tells rsync to delete extraneous files from the receiving side (ones that aren’t on the sending side), but only for the directories that are being synchronized. You must have asked rsync to send the whole directory (e.g. lqdirrq or lqdir/rq) without using a wildcard for the directory’s contents (e.g. lqdir/*rq) since the wildcard is expanded by the shell and rsync thus gets a request to transfer individual files, not the files’ parent directory. Files that are excluded from the transfer are also excluded from being deleted unless you use the –delete-excluded option or mark the rules as only matching on the sending side (see the include/exclude modifiers in the FILTER RULES section).” —

    Next is the “/”, which means we’re backing up everything in “/”, which is everything.

    Lastly, we’re specifying the destination. In this case, we’re doing RSYNC over SSH, so we’ll be specifying a location in the way that you would specify a destination in SCP.

    Now test running your backup. I’ve run mine before, so my update is pretty quick. But this is going to backup your whole system for, so expect it to take a while.

    steve @ steve-G75VX ~ :( ᛤ>   backupallnas
    steve@'s password:
    sending incremental file list

    sent 1.09M bytes  received 50.77K bytes  58.56K bytes/sec
    total size is 1.91G  speedup is 1673.17
    rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.9]
    steve @ steve-G75VX ~ :( ᛤ>

    Now we need to create our script, and make it executable.

    root @ steve-G75VX ~ :) ##   nano /backups/backupall
    root @ steve-G75VX ~ :) ##   chmod +x /backups/backupall
    root @ steve-G75VX ~ :) ##   ll /backups/backupall
    -rwxr-xr-x 1 root root 96 Nov  1 17:02 /backups/backupall*
    root @ steve-G75VX ~ :) ##

    I added this one line to the backup file:

    sudo rsync -athvz --delete / steve@

    This looks pretty good! Now that we have a full backup of our machine, lets get this setup in CRON.

    steve @ steve-G75VX ~ :) ##   sudo su
    root @ steve-G75VX ~ :) ##   crontab -l
    no crontab for root
    root @ steve-G75VX ~ :( ##   crontab -e
    no crontab for root - using an empty one

    Select an editor.  To change later, run 'select-editor'.
      1. /bin/ed
      2. /bin/nano        <---- easiest
      3. /usr/bin/vim.tiny

    Choose 1-3 [2]: 2
    crontab: installing new crontab
    root @ steve-G75VX ~ :) ##

    The line that I added to CRON was this:

    0 3 * * * /backups/backupall >/dev/null 2&>1

    This basically states that every day at 3am, this script will be run.

    From here we need to make sure our local system can perform password-less logon to the SSH server. To do that we’ll be working off of a prior blog I wrote on SSH Keys, here: Using SSH Keys to simplify logins to remote systems.

    You’ll want to test that your system can SSH to your remote system without entering a password. As long as that works, we’re good to go!

    That’s it! It’s that simple!

    I have run into issues on some machines where SSH keys don’t work. I haven’t had the time to troubleshoot why, so I got a different way to figure out how to make backups work, without using SSH keys. The down side is that this is MUCH less secure, and I really don’t recommend running this in a production setting. But for home or non-business use, you’re probably just fine.

    So to do this, we’re going to use “SSHPASS” package. It’s out there for Debian and Ubuntu, so I’m sure it’s out there for other Linux/Unix systems as well.

    root @ steve-G75VX ~ :) ##   sudo apt-get install sshpass
    Reading package lists... Done
    Building dependency tree      
    Reading state information... Done
    The following NEW packages will be installed:
    0 upgraded, 1 newly installed, 0 to remove and 38 not upgraded.
    Need to get 10.5 kB of archives.
    After this operation, 56.3 kB of additional disk space will be used.
    Get:1 vivid/universe sshpass amd64 1.05-1 [10.5 kB]
    Fetched 10.5 kB in 0s (65.3 kB/s)  
    Selecting previously unselected package sshpass.
    (Reading database ... 258807 files and directories currently installed.)
    Preparing to unpack .../sshpass_1.05-1_amd64.deb ...
    Unpacking sshpass (1.05-1) ...
    Processing triggers for man-db ( ...
    Setting up sshpass (1.05-1) ...
    root @ steve-G75VX ~ :) ##

    Go ahead and test logging into your NAS box, or any box really, with this. The idea is that, when you’re scripting you need to logon to remote systems without a password. If you can’t use SSH keys, then this is your next best bet. Create a file in “root’s” home dir and name it whatever you want. I named mine, “backup.dat”. It must contain only the password you use to log into your remote machine, on one line, all by itself.

    root @ steve-G75VX ~ :) ##   nano ~/backup.dat
    root @ steve-G75VX ~ :) ##   chmod 600 backup.dat

    You’ll call “sshpass”, -f for the file with the password, the location of your “ssh” program, -p and the port number (default port for ssh is 22), followed by the username you login with (make sure it’s in the format of, “user@machine-ip”).

    root @ steve-G75VX ~ :) ##   sshpass -f /root/backup.dat /usr/bin/ssh -p 22 steve@
    Last login: Sun Nov  1 17:22:08 2015 from
    FreeBSD 9.2-RELEASE (FREENAS.amd64) #0 r+2315ea3: Fri Dec 20 12:48:50 PST 2013

        FreeNAS (c) 2009-2013, The FreeNAS Development Team
        All rights reserved.
        FreeNAS is released under the modified BSD license.

        For more information, documentation, help or support, go here:
    Welcome to FreeNAS
    [steve@freenas ~]$ exit
    Connection to closed.
    root @ steve-G75VX ~ :) ##

    Okay, now that we’ve tested this and know it’s working, lets modify our script here and get this working with “sshpass”.

    root @ steve-G75VX ~ :) ##   /usr/bin/rsync -athvz --delete --rsh="/usr/bin/sshpass -f /root/backup.dat ssh -o StrictHostKeyChecking=no -l YourUserN@me" /home/steve steve@

    Now test to make sure the script is working (as soon as you see the incremental file list being sent, you know it’s working properly):

    root @ steve-G75VX ~ :) ##   /usr/bin/rsync -athvz --delete --rsh="/usr/bin/sshpass -f /root/backup.dat ssh -o StrictHostKeyChecking=no -l steve" /home/steve steve@
    sending incremental file list
    ^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(632) [sender=3.1.1]
    root @ steve-G75VX ~ :) ##
    root @ steve-G75VX ~ :) ##
    root @ steve-G75VX ~ :) ##   /backups/backupall
    sending incremental file list
    ^Crsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(632) [sender=3.1.1]
    root @ steve-G75VX ~ :( ##


    VN:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VN:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

    Linux Stuff: How to setup SSH certificates to simplify logins to remote systems

    SSH and Server Certificates

    If you haven’t done this yet, we’re going to make life easy and get the SSH Certificates setup to make it super easy to SSH from our Linux Desktop.


    You’ll want to make sure to install SSH Server and client on both the machines you’re planning on configuring. Most of the time this is done already.

    Debian Based machines:

    apt-get install ssh openssh-server openssh-client


    Red Hat Based machines:

    yum install ssh openssh-server openssh-client


    When that’s done test out connecting from your local machine to your remote host using:

    ssh steve@
    The authenticity of host ' (' can't be established.
    RSA key fingerprint is 69:23:4c:49:35:41:ca:ae:23:3f:69:63:b2:ba:12:3c.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '' (RSA) to the list of known hosts.
    user03@'s password:
    user03 @ newstudent ~ :) ᛤ>   pwd
    user03 @ newstudent ~ :) ᛤ>   exit
    Connection to closed.
    steve @ mintdebianvm ~ :) ᛤ>

    Now we can setup SSH keys on this system so that you can easily log in from your main Linux Desktop machine.


    So go to your home directory on your local machine (NOT THE REMOTE SYSTEM!) and your navigate to your home folder. From here CD into your .ssh directory and we’ll create your SSH Certificates. If your “.ssh” directory doesn’t exist, just make one! Same goes for your REMOTE system too! Make sure that exists or this won’t work!

    cd ~/.ssh/
    ssh-keygen -t rsa -b 2048
    {save as default file, press enter}        
    {enter your own password and hit enter}     <-- this can be blank
    {confirm your password}                     <-- this can be blank


    Once this is done we’ll setup your host with keys to stay authenticated

    cat ~/.ssh/ | ssh user03@ "cat - >> ~/.ssh/authorized_keys"


    Now edit your LOCAL “.ssh/config” file and add in your new server. If you don’t have one, again, just create one!

    Host 208              <-- make that whatever you want. Keep it simple and easy to remember!
    HostName      <-- IP of remote host
    User user03                 <-- Your username on the remote machine.


    And now you can test your new ssh keys by doing this:

    ssh 208


    You may need to adjust your permissions properly. To do so, simply run this command on your local system:

    chmod 700 ~/.ssh && chmod 600 ~/.ssh/*


    And this command on your remote system that you’re trying to connect to:

    chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh/


    Now you should be able to just log in without a password to any Remote system you set this up on!! 🙂

    ssh 208



    VN:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VN:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

    Open Source can save you millions: Part 1, the intro…

    After dealing with some vendors in the last couple years, I’ve come to realize one major tone keeps rearing it’s ugly head: Vendor sales people will tell you anything to get you to buy their product or service, regardless as to whether or not their product/service is the best solution at the best price out there.

    Now, wait just a minute. I’m not going to demonize salesmen or be some hippie tree hugger and say, “don’t buy commercial products, man!”. Some companies and products are pretty damn good. Some are definitely not. Some are ridiculously expensive; some are not. But How do you know which ones to actually spend money on, or not to spend money on, if your company, or personal outlook on life, is telling you to just listen to a vendor and buy his products? When was the last time you went to your grey beards and asked them if they have a solution to your problem?

    Well, I’m not a grey beard, but I am a big proponent of the “DIY” projects. I try to do things around my house all the time, and that includes my home network. I also carry that philosophy into work.

    This is a multi-part blog that is going to attempt to outline why I’d rather spend $100,000/yr on a Salary for a good worker than to spend that same amount on some appliance to install in the Data Center. Here we’ll be talking about replacing products from companies like CA, Centrify and others with some already built-in modules in your Linux/Unix environments that many people don’t even know they have. We’ll talk about that topic in the next blog though, because I really want to focus on the fact that good Security and IT products can be difficult to come by. And sometimes you have a solution to your problem inside your organization already, but don’t know it yet. Don’t automatically think that if there is a problem, your solution is to buy another product or service from your vendor supply chain. Stop throwing money at the solution hoping it will work out!

    Here’s what I started with. There is a large need to get all of our Linux/Unix environment to authenticate to Active Directory (AD). Just like the VAST majority of companies out there, we are largely a Microsoft shop. News Flash: Almost everyone is. And that’s because AD is the best at what it does; no one comes close. Same for Microsoft Exchange; I beg you to tell me who makes a product that comes anywhere close to what Exchange does. Regardless, we need to auth to AD from Linux/Unix, and the costs surrounding 3rd party vendors is ridiculous. Now I know people need to make money, but over $100 grand every couple years for software and support is insane to do such a simple task as this. I talked to a co-worker and he led me down the path of, “Why pay to do it when you can do it for, well, basically free?”

    Free is a relative term, right? I mean, “there is no such thing as a free lunch.” So you’re paying my salary, and the salary of a Linux/Unix admin, and whoever else, but weren’t you already paying those salaries? And How much does it cost your company to have a (most likely well paid) Linux/Unix admin sitting around all day doing account provisioning, password resets and setting up users to have the specific access they need? Shouldn’t your account provisioning team be doing that? The costs of that are pretty high. According to a Gartner study it could cost up to $600,000/yr just sitting there resetting passwords on 300 Linux/Unix systems. Now, that number is pretty high. They are basing that on $17/password reset X 300 servers X 30 accounts per server which is $153,000/yr times 4 times a year = $612 grand.

    Whether or not you’re doing that many password resets is irrelevant, and lets say a password reset costs $10 in time, and lets say you’re resetting 50 passwords a week. You’re still spending over $25,000/year on performing password resets! And that doesn’t even account for user account management, managing the rest of your server fleet, managing all the “passwd” and “shadow” files on those servers, etc… So in reality, are you going to spend $125 grand on a solution to save $25 grand? I don’t think so. But How about spending $0 to save $25 grand? 🙂

    So, at the end of the day, all I’m trying to convey here is that you need to rely on your employees. If you give them the tools to succeed, you allow them the latitude to innovate  and you treat your business like a small business, I promise you that you’ll get cost savings and better service.

    VN:F [1.9.22_1171]
    Rating: 5.0/5 (1 vote cast)
    VN:F [1.9.22_1171]
    Rating: +1 (from 1 vote)