From 0c0f0d1a09a7307583db71d82e44dfeca263ece7 Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Mon, 3 Apr 2006 19:47:07 +0000 Subject: [PATCH] - customize bootcd and bootmanager - use bash v2 ${!variable} syntax instead of kludgy evals - config_ssl: regenerate self-signed certificate if hostname changes, or the certificate expires. Check if have already have a self-signed certificate for the same hostname before deciding to generate a new one, since name-based virtual hosting doesn't work with SSL. - allow the API, web, and boot servers to run on different ports --- guest.init | 258 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 180 insertions(+), 78 deletions(-) diff --git a/guest.init b/guest.init index 68e920c..510e4ac 100755 --- a/guest.init +++ b/guest.init @@ -6,7 +6,7 @@ # # description: Manages all PLC services on this machine # -# $Id: guest.init,v 1.8 2006/03/29 17:03:15 mlhuang Exp $ +# $Id: guest.init,v 1.9 2006/03/31 00:41:03 mlhuang Exp $ # PATH=/sbin:/bin:/usr/bin:/usr/sbin @@ -32,6 +32,8 @@ ssh apache api cron +bootcd +bootmanager ) nsteps=${#steps[@]} @@ -73,8 +75,8 @@ reload () PLC_API_MAINTENANCE_SOURCES=$( for server in API BOOT WWW ; do - eval hostname=\${PLC_${server}_HOST} - gethostbyname $hostname + hostname=PLC_${server}_HOST + gethostbyname ${!hostname} done | sort -u ) plc-config --category=plc_api --variable=maintenance_sources --value="$PLC_API_MAINTENANCE_SOURCES" --save @@ -154,8 +156,8 @@ config_network () echo "127.0.0.1 localhost.localdomain localhost" >/etc/hosts ( for server in API BOOT WWW ; do - eval hostname=\${PLC_${server}_HOST} - ip=$(gethostbyname $hostname) + hostname=PLC_${server}_HOST + ip=$(gethostbyname ${!hostname}) if [ -n "$ip" ] ; then echo "$ip $hostname" fi @@ -309,6 +311,12 @@ EOF esac } +ssl_cname () +{ + openssl x509 -noout -in $1 -subject | \ + sed -n -e 's@.*/CN=\([^/]*\).*@\1@p' +} + symlink () { mkdir -p $(dirname $2) @@ -321,72 +329,97 @@ config_ssl () { case "$1" in start) - # Generate a self-signed SSL certificate. These nice - # commands came from the mod_ssl spec file for Fedora Core - # 2. We generate only a single certificate for the web - # server, then make copies for the API and boot - # servers. As always, these certificates may be overridden - # later. - - # Generate SSL private key - if [ ! -f $PLC_WWW_SSL_KEY ] ; then - mkdir -p $(dirname $PLC_WWW_SSL_KEY) - openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 1024 >$PLC_WWW_SSL_KEY - check - chmod 600 $PLC_WWW_SSL_KEY - fi + # Generate self-signed SSL certificate(s). These nice + # commands come from the mod_ssl spec file for Fedora Core + # 2. We generate a certificate for each enabled server + # with a different hostname. These self-signed + # certificates may be overridden later. + for server in WWW API BOOT ; do + ssl_key=PLC_${server}_SSL_KEY + ssl_crt=PLC_${server}_SSL_CRT + hostname=PLC_${server}_HOST + + # Check if we have already generated a certificate for + # the same hostname. + for previous_server in WWW API BOOT ; do + if [ "$server" = "$previous_server" ] ; then + break + fi + previous_ssl_key=PLC_${previous_server}_SSL_KEY + previous_ssl_crt=PLC_${previous_server}_SSL_CRT + previous_hostname=PLC_${previous_server}_HOST + + if [ -f ${!previous_ssl_crt} ] && \ + [ "$(ssl_cname ${!previous_ssl_crt})" = "${!hostname}" ] ; then + cp -a ${!previous_ssl_key} ${!ssl_key} + cp -a ${!previous_ssl_crt} ${!ssl_crt} + break + fi + done + + # Generate new SSL private key + if [ ! -f ${!ssl_key} ] ; then + mkdir -p $(dirname ${!ssl_key}) + openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 1024 >${!ssl_key} + check + chmod 600 ${!ssl_key} + fi - # Generate self-signed certificate - if [ ! -f $PLC_WWW_SSL_CRT ] ; then - mkdir -p $(dirname $PLC_WWW_SSL_CRT) - openssl req -new -x509 -days 365 -set_serial $RANDOM \ - -key $PLC_WWW_SSL_KEY -out $PLC_WWW_SSL_CRT <&2 + fi + fi + + # Generate new self signed certificate + if [ ! -f ${!ssl_crt} ] ; then + mkdir -p $(dirname ${!ssl_crt}) + openssl req -new -x509 -days 365 -set_serial $RANDOM \ + -key ${!ssl_key} -out ${!ssl_crt} <$PLC_API_SSL_KEY_PUB check fi - if [ ! -f $PLC_API_SSL_CRT ] ; then - cp -a $PLC_WWW_SSL_CRT $PLC_API_SSL_CRT - fi - if [ ! -f $PLC_BOOT_SSL_KEY ] ; then - cp -a $PLC_WWW_SSL_KEY $PLC_BOOT_SSL_KEY - fi - if [ ! -f $PLC_BOOT_SSL_CRT ] ; then - cp -a $PLC_WWW_SSL_CRT $PLC_BOOT_SSL_CRT - fi # Install into both /etc/pki (Fedora Core 4) and # /etc/httpd/conf (Fedora Core 2). If the API, boot, and # web servers are all running on the same machine, the web # server certificate takes precedence. for server in API BOOT WWW ; do - eval enabled=\${PLC_${server}_ENABLED} - if [ "$enabled" != "1" ] ; then + enabled=PLC_${server}_ENABLED + if [ "${!enabled}" != "1" ] ; then continue fi - eval ssl_crt=\${PLC_${server}_SSL_CRT} - eval ssl_key=\${PLC_${server}_SSL_KEY} + ssl_key=PLC_${server}_SSL_KEY + ssl_crt=PLC_${server}_SSL_CRT - symlink $ssl_crt /etc/pki/tls/certs/localhost.crt - symlink $ssl_key /etc/pki/tls/private/localhost.key - symlink $ssl_crt /etc/httpd/conf/ssl.crt/server.crt - symlink $ssl_key /etc/httpd/conf/ssl.key/server.key + symlink ${!ssl_crt} /etc/pki/tls/certs/localhost.crt + symlink ${!ssl_key} /etc/pki/tls/private/localhost.key + symlink ${!ssl_crt} /etc/httpd/conf/ssl.crt/server.crt + symlink ${!ssl_key} /etc/httpd/conf/ssl.key/server.key done ;; esac @@ -450,37 +483,70 @@ config_apache () include_path=".:$DocumentRoot/includes:$DocumentRoot/generated:/etc/planetlab/php" sed -i -e "s@;include_path = \"\.:.*\"@include_path = \"$include_path\"@" $php_ini - # Set the port numbers. If the API, boot, and web servers - # are all running on the same machine, the web server port - # numbers take precedence. - for server in API BOOT WWW ; do - eval enabled=\${PLC_${server}_ENABLED} - if [ "$enabled" != "1" ] ; then + # Disable default Listen directive + sed -i -e '/^Listen/d' $httpd_conf + + # Set the port numbers + for server in WWW API BOOT ; do + enabled=PLC_${server}_ENABLED + if [ "${!enabled}" != "1" ] ; then continue fi - eval http_port=\${PLC_${server}_PORT} - eval https_port=\${PLC_${server}_SSL_PORT} + hostname=PLC_${server}_HOST + http_port=PLC_${server}_PORT + https_port=PLC_${server}_SSL_PORT + + # API should always be accessed via SSL + if [ "$server" = "API" ] ; then + https_port=${!http_port} + http_port= + fi + + # Check if we are already listening on these ports + skip_http=0 + skip_https=0 + for previous_server in WWW API BOOT ; do + if [ "$server" = "$previous_server" ] ; then + break + fi + previous_hostname=PLC_${previous_server}_HOST + previous_http_port=PLC_${previous_server}_PORT + previous_https_port=PLC_${previous_server}_SSL_PORT + + if [ "${!http_port}" = "${!previous_http_port}" ] ; then + skip_http=1 + fi + if [ "${!https_port}" = "${!previous_https_port}" ] ; then + skip_https=1 + fi + done - if [ -n "$http_port" ] ; then - sed -i -e "s/^Listen .*/Listen $http_port/" $httpd_conf + # Listen on these ports + if [ $skip_http -eq 0 -a -n "${!http_port}" ] ; then + cat < + Redirect /db https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/db + # XXX Not yet until we can get rid of oldapi + # Redirect /$PLC_API_PATH https://$PLC_API_HOST:$PLC_API_PORT/$PLC_API_PATH + +EOF fi - if [ -n "$https_port" ] ; then + if [ $skip_https -eq 0 -a -n "${!https_port}" ] ; then + # XXX Cannot support NameVirtualHost over SSL. If + # the API, boot, and web servers are all running + # on the same machine, the web server certificate + # takes precedence. sed -i \ - -e "s/^Listen .*/Listen $https_port/" \ - -e "s///" \ + -e "s/^Listen .*/Listen ${!https_port}/" \ + -e "s///" \ $ssl_conf fi - done - + done >$plc_conf + # Set custom Apache directives ( if [ "$PLC_API_ENABLED" = "1" ] ; then - # XXX We should only support non-SSL access to the - # API by writing this to conf.d/plc_ssl.conf, then - # writing "Include conf.d/plc_ssl.conf" to - # conf.d/ssl.conf. Once oldapi, which does not - # support SSL, is removed from the web pages, we - # can do this. cat < SetHandler python-program @@ -488,22 +554,22 @@ config_apache () PythonHandler mod_pythonXMLRPC EOF - fi - - if [ "$PLC_WWW_ENABLED" = "1" ] ; then + else cat < - Redirect /db https://$PLC_WWW_HOST:$PLC_WWW_SSL_PORT/db - + + Deny from all + EOF - else + fi + + if [ "$PLC_WWW_ENABLED" != "1" ] ; then cat < Deny from all EOF fi - ) >$plc_conf + ) >>$plc_conf # Make alpina-logs directory writable for bootmanager log upload chown apache:apache $DocumentRoot/alpina-logs/nodes @@ -581,6 +647,42 @@ EOF esac } +config_bootcd () +{ + case "$1" in + start) + if [ "$PLC_BOOT_ENABLED" != "1" -a \ + "$PLC_WWW_ENABLED" != "1" ] ; then + return 0 + fi + + # Customize the BootCD + pushd /var/www/html/download + /usr/share/bootcd/build.sh + check + popd + ;; + esac +} + +config_bootmanager () +{ + case "$1" in + start) + if [ "$PLC_BOOT_ENABLED" != "1" -a \ + "$PLC_WWW_ENABLED" != "1" ] ; then + return 0 + fi + + # Customize the Boot Manager + pushd /var/www/html/boot + /usr/share/bootmanager/build.sh + check + popd + ;; + esac +} + usage() { echo "Usage: $0 [OPTION]... [COMMAND]" -- 2.47.0