Retour

FAQ sur Apache

Note importante : Ceci est une vielle F.A.Q. et certaines parties sont peut être obsoletes. En particulier, tout ce qui concerne le SSL a été écrit alors que j'utilisais Apache 1.3.x et ne sera peut-être plus applicable avec les versions suivantes d'Apache.
Si vous trouvez quelque chose d'obsolete, merci d'y apporter vos corrections pour que je mette a jour cette FAQ.

Au menu

  1. Les liens
  2. Démarrage automatique d'Apache au boot
  3. Le mode SSL :
    1. Démarrage d'Apache
    2. Changement de mode SSL ou non SSL par l'URL
    3. Comment empêcher l'accès à certaines pages lorsque le SSL n'est pas activé ?
    4. Apache est configuré pour le 128 bits, mais pourquoi la communication ne se fait qu'en 40 bits ?
    5. Comment obliger l'utilisation d'un cryptage à 128 bits ?
  4. Comment accéder à des pages compressées ?
  5. Comment obliger l'affichage d'un fichier d'un type connu (texte, images, …) par un navigateur externe ?
  6. Comment forcer le téléchargement d'un fichier ? ( et comment changer le type MIME d'un fichier)
  7. Comment afficher une page lorsque le serveur à changé de port (ou d'adresse) ?
  8. Comment forcer le changement de page après un certains laps de temps ?
  9. Comment éviter qu'une page soit 'cachée' par le navigateur ?
  10. Est-il possible de soumettre un formulaire avec un élément qui normalement ne peut pas soumettre (par exemple, une checkbox ) ?
  11. Comment soumettre un formulaire en cliquant sur une image tout en donnant une valeur à un paramètre de CGI ?
  12. Comment afficher la date de dernière modification d'un fichier ou d'un répertoire (par exemple, pour un répertoire où sont indiquées les dernières nouveautés d'un serveur) ?
  13. Vérification de la validité d'une date.

Les liens

Le site de mod_ssl contient toutes les instructions pour compiler et installer un Apache SSL.
On y notera que l'installation d'OpenSSL sur le système n'est pas nécessaire au bon fonctionnement du serveur ni même lors de sa compilation.

Démarrage automatique d'Apache au boot

Voici un exemple de script permettant le démarrage automatique d'Apache au boot de la machine.
Notes :

Le script suivant est a installer dans le répertoire /etc/init.d sous le nom httpd.

#
# /etc/init.d/httpd
#
# Démarrage d'Apache
# par L.Faillie
#

[ ! -d /usr/local/apache ] && exit

case "$1" in
'start')
        /usr/local/apache/bin/apachectl start
        ;;
'stop')
        /usr/local/apache/bin/apachectl stop
        ;;
*)
        echo "Usage: $0 { start | stop }"
        exit 1
        ;;
esac
exit 0

Pour qu'il soit pris en compte lors du démarrage de la machine, il faut créer les liens suivants vers ce fichier.

