\documentclass[10pt,letterpaper]{article}

% DESTDIR="adventures_in_networking"

\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\hypersetup{
colorlinks=true,
linkcolor=OliveGreen,
urlcolor=blue 
}
%\usepackage{gensymb}
\usepackage[usenames,dvipsnames]{color}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\newcommand{\degree}{$^{\circ}$\space}
\usepackage{graphicx}
\usepackage{float}
\usepackage{wrapfig}
\usepackage{color}
%\usepackage{xcolor}
\definecolor{sageIn}{rgb}{1,1,.95}
\definecolor{sageOut}{rgb}{.95,1,.95}
\definecolor{codeList}{rgb}{.95,.95,.95}
\usepackage{listings}
\usepackage{lmodern}
\lstset{language=Python}
\usepackage{endnotes}
\usepackage{enumitem}
\usepackage{mdframed}
\numberwithin{equation}{section}
\usepackage[margin=.75in]{geometry}
\newcommand\Hrule{\hrule\vspace{\baselineskip}}
\renewcommand\notesname{References}
%\let\footnote=\endnote
%\setlength{\parskip}{0.3\baselineskip}%

\newcommand\ParDivider{\vspace{.5\baselineskip}\centerline{\tiny \textbullet\hspace{2em}\textbullet\hspace{2em}\textbullet}\vspace{.5\baselineskip}}

\usepackage{perpage}
\MakePerPage{footnote}
\renewcommand{\thefootnote}{\fnsymbol{footnote}}

% the location of the target HTML and PDF output files

\newcommand{\dest}{/netbackup/data/Network/arachnoid/adventrures_in_networking}

