virt-pki-validate.in 9.6 KB
Newer Older
1 2 3 4
#!/bin/sh
#
# This shell script checks the TLS certificates and options needed
# for the secure client/server support of libvirt as documented at
5
# https://libvirt.org/remote.html#Remote_certificates
6
#
E
Eric Blake 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 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/>.
#
23 24
# Daniel Veillard <veillard@redhat.com>
#
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

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

55 56 57 58 59 60 61 62
USER=`who am i | awk '{ print $1 }'`
SERVER=1
CLIENT=1
PORT=16514
#
# First get certtool
#
CERTOOL=`which certtool 2>/dev/null`
63
if [ ! -x "$CERTOOL" ]
64
then
65 66
    echo "Could not locate the certtool program"
    echo "make sure the gnutls-utils (or gnutls-bin) package is installed"
67 68
    exit 1
fi
69
echo Found "$CERTOOL"
70 71 72 73

#
# Check the directory structure
#
74
SYSCONFDIR="@sysconfdir@"
75
PKI="$SYSCONFDIR/pki"
76
if [ ! -d "$PKI" ]
77 78 79 80 81 82
then
    echo the $PKI directory is missing, it is usually
    echo installed as part of the filesystem or openssl packages
    exit 1
fi

83
if [ ! -r "$PKI" ]
84 85 86 87 88
then
    echo the $PKI directory is not readable by $USER
    echo "as root do: chmod a+rx $PKI"
    exit 1
fi
89
if [ ! -x "$PKI" ]
90 91 92 93 94 95 96
then
    echo the $PKI directory is not listable by $USER
    echo "as root do: chmod a+rx $PKI"
    exit 1
fi

CA="$PKI/CA"
97
if [ ! -d "$CA" ]
98 99 100 101 102 103
then
    echo the $CA directory is missing, it is usually
    echo installed as part of the or openssl package
    exit 1
fi

104
if [ ! -r "$CA" ]
105 106 107 108 109
then
    echo the $CA directory is not readable by $USER
    echo "as root do: chmod a+rx $CA"
    exit 1
fi
110
if [ ! -x "$CA" ]
111 112 113 114 115 116 117
then
    echo the $CA directory is not listable by $USER
    echo "as root do: chmod a+rx $CA"
    exit 1
fi

LIBVIRT="$PKI/libvirt"
118
if [ ! -d "$LIBVIRT" ]
119 120 121 122 123 124 125
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

126
if [ ! -r "$LIBVIRT" ]
127 128 129 130 131
then
    echo the $LIBVIRT directory is not readable by $USER
    echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
    exit 1
fi
132
if [ ! -x "$LIBVIRT" ]
133 134 135 136 137 138 139
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"
140
if [ ! -d "$LIBVIRTP" ]
141 142 143 144 145 146 147
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

148
if [ ! -r "$LIBVIRTP" ]
149 150 151 152 153
then
    echo the $LIBVIRTP directory is not readable by $USER
    echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
    exit 1
fi
154
if [ ! -x "$LIBVIRTP" ]
155 156 157 158 159 160 161 162 163 164
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
#
165
if [ ! -f "$CA/cacert.pem" ]
166 167 168
then
    echo the CA certificate $CA/cacert.pem is missing while it
    echo should be installed on both client and servers
169
    echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
170 171 172
    echo on how to install it
    exit 1
fi
173
if [ ! -r "$CA/cacert.pem" ]
174 175 176 177 178
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
179 180 181 182 183
sed_get_org='/Issuer:/ {
  s/.*Issuer:.*CN=//
  s/,.*//
  p
}'
184
ORG=`"$CERTOOL" -i --infile "$CA/cacert.pem" | sed -n "$sed_get_org"`
185
if [ "$ORG" = "" ]
186 187 188
then
    echo the CA certificate $CA/cacert.pem does not define the organization
    echo it should probably regenerated
189
    echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
