Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/06/2020, à 23:05

DonutMan75

[RESOLU] Apache2 et VirtualHosts (question de débutant)

Bonjour à tous,
afin de bien comprendre comment fonctionnent les virtualshosts d'Apache, j'ai voulu mettre en place en local uniquement deux pseudo sites.

Le premier, accessible en http via blog1.local, contient un index.html avec juste écrit "blog1"
Le second, accessible en https via blog2.local, contient un index.html avec juste écrit "blog2"

C'est donc l'objectif (didactique) que je me suis fixé.

J'ai commencé par modifer mon /etc/hosts afin que blog1.local et blog2.local soient connus :

$ grep 'blog' < /etc/hosts
127.0.0.1	blog1.local blog1
127.0.0.1	blog2.local blog2

J'ai ensuite modifié la conf d'Apache en ajoutant les VirtualHost qui me paraissaient adaptés (en m'inspirant de cette doc) :

Listen 80
Listen 443

<VirtualHost *:80>
	ServerName blog1.local
	ServerAlias www.blog1.local
	DocumentRoot	/path/to/htdocs_blog1

	<Directory /path/to/htdocs_blog1>
		Require	all	granted
	</Directory>
	
</VirtualHost>

<VirtualHost *:443>
	ServerName blog2.local
	ServerAlias www.blog2.local
	DocumentRoot	/path/to/htdocs_blog2

	<Directory /path/to/htdocs_blog2>
		Require	all	granted
	</Directory>

	SSLEngine		on
	SSLCertificateFile	conf/certificate/blog2.cert
	SSLCertificateKeyFile	conf/certificate/blog2.key
	
</VirtualHost>

J'ai généré le certificat auto-signé avec la commande suivante :

$ sudo openssl req -x509 -nodes -days 100 -newkersa:2048 -sha256 -out ./blog2.cert -keyout ./blog2.key

En pratique, ce qui marche :

  1. l'adresse "blog1.local" dans firefox affiche bien "blog1"

  2. l'adresse "https://blog2.local" dans firefox affiche bien "blog2" après la mise-en-garde (prévisible) de firefox rapport au certificat auto-signé

En revanche :

  1. l'adresse "blog2.local" affiche étrangement "blog1"

  2. www.blog1.local et www.blog2.local ne fonctionnent pas

  3. et si je tape "blog2.local:443", je tombe sur une magnifique erreur <Bad Request>...

Le (1) et le (2) je ne l'explique pas... mais je ne suis pas sûr de bien maîtriser les directives ServerName et ServerAlias...
Le (3), je crois comprendre que mon navigateur tente de communiquer en http sur le port 443 tout simplement..

Qu'en dites-vous ?

Merci d'avance pour vos lumières smile

D.

Dernière modification par DonutMan75 (Le 03/06/2020, à 08:46)

Hors ligne

#2 Le 02/06/2020, à 06:31

krodelabestiole

Re : [RESOLU] Apache2 et VirtualHosts (question de débutant)

hésite pas à suivre la doc d'ubuntu en complément de celle d'apache : la configuration y est spécifique et morcelée.

par ex. les directives listen sont déclarées dans le fichier /etc/apache2/ports.conf, tu n'as donc pas besoin de les ajouter.

grâce a systemd-resolved tu pourrais aussi utiliser des SLD (sous-domaines) de localhost, tu n'aurais pas besoin de les résoudre dans ton fichiers hosts.
en gros ubuntu blog1.localhost et blog2.localhost marcheraient direct, pas besoin de les résoudre dans /etc/hosts.
de même que www.blog1.localhost et www.blog2.localhost.

ce qui répond d'ailleurs au 2. : ici il faut résoudre www.blog1.local et www.blog2.local dans ton fichier hosts pour qu'ils pointent sur ton serveur.

ensuite pour qu'on puisse t'aider merci d'indiquer les vrais virtualhosts que tu utilises, j'imagine que /path/to n'est pas un vrai chemin...

Hors ligne

#3 Le 02/06/2020, à 06:56

bruno

Re : [RESOLU] Apache2 et VirtualHosts (question de débutant)

J'ajoute qu'il faut éviter d'utiliser le TLD .local dont l'usage est réservé à mDNS (zeronconf)

#4 Le 03/06/2020, à 08:43

DonutMan75

Re : [RESOLU] Apache2 et VirtualHosts (question de débutant)

Bonjour à vous,
merci pour vos retours !
Bon j'ai relu en détail la doc d'Ubuntu et aussi celle d'Apache et voici les conclusions auxquelles je suis arrivé.

Ce que je cherche à faire s'appelle de l'hébergement de serveurs virtuels par nom.
Le prototype *minimal* de base est le suivant :

<VirtualHost *:80>
    ServerName toto.fr
    DocumentRoot /var/www/toto/
</VirtualHost>

Quand, au lancement du serveur, Apache rencontre ce bloc il interprète cela de la manière suivante :
VirtualHost *:80 -> Ok, tout ce qui arrive sur le port 80 toutes interfaces confondues, devra être interprété comme un serveur virtuel
ServerName : comment est-ce que le client est arrivé à me joindre ? Je regarde le champ "Host:" de l'entête http et s'il contient "toto.fr" alors j'applique les directives du bloc.
DocumentRoot : en l'occurence le site toto.fr sera servi par le répertoire /var/www/toto/

On peut ensuite raffiner et rajouter d'autres ServerName grâce à ServerAlias (par exemple toto.org...)

Les deux mécanismes que je ne maîtrisais pas sont les suivants :
- les blocs VirtualHost ont une priorité ! Si plusieurs blocs matchent alors seul le premier d'entre eux sera pris en compte
- et surtout, si aucun bloc ne matche alors le premier VirtualHost sera pris en compte !!

Pour reprendre les trois points que je ne comprenais pas, j'ajouterai donc ces commentaires :

1) l'adresse "blog2.local" affiche étrangement "blog1"

