#!/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/kbase/tlscerts.html # # 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 # . # # Daniel Veillard # case $1 in -h | --h | --he | --hel | --help) cat <&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" INITCONFDIR="@initconfdir@" 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/kbase/tlscerts.html#setting-up-a-certificate-authority-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/kbase/tlscerts.html#setting-up-a-certificate-authority-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/kbase/tlscerts.html#issuing-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/kbase/tlscerts.html#issuing-server-certificates" echo on how to regenerate it SERVER=0 fi if [ "$SERVER" = "1" ] then if [ -r "$INITCONFDIR"/libvirtd ] then if grep "^LIBVIRTD_ARGS.*--listen" "$INITCONFDIR"/libvirtd \ >/dev/null 2>&1 then : else echo Make sure "$INITCONFDIR"/libvirtd is setup to listen to echo TCP/IP connections and restart the libvirtd service fi fi if [ -r "$INITCONFDIR"/iptables ] then if grep "$PORT" "$INITCONFDIR"/iptables >/dev/null 2>&1 then : else echo Make sure "$INITCONFDIR"/iptables is setup to allow echo incoming TCP/IP connections on port $PORT and echo restart the iptables service fi fi fi exit 0