Objectif#
Accéder aux services web du réseau local par les ports normalisés (80/443) pour franchir les pare-feux.
│ mandataire ├──
└──Par exemple cockpit répond par defaut sur le port 9090, on veut pouvoir y accéder via https://cockpit.example.com. Cockpit est hébergé sur la machine hostnmame.localdomain.
Modules nécessaires :
mod_proxymod_proxy_http
Modules utiles :
mod_proxy_htmlmod_sslet d’autres DirectivesProxyPassProxyPassReverseProxyRequests
Un site statique à travers un mandataire inverse (Apache)#
DNS#
site.example.com doit pointer vers l’adresse ip du mandataire (en enregistrement CNAME est bien indiqué car il permet d’utiliser IP V4 et V6)
Le serveur de contenu :#
Le serveur de contenu (host.localdomain) doit répondre aux requêtes vers site.example.com aussi bine http que https, quel que soit le port. Il doit fournir un certificat SSL valide pour host.localdomain éventuellement auto-signé.
Sur le mandataire :#
On commence par réer un hôte virtuel correspondant par exemple dans le fichier /etc/sites-availables/site.example.com.conf :
<VirtualHost *:80>
ServerName site.example.com
</VirtualHost>Inutile de préciser la racine de documents (DocumentRoot), le mandataire ne servira aucun contenu et en particulier pas en http ; l’hôte servira probablement une page d’erreur 503 mais pour l’instant rien de grave.
Il faut ensuite l’activer et recharger apache :
$ sudo a2ensite site.example.com
Enabling site site.example.com.
To activate the new configuration, you need to run:
systemctl reload apache2
$ sudo systemctl reload apache2
$Pour l’accès https, certbot va faire tout le travail en mode interactif :
$ sudo certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/serv
er block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: xxxxx.xxxxx.xxxxx
2: site.example.com
3: xxxxx.xxxxxxx.xx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12345678901234567890123456789012345678901234567890123456789012345678901234567890
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2
Requesting a certificate for site.example.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/site.example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/site.example.com/privkey.pem
This certificate expires on 2025-07-13.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the
background.
Deploying certificate
Successfully deployed certificate for site.example.com to /etc/apache2/sites-avail
able/site.example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://site.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$cerbot modifie le fichier /etc/sites-availables/site.example.com.conf pour y ajouter la redirection de http vers https :
<VirtualHost *:80>
ServerName site.example.com
RewriteEngine on
RewriteCond %{SERVER_NAME} =site.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>certbot met en place une redirection avec des directives Rewrite* alors que la documentation apache recommande d’utiliser la directive Redirect (on verra ça ensuite).
D’après la doc, il faudrait utiliser :
Redirect "/" "https://www.example.com/"cerbot crée aussi un fichier /etc/apache2/sites-available/site.example.com-le-ssl.conf :
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName site.example.com
SSLCertificateFile /etc/letsencrypt/live/site.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>Et le site https est activé ! Rien à redire, tout est prêt. On peut vérifier en consultant http://site.example.com que le navigateur est bien renvoyé vers https://site.example.com.
À ce stade, le serveur renvoie toujours la page d’erreur 503 Service Unavailable mais le certificat est bien reconnu par le navigateur. Le certificat restera sur le mandataire et sera servi par celui-ci et pas par le serveur de contenu (on aurait pu faire un choix différent).
Mise en place du mandataire inverse :
On veut que toutes les requêtes https://site.example.com/* soient transmise vers la machine locale qui servira le contenu (host.localdomain) en http ou https. Apache propose plusieurs solutions, on retient la plus simple (et la plus courrante), la directive ProxyPass. Auparavant il est fortement conseillé d’interdire la fonction de madataire direct en mettant ProxyRequests à off [edit: ProxyRequests est à off par défaut donc inutile de la redéclarer.]:
ProxyRequests Off
ProxyPass "/" "http://host.localdomain[:port]"Maintenant toutes les requêtes vers site.example.com sont transmises à host.localdomain qui doit être configuré pour les servir (par exemple avoir une directive VirtualHost appropriée) mais la liaison n’est pas chiffrée.
#TODO Whatif le serveur de contenu est indisponible ? (actuellement le mandataire renvoie une erreur 500 avec une page mentionnant le nom du serveur de contenu, bad…)
ProxyPassReverse "/" "https://host.localdomain:port" ProxyRequests Off
SSLProxyEngine on
ProxyPass "/test" "https://sicie.miradou.com:5001/"
ProxyPassReverse "/test" "https://sicie.miradou.com:5001/"<VirtualHost *:80> ServerName URL
ProxyRequests :
Offpour un reverse proxy sinon on a un proxy ouvert.Onpour un proxy direct (avec contrôle d’accès)
Ici Off
ProxyPass /location 192....
ProxyPassReverse /location 192... </VirtualHost >
### Finalement :<VirtualHost *:80>
ServerName cepet.denfroch.miradou.com
Redirect "/" https://cepet.denfroch.miradou.com
# RewriteEngine on
# RewriteCond %{SERVER_NAME} =cepet.denfroch.miradou.com
# RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
ServerName cepet.denfroch.miradou.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/www.miradou.com
SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyRequests off
ProxyPreserveHost on
# RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
# RequestHeader set X-Forwarded-Proto %{HTTPS}s
ProxyPass "/" "https://cepet.denfroch:9090/"
ProxyPassReverse "/" "https://cepet.denfroch:9090/"
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "wss://cepet.denfroch:9090/$1" [P,L]
SSLCertificateFile /etc/letsencrypt/live/cepet.denfroch.miradou.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cepet.denfroch.miradou.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost> SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyRequests off
ProxyPreserveHost onPour cockpit il faut prévenir le serveur qui l’héberge que des requètes peuvent venir d’un sous-domaine extérieur et modifier ou créer /etc/cockpit/cockpit.conf pour y ajouter :
[WebService]
Origins = https://cockpit.domain.tld wss://cockpit.domain.tld
ProtocolHeader = X-Forwarded-Proto
Configuration de dovecot#
Entre la version 2.3 et 2.4 la syntax et les options de configuration ont beaucoup changé et sans compatitbilité.
En particulier la configuration de l’accès mysql (dans auth-sql.con.ext) :
mysql localhost {
dbname=postfixadmin
user=postfixadmin
password=XXXXXXXXX
}ainsi que la définition de la requête :
passdb sql {
default_password_scheme = PLAIN-MD5
query = SELECT username as user, password as password FROM mailbox\
WHERE username = '%{user}'
}Configuration de dovecot#
/etc/dovecot
├── conf.d
│ ├── 10-auth.conf
│ ├── 10-auth.conf.bak
│ ├── 10-auth.conf.ucf-dist
│ ├── 10-logging.conf
│ ├── 10-logging.conf.ucf-old
│ ├── 10-mail.conf
│ ├── 10-mail.conf.ucf-dist
│ ├── 10-master.conf
│ ├── 10-master.conf.ucf-dist
│ ├── 10-metrics.conf
│ ├── 10-ssl.conf
│ ├── 10-ssl.conf.ucf-dist
│ ├── 15-lda.conf
│ ├── 15-lda.conf.ucf-dist
│ ├── 15-mailboxes.conf
│ ├── 20-imap.conf
│ ├── 20-managesieve.conf
│ ├── 20-managesieve.conf.ucf-dist
│ ├── 20-pop3.conf
│ ├── 30-dict-server.conf
│ ├── 90-acl.conf
│ ├── 90-fts.conf
│ ├── 90-quota.conf
│ ├── 90-sieve.conf
│ ├── 90-sieve.conf.ucf-dist
│ ├── 90-sieve-extprograms.conf
│ ├── auth-checkpassword.conf.ext
│ ├── auth-deny.conf.ext
│ ├── auth-dict.conf.ext
│ ├── auth-ldap.conf.ext
│ ├── auth-master.conf.ext
│ ├── auth-oauth2.conf.ext
│ ├── auth-passwdfile.conf.ext
│ ├── auth-sql.conf.ext
│ ├── auth-sql.conf.ext.bak
│ ├── auth-sql.conf.ext.bak2
│ ├── auth-sql.conf.ext.ucf-dist
│ ├── auth-static.conf.ext
│ ├── auth-system.conf.ext
│ └── auth-system.conf.ext.ucf-dist
├── dh.pem
├── dovecot.conf
├── dovecot.conf.ucf-dist
├── dovecot.conf.ucf-old
├── dovecot-db.conf.ext
├── dovecot-ldap.conf.ext
├── dovecot-sql.conf
├── dovecot-sql.conf.ext
├── dovecot-sql.conf.ext.ucf-dist
└── private
├── dovecot.key -> /etc/ssl/private/ssl-cert-snakeoil.key
├── dovecot.pem -> /etc/ssl/certs/ssl-cert-snakeoil.pem
└── private-password.confEnlever les traces d’un vieux paquet#
Xuheki était un client web imap supposé se rapprocher d’un client de bureau.
Le projet était sympa mais n’a pas vécu longtemps et je n’ai pas trouvé trace de ses sources.
Installé dans /opt, il utilise un script d’installationn en perl mais pas de moyen pour le désinstaller.
En lisant le script, on voit qu’il installe des sites web pour apache,
un script de démarrage init.d quelques petites chose dans /var/lib. Ouf, un petit README :
frv@coudon:~$ cat /opt/Xuheki/manual/README
www.xuheki.com/doc is all there is for now...
frv@coudon:~$ curl http://www.xuheki.com
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>
frv@coudon:~$Dommage…
On désactive le service :
coudon:~# systemctl status xuheki
○ xuheki.service - LSB: Xuheki Mailserver daemon
Loaded: loaded (/etc/init.d/xuheki; generated)
Active: inactive (dead)
Docs: man:systemd-sysv-generator(8)
sept. 26 12:11:19 coudon systemd[1]: Started xuheki.service - LSB: Xuheki Mailserver daemon.
sept. 26 12:16:43 coudon systemd[1]: Stopping xuheki.service - LSB: Xuheki Mailserver daemon...
sept. 26 12:16:43 coudon systemd[1]: xuheki.service: Deactivated successfully.
sept. 26 12:16:43 coudon systemd[1]: Stopped xuheki.service - LSB: Xuheki Mailserver daemon.
sept. 26 12:16:43 coudon systemd[1]: Starting xuheki.service - LSB: Xuheki Mailserver daemon...
sept. 26 12:16:43 coudon xuheki[312445]: start: webmail.miradou.com
sept. 26 12:16:43 coudon systemd[1]: Started xuheki.service - LSB: Xuheki Mailserver daemon.
sept. 26 12:18:07 coudon systemd[1]: Stopping xuheki.service - LSB: Xuheki Mailserver daemon...
sept. 26 12:18:07 coudon systemd[1]: xuheki.service: Deactivated successfully.
sept. 26 12:18:07 coudon systemd[1]: Stopped xuheki.service - LSB: Xuheki Mailserver daemon.
coudon:~# systemctl disable xuheki
xuheki.service is not a native service, redirecting to systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install disable xuheki
coudon:~# Et c’est parti pour le ménage :
coudon:~# find / -iname *xuheki*
/opt/Xuheki
/opt/Xuheki/bin/xuheki.pl
/opt/Xuheki/docroot/js/xuheki-1238000750.js
/run/systemd/generator.late/xuheki.service
/etc/rc6.d/K01xuheki
/etc/init.d/xuheki
/etc/rc0.d/K01xuheki
/etc/rc3.d/K01xuheki
/etc/rc2.d/K01xuheki
/etc/rc1.d/K01xuheki
/etc/rc4.d/K01xuheki
/etc/rc5.d/K01xuheki
/var/lib/Xuheki
/var/lib/Xuheki/logs/webmail.miradou.com/xuheki.log
/var/lib/Xuheki/logs/webmail.miradou.com/xuheki-stdout.log
coudon:~# Ouf que j’ai un petit systéme de fichier…
coudon:~# rm -r /opt/Xuheki
coudon:~# rm -r /var/lib/Xuheki
coudon:~# rm -v /etc/rc?.d/K01xuheki
'/etc/rc0.d/K01xuheki' supprimé
'/etc/rc1.d/K01xuheki' supprimé
'/etc/rc2.d/K01xuheki' supprimé
'/etc/rc3.d/K01xuheki' supprimé
'/etc/rc4.d/K01xuheki' supprimé
'/etc/rc5.d/K01xuheki' supprimé
'/etc/rc6.d/K01xuheki' supprimé
coudon:~# Stabilisation du reseau#
L’interface réseau principale est configurée par DHCP donc le fichier de configuration de la résolution des noms est mise à jour par un serveur DHCP gandi qui ne fournit pas l’adresse de mon resolveur local.