C'est attendu.
Le premier vhost ne marche pas (on attend comme ServerName blog1.local mais l'entête contient blog2.local)
Le second vhost n'est carrément pas pris en compte car il ne traite que des requêtes parvenant sur le port 443.

Comme aucun vhost ne fonctionne, c'est le premier vhost qui sera appliqué en l'occurence blog1.local. Voici pourquoi l'adresse "blog2.local" pointera vers le blog1.

Si ce comportement n'est pas celui attendu, il aurait fallu (je pense) ajouter une règle explicite pour prendre en compte l'adresse blog2.local. Quelque chose comme :

<VirtualHost *:80>
	ServerName blog2.local
	ServerAlias www.blog2.local
	DocumentRoot	/path/to/htdocs_blog2

	<Directory /path/to/htdocs_blog2>
		Require	all	granted
	</Directory>
	
</VirtualHost>

2) www.blog1.local et www.blog2.local ne fonctionnent pas

Réponse trouvée par krodelabestiole. Effectivement il fallait rajouter les adresses en www dans /etc/hosts.
Au passage, je ne connaissais pas systemd.resolved, je vais regarder ça ! Ca me paraît effectivement plus "propre" que ma solution.

3) si je tape "blog2.local:443", je tombe sur une magnifique erreur <Bad Request>...

Je pense que mon interprétation est la bonne (voir message initial). Pour contourner ce problème, une solution serait de forcer le passage en https.

Voici les citations pertinentes de la documentation Apache qui appuient mon propos.

https://httpd.apache.org/docs/2.2/fr/vhosts/details.html a écrit :

Le premier serveur virtuel de cette liste (donc, le premier serveur virtuel du fichier de configuration attribué à l'adresse IP spécifiée) se voit attribuer la plus grande priorité, ce qui signifie que c'est lui qui traite les requêtes présentant un nom de serveur invalide ou ne présentant pas de champ Host: dans l'en-tête.

Si un champ Host: est transmis dans l'en-tête de la requête, son occurrence est recherchée dans la liste et le premier serveur virtuel qui présente un ServerName ou un ServerAlias correspondant est choisi pour servir la requête. Il est possible que le champ Host: contienne un numéro de port, mais Apache utilise toujours le port sur lequel il a effectivement reçu la requête.

https://httpd.apache.org/docs/2.4/fr/mod/core.html#servername a écrit :

La directive ServerName permet (éventuellement en conjonction avec la directive ServerAlias) d'identifier de manière unique un serveur virtuel, lorsqu'elle est utilisée dans un contexte de serveurs virtuels à base de noms.

(...)

Si vous définissez des serveurs virtuels à base de nom, une directive ServerName située à l'intérieur d'une section <VirtualHost> spécifiera quel nom d'hôte doit apparaître dans l'en-tête de requête Host: pour pouvoir atteindre ce serveur virtuel.

Merci par avance de me corriger si vous pensez que j'interprète mal la doc smile

Bonne journée à tous !

Donut

Hors ligne

#5 Le 03/06/2020, à 08:46

DonutMan75

Re : [RESOLU] Apache2 et VirtualHosts (question de débutant)

Au passage, si vous souhaitez voir l'interprétation de vos fichiers de conf par Apache, il y a l'option -S

$ man httpd
(...)
-S     Show the settings as parsed from the config file (currently only shows the virtualhost settings).
(...)

Chez moi :

$ sudo httpd -S
VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server blog1.local (/usr/local/apache2/vhosts/blog1.conf:1)
         port 80 namevhost blog1.local (/usr/local/apache2/vhosts/blog1.conf:1)
                 alias www.blog1.local
         port 80 namevhost blog2.local (/usr/local/apache2/vhosts/blog2.conf:2)
*:443                  blog2.local (/usr/local/apache2/vhosts/blog2.conf:12)

Hors ligne

#6 Le 03/06/2020, à 10:41

krodelabestiole

Re : [RESOLU] Apache2 et VirtualHosts (question de débutant)

DonutMan75 a écrit :

Le premier vhost ne marche pas (on attend comme ServerName blog1.local mais l'entête contient blog2.local)
Le second vhost n'est carrément pas pris en compte car il ne traite que des requêtes parvenant sur le port 443.

tu as bien compris ! j'avais pas fait gaffe au :443 du second virtualhost sans ça j'aurais pu te le dire.

perso pour gérer les virtualhost en prod je force (forçais) systématiquement le https de cette manière :

<VirtualHost *:80>
        ServerName example.com
        RewriteEngine on
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
        <VirtualHost *:443>
                ServerName example.com

                DocumentRoot /srv/www/example.com
                <Directory /srv/www/example.com>
                        Options +FollowSymLinks
                        AllowOverride all
                        Require all granted
                </Directory>

                ErrorLog /var/log/apache2/error.example.com.log
                CustomLog /var/log/apache2/access.example.com combined

                SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
                SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
                Include /etc/letsencrypt/options-ssl-apache.conf
        </VirtualHost>
</IfModule>

maintenant je gère ça via un reverse proxy (traefik).

Hors ligne