From: Mark Wooding Date: Thu, 23 Apr 2015 14:57:33 +0000 (+0100) Subject: sshsvc-mkauthkeys: A new script joins the collection. X-Git-Tag: 1.4.0.1~3 X-Git-Url: https://git.distorted.org.uk/~mdw/misc/commitdiff_plain/b9ee4e831fd0ec859702eafdfec8fef4475eb028 sshsvc-mkauthkeys: A new script joins the collection. --- diff --git a/Makefile.am b/Makefile.am index 2e70051..c896216 100644 --- a/Makefile.am +++ b/Makefile.am @@ -181,6 +181,9 @@ hush.1: hush.1.in Makefile dist_bin_SCRIPTS += with-umask dist_man_MANS += with-umask.1 +dist_bin_SCRIPTS += sshsvc-mkauthkeys +dist_man_MANS += sshsvc-mkauthkeys.1 + ## bash scripts. if HAVE_BASH diff --git a/debian/control b/debian/control index e8f226e..fa05cca 100644 --- a/debian/control +++ b/debian/control @@ -29,7 +29,8 @@ Depends: space, getpass, hush, - with-umask + with-umask, + sshsvc-mkauthkeys Description: Dummy package for convenience. Package: mdwopt-perl @@ -167,3 +168,12 @@ Description: Run a command, hiding its output in a logfile unless it fails where you get spammed with uninteresting success reports. hush runs a command, logging its output, but, unless the command actually fails, it produces no output of its own. + +Package: sshsvc-mkauthkeys +Architecture: all +Section: utils +Description: Construct .ssh/authorized_keys files for SSH services. + SSH is a fine way to provide services to external users. It conveniently + takes care of details like authenticating users and encrypting + communications. Unfortunately, managing the key files is rather painful. + This simple script does a lot of the heavy lifting. diff --git a/debian/inst b/debian/inst index 5e26960..7a46492 100644 --- a/debian/inst +++ b/debian/inst @@ -52,3 +52,5 @@ hush hush /usr/bin hush.1 hush /usr/share/man/man1 with-umask with-umask /usr/bin with-umask.1 with-umask /usr/share/man/man1 +sshsvc-mkauthkeys sshsvc-mkauthkeys /usr/bin +sshsvc-mkauthkeys.1 sshsvc-mkauthkeys /usr/share/man/man1 diff --git a/sshsvc-mkauthkeys b/sshsvc-mkauthkeys new file mode 100755 index 0000000..a8a370a --- /dev/null +++ b/sshsvc-mkauthkeys @@ -0,0 +1,123 @@ +#! /bin/sh +### +### Generate .ssh/authorized_keys files for SSH services +### +### (c) 2015 Mark Wooding +### + +###----- Licensing notice --------------------------------------------------- +### +### This program is free software; you can redistribute it and/or modify +### it under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 2 of the License, or +### (at your option) any later version. +### +### This program is distributed in the hope that it will be useful, +### but WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with this program; if not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +set -e + +## Initial setup. +allow_agent_forwarding=no +allow_x11_forwarding=no +allow_port_forwarding=no +allow_pty=no +env="SSHSVC_USER=@user" +cmd="bin/sshsvc" + +## Hook functions. +make_key_line () { + user=$1 + e=$env + while :; do + progressp=t + case "$e" in + *@user*) e=${e%%@user*}$user${e#*@user} ;; + *) progressp=nil ;; + esac + case $progressp in nil) break ;; esac + done + line="environment=\"$e\"" + echo "$line" +} + +make_full_key_line () { + user=$1 + line=$(make_key_line "$user") + case "${cmd+t},$line" in + ,* | *,command=*) ;; + t,*) line="command=\"$cmd\",$line" ;; + esac + case "$allow_port_forwarding" in + yes) ;; *) line="no-port-forwarding,$line" ;; + esac + case "$allow_x11_forwarding" in + yes) ;; *) line="no-X11-forwarding,$line" ;; + esac + case "$allow_agent_forwarding" in + yes) ;; *) line="no-agent-forwarding,$line" ;; + esac + case "$allow_pty" in + yes) ;; *) line="no-pty,$line" ;; + esac + echo "$line" +} + +## Scan the command line. +prog=${0##*/} bogusp=nil +conf=sshsvc.conf out=authorized_keys keysdir=keys +head=sshsvc-authkeys.head tail=sshsvc-authkeys.tail +usage () { + echo "usage: $prog [-c CONF] [-k DIR] [-o OUTPUT] [-H HEAD] [-T TAIL]" +} +while getopts hc:k:o:H:T: opt; do + case $opt in + h) usage; exit 0 ;; + c) conf=$OPTARG ;; + k) keysdir=$OPTARG ;; + o) out=$OPTARG ;; + H) head=$OPTARG ;; + T) tail=$OPTARG ;; + *) bogusp=t ;; + esac +done +shift $(( $OPTIND - 1 )) +case $# in 0) ;; *) bogusp=t ;; esac +case $bogusp in t) usage >&2; exit 1 ;; esac + +## Read the configuration. +case $conf in /*) ;; *) conf=./$conf ;; esac +. "$conf" + +## Do the thing. +case $out in + -) exec 3>&1 ;; + *) exec 3>"$out.new" ;; +esac + +echo >&3 "### GENERATED by $prog" + +if [ -r "$head" ]; then cat "$head" >&3; fi + +for i in "$keysdir"/*.pub; do + u=${i#*/}; u=${u%.*}; u=${u%%!*} + l=$(make_full_key_line "$u") + k=$(cat "$i") + echo >&3 "$l $k" +done + +if [ -r "$tail" ]; then cat "$tail" >&3; fi + +echo >&3 "### GENERATED by $prog" + +exec 3>&- +case $out in + -) ;; + *) mv "$out.new" "$out" ;; +esac diff --git a/sshsvc-mkauthkeys.1 b/sshsvc-mkauthkeys.1 new file mode 100644 index 0000000..958e41c --- /dev/null +++ b/sshsvc-mkauthkeys.1 @@ -0,0 +1,281 @@ +.de hP +.IP +\h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c +.. +.ie t .ds o \(bu +.el .ds o o +. +.TH sshsvc-mkauthkeys 1 "23 April 2015" "distorted.org.uk" "Utilities" +.SH NAME +sshsvc-mkauthkeys \- build authorized_keys files for SSH services +.SH SYNOPSIS +.B sshsvc-mkauthkeys +.RB [ \-c +.IR config ] +.RB [ \-k +.IR keysdir ] +.RB [ \-o +.IR output ] +.br +\&\h'8n' +.RB [ \-H +.IR head ] +.RB [ \-T +.IR tail ] +.SH DESCRIPTION +The +.B sshsvc-mkauthkeys +script constructs an OpenSSH +.B authorized_keys +file +from a collection of SSH public keys +and some configuration in the form of shell variable and function +definitions. +The script expects to be run from a makefile +within a +.B .ssh/ +directory +and reads and writes files with fixed relative pathnames by default. +These can be overridden using command-line options. +.SS "Command line options" +.TP +.BI \-c " config" +Source configuration from +.I config +instead of the default +.BR sshsvc.conf . +.TP +.BI \-k " keysdir" +Collect user keys from +.I keysdir +instead of the default +.BR keys/ . +.TP +.BI \-o " output" +Write the output to +.I output +instead of the default +.BR authorized_keys . +.TP +.BI \-H " head" +Read initial raw entries from +.I head +(if it exists) +instead of the default +.BR sshsvc-authkeys.head . +.TP +.BI \-T " tail" +Read final raw entries from +.I tail +(if it exists) +instead of the default +.BR sshsvc-authkeys.tail . +.SS "Overall operation" +The +.I output +file +.RB ( authorized_keys +by default) +is constructed as follows. +.hP 0. +A comment is written to +the very top of +the output file +explaining that it was generated by +.BR sshsvc-mkauthkeys . +.hP 1. +If the +.I head +file +.RB ( sshsvc-authkeys.head +by default) +exists then its contents are written unchanged to the output. +.hP 2. +Each of the files +.IB keysdir / user\fR[ ! label\fR] .pub +is processed in turn +(see below) +in ascending lexicographic order +to make a single-line entry +in the output file. +The default +.I keysdir +is +.BR keys/ . +.hP 3. +If the +.I tail +file +.RB ( sshsvc-authkeys.tail +by default) +exists then its contents are written unchanged to the output. +.hP 4. +A commend is written to +the very bottom of +the output file +explaining that it was generated by +.BR sshsvc-mkauthkeys . +.SS "Configuration" +The configuration +for a particular SSH service +is read from +.BR sshsvc.conf . +This file must exist +in the current working directory, +though it needn't have any content +since all configurable parameters have sensible +(though not necessarily useful) +defaults. +.SS "The make_full_key_line function" +The most general configuration hook +(and therefore the one requiring most effort from the user) +is the +.B make_full_key_line +function. +It is given the key file's +.I user +name as an argument and +expected to write +the +.I options +portion of an +.B authorized_keys +entry to standard output. +.PP +The default implementation is likely to be suitable +for almost all services. It calls +.B make_key_line +(see below) +to construct +environment variable settings +and other per-user configuration settings, +and attaches general policy settings. +.PP +It uses the following variables. +.TP +.B allow_port_forwarding +If not +.B yes +then forbid port forwarding +(include +.B no-port-forwarding +in the line). +The default is +.BR no . +.TP +.B allow_x11_forwarding +If not +.B yes +then forbid X11 connection forwarding +(include +.B no-X11-forwarding +in the line). +The default is +.BR no . +.TP +.B allow_agent_forwarding +If not +.B yes +then forbid SSH agent forwarding +(include +.B no-agent-forwarding +in the line). +The default is +.BR no . +It's probably not a good idea to enable this. +.TP +.B allow_pty +If not +.B yes +then forbid pty allocation +(include +.B no-pty +in the line). +The default is +.BR no . +This is usually what you want +unless your service needs an interactive terminal +(e.g., a console for a virtual machine). +.TP +.B cmd +If set to any value +and the line from +.B make_key_line +doesn't already contain a +.RB ` command= ...' +option, +then always run +.I cmd +(with the service user's shell) +rather than using the client's requested command line, +which is left in +.B SSH_ORIGINAL_COMMAND +(include +.BI command="" cmd "" +in the line). +The default is +.BR bin/sshsvc . +.SS "The make_key_line function" +The +.B make_key_line +function is called with +the key file's +.I user +name as its only argument, +and is expected to write any per-user +(and unusual) +options to standard output. +Mostly it will be sufficient to generate an +.RB ` environment= ...' +option +and leave the rest to +.BR make_full_key_line . +.PP +The default +.B make_key_line +function is suitable for simple cases. +It examines the +.B env +variable, +replacing +.B @user +placeholders with the key's +.I user +name, +and emits the line +.BI environment= env\fR. +The default value of +.B env +is +.B SSHSVC_USER=@user +which may be good enough for services +explicitly written to work with it. +.SH FILES +.TP +.BR sshsvc.conf +Read for configuration +(shell variable and function definitions). +.TP +.BI keys/ user\fR[ ! label\fR] .pub +Input public keys to process. +.TP +.B sshsvc-authkeys.head +Pre-cooked +.B authorized_keys +entries to write at the top of the output. +.TP +.B sshsvc-authkeys.tail +Pre-cooked +.B authorized_keys +entries to write at the bottom of the output. +.TP +.B authorized_keys +Output file. +.SH BUGS +Perfection guaranteed. +Satisfaction, or your money back. +.SH "SEE ALSO" +.BR ssh (1), +.BR sshd (8). +.SH AUTHOR +Mark Wooding,