2007-07-12 23:47:19 +08:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# This shell script checks the TLS certificates and options needed
|
|
|
|
# for the secure client/server support of libvirt as documented at
|
2017-10-13 23:30:41 +08:00
|
|
|
# https://libvirt.org/remote.html#Remote_certificates
|
2007-07-12 23:47:19 +08:00
|
|
|
#
|
2013-05-15 07:42:12 +08:00
|
|
|
# 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/>.
|
|
|
|
#
|
2007-07-12 23:47:19 +08:00
|
|
|
# Daniel Veillard <veillard@redhat.com>
|
|
|
|
#
|
2013-08-20 06:38:57 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2007-07-12 23:47:19 +08:00
|
|
|
USER=`who am i | awk '{ print $1 }'`
|
|
|
|
SERVER=1
|
|
|
|
CLIENT=1
|
|
|
|
PORT=16514
|
|
|
|
#
|
|
|
|
# First get certtool
|
|
|
|
#
|
|
|
|
CERTOOL=`which certtool 2>/dev/null`
|
2011-02-21 04:29:25 +08:00
|
|
|
if [ ! -x "$CERTOOL" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
2010-04-22 05:52:10 +08:00
|
|
|
echo "Could not locate the certtool program"
|
|
|
|
echo "make sure the gnutls-utils (or gnutls-bin) package is installed"
|
2007-07-12 23:47:19 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
echo Found "$CERTOOL"
|
2007-07-12 23:47:19 +08:00
|
|
|
|
|
|
|
#
|
|
|
|
# Check the directory structure
|
|
|
|
#
|
build: use common .in replacement mechanism
We had several different styles of .in conversion in our Makefiles:
ALLCAPS, @ALLCAPS@, @lower@, ::lower::
Canonicalize on one form, to make it easier to copy and paste
between .in files.
Also, we were using some non-portable sed constructs: \@ is an
undefined escape sequence (it happens to be @ itself in GNU sed,
but POSIX allows it to mean something else), as well as risky
behavior (failure to consistently quote things means a space
in $(sysconfdir) could throw things off; also, Autoconf recommends
using | rather than , or ! in the s||| operator, because | has to
be quoted in shell and is therefore less likely to appear in file
names than , or !).
Fix all of these uses to follow the same syntax.
* daemon/libvirtd.8.in: Switch to @var@.
* tools/virt-xml-validate.in: Likewise.
* tools/virt-pki-validate.in: Likewise.
* src/locking/virtlockd.init.in: Likewise.
* daemon/Makefile.am: Prefer | over ! in sed.
(libvirtd.8): Prefer consistent substitution.
(libvirtd.init, libvirtd.service): Avoid non-portable sed.
* tools/Makefile.am (libvirt-guests.sh, libvirt-guests.init)
(libvirt-guests.service): Likewise.
(virt-xml-validate, virt-pki-validate, virt-sanlock-cleanup):
Prefer consistent capitalization.
* src/Makefile.am (virtlockd.init, virtlockd.service)
(virtlockd.socket): Prefer consistent substitution.
2013-01-05 04:35:04 +08:00
|
|
|
SYSCONFDIR="@sysconfdir@"
|
2010-04-22 05:52:10 +08:00
|
|
|
PKI="$SYSCONFDIR/pki"
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -d "$PKI" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $PKI directory is missing, it is usually
|
|
|
|
echo installed as part of the filesystem or openssl packages
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$PKI" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $PKI directory is not readable by $USER
|
|
|
|
echo "as root do: chmod a+rx $PKI"
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -x "$PKI" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $PKI directory is not listable by $USER
|
|
|
|
echo "as root do: chmod a+rx $PKI"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
CA="$PKI/CA"
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -d "$CA" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $CA directory is missing, it is usually
|
|
|
|
echo installed as part of the or openssl package
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$CA" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $CA directory is not readable by $USER
|
|
|
|
echo "as root do: chmod a+rx $CA"
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -x "$CA" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $CA directory is not listable by $USER
|
|
|
|
echo "as root do: chmod a+rx $CA"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
LIBVIRT="$PKI/libvirt"
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -d "$LIBVIRT" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
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
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$LIBVIRT" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $LIBVIRT directory is not readable by $USER
|
|
|
|
echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -x "$LIBVIRT" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
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"
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -d "$LIBVIRTP" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
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
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$LIBVIRTP" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the $LIBVIRTP directory is not readable by $USER
|
|
|
|
echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -x "$LIBVIRTP" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
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
|
|
|
|
#
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -f "$CA/cacert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the CA certificate $CA/cacert.pem is missing while it
|
|
|
|
echo should be installed on both client and servers
|
2017-10-13 23:30:41 +08:00
|
|
|
echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
|
2007-07-12 23:47:19 +08:00
|
|
|
echo on how to install it
|
|
|
|
exit 1
|
|
|
|
fi
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$CA/cacert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
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
|
2010-04-30 05:20:50 +08:00
|
|
|
sed_get_org='/Issuer:/ {
|
|
|
|
s/.*Issuer:.*CN=//
|
|
|
|
s/,.*//
|
|
|
|
p
|
|
|
|
}'
|
2011-02-21 04:29:26 +08:00
|
|
|
ORG=`"$CERTOOL" -i --infile "$CA/cacert.pem" | sed -n "$sed_get_org"`
|
2010-04-22 05:52:10 +08:00
|
|
|
if [ "$ORG" = "" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo the CA certificate $CA/cacert.pem does not define the organization
|
|
|
|
echo it should probably regenerated
|
2017-10-13 23:30:41 +08:00
|
|
|
echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
|
2007-07-12 23:47:19 +08:00
|
|
|
echo on how to regenerate it
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
echo Found CA certificate $CA/cacert.pem for $ORG
|
|
|
|
|
|
|
|
# Second the client certificates
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ -f "$LIBVIRT/clientcert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$LIBVIRT/clientcert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo Client certificate $LIBVIRT/clientcert.pem should be world readable
|
2010-04-22 07:21:06 +08:00
|
|
|
echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
|
2007-07-12 23:47:19 +08:00
|
|
|
else
|
2018-12-11 22:58:43 +08:00
|
|
|
C_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
|
|
|
|
if [ "$ORG" != "$C_ORG" ]
|
2010-04-22 07:21:06 +08:00
|
|
|
then
|
|
|
|
echo The CA certificate and the client certificate do not match
|
|
|
|
echo CA organization: $ORG
|
2018-12-11 22:58:43 +08:00
|
|
|
echo Client organization: $C_ORG
|
2010-04-22 07:21:06 +08:00
|
|
|
fi
|
2018-12-11 00:50:10 +08:00
|
|
|
CLIENT=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*CN=\(.[^,]*\).*+\1+'`
|
2010-04-22 07:21:06 +08:00
|
|
|
echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -e "$LIBVIRTP/clientkey.pem" ]
|
2010-04-22 07:21:06 +08:00
|
|
|
then
|
|
|
|
echo Missing client private key $LIBVIRTP/clientkey.pem
|
|
|
|
else
|
|
|
|
echo Found client private key $LIBVIRTP/clientkey.pem
|
2011-02-21 04:29:26 +08:00
|
|
|
OWN=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print $3 }'`
|
2012-05-31 17:00:06 +08:00
|
|
|
# The substr($1, 1, 10) gets rid of acl and xattr markers
|
|
|
|
MOD=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print substr($1, 1, 10) }'`
|
2010-04-22 07:21:06 +08:00
|
|
|
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
|
2007-07-12 23:47:19 +08:00
|
|
|
|
|
|
|
fi
|
|
|
|
else
|
2011-02-21 04:29:26 +08:00
|
|
|
echo Did not find "$LIBVIRT/clientcert.pem" client certificate
|
2007-07-12 23:47:19 +08:00
|
|
|
echo The machine cannot act as a client
|
2017-10-13 23:30:41 +08:00
|
|
|
echo "see https://libvirt.org/remote.html#Remote_TLS_client_certificates"
|
2007-07-12 23:47:19 +08:00
|
|
|
echo on how to regenerate it
|
|
|
|
CLIENT=0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Third the server certificates
|
|
|
|
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ -f "$LIBVIRT/servercert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -r "$LIBVIRT/servercert.pem" ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
|
|
|
echo Server certificate $LIBVIRT/servercert.pem should be world readable
|
2010-04-22 07:21:06 +08:00
|
|
|
echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
|
2007-07-12 23:47:19 +08:00
|
|
|
else
|
2018-12-11 00:50:10 +08:00
|
|
|
S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
|
2010-04-22 07:21:06 +08:00
|
|
|
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
|
2018-12-11 00:50:10 +08:00
|
|
|
S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\([^,]*\).*+\1+'`
|
2010-04-22 07:21:06 +08:00
|
|
|
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
|
2011-02-21 04:29:26 +08:00
|
|
|
if [ ! -e "$LIBVIRTP/serverkey.pem" ]
|
2010-04-22 07:21:06 +08:00
|
|
|
then
|
|
|
|
echo Missing server private key $LIBVIRTP/serverkey.pem
|
|
|
|
else
|
|
|
|
echo Found server private key $LIBVIRTP/serverkey.pem
|
2011-02-21 04:29:26 +08:00
|
|
|
OWN=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print $3 }'`
|
2012-05-31 17:00:06 +08:00
|
|
|
# The substr($1, 1, 10) gets rid of acl and xattr markers
|
|
|
|
MOD=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print substr($1, 1, 10) }'`
|
2010-04-22 07:21:06 +08:00
|
|
|
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
|
2007-07-12 23:47:19 +08:00
|
|
|
|
|
|
|
fi
|
|
|
|
else
|
2011-02-21 04:29:26 +08:00
|
|
|
echo Did not find $LIBVIRT/servercert.pem server certificate
|
2007-07-12 23:47:19 +08:00
|
|
|
echo The machine cannot act as a server
|
2017-10-13 23:30:41 +08:00
|
|
|
echo "see https://libvirt.org/remote.html#Remote_TLS_server_certificates"
|
2007-07-12 23:47:19 +08:00
|
|
|
echo on how to regenerate it
|
|
|
|
SERVER=0
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$SERVER" = "1" ]
|
|
|
|
then
|
2010-04-22 05:52:10 +08:00
|
|
|
if [ -r "$SYSCONFDIR"/sysconfig/libvirtd ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
2010-04-22 05:52:10 +08:00
|
|
|
if grep "^LIBVIRTD_ARGS.*--listen" "$SYSCONFDIR"/sysconfig/libvirtd \
|
|
|
|
>/dev/null 2>&1
|
2010-04-22 07:21:06 +08:00
|
|
|
then
|
2010-04-22 05:52:10 +08:00
|
|
|
:
|
|
|
|
else
|
|
|
|
echo Make sure "$SYSCONFDIR"/sysconfig/libvirtd is setup to listen to
|
2010-04-22 07:21:06 +08:00
|
|
|
echo TCP/IP connections and restart the libvirtd service
|
|
|
|
fi
|
2007-07-12 23:47:19 +08:00
|
|
|
fi
|
2010-04-22 05:52:10 +08:00
|
|
|
if [ -r "$SYSCONFDIR"/sysconfig/iptables ]
|
2007-07-12 23:47:19 +08:00
|
|
|
then
|
2011-02-21 04:29:26 +08:00
|
|
|
if grep "$PORT" "$SYSCONFDIR"/sysconfig/iptables >/dev/null 2>&1
|
2010-04-22 07:21:06 +08:00
|
|
|
then
|
2010-04-22 05:52:10 +08:00
|
|
|
:
|
|
|
|
else
|
|
|
|
echo Make sure "$SYSCONFDIR"/sysconfig/iptables is setup to allow
|
2010-04-22 07:21:06 +08:00
|
|
|
echo incoming TCP/IP connections on port $PORT and
|
|
|
|
echo restart the iptables service
|
|
|
|
fi
|
2007-07-12 23:47:19 +08:00
|
|
|
fi
|
|
|
|
fi
|
2009-09-16 21:42:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
exit 0
|