mirror of https://gitee.com/openkylin/libvirt.git
387 lines
11 KiB
Bash
Executable File
387 lines
11 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
|
|
# http://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 http://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 http://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
|
|
S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*O=\([a-zA-Z \._-]*\).*+\1+'`
|
|
if [ "$ORG" != "$S_ORG" ]
|
|
then
|
|
echo The CA certificate and the client certificate do not match
|
|
echo CA organization: $ORG
|
|
echo Client organization: $S_ORG
|
|
fi
|
|
CLIENT=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*CN=\(.[a-zA-Z \._-]*\).*+\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 http://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=\([a-zA-Z\. _-]*\).*+\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=\([a-zA-Z\. _-]*\)+\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 http://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
|
|
|
|
: <<=cut
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
virt-pki-validate - validate libvirt PKI files are configured correctly
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
virt-pki-validate [OPTION]
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This tool validates that the necessary PKI files are configured for
|
|
a secure libvirt server or client using the TLS encryption protocol.
|
|
It will report any missing certificate or key files on the host. It
|
|
should be run as root to ensure it can read all the necessary files
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over
|
|
|
|
=item B<-h, --help>
|
|
|
|
Display command line help usage then exit.
|
|
|
|
=item B<-V, --version>
|
|
|
|
Display version information then exit.
|
|
|
|
=back
|
|
|
|
=head1 EXIT STATUS
|
|
|
|
Upon successful validation, an exit status of 0 will be set. Upon
|
|
failure a non-zero status will be set.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Richard Jones
|
|
|
|
=head1 BUGS
|
|
|
|
Report any bugs discovered to the libvirt community via the
|
|
mailing list C<http://libvirt.org/contact.html> or bug tracker C<http://libvirt.org/bugs.html>.
|
|
Alternatively report bugs to your software distributor / vendor.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (C) 2006-2012 by Red Hat, Inc.
|
|
|
|
=head1 LICENSE
|
|
|
|
virt-pki-validate is distributed under the terms of the GNU GPL v2+.
|
|
This is free software; see the source for copying conditions. There
|
|
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE
|
|
|
|
=head1 SEE ALSO
|
|
|
|
C<virsh(1)>, online PKI setup instructions C<http://libvirt.org/remote.html>
|
|
|
|
=cut
|