You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

323 lines
9.6 KiB

  1. #!/bin/sh
  2. #
  3. # This shell script checks the TLS certificates and options needed
  4. # for the secure client/server support of libvirt as documented at
  5. # https://libvirt.org/remote.html#Remote_certificates
  6. #
  7. # Copyright (C) 2009-2013 Red Hat, Inc.
  8. #
  9. # This library is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU Lesser General Public
  11. # License as published by the Free Software Foundation; either
  12. # version 2.1 of the License, or (at your option) any later version.
  13. #
  14. # This library is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. # Lesser General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Lesser General Public
  20. # License along with this library. If not, see
  21. # <http://www.gnu.org/licenses/>.
  22. #
  23. # Daniel Veillard <veillard@redhat.com>
  24. #
  25. case $1 in
  26. -h | --h | --he | --hel | --help)
  27. cat <<EOF
  28. Usage:
  29. $0 [OPTION]
  30. Options:
  31. -h | --help Display program help
  32. -V | --version Display program version
  33. EOF
  34. exit ;;
  35. -V | --v | --ve | --ver | --vers | --versi | --versio | --version)
  36. cat <<EOF
  37. $0 (libvirt) @VERSION@
  38. EOF
  39. exit ;;
  40. --) shift ;;
  41. -) # Not an option but an argument; it gets rejected later
  42. ;;
  43. -*)
  44. echo "$0: unrecognized option '$1'" >&2
  45. exit 1 ;;
  46. esac
  47. if test $# != 0; then
  48. echo "$0: unrecognized argument '$1'" >&2
  49. exit 1
  50. fi
  51. USER=`who am i | awk '{ print $1 }'`
  52. SERVER=1
  53. CLIENT=1
  54. PORT=16514
  55. #
  56. # First get certtool
  57. #
  58. CERTOOL=`which certtool 2>/dev/null`
  59. if [ ! -x "$CERTOOL" ]
  60. then
  61. echo "Could not locate the certtool program"
  62. echo "make sure the gnutls-utils (or gnutls-bin) package is installed"
  63. exit 1
  64. fi
  65. echo Found "$CERTOOL"
  66. #
  67. # Check the directory structure
  68. #
  69. SYSCONFDIR="@sysconfdir@"
  70. PKI="$SYSCONFDIR/pki"
  71. if [ ! -d "$PKI" ]
  72. then
  73. echo the $PKI directory is missing, it is usually
  74. echo installed as part of the filesystem or openssl packages
  75. exit 1
  76. fi
  77. if [ ! -r "$PKI" ]
  78. then
  79. echo the $PKI directory is not readable by $USER
  80. echo "as root do: chmod a+rx $PKI"
  81. exit 1
  82. fi
  83. if [ ! -x "$PKI" ]
  84. then
  85. echo the $PKI directory is not listable by $USER
  86. echo "as root do: chmod a+rx $PKI"
  87. exit 1
  88. fi
  89. CA="$PKI/CA"
  90. if [ ! -d "$CA" ]
  91. then
  92. echo the $CA directory is missing, it is usually
  93. echo installed as part of the or openssl package
  94. exit 1
  95. fi
  96. if [ ! -r "$CA" ]
  97. then
  98. echo the $CA directory is not readable by $USER
  99. echo "as root do: chmod a+rx $CA"
  100. exit 1
  101. fi
  102. if [ ! -x "$CA" ]
  103. then
  104. echo the $CA directory is not listable by $USER
  105. echo "as root do: chmod a+rx $CA"
  106. exit 1
  107. fi
  108. LIBVIRT="$PKI/libvirt"
  109. if [ ! -d "$LIBVIRT" ]
  110. then
  111. echo the $LIBVIRT directory is missing, it is usually
  112. echo installed by the libvirt package
  113. echo "as root do: mkdir -m 755 $LIBVIRT ; chown root:root $LIBVIRT"
  114. exit 1
  115. fi
  116. if [ ! -r "$LIBVIRT" ]
  117. then
  118. echo the $LIBVIRT directory is not readable by $USER
  119. echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
  120. exit 1
  121. fi
  122. if [ ! -x "$LIBVIRT" ]
  123. then
  124. echo the $LIBVIRT directory is not listable by $USER
  125. echo "as root do: chown root:root $LIBVIRT ; chmod 755 $LIBVIRT"
  126. exit 1
  127. fi
  128. LIBVIRTP="$LIBVIRT/private"
  129. if [ ! -d "$LIBVIRTP" ]
  130. then
  131. echo the $LIBVIRTP directory is missing, it is usually
  132. echo installed by the libvirt package
  133. echo "as root do: mkdir -m 755 $LIBVIRTP ; chown root:root $LIBVIRTP"
  134. exit 1
  135. fi
  136. if [ ! -r "$LIBVIRTP" ]
  137. then
  138. echo the $LIBVIRTP directory is not readable by $USER
  139. echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
  140. exit 1
  141. fi
  142. if [ ! -x "$LIBVIRTP" ]
  143. then
  144. echo the $LIBVIRTP directory is not listable by $USER
  145. echo "as root do: chown root:root $LIBVIRTP ; chmod 755 $LIBVIRTP"
  146. exit 1
  147. fi
  148. #
  149. # Now check the certificates
  150. # First the CA certificate
  151. #
  152. if [ ! -f "$CA/cacert.pem" ]
  153. then
  154. echo the CA certificate $CA/cacert.pem is missing while it
  155. echo should be installed on both client and servers
  156. echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
  157. echo on how to install it
  158. exit 1
  159. fi
  160. if [ ! -r "$CA/cacert.pem" ]
  161. then
  162. echo the CA certificate $CA/cacert.pem is not readable by $USER
  163. echo "as root do: chmod 644 $CA/cacert.pem"
  164. exit 1
  165. fi
  166. sed_get_org='/Issuer:/ {
  167. s/.*Issuer:.*CN=//
  168. s/,.*//
  169. p
  170. }'
  171. ORG=`"$CERTOOL" -i --infile "$CA/cacert.pem" | sed -n "$sed_get_org"`
  172. if [ "$ORG" = "" ]
  173. then
  174. echo the CA certificate $CA/cacert.pem does not define the organization
  175. echo it should probably regenerated
  176. echo "see https://libvirt.org/remote.html#Remote_TLS_CA"
  177. echo on how to regenerate it
  178. exit 1
  179. fi
  180. echo Found CA certificate $CA/cacert.pem for $ORG
  181. # Second the client certificates
  182. if [ -f "$LIBVIRT/clientcert.pem" ]
  183. then
  184. if [ ! -r "$LIBVIRT/clientcert.pem" ]
  185. then
  186. echo Client certificate $LIBVIRT/clientcert.pem should be world readable
  187. echo "as root do: chown root:root $LIBVIRT/clientcert.pem ; chmod 644 $LIBVIRT/clientcert.pem"
  188. else
  189. C_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
  190. if [ "$ORG" != "$C_ORG" ]
  191. then
  192. echo The CA certificate and the client certificate do not match
  193. echo CA organization: $ORG
  194. echo Client organization: $C_ORG
  195. fi
  196. CLIENT=`"$CERTOOL" -i --infile "$LIBVIRT/clientcert.pem" | grep Subject: | sed 's+.*CN=\(.[^,]*\).*+\1+'`
  197. echo Found client certificate $LIBVIRT/clientcert.pem for $CLIENT
  198. if [ ! -e "$LIBVIRTP/clientkey.pem" ]
  199. then
  200. echo Missing client private key $LIBVIRTP/clientkey.pem
  201. else
  202. echo Found client private key $LIBVIRTP/clientkey.pem
  203. OWN=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print $3 }'`
  204. # The substr($1, 1, 10) gets rid of acl and xattr markers
  205. MOD=`ls -l "$LIBVIRTP/clientkey.pem" | awk '{ print substr($1, 1, 10) }'`
  206. if [ "$OWN" != "root" ]
  207. then
  208. echo The client private key should be owned by root
  209. echo "as root do: chown root $LIBVIRTP/clientkey.pem"
  210. fi
  211. if [ "$MOD" != "-rw-r--r--" ]
  212. then
  213. echo The client private key need to be read by client tools
  214. echo "as root do: chmod 644 $LIBVIRTP/clientkey.pem"
  215. fi
  216. fi
  217. fi
  218. else
  219. echo Did not find "$LIBVIRT/clientcert.pem" client certificate
  220. echo The machine cannot act as a client
  221. echo "see https://libvirt.org/remote.html#Remote_TLS_client_certificates"
  222. echo on how to regenerate it
  223. CLIENT=0
  224. fi
  225. # Third the server certificates
  226. if [ -f "$LIBVIRT/servercert.pem" ]
  227. then
  228. if [ ! -r "$LIBVIRT/servercert.pem" ]
  229. then
  230. echo Server certificate $LIBVIRT/servercert.pem should be world readable
  231. echo "as root do: chown root:root $LIBVIRT/servercert.pem ; chmod 644 $LIBVIRT/servercert.pem"
  232. else
  233. S_ORG=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*O=\([^,]*\).*+\1+'`
  234. if [ "$ORG" != "$S_ORG" ]
  235. then
  236. echo The CA certificate and the server certificate do not match
  237. echo CA organization: $ORG
  238. echo Server organization: $S_ORG
  239. fi
  240. S_HOST=`"$CERTOOL" -i --infile "$LIBVIRT/servercert.pem" | grep Subject: | sed 's+.*CN=\([^,]*\).*+\1+'`
  241. if test "$S_HOST" != "`hostname -s`" && test "$S_HOST" != "`hostname`"
  242. then
  243. echo The server certificate does not seem to match the host name
  244. echo hostname: '"'`hostname`'"'
  245. echo Server certificate CN: '"'$S_HOST'"'
  246. fi
  247. echo Found server certificate $LIBVIRT/servercert.pem for $S_HOST
  248. if [ ! -e "$LIBVIRTP/serverkey.pem" ]
  249. then
  250. echo Missing server private key $LIBVIRTP/serverkey.pem
  251. else
  252. echo Found server private key $LIBVIRTP/serverkey.pem
  253. OWN=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print $3 }'`
  254. # The substr($1, 1, 10) gets rid of acl and xattr markers
  255. MOD=`ls -l "$LIBVIRTP/serverkey.pem" | awk '{ print substr($1, 1, 10) }'`
  256. if [ "$OWN" != "root" ]
  257. then
  258. echo The server private key should be owned by root
  259. echo "as root do: chown root $LIBVIRTP/serverkey.pem"
  260. fi
  261. if [ "$MOD" != "-rw-------" ]
  262. then
  263. echo The server private key need to be read only by root
  264. echo "as root do: chmod 600 $LIBVIRTP/serverkey.pem"
  265. fi
  266. fi
  267. fi
  268. else
  269. echo Did not find $LIBVIRT/servercert.pem server certificate
  270. echo The machine cannot act as a server
  271. echo "see https://libvirt.org/remote.html#Remote_TLS_server_certificates"
  272. echo on how to regenerate it
  273. SERVER=0
  274. fi
  275. if [ "$SERVER" = "1" ]
  276. then
  277. if [ -r "$SYSCONFDIR"/sysconfig/libvirtd ]
  278. then
  279. if grep "^LIBVIRTD_ARGS.*--listen" "$SYSCONFDIR"/sysconfig/libvirtd \
  280. >/dev/null 2>&1
  281. then
  282. :
  283. else
  284. echo Make sure "$SYSCONFDIR"/sysconfig/libvirtd is setup to listen to
  285. echo TCP/IP connections and restart the libvirtd service
  286. fi
  287. fi
  288. if [ -r "$SYSCONFDIR"/sysconfig/iptables ]
  289. then
  290. if grep "$PORT" "$SYSCONFDIR"/sysconfig/iptables >/dev/null 2>&1
  291. then
  292. :
  293. else
  294. echo Make sure "$SYSCONFDIR"/sysconfig/iptables is setup to allow
  295. echo incoming TCP/IP connections on port $PORT and
  296. echo restart the iptables service
  297. fi
  298. fi
  299. fi
  300. exit 0