##@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 } 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 local src="$1" dest="$2" sedscript="$3" perms="${4:-go+rX}" local var found for var in "${FILLVARS[@]}"; do if quietgrep "@@${var}@@" "$1"; then found=1 break fi done if [ "$found" ]; then sed "$FILLSCRIPT $sedscript" <"$src" >"$FILLTEMP" src="$FILLTEMP" fi copy_update "$src" "$dest" "$perms" } function apache_autoconf() { eval "$(utools_local)" local autoconfdir certsdir confdir modulesdir sitesdir cgibindir wwwdir certsconfdir rrdir local restart=1 parse_opts "${PRETTYOPTS[@]}" \ --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 # 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 "$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 # Faire un script sed pour remplacer les variables spécifiées par leur # valeur dans les fichiers local -a FILLVARS; local FILLSCRIPT FILLTEMP 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 # Copie des certificats local modified conf if [ -d "$certsconfdir" ]; then local -a certsconfs local certsconf 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 apache_resolvecert "$certsconf" "$certsdir" cert key ca || return 1 apache_addcert -y "$cert" "$key" "$ca" modified=1 done eend fi # Configuration des modules 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" __apache_autoconf_fillcopy \ "$modulesdir/$conf" \ "$APACHECONFDIR/mods-available/$conf" && modified=1 done eend fi # Règles de réécriture 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" __apache_autoconf_fillcopy \ "$rrdir/$conf" \ "$APACHECONFDIR/$conf" && modified=1 done eend fi # Sites local -a enablesites disablesites if [ -d "$sitesdir" ]; then local -a confs local conf confname destconf certsconf 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 __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" ]; 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" __apache_autoconf_fillcopy \ "$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#-}" 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 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 array_del disablesites "${sitesconf#+}" array_add enablesites "${sitesconf#+}" elif [ "${sitesconf#-}" != "$sitesconf" ]; then array_del enablesites "${sitesconf#-}" array_add disablesites "${sitesconf#-}" else array_del disablesites "$sitesconf" array_add enablesites "$sitesconf" fi done fi fi eend fi # Scripts CGI if [ -d "$cgibindir" ]; then etitle "Installation des scripts CGI" cpdirnovcs "$cgibindir" "$CGIBINDIR" eend fi # Contenu web if [ -d "$wwwdir" ]; 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" -a -n "$restart" ]; then estep "Redémarrage d'apache" "$APACHECTL" restart fi }