libvirt/tools/virt-pki-validate.in

323 lines
9.6 KiB
Bash
Executable File

#!/bin/sh
#
# This shell script checks the TLS certificates and options needed
# for the secure client/server support of libvirt as documented at
# https://libvirt.org/remote.html#Remote_certificates
#
# Copyright (C) 2009-2013 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
# Daniel Veillard <veillard@redhat.com>
#
case $1 in
-h | --h | --he | --hel | --help)
cat <<EOF
Usage:
$0 [OPTION]
Options:
-h | --help Display program help
-V | --version Display program version
EOF
exit ;;
-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
cat <<EOF
$0 (libvirt) @VERSION@
EOF
exit ;;
--) shift ;;
-) # Not an option but an argument; it gets rejected later
;;
-*)
echo "$0: unrecognized option '$1'" >&2
exit 1 ;;
esac
if test $# != 0; then
echo "$0: unrecognized argument '$1'" >&2
exit 1
fi
USER=`who am i | awk '{ print $1 }'`
SERVER=1
CLIENT=1
PORT=16514
#
# First get certtool
#
CERTOOL=`which certtool 2>/dev/null`
if [ ! -x "$CERTOOL" ]
then
echo "Could not locate the certtool program"
echo "make sure the gnutls-utils (or gnutls-bin) package is installed"
exit 1
fi
echo Found "$CERTOOL"
#
# Check the directory structure
#
SYSCONFDIR="@sysconfdir@"
PKI="$SYSCONFDIR/pki"
if [ ! -d "$PKI" ]
then
echo the $PKI directory is missing, it is usually
echo installed as part of the filesystem or openssl packages
exit 1
fi
if [ ! -r "$PKI" ]
then
echo the $PKI directory is not readable by $USER
echo "as root do: chmod a+rx $PKI"
exit 1
fi
if [ ! -x "$PKI" ]
then
echo the $PKI directory is not listable by $USER
echo "as root do: chmod a+rx $PKI"
exit 1
fi
CA="$PKI/CA"
if [ ! -d "$CA" ]
then
echo the $CA directory is missing, it is usually
echo installed as part of the or openssl package
exit 1
fi
if [ ! -r "$CA" ]
then
echo the $CA directory is not readable by $USER
echo "as root do: chmod a+rx $CA"
exit 1
fi
if [ ! -x "$CA" ]
then
echo the $CA directory is not listable by $USER
echo "as root do: chmod a+rx $CA"
exit 1
fi
LIBVIRT="$PKI/libvirt"
if [ ! -d "$LIBVIRT" ]
then
echo the $LIBVIRT directory is missing, it is usually
echo installed by the libvirt package
echo "as root do: mkdir -m 755 $LIBVIRT ; chown root:root $LIBVIRT"
exit 1
fi
if [ ! -r "$LIBVIRT" ]
then
echo the $LIBVIRT directory is not readable by $USER
echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
exit 1
fi
if [ ! -x "$LIBVIRT" ]
then
echo the $LIBVIRT directory is not listable by $USER
echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
exit 1
fi
LIBVIRTP="$LIBVIRT/private"
if [ ! -d "$LIBVIRTP" ]
then
echo the $LIBVIRTP directory is missing, it is usually
echo installed by the libvirt package
echo "as root do: mkdir -m 755 $LIBVIRTP ; chown root:root $LIBVIRTP"
exit 1
fi
if [ ! -r "$LIBVIRTP" ]
then
echo the $LIBVIRTP directory is not readable by $USER
echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
exit 1
fi
if [ ! -x "$LIBVIRTP" ]
then
echo the $LIBVIRTP directory is not listable by $USER
echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
exit 1
fi
#
# Now check the certificates
# First the CA certificate
#
if [ ! -f "$CA/cacert.pem" ]
then
echo the CA certificate $CA/cacert.pem is missing while it
echo should be installed on both client and servers
echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
echo on how to install it
exit 1
fi
if [ ! -r "$CA/cacert.pem" ]
then
echo the CA certificate $CA/cacert.pem is not readable by $USER
echo "as root do: chmod 644 $CA/cacert.pem"
exit 1
fi
sed_get_org='/Issuer:/ {
s/.*Issuer:.*CN=//
s/,.*//
p
}'
ORG=`"$CERTOOL" -i --infile "$CA/cacert.pem" | sed -n "$sed_get_org"`
if [ "$ORG" = "" ]
then
echo the CA certificate $CA/cacert.pem does not define the organization
echo it should probably regenerated
echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
echo on how to regenerate it
exit 1
fi
echo Found CA certificate $CA/cacert.pem for $ORG
# Second the client certificates
if [ -f "$LIBVIRT/clientcert.pem" ]
then
if [ ! -r "$LIBVIRT/clientcert.pem" ]
then
echo Client certificate $LIBVIRT/clientcert.pem should be world readable
echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
else
C_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
if [ "$ORG" != "$C_ORG" ]
then
echo The CA certificate and the client certificate do not match
echo CA organization: $ORG
echo Client organization: $C_ORG
fi
CLIENT=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*CN=\(.[^,]*\).*+\1+'`
echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
if [ ! -e "$LIBVIRTP/clientkey.pem" ]
then
echo Missing client private key $LIBVIRTP/clientkey.pem
else
echo Found client private key $LIBVIRTP/clientkey.pem
OWN=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print $3 }'`
# The substr($1, 1, 10) gets rid of acl and xattr markers
MOD=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print substr($1, 1, 10) }'`
if [ "$OWN" != "root" ]
then
echo The client private key should be owned by root
echo "as root do: chown root $LIBVIRTP/clientkey.pem"
fi
if [ "$MOD" != "-rw-r--r--" ]
then
echo The client private key need to be read by client tools
echo "as root do: chmod 644 $LIBVIRTP/clientkey.pem"
fi
fi
fi
else
echo Did not find "$LIBVIRT/clientcert.pem" client certificate
echo The machine cannot act as a client
echo "see https://libvirt.org/remote.html#Remote_TLS_client_certificates"
echo on how to regenerate it
CLIENT=0
fi
# Third the server certificates
if [ -f "$LIBVIRT/servercert.pem" ]
then
if [ ! -r "$LIBVIRT/servercert.pem" ]
then
echo Server certificate $LIBVIRT/servercert.pem should be world readable
echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
else
S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
if [ "$ORG" != "$S_ORG" ]
then
echo The CA certificate and the server certificate do not match
echo CA organization: $ORG
echo Server organization: $S_ORG
fi
S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\([^,]*\).*+\1+'`
if test "$S_HOST" != "`hostname -s`" && test "$S_HOST" != "`hostname`"
then
echo The server certificate does not seem to match the host name
echo hostname: '"'`hostname`'"'
echo Server certificate CN: '"'$S_HOST'"'
fi
echo Found server certificate $LIBVIRT/servercert.pem for $S_HOST
if [ ! -e "$LIBVIRTP/serverkey.pem" ]
then
echo Missing server private key $LIBVIRTP/serverkey.pem
else
echo Found server private key $LIBVIRTP/serverkey.pem
OWN=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print $3 }'`
# The substr($1, 1, 10) gets rid of acl and xattr markers
MOD=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print substr($1, 1, 10) }'`
if [ "$OWN" != "root" ]
then
echo The server private key should be owned by root
echo "as root do: chown root $LIBVIRTP/serverkey.pem"
fi
if [ "$MOD" != "-rw-------" ]
then
echo The server private key need to be read only by root
echo "as root do: chmod 600 $LIBVIRTP/serverkey.pem"
fi
fi
fi
else
echo Did not find $LIBVIRT/servercert.pem server certificate
echo The machine cannot act as a server
echo "see https://libvirt.org/remote.html#Remote_TLS_server_certificates"
echo on how to regenerate it
SERVER=0
fi
if [ "$SERVER" = "1" ]
then
if [ -r "$SYSCONFDIR"/sysconfig/libvirtd ]
then
if grep "^LIBVIRTD_ARGS.*--listen" "$SYSCONFDIR"/sysconfig/libvirtd \
>/dev/null 2>&1
then
:
else
echo Make sure "$SYSCONFDIR"/sysconfig/libvirtd is setup to listen to
echo TCP/IP connections and restart the libvirtd service
fi
fi
if [ -r "$SYSCONFDIR"/sysconfig/iptables ]
then
if grep "$PORT" "$SYSCONFDIR"/sysconfig/iptables >/dev/null 2>&1
then
:
else
echo Make sure "$SYSCONFDIR"/sysconfig/iptables is setup to allow
echo incoming TCP/IP connections on port $PORT and
echo restart the iptables service
fi
fi
fi
exit 0