nutools/ulib/apache

672 lines
23 KiB
Plaintext
Raw Normal View History

2013-08-27 15:14:44 +04:00
##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Gestion du service apache (démarrage/arrêt), et de sa configuration
##@cooked nocomments
##@require base
##@require sysinfos
uprovide apache
urequire base sysinfos
function __apache_prefixes_checkdir() {
local dir
for dir in "$@"; do
if [ -d "$dir" ]; then
echo "$dir"
return 0
fi
done
return 1
}
function __apache_prefixes_checkfile() {
local file
for file in "$@"; do
if [ -f "$file" ]; then
echo "$file"
return 0
fi
done
return 1
}
function __apache_prefixes_checkexec() {
local exec
for exec in "$@"; do
if [ -x "$exec" ]; then
echo "$exec"
return 0
fi
done
return 1
}
function get_default_apachebin_prefix() {
__apache_prefixes_checkexec /usr/sbin/{apache2,apache,httpd}
}
function get_default_apacheversion_prefix() {
[ -n "$APACHEBIN" ] || return
local version="$($APACHEBIN -v | grep version:)"
if [[ "$version" == *1.3* ]]; then
echo ""
elif [[ "$version" == *2.0* ]]; then
echo "2"
elif [[ "$version" == *2.2* ]]; then
echo "2.2"
elif [[ "$version" == *2.4* ]]; then
echo "2.4"
fi
}
function get_default_apachectl_prefix() {
[ -n "$APACHEBIN" ] || return
__apache_prefixes_checkexec "$(dirname "$APACHEBIN")"/apache*ctl
}
function get_default_apachelogdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /var/log/{apache2,httpd}
elif check_sysinfos -s linux; then
if check_sysinfos -d debianlike; then
__apache_prefixes_checkdir /var/log/{apache2,apache}
elif check_sysinfos -d redhatlike; then
__apache_prefixes_checkdir /var/log/httpd
elif check_sysinfos -d gentoo; then
# XXX à vérifier
__apache_prefixes_checkdir /var/log/{apache{2,},httpd}
fi
fi
}
function get_default_apachesslcertsdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /etc/{apache2,httpd}/ssl.crt
elif check_sysinfos -s linux; then
__apache_prefixes_checkdir /etc/ssl/certs /etc/pki/tls/certs /etc/httpd/conf/ssl.crt
fi
}
function get_default_apachesslkeysdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /etc/{apache2,httpd}/ssl.key
elif check_sysinfos -s linux; then
__apache_prefixes_checkdir /etc/ssl/private /etc/pki/tls/private /etc/httpd/conf/ssl.key
fi
}
function get_default_apacheconfdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /etc/{apache2,httpd}
elif check_sysinfos -s linux; then
if check_sysinfos -d debianlike; then
__apache_prefixes_checkdir /etc/{apache{2,,-ssl},httpd}
elif check_sysinfos -d redhatlike; then
__apache_prefixes_checkdir /etc/httpd
elif check_sysinfos -d gentoo; then
__apache_prefixes_checkdir /etc/{apache{2,},httpd}
fi
fi
}
function get_default_apacheconf_prefix() {
[ -n "$APACHECONFDIR" ] || return
__apache_prefixes_checkfile "$APACHECONFDIR"/{apache2,{,conf/}httpd}.conf
}
function get_default_apacheavsitesdir_prefix() {
[ -n "$APACHECONFDIR" ] || return
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir "$APACHECONFDIR/sites_disabled"
elif check_sysinfos -d debianlike gentoo; then
__apache_prefixes_checkdir "$APACHECONFDIR/sites-available"
fi
}
function get_default_apachesitesdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir "$APACHECONFDIR/sites"
elif check_sysinfos -d debianlike gentoo; then
__apache_prefixes_checkdir "$APACHECONFDIR/sites-enabled"
fi
}
function get_default_htdocsdir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /Library/WebServer/Documents
elif check_sysinfos -s linux; then
if check_sysinfos -d debianlike; then
__apache_prefixes_checkdir /var/www
elif check_sysinfos -d redhatlike; then
__apache_prefixes_checkdir /var/www/html
elif check_sysinfos -d gentoo; then
__apache_prefixes_checkdir /var/www/localhost/htdocs
fi
fi
}
function get_default_cgibindir_prefix() {
if check_sysinfos -s darwin; then
__apache_prefixes_checkdir /Library/WebServer/CGI-Executables
elif check_sysinfos -s linux; then
if check_sysinfos -d debianlike; then
__apache_prefixes_checkdir /usr/lib/cgi-bin
elif check_sysinfos -d redhatlike; then
__apache_prefixes_checkdir /var/www/cgi-bin
elif check_sysinfos -d gentoo; then
__apache_prefixes_checkdir /var/www/localhost/cgi-bin
fi
fi
}
__apache_prefixes=
function __compute_apache_prefixes() {
[ -n "$__apache_prefixes" ] && return
APACHEBIN="${APACHEBIN:-$(get_default_apachebin_prefix)}"
APACHEVERSION="${APACHEVERSION:-$(get_default_apacheversion_prefix)}"
APACHECTL="${APACHECTL:-$(get_default_apachectl_prefix)}"
APACHELOGDIR="${APACHELOGDIR:-$(get_default_apachelogdir_prefix)}"
APACHESSLCERTSDIR="${APACHESSLCERTSDIR:-$(get_default_apachesslcertsdir_prefix)}"
APACHESSLKEYSDIR="${APACHESSLKEYSDIR:-$(get_default_apachesslkeysdir_prefix)}"
APACHECONFDIR="${APACHECONFDIR:-$(get_default_apacheconfdir_prefix)}"
APACHECONF="${APACHECONF:-$(get_default_apacheconf_prefix)}"
APACHEAVSITESDIR="${APACHEAVSITESDIR:-$(get_default_apacheavsitesdir_prefix)}"
APACHESITESDIR="${APACHESITESDIR:-$(get_default_apachesitesdir_prefix)}"
HTDOCSDIR="${HTDOCSDIR:-$(get_default_htdocsdir_prefix)}"
CGIBINDIR="${CGIBINDIR:-$(get_default_cgibindir_prefix)}"
__apache_prefixes=1
}
UTOOLS_PREFIXES=("${UTOOLS_PREFIXES[@]}" APACHEBIN APACHEVERSION APACHECTL APACHELOGDIR APACHESSLCERTSDIR APACHESSLKEYSDIR APACHECONFDIR APACHECONF APACHEAVSITESDIR APACHESITESDIR HTDOCSDIR CGIBINDIR)
function compute_apache_prefixes() {
__compute_apache_prefixes
}
function recompute_apache_prefixes() {
__apache_prefixes=
__compute_apache_prefixes
}
function get_APACHEBIN_prefix() {
__compute_apache_prefixes
echo "$APACHEBIN"
}
function get_APACHEVERSION_prefix() {
__compute_apache_prefixes
echo "$APACHEVERSION"
}
function get_APACHECTL_prefix() {
__compute_apache_prefixes
echo "$APACHECTL"
}
function get_APACHELOGDIR_prefix() {
__compute_apache_prefixes
echo "$APACHELOGDIR"
}
function get_APACHESSLCERTSDIR_prefix() {
__compute_apache_prefixes
echo "$APACHESSLCERTSDIR"
}
function get_APACHESSLKEYSDIR_prefix() {
__compute_apache_prefixes
echo "$APACHESSLKEYSDIR"
}
function get_APACHECONFDIR_prefix() {
__compute_apache_prefixes
echo "$APACHECONFDIR"
}
function get_APACHECONF_prefix() {
__compute_apache_prefixes
echo "$APACHECONF"
}
function get_APACHEAVSITESDIR_prefix() {
__compute_apache_prefixes
echo "$APACHEAVSITESDIR"
}
function get_APACHESITESDIR_prefix() {
__compute_apache_prefixes
echo "$APACHESITESDIR"
}
function get_HTDOCSDIR_prefix() {
__compute_apache_prefixes
echo "$HTDOCSDIR"
}
function get_CGIBINDIR_prefix() {
__compute_apache_prefixes
echo "$CGIBINDIR"
}
function __apache_resolvcert() {
[ -n "$__rc_dir" ] || __rc_dir="$(dirname "$__rc_conf")"
eval "$(
source "$__rc_conf"
set_var_cmd __rc_cert "$cert"
set_var_cmd __rc_key "$key"
set_var_cmd __rc_ca "$ca"
)"
[ -n "$__rc_cert" ] && __rc_cert="$(abspath "$__rc_cert" "$__rc_dir")"
[ -n "$__rc_key" ] && __rc_key="$(abspath "$__rc_key" "$__rc_dir")"
[ -n "$__rc_ca" ] && __rc_ca="$(abspath "$__rc_ca" "$__rc_dir")"
}
function __apache_checkvars() {
if [ -n "$__rc_cert" -a -z "$__rc_key" ]; then
local __rc_name __rc_ext
splitname "$__rc_cert" __rc_name __rc_ext
if [ "$__rc_ext" == "crt" -o "$__rc_ext" == "pem" ]; then
__rc_key="$__rc_name.key"
enote "La clé privée n'a pas été spécifiée. La valeur $(ppath "$__rc_key") sera utilisée"
else
eerror "Impossible de trouver la clé privée correspondant au certificat $(ppath "$__rc_cert")"
return 1
fi
fi
if [ -z "$__rc_cert" -a -z "$__rc_ca" ]; then
eerror "Vous devez spécifier le certificat à installer"
return 1
elif [ -z "$__rc_cert" ]; then
eattention "Seul le certificat autorité a été spécifié."
elif [ -z "$__rc_ca" ]; then
ewarn "Aucun certificat autorité n'a pas été spécifié. Cela ne peut marcher que si le certificat est autosigné"
fi
local i
for i in "$__rc_cert" "$__rc_key" "$__rc_ca"; do
[ -n "$i" ] || continue
[ -f "$i" ] || {
eerror "$i: Fichier introuvable"
return 1
}
done
}
function apache_resolvecert() {
# Calculer l'emplacement des certificats correspondant aux arguments $1 et
# $2 (qui correspondent aux options --conf et --dir de apache_addcert()),
# puis initialiser les variables $3(=cert), $4(=key) et $5(=ca)
local __rc_conf="$1" __rc_dir="$2"
local __rc_cert __rc_key __rc_ca
__apache_resolvcert
__apache_checkvars || return 1
set_var "${3:-cert}" "$__rc_cert"
set_var "${4:-key}" "$__rc_key"
set_var "${5:-ca}" "$__rc_ca"
}
function apache_addcert() {
function __apache_addcert_display_help() {
uecho "apache_addcert: Installer un certificat sur le serveur
USAGE
apache_addcert [options] [cert.pem [cert.key [ca.pem]]]
OPTIONS
--conf certsconf
--dir certsdir
Spécifier un fichier de configuration et un répertoire depuis lesquels
prendre les informations sur les certificats à utiliser.
Le fichier de configuration doit définir les variables cert, key et ca
avec les noms des fichiers contenant respectivement le certificat, la
clé privée, et les certificats autorités, exprimés relativement au
répertoire certsdir.
Si ces options ne sont pas spécifiées, les fichiers doivent être donnés
sur la ligne de commande.
--out-cert cert
--out-key key
--out-ca ca
Au lieu d'installer les certificats, placer les chemins vers les
fichiers correspondant dans les variables spécifiées"
}
eval "$(utools_local)"
local action=install
local certsconf certsdir cert key ca
local __out_cert __out_key __out_ca
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __apache_addcert_display_help' \
-C:,--conf: certsconf= \
-d:,--dir: certsdir= \
--out-cert: '$set@ __out_cert; action=dump' \
--out-key: '$set@ __out_key; action=dump' \
--out-ca: '$set@ __out_ca; action=dump' \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
local __rc_conf __rc_dir
local __rc_cert __rc_key __rc_ca
if [ -n "$certsconf" ]; then
__rc_conf="$certsconf"
__rc_dir="$certsdir"
__apache_resolvconf
__apache_checkvars || return 1
else
__rc_cert="$1"
__rc_key="$2"
__rc_ca="$3"
__apache_checkvars || return 1
fi
cert="$__rc_cert"
key="$__rc_key"
ca="$__rc_ca"
if [ -n "$cert" ]; then
estepi "Certificat: $(ppath "$cert")"
estepi "Clé privée: $(ppath "$key")"
fi
[ -n "$ca" ] && estepi "CAutorités: $(ppath "$ca")"
ask_yesno "Voulez-vous continuer?" O || return 1
urequire install
etitle "Installation des certificats"
certsdir="$(get_APACHESSLCERTSDIR_prefix)"
keysdir="$(get_APACHESSLKEYSDIR_prefix)"
if [ ! -d "$certsdir" ]; then
mkdir -p "$certsdir" || return 1
chmod 755 "$certsdir" || return 1
fi
if [ ! -d "$keysdir" ]; then
mkdir -p "$keysdir" || return 1
chmod 710 "$keysdir" || return 1
fi
if [ -n "$cert" ]; then
copy_replace "$cert" "$certsdir" || return 1
chmod 644 "$certsdir/$(basename "$cert")" || return 1
copy_replace "$key" "$keysdir" || return 1
chmod 640 "$keysdir/$(basename "$key")" || return 1
fi
if [ -n "$ca" ]; then
copy_replace "$ca" "$certsdir" || return 1
chmod 644 "$certsdir/$(basename "$ca")" || return 1
fi
eend
return 0
}
function apache_autoconf() {
function __apache_autoconf_display_help() {
uecho "apache_autoconf: Mettre à jour la configuration d'apache
USAGE
apache_autoconf AUTOCONFDIR [CERTSDIR]
AUTOCONFDIR peut contenir les fichiers et répertoires suivants, qui sont tous
optionnels:
- modules.conf la liste des modules qu'il faut activer. Si un module n'existe
pas dans ce fichier, ou si ce fichier n'existe pas, aucune modification n'est
effectuée. Si un module est de la forme -module, il est désactivé. Si un
module est de la forme +module, il est activé. Cette syntaxe permet de
supporter les modules dont le nom commencerait par '-'
- sites.conf la liste des sites qu'il faut activer. Si un site ne figure pas
dans ce fichier, il est désactivé. Si ce fichier n'existe pas, tous les sites
existant sont activés.
- tous les autres fichiers sont copiés tels quels dans /etc/apache2. Notamment,
apache2.conf est le fichier de configuration principal d'apache et ports.conf
le fichier de configuration des ports d'écoute.
- modules/ le répertoire des configurations de modules à installer. Les fichiers
de ce répertoire sont de la forme MODULE.conf et sont installés dans le
répertoire /etc/apache2/mods-available. Il faut mentioner le module dans le
fichier modules.conf pour l'activer.
- sites/ le répertoire des sites à installer. Les fichiers de ce répertoire sont
de la forme NAME.conf pour les sites écoutant en clair, et NAME.ssl.conf pour
les sites écoutant en https. Pour chaque site NAME.ssl.conf, un fichier
NAME-certs.conf doit exister dans certsconf/
Dans les fichiers NAME.ssl.conf, les valeurs @@cert@@, @@key@@ et @@ca@@ sont
respectivement remplacées par l'emplacement des fichiers de certificats
définis dans les fichiers correspondants NAME-certs.conf
- cgi-bin/ le répertoire des scripts cgi à installer
- www/ le répertoire qui contient les fichiers du serveur web à installer dans
l'emplacement par défaut.
- certsconf/ le répertoire qui contient la configuration pour les certificats à
installer. Si ce répertoire existe, il faut spécifier CERTSDIR
Les fichiers de ce répertoire sont de la forme NAME-certs.conf et chacun d'eux
correspondant en principe à un fichier NAME.ssl.conf dans sites/
- RewriteRules/ le répertoire qui contient la configuration de réécriture. Tous
les fichiers RewriteRules*.conf de ce répertoire sont copiés dans /etc/apache2
IMPORTANT: Cette fonction n'est pour le moment supporté que sur debian
OPTIONS
--confdir CONFDIR
Spécifier l'emplacement des fichiers de configuration apache ainsi que
modules.conf et sites.conf
Par défaut, utiliser AUTOCONFDIR
--modulesdir MODULESDIR
Spécifier l'emplacement des fichiers de configuration des modules.
Par défaut, utiliser AUTOCONFDIR/modules si ce répertoire existe.
--sitesdir SITESDIR
Spécifier l'emplacement des fichiers de configuration des sites.
Par défaut, utiliser AUTOCONFDIR/sites si ce répertoire existe.
--cgibindir CGIBINDIR
Spécifier l'emplacement des scripts cgi à installer.
Par défaut, utiliser AUTOCONFDIR/cgi-bin si ce répertoire existe.
--wwwdir WWWDIR
Spécifier l'emplacement des fichiers du serveur web
Par défaut, utiliser AUTOCONFDIR/www si ce répertoire existe.
--certsconfdir CERTSCONFDIR
Spécifier l'emplacement des fichiers de configuration des certificats.
Par défaut, utiliser AUTOCONFDIR/certsconf si ce répertoire existe.
Il faut alors spécifier aussi CERTSDIR, l'emplacement des certificats à
installer.
--rrdir RRDIR
Spécifier l'emplacement des fichiers de réécriture.
Par défaut, utiliser AUTOCONFDIR/RewriteRules si ce répertoire existe.
--no-restart
Ne pas redémarrer apache en cas de modification de la configuration"
}
eval "$(utools_local)"
local autoconfdir certsdir confdir modulesdir sitesdir cgibindir wwwdir certsconfdir rrdir
local restart=1
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __apache_autoconf_display_help' \
--confdir: confdir= \
--modulesdir: modulesdir= \
--sitesdir: sitesdir= \
--cgibindir: cgibindir= \
--wwwdir: wwwdir= \
--certsconfdir: certsconfdir= \
--rrdir: rrdir= \
--no-restart restart= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if ! check_sysinfos -s linux -d debian; then
eerror "apache_autoconf n'est supporté que sur Debian linux"
return 1
fi
urequire install
compute_apache_prefixes
autoconfdir="$1"
[ -n "$autoconfdir" ] || {
eerror "Vous devez spécifier le répertoire de base de la configuration apache"
return 1
}
certsdir="$2"
if [ -z "$confdir" -o -z "$modulesdir" -o -z "$sitesdir" \
-o -z "$cgibindir" -o -z "$wwwdir" -o -z "$certsconfdir" \
-o -z "$rrdir" ]; then
[ -d "$autoconfdir" ] || {
eerror "$autoconfdir: répertoire invalide"
return 1
}
fi
[ -n "$confdir" ] || confdir="$autoconfdir"
[ -n "$modulesdir" ] || modulesdir="$autoconfdir/modules"
[ -n "$sitesdir" ] || sitesdir="$autoconfdir/sites"
[ -n "$cgibindir" ] || cgibindir="$autoconfdir/cgi-bin"
[ -n "$wwwdir" ] || wwwdir="$autoconfdir/www"
[ -n "$certsconfdir" ] || certsconfdir="$autoconfdir/certsconf"
[ -n "$rrdir" ] || rrdir="$autoconfdir/RewriteRules"
if [ -d "$certsconfdir" ]; then
if [ -z "$certsdir" ]; then
eerror "CERTSDIR est requis si --certsconfdir est spécifié"
return 1
elif [ ! -d "$certsdir" ]; then
eerror "$certsdir: répertoire invalide"
return 1
fi
fi
local modified conf
if [ -d "$certsconfdir" ]; then
local -a certsconfs
local certsconf cert key ca
etitle "Installation des certificats"
array_lsfiles certsconfs "$certsconfdir" "*.conf"
for certsconf in "${certsconfs[@]}"; do
apache_resolvecert "$certsconf" "$certsdir" cert key ca || return 1
apache_addcert -y "$cert" "$key" "$ca"
modified=1
done
eend
fi
if [ -d "$modulesdir" ]; then
local -a confs
local conf
etitle "Installation des configurations des modules"
array_from_lines confs "$(list_files "$modulesdir" "*.conf")"
for conf in "${confs[@]}"; do
estep "$conf"
copy_update "$modulesdir/$conf" "$APACHECONFDIR/mods-available/$conf" && modified=1
done
eend
fi
if [ -d "$rrdir" ]; then
local -a confs
local conf
etitle "Installation des règles de réécriture"
array_from_lines confs "$(list_files "$rrdir" "RewriteRules*.conf")"
for conf in "${confs[@]}"; do
estep "$conf"
copy_update "$rrdir/$conf" "$APACHECONFDIR/$conf" && modified=1
done
eend
fi
local -a enablesites disablesites
if [ -d "$sitesdir" ]; then
local -a confs
local conf confname destconf certsconf tmpconf
etitle "Installation des sites"
array_lsfiles confs "$sitesdir" "*.conf"
for conf in "${confs[@]}"; do
confname="$(basename "$conf")"
destconf="$confname"
certsconf=
if [ "${destconf%.ssl.conf}" != "$destconf" ]; then
if [ -d "$certsconfdir" ]; then
certsconf="${destconf%.ssl.conf}-certs.conf"
else
ewarn "$conf: fichier ignoré parce que --certsconfdir n'a pas été spécifié"
fi
fi
case "$destconf" in
default.conf) destconf=default;;
default.ssl.conf) destconf=default-ssl;;
esac
if [ -n "$certsconf" ]; then
certsconf="$certsconfdir/$certsconf"
if [ -f "$certsconf" ]; then
apache_resolvecert "$certsconf" "$certsdir" cert key ca || return 1
ac_set_tmpfile tmpconf
sed "\
s#@@cert@@#$APACHESSLCERTSDIR/$(basename "$cert")#g
s#@@key@@#$APACHESSLKEYSDIR/$(basename "$key")#g
s#@@ca@@#$APACHESSLCERTSDIR/$(basename "$ca")#g
" <"$conf" >"$tmpconf"
copy_update "$tmpconf" "$APACHEAVSITESDIR/$destconf"
else
eerror "$(ppath "$certsconf"): fichier introuvable. Il a été ignoré"
fi
else
copy_update "$conf" "$APACHEAVSITESDIR/$destconf"
fi
enablesites=("${enablesites[@]}" "$destconf")
modified=1
done
eend
fi
if [ -d "$confdir" ]; then
local -a confs
local conf
etitle "Configuration de base"
array_from_lines confs "$(list_files "$confdir")"
for conf in "${confs[@]}"; do
case "$conf" in
modules.conf|sites.conf) continue;;
esac
estep "$conf"
copy_update "$confdir/$conf" "$APACHECONFDIR/$conf" && modified=1
done
if [ -f "$confdir/modules.conf" ]; then
local -a modules
local module
array_from_lines modules "$(<"$confdir/modules.conf" filter_conf)"
for module in "${modules[@]}"; do
if [ "${module#-}" != "$module" ]; then
module="${module#-}"
if a2dismod "$module"; then
estep "Désactivation du module $module"
modified=1
fi
else
module="${module#+}"
if a2enmod "$module"; then
estep "Activation du module $module"
modified=1
fi
fi
done
fi
if [ -f "$confdir/sites.conf" ]; then
#enablesites=()
#disablesites=()
# refaire enablesites et disablesites
: #XXX activer les sites
fi
eend
fi
if [ -d "$cgibindir" ]; then
etitle "Installation des scripts CGI"
cpdirnovcs "$cgibindir" "$CGIBINDIR"
eend
fi
if [ -d "$wwwdir" ]; then
etitle "Installation des fichiers du serveur web"
cpdirnovcs "$wwwdir" "$HTDOCSDIR"
eend
fi
if [ -n "${enablesites[*]}" -o -n "${disablesites[*]}" ]; then
etitle "Activation des sites"
local site
for site in "${enablesites[@]}"; do
a2ensite "$site"
done
for site in "${disablesites[@]}"; do
a2dissite "$site"
done
eend
fi
if [ -n "$modified" -a -n "$restart" ]; then
estep "Redémarrage d'apache"
"$APACHECTL" restart
fi
}