190 191 192 193 194 195 196
    echo on how to regenerate it
    exit 1
fi
echo Found CA certificate $CA/cacert.pem for $ORG

# Second the client certificates

197
if [ -f "$LIBVIRT/clientcert.pem" ]
198
then
199
    if [ ! -r "$LIBVIRT/clientcert.pem" ]
200 201
    then
        echo Client certificate $LIBVIRT/clientcert.pem should be world readable
202
        echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
203
    else
204
        S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*O=\([a-zA-Z \._-]*\).*+\1+'`
205 206 207 208 209 210
        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
211
        CLIENT=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*CN=\(.[a-zA-Z \._-]*\).*+\1+'`
212
        echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
213
        if [ ! -e "$LIBVIRTP/clientkey.pem" ]
214 215 216 217
        then
            echo Missing client private key $LIBVIRTP/clientkey.pem
        else
            echo Found client private key $LIBVIRTP/clientkey.pem
218
            OWN=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print $3 }'`
219 220
            # The substr($1, 1, 10) gets rid of acl and xattr markers
            MOD=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print substr($1, 1, 10) }'`
221 222 223 224 225 226 227 228 229 230 231
            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
232 233 234

    fi
else
235
    echo Did not find "$LIBVIRT/clientcert.pem" client certificate
236
    echo The machine cannot act as a client
237
    echo "see https://libvirt.org/remote.html#Remote_TLS_client_certificates"
238 239 240 241 242 243
    echo on how to regenerate it
    CLIENT=0
fi

# Third the server certificates

244
if [ -f "$LIBVIRT/servercert.pem" ]
245
then
246
    if [ ! -r "$LIBVIRT/servercert.pem" ]
247 248
    then
        echo Server certificate $LIBVIRT/servercert.pem should be world readable
249
        echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
250
    else
251
        S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*O=\([a-zA-Z\. _-]*\).*+\1+'`
252 253 254 255 256 257
        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
258
        S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\([a-zA-Z\. _-]*\)+\1+'`
259 260 261 262 263 264 265
        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
266
        if [ ! -e "$LIBVIRTP/serverkey.pem" ]
267 268 269 270
        then
            echo Missing server private key $LIBVIRTP/serverkey.pem
        else
            echo Found server private key $LIBVIRTP/serverkey.pem
271
            OWN=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print $3 }'`
272 273
            # The substr($1, 1, 10) gets rid of acl and xattr markers
            MOD=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print substr($1, 1, 10) }'`
274 275 276 277 278 279 280 281 282 283 284
            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
285 286 287

    fi
else
288
    echo Did not find $LIBVIRT/servercert.pem server certificate
289
    echo The machine cannot act as a server
290
    echo "see https://libvirt.org/remote.html#Remote_TLS_server_certificates"
291 292 293 294 295 296
    echo on how to regenerate it
    SERVER=0
fi

if [ "$SERVER" = "1" ]
then
297
    if [ -r "$SYSCONFDIR"/sysconfig/libvirtd ]
298
    then
299 300
        if grep "^LIBVIRTD_ARGS.*--listen" "$SYSCONFDIR"/sysconfig/libvirtd \
            >/dev/null 2>&1
301
        then
302 303 304
            :
        else
            echo Make sure "$SYSCONFDIR"/sysconfig/libvirtd is setup to listen to
305 306
            echo TCP/IP connections and restart the libvirtd service
        fi
307
    fi
308
    if [ -r "$SYSCONFDIR"/sysconfig/iptables ]
309
    then
310
        if grep "$PORT" "$SYSCONFDIR"/sysconfig/iptables >/dev/null 2>&1
311
        then
312 313 314
            :
        else
            echo Make sure "$SYSCONFDIR"/sysconfig/iptables is setup to allow
315 316 317
            echo incoming TCP/IP connections on port $PORT and
            echo restart the iptables service
        fi
318 319
    fi
fi
320 321 322


exit 0