Sans entrer tros dans les détails, les K27httpd indiquent que le serveur doit être stoppé lors du passage aux niveaux 0, 1, 2 (typiquement lors de l'arrêt de la machine) et single user. Le rc3.d/S16httpd démarre le serveur lors du passage du Kernel au niveau 3, mode de fonctionnement normal de la machine.

Démarrage d'Apache avec SSL

Pour des questions de sécurité, il est préférable de crypter les clefs du serveur. L'inconvénient est qu'un mot de passe est demandé pour décrypter ces clefs, interdisant de fait un redémarrage automatique du serveur.
La solution est de prévoir deux modes de fonctionnement :

Ces deux modes de fonctionnement sont configurés automatiquement par le script d'installation d'Apache, en particulier grâce aux directives :

	
	<IfDefine SSL>
	…
	</IfDefine>

Le démarrage en mode dégradé se fait par un simple httpd alors que le mode SSL se lance par httpd -DSSL

Il est aussi possible d'empêcher le redémarrage en mode dégradé en placant les directives suivantes dans le fichier httpd.conf

	
	<IfDefine !SSL>
		Erreur_:_Utilisez_-DSSL
	</IfDefine>

Comment passer et revenir automatiquement du mode SSL ?

Une communication en mode SSL entraîne une légère surcharge du serveur. C'est pourquoi il est souvent préférable de ne le réserver qu'aux parties du site vraiment critiques. Si une connexion normale utilise le protocole http: (port 80), une communication SSL se caractérise par le protocole https: (port 443).
Le problème étant que passer du SSL au mode normal (ou inversement) peut être assimilé à un changement de serveur, donc on ne peut plus utiliser les liens relatifs.

Pour palier à ce problème, mod_rewrite d'Apache vient à notre secours.

Pour que cela fonctionne, il faut ajouter les commandes suivantes dans le fichier de configuration d'apache :

	
	RewriteEngine on
	RewriteRule   ^/(.*):SSL$ 
	 https://%{SERVER_NAME}/$1	[R,L]
	RewriteRule  
	^/(.*):NOSSL$ http://%{SERVER_NAME}/$1	[R,L]

Note : par défaut, le module rewrite n'est pas activé dans les "virtualhost". On notera que le serveur https est en fait un virtualhost donc il est nécessaire de rajouter dans sa définition les commandes suivantes :

	
	<VirtualHost _default_:443>

		RewriteEngine on
		RewriteOptions inherit

	…

Note2 :les ":SSL" et ":NOSSL" doivent être placée à la fin de l'URL et non après les arguments d'un CGI.
Ainsi http://monserveur/moncgi?argument1=truc&argument2=bidule:SSL ne fonctionnera pas.
La version correcte est http://monserveur/moncgi:SSL?argument1=truc&argument2=bidule.

Comment empêcher l'accès à certaines pages lorsque le SSL n'est pas activé ?

Pour faciliter la gestion du site, il est souvent préférable que les pages protégées et les autres se trouvent dans la même arborescence. L'astuce des :SSL et :NOSSL permet de changer de mode, mais n'empêche pas d'accéder aux pages protégées en mode non-SSL en spécifiant directement leur URL.
Pour bloquer de tels accès, il suffit de rajouter dans les blocs qui protège la page (<Directory>, <Location> , <Files> ou dans un fichier .htaccess) la directive SSLRequireSSL

Apache est configuré pour le 128 bits, mais pourquoi la communication ne se fait qu'en 40 bits ?

La limite vient du navigateur et non d'Apache. En effet, la communication se fait avec le cryptage le plus fort accepté par les deux parties. Hors, les navigateurs les plus courants (Netscape Navigator et M$-IE) proviennent des USA où la loi interdit d'exporter des logiciels dont la clef de cryptage dépasse les 40 bits. L'utilisation d'une clef de plus de 40 bits dépend de la loi de chaque pays, mais pour la France, la loi autorise maintenant le cryptage à 128 bits.

Il est possible de débrider le navigateur de NetScape en utilisant un logiciel nommé Fortify (http://www.fortify.net).
Il est payant pour une utilisation commerciale.

Comment obliger l'utilisation d'un cryptage à 128 bits ?

Pour les données vraiment sensibles, on peut forcer l'utilisation d'un cryptage à clef de 128 bits par la commande suivante, a placer dans les blocs qui protège la page (<Directory>, <Location> , <Files> ou dans un fichier .htaccess) :
SSLCipherSuite HIGH:MEDIUM

Notez bien que dans ce cas, les utilisateurs qui n'ont pas passé leur navigateur à 128 bits ne pourront accéder à ces pages.

Comment accéder à des pages compressées ?

Les versions Unix des navigateurs permettent généralement de lire des pages compressées (.Z ou .gz). Malheureusement, ça ne fonctionne pas toujours lorsque le navigateur est sur une autre plate-forme (m$-windows en particulier). La solution est alors d'utiliser une décompression du coté du serveur.

Ajouter les commandes suivantes dans le fichier de configuration du serveur Apache

	

	Action	dec_au_vol	/cmd/decrunch_txt
	AddHandler dec_au_vol .Z
	AddHandler dec_au_vol .gz

Créer le script /cmd/decrunch_txt suivant :

	
	#!/bin/ksh

	echo content-type: text/plain
	echo

	gzcat $PATH_INFO

A noter le script est traité comme un CGI classique donc il doit en avoir les prérogatives (en particulier les autorisations d'exécution).

Comment obliger l'affichage d'un fichier d'un type connu (texte, images, …) par un navigateur externe ?

Lorsque le serveur http sert un fichier, il détermine automatiquement un type MIME associé. Il ne se base pas uniquement sur son extension (sous Unix du moins) mais examine son contenu. C'est ainsi qu'un fichier nommé "etiquettes.liste" aura comme type "text/plain" s'il ne contient que du texte. Si l'on souhaite forcer l'utilisation d'un programme externe pour le visualiser, un traitement de texte, il est nécessaire de lui associer un nouveau type MIME. C'est ce que fait par exemple ce simple CGI.

	
	#!/bin/sh
	#
	#	/cgi-bin/force_etq
	#	© L.Faillie 1999
	#       Ce 'CGI' permet de forcé le "Content-type" pour afficher les étiquettes.
	# si on tente de l'afficher directement, les données sont considérées comme
	# étant du texte simple.

	echo Content-type: application/etq
	echo

	cat $PATH_INFO

Reste à associer dans le navigateur le type "application/etq" au traitement de texte.
Pour afficher le fichier /tmp/etiquettes.liste, on utilisera l'URL suivante : /cgi-bin/force_etq/tmp/etiquettes.liste

Notes :

Comment forcer le téléchargement d'un fichier ? ( et comment changer le type MIME d'un fichier)

Il arrive parfoit que les navigateurs essaient d'afficher le contenu des fichiers gtarés. Evidemment, le résultat n'est qu'un charabia incompréhensible.
Pour éviter ce genre de problème, il suffit de forcer le type MIME à application/octet-stream.
Les directives suivantes permettent de forcer le téléchargement de tous les fichiers tgz (archive gtarée) et lha.

	
<FilesMatch "\.(lha|tgz)$">
        ForceType       application/octet-stream
</FilesMatch>

Comment afficher une page lorsque le serveur à changé de port (ou d'adresse) ?

Lors des phases de développement, on utilise souvent des ports non standard pour accéder au serveur web (par exemple, on utilisera le port 8080). Le jour ou le serveur est mis en production, il peut-être utile d'afficher un message indiquant aux personnes qui ont mises l'ancienne URL dans leur bookmark que le serveur à changé d'URL.
La solution est d'utiliser un virtual host.

Dans le fichier conf/httpd.conf, ajouter les commandes suivantes :

	
	Listen 8080

	<VirtualHost	VirtualHost _default_:8080>
	    DocumentRoot /apache/redirect

	        ErrorDocument	404       /
	</VirtualHost>
  1. Le listen indique au serveur qu'il faut écouter aussi l'ancien port, qui est servit par le virtual host défini par la suite.
  2. Le « /apache/redirect » devra être remplacé par l'URL de la page indiquant le changement (Attention, par commodité, préférer utiliser un répertoire entier au lieu de l'URL sur un fichier, sinon, il ne sera pas possible d'utiliser des images ...).
  3. Comme aucun autre fichier n'est servi par ce 'serveur', il faut aussi redéfinir l'erreur 404 (fichier absent) pour qu'elle pointe sur ce même fichier.
  4. Il peut être aussi utile de forcer la redirection vers le nouveau site, comme expliqué dans la question suivante.

Comment forcer le changement de page après un certains laps de temps ?

Utilisez la balise suivante dans la partie <head> du document HTML :

	
	<meta
	http-equiv="refresh"
	content="30;URL=http://wwwd.nv_serveur.com">

Note :

  1. la durée avant le rafraîchissement exprimée en seconde (ici 30 secondes); elle peut être nulle, dans ce cas la nouvelle URL est chargée immédiatement (interdit l'utilisation du 'back' du navigateur mais peut être très laid visuellement si la nouvelle page provient d'un serveur lent,
  2. l'URL de destination, qui peut être relative à la page actuelle ...

Comment éviter qu'une page soit 'cachée' par le navigateur ?

La methode la plus simple est d'ajouter les tags suivants dans l'entête <head> de la page :

	
	<html>
	<head>
		<META HTTP-EQUIV="pragma" CONTENT="no-cache">
		<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
		<META HTTP-EQUIV="Expires" CONTENT="Thu, 01 Dec 1994 120000 GMT">
	</head>
	...

Les 2 premiers simulent l'émission d'entêtes HTTP indiquant que la page ne doit pas être cachée. Si elles ne sont pas reconnues, la troisieme simule l'émission du entête qui indique que la page est obsolete : on a prédaté la page !
Attention : les meta ne fonctionnent pas toujours avec tous les navigateurs, en particulier avec les anciennes (heu, pas temps que ça) versions d'MS-Internet-Exploiteur. Etonnant non ?
Pour etre sur que la page n'est pas cachée, générer ces entêtes par un CGI.

Notes :

Est-il possible de soumettre un formulaire avec un élément qui normalement ne peut pas soumettre (par exemple, une checkbox ) ?

Il suffit d'ajouter un onclick dans la balise de l'élément et d'utiliser une fonction identique à celle décrite dans la question suivante.

Comment soumettre un formulaire en cliquant sur une image tout en donnant une valeur à un paramètre de CGI ?

Il est possible d'utiliser une image comme bouton de soumission d'un formulaire grâce aux balises <BUTTON> (mais malheureusement, ça ne semble pas marcher avec tous les navigateurs :-( ) ou au type « image » des balises INPUT, comme dans : <input type=image name=fleur src=/images/rose.jpg>

Dans ce cas, on ne peut pas spécifier de valeur à associer à 'fleur' car seul les coordonnées du click dans la fenêtre nous sont transmis (champs « fleur.x » et « fleur.y »). De plus, malgré les spécifications d'HTML 4.0, onclick dans des INPUTs sur des images ou directement dans des IMGs ne semblent pas fonctionner :-(
Il est possible d'avoir le fonctionnement souhaité en passant par des javascript.

	
	<html>
	<head>
		<script
	type="text/javascript">
	function envoie(val){
		this.document.formulaire.fleur.value=val;
		this.document.formulaire.submit();
	}
		</script>
	</head>
	<body>
		<form name=formulaire action=moncgi.cgi>
			<a href="bidon" onclick="envoie('ma valeur'); return(false);" >
				<IMG src="/images/rose.jpg" border=0 >
			</a>
		</form>
	</body>
	</html>

Notes :

Comment afficher la date de dernière modification d'un fichier ou d'un répertoire (par exemple, pour un répertoire où sont indiquées les dernières nouveautés d'un serveur) ?

Il faut utiliser les commandes SSI suivantes :

  1. Dans l'entête du fichier html (<head></head>)
    <!--#config timefmt="%d/%m/%Y" \>
    qui spécifie le format à utiliser pour l'affichage des dates.
  2. <!--#flastmod virtual="news" \>
    pour afficher la date du répertoire news.

Notez qu'avec virtual, il faut spécifier l'URL du fichier ou du répertoire alors qu'avec file on indique le chemin physique.
Attention : depuis Apache 1.3.9, il n'est plus autorisé d'utiliser des chemins absolus avec file.

Vérification de la validité d'une date.

Le javascript suivant vérifie la validité d'une date saisie dans un champs de type « text » qui est passé en paramètre.

	
	function valide_date(dt){
		if(dt.value.length == 6)	// Préformatage jj/mm/aa si nécessaire
			dt.value = dt.value.substr(0,2) + "/" + dt.value.substr(2,2) + "/" + dt.value.substr(4);

		rep = new Date();
		if(dt.value.length == 8){
			tmp = Number(dt.value.substr(6));
			tmp += (tmp < 90) ? 2000 : 1900;
			rep= new Date(tmp, Number(dt.value.substr(3,2))-1, dt.value.substr(0,2));
		}
		
		dt.value= rep.getDate() + "/" + (rep.getMonth()+1) + "/" + (rep.getYear() % 100);
	}

La date saisie doit être au format jj/mm/aa (ou éventuellement 'jjmmaa' mais dans ce cas, elle est forcée au premier format). C'est aussi le format utilisé comme résultat.

On utilise unblur pour que la fonction soit appelée lorsque le curseur quitte le champs de saisie :
<input type=text name=date onblur="valide_date(this)">