##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Outils de haut niveau pour gérer apache et sa configuration ##@cooked nocomments ##@require base ##@require sysinfos ##@require apache uprovide apache.tools urequire base sysinfos apache 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 } __APACHE_AUTOCONF_SUFFIXES=(d8 d) __APACHE_AUTOCONF_SUFFIX_d8=(-d debian -v jessie+) __APACHE_AUTOCONF_SUFFIX_d=(-d debian) function __apache_autoconf_check_suffix() { array_contains __APACHE_AUTOCONF_SUFFIXES "$1" || return 1 local sysinfos="__APACHE_AUTOCONF_SUFFIX_${1}[@]" check_sysinfos --vars sysname sysdist sysver bits "${!sysinfos}" } function __apache_autoconf_filter_suffix_files() { grep -vF .. } function __apache_autoconf_setup() { if ! check_sysinfos --vars sysname sysdist sysver bits -s linux64 linux32 linux -d debian; then eerror "apache_autoconf n'est supporté que sur Debian linux" return 1 fi urequire install compute_apache_prefixes return 0 } function __apache_autoconf_fillxxx() { local var name value first=1 for var in "$@"; do splitvar "$var" name value array_addu FILLVARS "$name" [ -n "$first" ] || FILLSCRIPT="$FILLSCRIPT"$'\n' FILLSCRIPT="${FILLSCRIPT}s/@@${name}@@/$(qseds "${value}")/g" first= done # Il faut un fichier temporaire pour les remplacement de fichiers ac_set_tmpfile FILLTEMP } function __apache_autoconf_fillcopy() { # copier le fichier $1 vers le fichier $2. Si le fichier $1 contient l'une # des variables du tableau $FILLVARS, corriger d'abord le fichier avec le # script sed $FILLSCRIPT. Le fichier temporaire $FILLTEMP est utilisé pour # le remplacement des valeurs. $3 contient le cas échéant des commandes sed # supplémentaires # Si des fichiers suffixes existent, ne faire la copie que si un fichier # approprié correspondant au système courant est trouvé local src="$1" dest="$2" sedscript="$3" perms="${4:-go+rX}" # vérifier les fichiers suffixe local suffix have_suffix found_suffix for suffix in "${__APACHE_AUTOCONF_SUFFIXES[@]}"; do if [ -f "$src..$suffix" ]; then have_suffix=1 if __apache_autoconf_check_suffix "$suffix"; then found_suffix=1 src="$src..$suffix" break fi fi done [ -n "$have_suffix" -a -z "$found_suffix" ] && return 1 # valeurs à remplacer dans le fichier local var found_var for var in "${FILLVARS[@]}"; do if quietgrep "@@${var}@@" "$src"; then found_var=1 break fi done if [ "$found_var" ]; then sed "$FILLSCRIPT $sedscript" <"$src" >"$FILLTEMP" src="$FILLTEMP" fi copy_update "$src" "$dest" "$perms" } __APACHE_AUTOCONF_HELP="\ --confdir CONFDIR Spécifier l'emplacement des fichiers de configuration apache ainsi que des fichiers 'confs.conf', 'modules.conf' et 'sites.conf'. Par défaut, prendre le répertoire local DESTDIR. --confsdir CONFSDIR Spécifier l'emplacement des fichiers des configuration. Par défaut, utiliser DESTDIR/confs si ce répertoire existe. --modulesdir MODULESDIR Spécifier l'emplacement des fichiers des modules. Par défaut, utiliser DESTDIR/modules si ce répertoire existe. --sitesdir SITESDIR Spécifier l'emplacement des fichiers des sites. Par défaut, utiliser DESTDIR/sites si ce répertoire existe. --cgibindir CGIBINDIR Spécifier l'emplacement des scripts cgi à installer. Par défaut, utiliser DESTDIR/cgi-bin si ce répertoire existe. --wwwdir WWWDIR Spécifier l'emplacement des fichiers du serveur web. Par défaut, utiliser DESTDIR/www si ce répertoire existe. --certsconfdir CERTSCONFDIR Spécifier l'emplacement des fichiers de configuration des certificats. Par défaut, utiliser DESTDIR/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 DESTDIR/RewriteRules si ce répertoire existe. --no-restart Ne pas redémarrer apache en cas de modification de la configuration" function __display_apache_autoconf_help() { eecho "$__APACHE_AUTOCONF_HELP"; } function apache_autoconf() { eval "$(utools_local)" local -a ignores local autoconfdir certsdir confdir confsdir oneconf modulesdir onemodule local sitesdir onesite cgibindir wwwdir certsconfdir rrdir onecms local sysname sysdist sysver bits local destconfsdir a2xconf local restart=1 parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with __display_apache_autoconf_help' \ --ignore: ignores \ --confdir: confdir= \ --confsdir: confsdir= \ --one-conf: oneconf= \ --modulesdir: modulesdir= \ --one-module: onemodule= \ --sitesdir: sitesdir= \ --one-site: onesite= \ --cgibindir: cgibindir= \ --wwwdir: wwwdir= \ --certsconfdir: certsconfdir= \ --rrdir: rrdir= \ --no-restart restart= \ --sysname: sysname= \ --sysdist: sysdist= \ --sysver: sysver= \ -6,--squeeze sysver=squeeze \ -7,--wheezy sysver=wheezy \ -8,--jessie sysver=jessie \ --bits: bits= \ @ args -- "$@" && set -- "${args[@]}" || die "$args" if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then ensure_sysinfos sysname sysdist sysver else sysname=("${MYSYSNAME[@]}") sysdist=("${MYSYSDIST[@]}") sysver=("${MYSYSVER[@]}") bits="$MYBITS" fi __apache_autoconf_setup || return 1 if __apache_autoconf_check_suffix d8; then confdefault=000-default.conf confdefaultssl=default-ssl.conf destconfsdir="$APACHECONFDIR/conf-available" a2xconf=1 elif __apache_autoconf_check_suffix d; then confdefault=default confdefaultssl=default-ssl destconfsdir="$APACHECONFDIR/conf.d" fi # Configuration autoconfdir="$1"; shift [ -n "$autoconfdir" ] || { eerror "Vous devez spécifier le répertoire de base de la configuration apache" return 1 } certsdir="$1"; shift if [ -z "$confdir" -o -z "$confsdir" -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 "$confsdir" ] || confsdir="$autoconfdir/confs" [ -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" [ -n "$oneconf" -o -n "$onemodule" -o -n "$onesite" ] && onecms=1 # Faire un script sed pour remplacer les variables spécifiées par leur # valeur dans les fichiers local -a FILLVARS; local FILLSCRIPT FILLTEMP __apache_autoconf_fillxxx "$@" # Copie des certificats local modified rehash conf if [ -d "$certsconfdir" ]; then local -a certsconfs certspems local certsconf certspem cert key ca array_addu FILLVARS cert array_addu FILLVARS key array_addu FILLVARS ca etitle "Installation des certificats" array_lsfiles certsconfs "$certsconfdir" "*.conf" for certsconf in "${certsconfs[@]}"; do 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 apache_resolvecert "$certsconf" "$certsdir" cert key ca || return 1 apache_addcert -y "$cert" "$key" "$ca" modified=1 done array_lsfiles certspems "$certsconfdir" "*.crt" "*.pem" for certspem in "${certspems[@]}"; do if copy_update "$certspem" "$APACHESSLCERTSDIR/$(basename -- "$certspem")"; then modified=1 rehash=1 fi done eend fi # Gestion des configurations if [ -d "$confsdir" -a \( -z "$onecms" -o -n "$oneconf" \) ]; then local -a confs local conf etitle "Installation des configurations" array_from_lines confs "$(list_files "$confsdir" "*.conf" | __apache_autoconf_filter_suffix_files)" for conf in "${confs[@]}"; do [ -z "$oneconf" -o "$conf" == "$oneconf" ] || continue estep "$conf" __apache_autoconf_fillcopy \ "$confsdir/$conf" \ "$destconfsdir/$conf" && modified=1 done eend fi # Gestion des modules if [ -d "$modulesdir" -a \( -z "$onecms" -o -n "$onemodule" \) ]; then local -a confs local conf etitle "Installation des configurations des modules" array_from_lines confs "$(list_files "$modulesdir" "*.conf" | __apache_autoconf_filter_suffix_files)" for conf in "${confs[@]}"; do [ -z "$onemodule" -o "$conf" == "$onemodule" ] || continue estep "$conf" __apache_autoconf_fillcopy \ "$modulesdir/$conf" \ "$APACHECONFDIR/mods-available/$conf" && modified=1 done eend fi # Règles de réécriture if [ -d "$rrdir" -a -z "$onecms" ]; 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" __apache_autoconf_fillcopy \ "$rrdir/$conf" \ "$APACHECONFDIR/$conf" && modified=1 done eend fi # Sites local -a enablesites disablesites if [ -d "$sitesdir" -a \( -z "$onecms" -o -n "$onesite" \) ]; then local -a confs local conf confname destconf certsconf etitle "Installation des sites" array_from_lines confs "$(list_files "$sitesdir" "*.conf" | __apache_autoconf_filter_suffix_files)" for confname in "${confs[@]}"; do conf="$sitesdir/$confname" [ -z "$onesite" -o "$confname" == "$onesite" ] || continue certsconf= if [ "${confname%.ssl.conf}" != "$confname" ]; then if [ -d "$certsconfdir" ]; then certsconf="${confname%.ssl.conf}-certs.conf" else ewarn "$conf: fichier ignoré parce que --certsconfdir n'a pas été spécifié" fi fi case "$confname" in default.conf) destconf="$confdefault";; default.ssl.conf) destconf="$confdefaultssl";; *) destconf="$confname";; esac if [ -n "$certsconf" ]; then certsconf="$certsconfdir/$certsconf" if [ -f "$certsconf" ]; then apache_resolvecert "$certsconf" "$certsdir" cert key ca || return 1 __apache_autoconf_fillcopy \ "$conf" \ "$APACHEAVSITESDIR/$destconf" "\ s#@@cert@@#$APACHESSLCERTSDIR/$(basename "$cert")#g s#@@key@@#$APACHESSLKEYSDIR/$(basename "$key")#g s#@@ca@@#$APACHESSLCERTSDIR/$(basename "$ca")#g " else eerror "$(ppath "$certsconf"): fichier introuvable. Il a été ignoré" fi else __apache_autoconf_fillcopy \ "$conf" \ "$APACHEAVSITESDIR/$destconf" fi enablesites=("${enablesites[@]}" "$destconf") modified=1 done eend fi # Fichiers de configuration if [ -d "$confdir" -a -z "$onecms" ]; then local -a confs local conf etitle "Configuration de base" array_add ignores confs.conf modules.conf sites.conf array_from_lines confs "$(list_files "$confdir" | __apache_autoconf_filter_suffix_files)" for conf in "${confs[@]}"; do array_contains ignores "$conf" && continue estep "$conf" __apache_autoconf_fillcopy \ "$confdir/$conf" \ "$APACHECONFDIR/$conf" && modified=1 done if [ -f "$confdir/confs.conf" -a -n "$a2xconf" ]; then local -a confs local conf array_from_lines confs "$(<"$confdir/confs.conf" filter_conf)" for conf in "${confs[@]}"; do if [ "${conf#-}" != "$conf" ]; then conf="${conf#-}" estep "Désactivation de la configuration $conf" a2disconf "$conf" && modified=1 else conf="${conf#+}" estep "Activation de la configuration $conf" a2enconf "$conf" && modified=1 fi done fi 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#-}" estep "Désactivation du module $module" a2dismod "$module" && modified=1 else module="${module#+}" estep "Activation du module $module" a2enmod "$module" && modified=1 fi done fi if [ -f "$confdir/sites.conf" ]; then local -a sitesconfs; local sitesconf enable array_from_lines sitesconfs "$(<"$confdir/sites.conf" filter_conf)" if [ ${#sitesconfs[*]} -gt 0 ]; then # si une configuration existe, ignorer la configuration # automatique enablesites=() disablesites=() for sitesconf in "${sitesconfs[@]}"; do if [ "${sitesconf#+}" != "$sitesconf" ]; then enable=1 sitesconf="${sitesconf#+}" elif [ "${sitesconf#-}" != "$sitesconf" ]; then enable= sitesconf="${sitesconf#-}" else enable=1 fi case "$sitesconf" in default.conf) sitesconf="$confdefault";; default.ssl.conf) sitesconf="$confdefaultssl";; esac if [ -n "$enable" ]; then array_del disablesites "$sitesconf" array_add enablesites "$sitesconf" else array_del enablesites "$sitesconf" array_add disablesites "$sitesconf" fi done fi fi eend fi # Scripts CGI if [ -d "$cgibindir" -a -z "$onecms" ]; then etitle "Installation des scripts CGI" cpdirnovcs "$cgibindir" "$CGIBINDIR" eend fi # Contenu web if [ -d "$wwwdir" -a -z "$onecms" ]; then etitle "Installation des fichiers du serveur web" cpdirnovcs "$wwwdir" "$HTDOCSDIR" eend fi # Nettoyer le fichier temporaire ac_clean "$FILLTEMP" if [ -n "${enablesites[*]}" -o -n "${disablesites[*]}" ]; then etitle "(dés)Activation des sites" local site for site in "${enablesites[@]}"; do estep "Activation du site $site" a2ensite "$site" done for site in "${disablesites[@]}"; do estep "Désactivation du site $site" a2dissite "$site" done eend fi if [ -n "$modified" ]; then [ -n "$rehash" ] && elinedots "Hashage des certificats" c_rehash if [ -n "$restart" ]; then estep "Redémarrage d'apache" "$APACHECTL" restart fi fi } function apache_autoconf_localhosts() { eval "$(utools_local)" local autoconfdir sitesdir onesite parse_opts "${PRETTYOPTS[@]}" \ --sitesdir: sitesdir= \ --one-site: onesite= \ @ args -- "$@" && set -- "${args[@]}" || die "$args" __apache_autoconf_setup || return 1 # Configuration autoconfdir="$1"; shift [ -n "$autoconfdir" ] || { eerror "Vous devez spécifier le répertoire de base de la configuration apache" return 1 } [ -n "$sitesdir" ] || sitesdir="$autoconfdir/sites" # Faire un script sed pour remplacer les variables spécifiées par leur # valeur dans les fichiers local -a FILLVARS; local FILLSCRIPT FILLTEMP ULIB_INSTALL_VERBOSE __apache_autoconf_fillxxx "$@" local -a newhosts if [ -d "$sitesdir" ]; then local -a localips localhosts confs candidates newhosts local conf tmpconf candidate array_from_lines localips "$(>/etc/hosts done }