\author{\href{http://arachnoid.com/administration}{Paul Lutus}\\
\href{http://arachnoid.com}{http://arachnoid.com}}
\title{Adventures in Networking}
\date{January 27, 2016 \linebreak \linebreak Most recent revision: \today}

\begin{document}

\maketitle

\begin{abstract}
\noindent\rule{.9\textwidth}{.1px}

This article is as much a personal reminiscence as an exposition on networking methods. It covers several decades of time and describes a progression from the ``sneakernet'' networking approach, moves through intermediate steps including my experiments in transoceanic radio networking, and finally describes some modern network management methods like Zeroconf.

\noindent\rule{.9\textwidth}{.1px}
\end{abstract}

\tableofcontents
\listoffigures
%\listoftables

\section{Networking Chronology}

\subsection{From None to Peer-to-Peer}

% [ht]

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{graphics/apple_ii_desk_view.png}
\caption{My first computer (1977)}
\label{fig:First Computer}
\end{figure}

Early in the history of electronic computing the mere existence of a computer was sufficiently extraordinary that any thought of connecting one computer to another was put aside. Years later, as the personal computer era began, I went through the same process on a smaller scale -- a stack of cassette tapes held the data generated by my one computer (see Figure \ref{fig:First Computer}), and the thought of having more than one computer was quite beyond imagining. I eventually acquired more computers, the machines needed to share data, but a cassette tape or a floppy disk and a short walk (a ``sneakernet''\endnote{\href{https://en.wikipedia.org/wiki/Sneakernet}{Sneakernet} -- A slang term describing physical transfer of data using portable storage media.}) seemed the obvious solution.

\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{graphics/network_image_1.jpg}
\caption{Simple Peer-to-Peer Network}
\label{fig:Simple Network}
\end{figure}

A few years later, after I had acquired more and better machines, machines able to generate too much data for the sneakernet, I created my first actual network -- a peer-to-peer scheme based on a serial cable that linked two machines by way of their RS-232\endnote{\href{https://en.wikipedia.org/wiki/RS-232}{RS-232} -- A widely used protocol for serial communications.} ports. The data transfer rate was very slow, but faster than the cassette tapes and floppy disks that preceded it.

Consider how this simple network functioned. Since there were only two machines, no name resolution was required, indeed the scheme simply extended the Unix stream/pipeline\endnote{\href{https://en.wikipedia.org/wiki/Pipeline_(Unix)}{Pipeline (Unix)} -- a simple but powerful way to communicate between processes.} idea, with a Unix socket at each end of the circuit. There were no sophisticated features -- I couldn't see the other machine's filesystem, instead I would set up a pipeline on one machine, then move to the other machine to complete the transfer. Very primitive.

\subsection{High Seas Network}

\begin{figure}[H]
\centering
\includegraphics[width=.7\textwidth]{graphics/UnderwayWingAndWing.jpg}
\caption{Solo ocean sailing}
\label{fig:Sailing}
\end{figure}

About this time I began one of my more ambitious personal adventures -- an around-the-world solo sail in a small sailboat. Even though I was deliberately getting away from it all, I was aware that the voyage would extend over several years, so I needed a way to communicate with the world.

After some experiments before the voyage began, I decided to use a method called ``packet radio''\endnote{\href{https://en.wikipedia.org/wiki/Packet_radio}{Packet radio} -- a peer-to-peer networking scheme that relies on a radio link.}, a peer-to-peer scheme that relies on a radio link, in my case ham radio\endnote{\href{https://en.wikipedia.org/wiki/Amateur_radio}{Amateur radio} -- a non-commercial hobby that involves transmitting as well as receiving radio messages.}.

For this network, the scheme included two computers running a messaging application I wrote for the occasion -- at each end, the user could sit and type a message, then put it in a queue for later transmission. The transmission took place when I next made radio contact from wherever I happened to be sailing\endnote{\href{http://arachnoid.com/sailbook}{Confessions of a Long-Distance sailor} -- my free sailing book.}.

Once I established radio contact, any queued messages were transferred bidirectionally, to be printed on paper at my house (so the people living there wouldn't need to know much about computers), or to be read from a display on my boat (to save precious paper while on the high seas).

\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{graphics/network_image_2.jpg}
\caption{High Seas Packet Radio Network}
\label{fig:PacketRadioNet}
\end{figure}

This network was a bit more complicated than the earlier peer-to-peer scheme. Instead of a cable connecting two machines a short distance apart, the computers were supported at each end by a packet modem, then a radio transceiver, then a lot of empty air.

This scheme worked reasonably well as long as I was on the same side of the planet as my house, but I eventually sailed so far that the radio link became unreliable. Some years later, having circled the globe, I sailed back to within several thousand miles of my home address and tried to reëstablish contact. The radio link was still working, but it seems the people at my house were no longer checking the message printer -- not surprising, since it had been several years since the most recent message had arrived.

So, aware I had no other way to make contact, I wrote a little program that repeatedly rang the computer's bell and printed an alert message on the monitor. I tested it on the boat, transmitted it across the packet network and activated it remotely. According to later reports, it sounded like a fire alarm in my quiet house. It alerted my friends that I was once again within range of the packet network.

I tell this story just because it's interesting, but also to justify my calling a ham radio packet link a network. Obviously if I can transfer an executable file from some distant place on the Pacific Ocean to my house in Oregon, then run it remotely ... it's a network.

\subsection{First Hub}

After my solo sail, and at about the time the Internet first appeared in people's lives, I set up a network with more than two nodes, so a hub was required to manage things. If memory serves that hub's cabling was coaxial, not multiconductor, so it was a serial-data scheme (not a parallel transmission of multiple bits, but a time sequence of individual bits), and by modern standards it was very slow. But it was my first network with a topology resembling the modern network paradigm -- a scheme that in principle could accommodate any number of machines.

I think that should provide enough history -- now we can discuss some networking specifics.

\section{Networking Methods}

In this section I'll discuss some of the problems that a multi-node network creates -- address assignment and resolution, things like that -- but in an informal way with an emphasis on problem solving. The narrative assumes a Linux platform.

\subsection{Fixed Addressing}

In my first networks that required each machine to have a unique address, I simply configured each machine with a static address, then populated each machine's \texttt{/etc/hosts} file with the assigned addresses, and made sure this line:

\texttt{hosts: files dns}

was present in \texttt{/etc/nsswitch.conf}, to assure that names were resolved by first consulting \texttt{/etc/hosts} before an online search was carried out. To expand a bit on this point -- for the two essential network configuration tasks:

\begin{itemize}
\item For address \textit{assignment}, I manually configured each machine's Network Interface Card (NIC) with a fixed address and netmask.
\item For address \textit{resolution} (and as shown above), I populated \texttt{/etc/hosts} file with a list of system names and assigned addresses, then used \texttt{/etc/nsswitch.conf} to direct the machine's name resolver to first consult \texttt{/etc/hosts}.
\end{itemize}

Remember this two-element process -- address \textit{assignment} and address \textit{resolution} -- because it plays a part in what follows.

The described scheme is the simplest way to assign unique network addresses and accomplish name resolution. But it doesn't scale well -- as the number of machines increases, and if the network configuration changes over time, it becomes confusing, labor-intensive and eventually unworkable. Each machine needs to be hand-configured, and each machine needs to have an up-to-date copy of the \texttt{/etc/hosts} file.

\subsection{DHCP}

\begin{figure}[H]
\centering
\includegraphics[width=.8\textwidth]{graphics/network_image_2a.jpg}
\caption{DHCP Address Resolution Scheme}
\label{fig:DHCP}
\end{figure}

The next step in sophistication, and the next step I took in my personal networks, was Dynamic Host Configuration Protocol or DHCP\endnote{\href{https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol}{Dynamic Host Configuration Protocol (DHCP)} -- a scheme to automate network address assignment.}. In the DHCP scheme, instead of requiring that someone manually configure a static address for each networked machine, this sequence is automatically carried out:

\begin{itemize}
\item A client machine broadcasts a \textit{discovery} request on the local network (in this context ``broadcast'' means to no particular destination, and ``discovery'' means to find out whether there is a DHCP server available).
\item Assuming there is a DHCP server available, it broadcasts a reply containing its own address and an \textit{offer} of a particular client address.
\item The client then typically responds on the server's address with a \textit{request} for the offered client address.
\item The server \textit{acknowledges} the request and the offered address is assigned to the client.
\item The assigned address typically has a time limit, after which the above process is repeated. This allows the DHCP server to reclaim addresses from machines that have gone offline, and for other reasons.
\end{itemize}

A drawback to DHCP in its basic form is that, even though each participating machine gets an address by which to communicate with the local network and other networks, without additional information the local machines can't communicate with each other. In the default DHCP configuration there's no provision to resolve local network names -- each machine is given an address that isn't provided to the other machines, and the addresses typically change every two hours.

So, to summarize this level of networking, its primary advantage is there's no requirement to manually assign addresses or edit the content of \texttt{/etc/hosts} every time the network topology changes, but the drawback is that, even though the client machines can communicate with local and distant networks, without additional information they can't communicate with each other.

Because my machines need to communicate with each other, I required more than DHCP can offer by itself.

\subsection{DHCP Address Reservation}

DHCP address reservation is a scheme in which the DHCP server is provided with a table of Media Access Control (MAC)\endnote{\href{https://en.wikipedia.org/wiki/MAC_address}{MAC address} -- a unique address provided to each network-capable peripheral device.} addresses and corresponding IP addresses, so when the server receives a request, it hands out the IP address that specific device has been assigned in the table.

This scheme is slightly better than static address assignment, because it doesn't require the network administrator to manually configure each machine's network interface -- instead, the administrator maintains two lists:

\begin{itemize}
\item A cross-reference list containing each machine's MAC address along with an associated IP address, and provided to the DHCP address reservation scheme.
\item An up-to-date \texttt{/etc/hosts} file, shared among all the machines, containing machine names and DCHP reserved addresses.
\end{itemize}

Over the years I've owned a number of wireless routers that I was able to configure with DHCP reservations (for which each manufacturer seems to have a different name\endnote{\href{https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol\#Overview}{DHCP : Overview} -- a bit about DHCP address reservation.}), but I continued to search for a better scheme, more intelligent and flexible, maybe one that would work with devices that couldn't be instructed by means of an \texttt{/etc/hosts} file, like Android devices.

\subsection{Samba}

This is somewhat of a digression, since I didn't end up using the Samba\endnote{\href{https://www.samba.org/}{Samba} -- an open-source embodiment of Microsoft's Server Message Block (SMB) network management method.} scheme. Samba is an open-source embodiment of Microsoft's Server Message Block (SMB)\endnote{\href{https://en.wikipedia.org/wiki/Server_Message_Block}{Server Message Block (SMB)} -- Microsoft's network management method.} network management method. Samba is installed by default on most modern Linux distributions, and once configured and enabled, it allows machines running both Linux and Windows to find each other by host name.

Unfortunately Samba's resemblance to a real name resolution/network services scheme is slight -- it's not very well integrated into the Linux command set. One can access local machines by way of some utility programs like smbclient, but unlike more robust network protocols, you're obliged to use an unnatural and temporary environment to list directories and transfer files (not unlike ftp, which requires one to enter a special, limited command environment).

To summarize, Samba possesses many of the same undesirable traits as Windows -- no file and directory case sensitivity, a primitive file date/time and permissions scheme, no symbolic links, and others. It just wasn't suitable for one of my primary network tasks: synchronizing two directory trees so they're identical -- same files, same dates and times, same permissions. Samba/SMB is an interesting way to build a bridge between Linux and Windows machines, but it can only do this by adopting most of the undesirable traits for which Windows is famous.

\section{Practical Solutions}

The prior section described some methods that didn't work for me, or that worked poorly, or that were too labor-intensive for a large network. This section describes some that work well and are in current use. Two issues are covered:

\begin{itemize}
\item Automatic address assignment and management, and name-to-address mapping.
\item Network interactions including communications and file transfers.
\end{itemize}

\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{graphics/network_image_3.jpg}
\caption{Modern Local Network}
\label{fig:LocalNetwork}
\end{figure}



\subsection{Zeroconf}

Zeroconf\endnote{\href{https://en.wikipedia.org/wiki/Zero-configuration_networking}{Zero-configuration networking (Zeroconf)} --a scheme to automatically configure a network.} is a relatively new, clever scheme that provides local network name resolution and service/resource advertising with no manual configuration required, hence its name.

In the Zeroconf scheme, a DHCP server still assigns IP addresses, but once assigned an address, each machine uses the Zeroconf protocol to broadcast essential information to, and acquire information from, other machines, and there is no central Zeroconf server. Within a short time each machine on the local network acquires current information about machines and peripherals, their IP addresses, and what services and resources they offer.

The basic Zeroconf assumption is that the network will change over time. As machines enter and leave the network, as peripherals are attached and removed, and as the DHCP server periodically assigns new IP addresses, the shared Zeroconf information about services and resources is automatically brought up to date.

That's the good news. The bad news:

\begin{itemize}
\item Because Zeroconf's purpose is to maintain accurate and timely network state, participating machines broadcast an update any time they experience a change. This creates a lot of local network traffic.
\item Zeroconf network configuration is based on trust, not verification, and local-network spoofing is easy and an obvious threat. This means:
\begin{itemize}
\item The scope of the Zeroconf protocol should be limited to local, implicitly trusted networks.
\item Those who acquire Zeroconf information should use secure protocols when they apply it -- in other words, don't assume Zeroconf is reliable in the way that Secure Shell is.
\end{itemize}
\item Synchronization: there are times when a machine goes offline or its configuration or IP address has changed, but the Zeroconf shared state isn't updated in a timely way for all participating machines. In fairness, this is a problem common to all automatic service/resource discovery schemes.
\end{itemize}

In the Zeroconf scheme, a DHCP server still provides addresses and routing information, but most other network information is managed by Zeroconf.

\subsubsection{Zeroconf on Android}

On my local network, nearly all network-capable devices support Zeroconf, with the conspicuous exception of Android devices -- unless they're equipped with a Zeroconf-capable application. Well, as it happens, I know of an Android application that provides Zeroconf information to the local network. I know this because I wrote it. Recent versions of my free program SSHelper\endnote{\label{SSHelper}\href{https://play.google.com/store/apps/details?id=com.arachnoid.sshelper&hl=en}{SSHelper} -- my free Android application that provides Zeroconf services.} provide Zeroconf broadcasts of device name, IP address, and available services like the Secure Shell protocol.

\subsubsection{SSHelper}

This is a digression, mostly about a recently-corrected bug in SSHelper. I recently replaced my wireless routers, but the new routers, notwithstanding their many advantages over the old, don't have an easy way to write a DHCP reservation table. Until this equipment update I had been solving the name resolution problem by generating a reservation table of about 30 MAC and IP addresses for the various devices on my network and writing it directly to the old routers, without any fuss or hand entries. The new routers don't have this ability, but rather than abandon either the routers or the desire to have automatic name resolution, I decided to move to a complete reliance on Zeroconf for the first time. (Until now I had regarded Zeroconf as a nice protocol, but not essential.)

To prepare for this change, I updated all my (Debian-based) Linux machines with Zeroconf-capable software:

\begin{quote}
\texttt{\# apt-get install avahi-daemon avahi-utils avahi-dnsconfd avahi-discover libnss-mdns}
\end{quote}

As some of my readers may be aware, to resolve a name using Zeroconf (i.e. to distinguish a Zeroconf network name from one requiring DNS resolution), one simply appends ".local" to a network name: "ping hostname.local"\footnote{If desired, the ".local" domain name may be changed in \texttt{/etc/avahi/avahi-daemon.conf}}. I already had SSHelper installed on all my Android devices, so I began testing name resolution and service discovery on the local network. I quickly detected a problem -- even though my desktop and laptop machines worked perfectly with Zeroconf, my Android devices weren't updating the Zeroconf shared state with their current addresses, and they sometimes became inaccessible to the local network.

An examination of the output created by --

\begin{quote}
\texttt{\$ avahi-browse -a}
\end{quote}

-- showed why. Over a period of hours, each of my Android devices began to be listed multiple times with different IP addresses. After some investigation, I uncovered a bug in my SSHelper code that wasn't retiring old instances of the Zeroconf reporting/negotiation class. So I fixed that bug, recompiled and updated SSHelper and all is well (SSHelper versions 8.2 and newer have this error corrected).

\subsubsection{Zeroconf on Windows}

Windows is famous for avoiding advances in technology that aren't owned by Microsoft, but with respect to Zeroconf, it's possible to make it available, and the software is free. Here are the steps:

\begin{itemize}
\item Acquire the Bonjour Print Services installer\endnote{\label{Bonjour}\href{http://support.apple.com/downloads/DL999/en_US/BonjourPSSetup.exe)}{BonjourPSSetup.exe} -- Windows installation executable for Bonjour/Zeroconf.} from the Apple Support website\endnote{\href{https://support.apple.com/kb/DL999?viewlocale=en_US&locale=en_US}{Bonjour Print Services for Windows} -- Webpage that explains about Bonjour/Zeroconf on the Apple support site.}.
\item Either run the provided installer program as it is, or use the Windows utilities 7Zip\endnote{\href{http://www.7-zip.org/}{7-zip} -- a Windows compression/decompression utility.} or WinRAR\endnote{\href{http://www.rarlab.com/}{WinRAR} -- another Windows compression/decompression utility, but not free.} to extract and run \texttt{Bonjour64.msi} from within the Apple Printer Services installer program. The second option has the advantage that you may avoid installing some things you might not want.
\item Even though  the Apple Web page makes it sound as though you're only acquiring a way to find printers, the installed service is a full embodiment of Bonjour/Zeroconf, and in a mixed Windows/Linux/Android\footnote{With SSHelper installed.} local network as shown in Figure \ref{fig:LocalNetwork}, all the machines should be able to communicate with each other. 
\end{itemize}

\subsection{Secure Shell}

The above section describes my present method to assign and resolve IP addresses, but there's still the issue of communications and file transfers between machines. For this I rely primarily on the various embodiments of the Secure Shell\endnote{\href{https://en.wikipedia.org/wiki/Secure_Shell}{Secure Shell (SSH)} -- a reliable and very secure communications protocol in wide use.} protocol.

For file transfers there are alternatives on the Linux platform, like Samba and the Network File System (NFS)\endnote{\href{https://en.wikipedia.org/wiki/Network_File_System}{Network File System (NFS)} -- a network file management and transfer protocol.}, and for communications there are telnet and others, but over a period of years experience has taught me that the available Secure Shell clients (\texttt{rsync, ssh, scp, sftp}) are faster, more secure and more reliable than the alternatives.

\subsubsection{SSH Tutorial}

I can't resist adding a short tutorial on one of my favorite subjects, one that causes much confusion for those configuring SSH on Linux systems.

First, to make sure you have the required Secure Shell elements:
\begin{quote}
\texttt{\# apt-get install openssh-server openssh-client rsync}
\end{quote}

In modern Linux distributions it's very likely these programs are already in place, and the above command may only serve to confirm this.

Here's a typical Secure Shell setup procedure:
\begin{itemize}
\item Generate one or more SSH keys, essential to the Secure Shell security scheme:
\begin{itemize}
\item First, check to see if a key has already been generated:
 \begin{quote}
 \texttt{\$ ls $\sim$/.ssh/*.pub}
 \end{quote}
\item If a suitable key is not yet present, generate one:
 \begin{quote}
 \texttt{\$ ssh-keygen -t rsa -N '' -f $\sim$/.ssh/id\_rsa}
 \end{quote}
 \item The above command generates two files, a private key file named \texttt{id\_rsa} and a public, shareable key file named \texttt{id\_rsa.pub}. \textit{Only share the public key}. And for more about the \texttt{ssh-keygen} arguments, read the man page\endnote{\href{http://linux.die.net/man/1/ssh-keygen}{ssh-keygen(1) - Linux man page} -- always a good idea to read the manual.}.
 
 \end{itemize}
 \item SSH logon problems very often result from wrong permissions for the user's .ssh directory or its contents. Here's an example of an .ssh directory with all permissions set correctly:
 \begin{quote}
 \begin{verbatim}
drwx------  2 username users   4096 Jan 17 13:46 .
drwxr-xr-x 43 username users   4096 Jan 21 15:54 ..
-rw-r--r--  1 username users  10912 Jan 21 09:26 authorized_keys
-rw-r--r--  1 username users  10912 Jan 21 09:26 authorized_keys2
-rw-r--r--  1 username users    917 Jan 17 14:13 config
-rw-------  1 username users    668 Jan 11 03:10 id_dsa
-rw-r--r--  1 username users    605 Jan 11 03:10 id_dsa.pub
-rw-------  1 username users    227 Jan 17 13:03 id_ecdsa
-rw-r--r--  1 username users    177 Jan 17 13:03 id_ecdsa.pub
-rw-------  1 username users    411 Jan 17 13:46 id_ed25519
-rw-r--r--  1 username users     97 Jan 17 13:46 id_ed25519.pub
-rw-------  1 username users   1675 Jan 17 13:03 id_rsa
-rw-r--r--  1 username users    397 Jan 17 13:03 id_rsa.pub
-rw-r--r--  1 username users   7896 Jan 21 09:30 known_hosts
 \end{verbatim}
 \end{quote}
 \begin{itemize}
 \item In summary, private key files and the \texttt{.ssh} directory should only be readable/writable by the directory's owner, other files should be publicly readable and only writable by their owner.
 \item If the permissions on your \texttt{.ssh} directory and/or its files aren't the same as shown above, this may be the reason for failed logons and other problems. 
 \item The above example also shows a variety of generated keys. These keys are generated by changing the \texttt{-t} argument to \texttt{ssh-keygen} -- valid arguments are \texttt{rsa}, \texttt{ecdsa}, and \texttt{ed25519}. An older key type, \texttt{dsa}, is deprecated and is to be abandoned\endnote{\href{https://www.gentoo.org/support/news-items/2015-08-13-openssh-weak-keys.html}{OpenSSH 7.0 disables ssh-dss keys by default} -- an online notice that ``dsa'' keys are being abandoned.}.
 \end{itemize}
 \item To analyze SSH logon problems, use the \texttt{-v} (verbose) command-line option. More repetitions of \texttt{-v} provide more detail:
 \begin{quote}
 \texttt{\$ ssh -vvv user@hostname}
 \end{quote}
 \item To allow passwordless logons, share your public key with the target system like this:
 \begin{itemize}
 \item The simplest, default method:
 
 \begin{quote}
 \texttt{ssh-copy-id username@hostname}
 \end{quote}
 \item The above command copies the public key component of the default identity key (which at the time of writing is $\sim$/.ssh/id\_rsa.pub) and adds it to the target system's $\sim$/.ssh/authorized\_keys file. To copy a key other than the default identity key:
 
 \begin{quote}
 \texttt{ssh-copy-id -i /path/to/identity\_file.pub username@hostname}
 \end{quote}
 
 \item Once this step has been taken, and assuming the right key has been copied to the right location on the target system, it will no longer be necessary to enter a password to gain access.
 \end{itemize}
 \item When the above procedure is complete, SSH utilities like \texttt{rsync}, \texttt{sftp} and \texttt{scp} will function without requiring the entry of a password for each transaction.
\end{itemize}

\subsection{Summary}

My present network setup, described above, is much more robust and requires much less babysitting than in years past. The Zeroconf protocol almost completely eliminates the effort required for static addressing and/or DHCP address reservation.

Online discussions of this approach sometimes make the point that Zeronconf doesn't scale well and isn't secure, and these appear to be legitimate criticisms. But for a small local network, this approach greatly simplifies life compared to its alternatives.

To summarize, Zeroconf has ended my earlier practice of detecting MAC addresses of newly acquired systems and peripherals, adding the MACs to a cross-reference list of MACs and statically assigned IP addresses, writing the list to my routers for DHCP address reservation and disseminating an updated \texttt{/etc/hosts} list to each system for name resolution. Instead, I only need to find out whether devices I acquire support Zeroconf. If they do, problem solved -- I can simply attach the device to my network and it will auto-negotiate with DHCP and other Zeroconf-enabled devices on my LAN, and such devices become accessible in seconds. In the event that Zeroconf isn't available in a new device:

\begin{itemize}
\item Linux desktops and laptops either support Zeroconf by default or they can be set up in seconds:

 
 \texttt{\# apt-get install avahi-daemon avahi-utils avahi-dnsconfd avahi-discover libnss-mdns}
 
\item As explained above, Windows systems need only run the free executable \texttt{Bonjour64.msi} that's included with Apple's ``Bonjour Print Services for Windows'' installer\textsuperscript{\ref{Bonjour}}.
\item Android devices can run my free application SSHelper\textsuperscript{\ref{SSHelper}}, which includes a Zeroconf server.
\item Most of the new tiny computers like the Raspberry Pi\endnote{\href{https://www.raspberrypi.org/}{Raspberry Pi} -- a hugely popular tiny computer running Linux.} support Zeroconf out of the box, and if not, they can be easily configured.
\end{itemize}

For the few devices that don't support Zeroconf and that can't be programmed to support it, I assign static addresses and include them in \texttt{/etc/hosts}. And for such devices, I wait for the day they'll be updated with Zeroconf capability, so they can be removed from the \texttt{/etc/hosts} ``dunce cap'' list.\footnote{My personal goal is to have an \texttt{/etc/hosts} file consisting entirely of ``\texttt{127.0.0.1 localhost.localdomain localhost}''}.

There's one more exception to a pure Zeroconf network. Any port forwards through my routers from the wide area network to the local one must be routed by way of a static local-network port and address, so the target machine must have a static (or DHCP reserved) address. This issue would be solved if my routers supported Zeroconf, but they don't (and there's no OpenWrt\endnote{\href{https://openwrt.org/}{OpenWrt} -- A Linux distribution designed for wireless routers.} version available for them, another option that's sometimes available).

Notwithstanding these small wrinkles, the Zeroconf scheme represents a huge improvement in robustness and simplicity over what came before. You might even say that a Zeroconf-enabled network exhibits a tiny bit of native intelligence.

Thanks for reading!

\theendnotes
\end{document}
