# HG changeset patch # User Dominic Cleal # Date 1258631661 0 # Node ID d7fc9c3b4d87e64c6acf327d7649d0e301d63777 Adding SSHFP CGI and update script diff -r 000000000000 -r d7fc9c3b4d87 sshfp.cgi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sshfp.cgi Thu Nov 19 11:54:21 2009 +0000 @@ -0,0 +1,108 @@ +#!/usr/bin/perl +# +# Maintains and displays a list of SSH fingerprints for remote hosts. +# +# Permits remote host to update their SSH fingerprint and then displays the +# list of all recorded fingerprints. +# +# Warning: no limits are made on the number of fingerprints that can be stored, +# could potentially be DDoSed with lots of small files. This script should be +# locked down in the web server config. +# +# Copyright (c) 2009 CDO2 Limited +# Author: Dominic Cleal +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +use warnings; +use strict; +use CGI; +use Socket; +use POSIX qw/strftime/; + +my $STORE = '/var/local/sshfp/'; +my $IP_REGEX = qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; +my $FP_REGEX = qr/^([\da-f]{2}:?){16}$/; + +my $cgi = new CGI; +print $cgi->header(-type => 'text/html', + -pragma => 'no-cache', + -expires => '-365d'); + +my $action = $cgi->param('action') || 'display'; +my $sshfp_rsa = $cgi->param('rsa'); +my $sshfp_dsa = $cgi->param('dsa'); + +if ($action eq 'update') +{ + error('Both RSA or DSA fingerprints required') + unless (defined $sshfp_rsa && defined $sshfp_dsa); + + error('RSA fingerprint invalid') unless ($sshfp_rsa =~ $FP_REGEX); + error('DSA fingerprint invalid') unless ($sshfp_dsa =~ $FP_REGEX); + + my $time = time; + my $ip = $ENV{'REMOTE_ADDR'} || error('IP unavailable'); + error('IP invalid') unless ($ip =~ $IP_REGEX); + + open(FH, "> $STORE/$ip"); + print FH "$time,$sshfp_rsa,$sshfp_dsa"; + close(FH); +} +else +{ + print< +SSH fingerprint records + + + + +END + + opendir(my $dh, $STORE) || error("Can't open store: $!"); + my @files = sort grep { $IP_REGEX && -f "$STORE/$_" } readdir($dh); + closedir $dh; + + foreach my $ip (@files) + { + my $packedip = inet_aton($ip); + my $host = gethostbyaddr($packedip, AF_INET); + + open(FH, "< $STORE/$ip"); + my @text = split(/,/, ); + close(FH); + + my $time = strftime("%Y-%m-%d %H:%M:%S", gmtime $text[0]); + + print("" . + "\n"); + } + + print< +END +} + +sub error +{ + my $text = shift; + print "ERROR: $text\n"; + die $text; +} diff -r 000000000000 -r d7fc9c3b4d87 sshfp_update.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sshfp_update.sh Thu Nov 19 11:54:21 2009 +0000 @@ -0,0 +1,37 @@ +#!/bin/sh +# +# Updates this host's SSH fingerprints to the sshfp.cgi server +# +# Copyright (c) 2009 CDO2 Limited +# Author: Dominic Cleal +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +URL="https://admin.example.net/cgi-bin/sshfp.cgi" +RSA_KEY=/etc/ssh/ssh_host_rsa_key.pub +DSA_KEY=/etc/ssh/ssh_host_dsa_key.pub + +test -f "$RSA_KEY" || exit 1 +test -f "$DSA_KEY" || exit 1 + +RSA_FP=$(ssh-keygen -lf "$RSA_KEY" | awk '{ print $2 }') +DSA_FP=$(ssh-keygen -lf "$DSA_KEY" | awk '{ print $2 }') + +exec curl "$URL?action=update&rsa=$RSA_FP&dsa=$DSA_FP" +
HostnameIP addressLast updateRSA fingerprintDSA fingerprint
$host$ip$time$text[1]$text[2]