URI: 
       SSHD CONFIGURATION FOR FILE UPLOADS
       
       I want to test and debug a `sshd' configuration. My aim is to create
       some kind of configuration that restricts a user or key to one task:
       uploading files into a specific directory. This entry contains notes
       towards this objective. The first section sets out the steps for
       setting up an ad-hoc `sshd' process to test out arbitrary
       configurations. The second section covers my attempts and eventual
       success to meet my objective.
       
       
       Testing sshd configurations
       ----------------------------------------------------------------------
       Invoke ad-hoc sshd configuration
       ......................................................................
       I can test an arbitrary `sshd' configuration by invoking the program
       with a debug flag and a custom configuration file, specified as `-d'
       and `-f' respectively. The program must be invoked with elevated
       permissions. This is so it can read the system host keys (and maybe
       open a port?).
       
       `doas /usr/sbin/sshd -d -f new_sshd_config'
       
       It is necessary to invoke `sshd' with an absolute path. A
       StackOverflow post cites this part of the release notes for 3.9 as the
       reason:
       
       ,----
       | Make sshd(8) re-execute itself on accepting a new connection. This security measure ensures that all execute-time randomisations are reapplied for each connection rather than once, for the master process' lifetime. This includes mmap and malloc mappings, shared library addressing, shared library mapping order, ProPolice and StackGhost cookies on systems that support such things
       `----
       
       In otherwords, `sshd' needs to know exactly where it can re-execute
       itself.
       
       
       Temporarily allow new port through packet filter
       ......................................................................
       I want to temporarily punch a hole in the firewall to permit
       connections on the port associated with my ad-hoc `sshd'. If my
       `pf.conf' is using lists only, I could add a new rule line to the
       file. If my `pf.conf' is using tables, I can simply add a new IP to
       the table from the command line.
       
       
       Connect with ssh client
       ......................................................................
       Now from my client, I connect to the `sshd' process. Of course, I need
       to specify the port for this process using the `-p' flag.
       
       When login is successful, helpful debugging information is displayed.
       
       ,----
       | Environment:
       |   USER=roygbyte
       |   LOGNAME=roygbyte
       |   HOME=/home/roygbyte
       |   PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
       |   MAIL=/var/mail/roygbyte
       |   SHELL=/bin/ksh
       |   TERM=rxvt-256color
       |   SSH_TTY=/dev/ttypi
       `----
       
       Note that `-G' can be helpful for debugging client connections,
       too. This flag causes `ssh' to "print its configuration after
       evaluating Host and Match blocks and exiting."
       
       
       Small journey towards my objective
       ----------------------------------------------------------------------
       First, a note about the journey below: the knowledge gained and
       applied was largely gathered from the book Absolute OpenBSD by Michael
       W. Lucas.
       
       
       Restrictions via Match block?
       ......................................................................
       My initial assumption was that I could create and lock-down a user
       specifically for this task of uploading files. In effect, I could
       restrict the user with a `Match' block. The block would be declared to
       put the user inside a chroot, prohibit things like X11, and force a
       `rsync' command.
       
       I found this approach tedious. I needed to create the user and setup a
       home directory with all the `ssh' fixins. So I tried to take a
       shortcut, skipping the home directory setup and specifying the
       `AuthorizedKeysFile' option inside of the `Match' block to use a key
       contained within another user's home directory. This was a horrible
       idea, and I abandoned it when the web of permissions required to
       succeed overwhelmed me. I did however observe how and when `sshd'
       switches to the user it is authenticating during the authorized key
       lookup.
       
       
       Restrictions via key?
       ......................................................................
       My next thought was that I could modify an existing user's
       `authorized_keys' file. Perhaps I could add a key specifically for my
       file transfer operation, and restrict it from other operations with
       key arguments. Lo and below, this was a better way.
       
       I began by testing key argument I saw in Absolute OpenBSD:
       
       ,----
       |   restrict,command="internal-sftp -d public_gopher" <ssh key>
       `----
       
       I found I could  transfer files using programs like `sftp' and `scp', but not `rsync', which I want to use for its great features. That's probably no surprise. According to the authors of Wikipedia, `rsync' transfers files by connecting to a `rsync' process on the remote machine: "Upon connection [through a secure shell], a command is issued to start an rsync process on the remote host, which uses the connection thus established."
       
       I needed to revise the `command' argument to use `rsync', but I am not
       sure what that command should be. So I do some practical testing and
       debugging to find the value. Here's how.
       
       - On the server, I create a new `sshd' process with debugging
         enabled. This process uses a unique port, which must be permitted
         through the firewall and specified in any client connection attempts.
       
       - On the client, I create a new key pair, `id_rsync_operation' for this
         operation. It does not use a password. I transfer the public key to
         the server.
       
       - On the server, I add the key that will be used explicitly for rsync to
         the user's `authorized_keys' file. Then, I restrict and force the
         `rsync' command: `restrict,command'"rsync" <ssh-key>=. The forced
         command is too simple right now, I figured, but having it listed will
         let me gather some new information from the next step.
       
       - On the client, I modify my `ssh' `config' file and add a new `Match'
         block for a `host' that will be used exclusively for this file
         transfer operation. I use a bogus host, `sftp.roygbyte.com'. Later, in
         my `rsync' command, I will use that same host in the command's
         destination argument.
       
       ,----
       |   Match host sftp.roygbyte.com
       |   User roygbyte
       |   Hostname roygbyte.com
       |   Port <sshd process port>
       |   IdentitiesOnly yes # Ignore potential ssh-key-agent keys.
       |   IdentityFile ~/.ssh/id_rsync_operation
       `----
       
       - On the local machine, attempt an `rsync' transfer: `rsync -rt
         public_gopher/* roygbyte@sftp.roygbyte.com:public_gopher'. The
         operation will fail. That's OK. Environment information will be
         printed to the terminal anyways. And therein lies the true command I
         am after.
       
         ,----
         | > rsync -rt public_gopher/* roygbyte@sftp.roygbyte.com:public_gopher
         | Environment:
         |   USER=roygbyte
         |   LOGNAME=roygbyte
         |   ...
         |   SSH_ORIGINAL_COMMAND=rsync --server -r -t . public_gopher
         `----
       
       - Copy the value of `SSH_ORIGINAL_COMMAND' and use that as the value for
         `command' within `authorized_keys' on the server. In effect:
       
       ,----
       |   restrict,command="rsync --server -r -t . public_gopher" ssh-ed25518 <...>
       `----
       
       - Close the client connection and try the operation again. It should
         work. Now clean up the testing workflow and take a break.
       
       
       Postamble
       ----------------------------------------------------------------------
       So it works! I can transfer files from my client to my server using a
       key that has been sufficiently restricted. I'm quite pleased that I
       succeeded in this task. I'm not sure if this writting will be helpful
       for anyone but myself... but I am sharing it anyways. It feels good to
       cast off my experiences into the gophersphere. Happy burrowing!