Mercurial > hg > sshfp
changeset 0:d7fc9c3b4d87
Adding SSHFP CGI and update script
author | Dominic Cleal <dominic-cleal@cdo2.com> |
---|---|
date | Thu, 19 Nov 2009 11:54:21 +0000 |
parents | |
children | 9b1165b3f241 |
files | sshfp.cgi sshfp_update.sh |
diffstat | 2 files changed, 145 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /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 <dominic-cleal@cdo2.com> +# +# 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<<END; +<html> +<head><title>SSH fingerprint records</title></head> +<body> +<table border="1"> +<tr><th>Hostname</th><th>IP address</th><th>Last update</th> +<th>RSA fingerprint</th><th>DSA fingerprint</th></tr> +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(/,/, <FH>); + close(FH); + + my $time = strftime("%Y-%m-%d %H:%M:%S", gmtime $text[0]); + + print("<tr><td>$host</td><td>$ip</td><td>$time</td>" . + "<td>$text[1]</td><td>$text[2]</td></tr>\n"); + } + + print<<END; +</table></body></html> +END +} + +sub error +{ + my $text = shift; + print "ERROR: $text\n"; + die $text; +}
--- /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 <dominic-cleal@cdo2.com> +# +# 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" +