Description
OpenBSD intègre par défaut dans le système de base, depuis 5.7 :
-
un serveur web, nommé httpd - que j’ai présenté plus ou moins succinctement ici
-
un serveur relay, nommé relayd
-
Site web : https://bsd.plumbing/
-
OpenBSD : 6.6, 6.7
Le problème est que le serveur httpd n’est pas capable de gérer les entêtes HTTP (en anglais : header ), et que l’auteur ne le veut pas.
Nous passons donc le relais au serveur relayd qui lui est capable de les gérer - par contre, il le fait de manière globale, çad non spécifique à un domaine en particulier -
Configuration
Étant donné que relayd est en frontal d’httpd, nous allons modifier la configuration des deux fichiers de configuration relatifs.
- relayd va recevoir tout le traffic à destination des ports web, 80, voire 443, si TLS et le rediriger en local sur les ports correspondant. Bien sûr, il est possible d’agir sur chacune des piles réseaux des protocoles IPv4 et IPv6.
- quant à lui, httpd ne fera qu’interroger la boucle locale sur les ports redirigés.
Ne pas oublier de redémarrer les services correspondants après modifier de la configuration !
httpd
- Le fichier de configuration est
/etc/httpd.conf
, par défaut.
Dans le contexte server
, il y a deux, trois modifications importantes à
faire :
- l’option d’écoute
listen on
doit écouter localhost - cf : listen on - l’option de journalisation
log
est à modifier pour que lestyle
soit paramétré surforwarder
- cf : style
Seule l’entête HSTS est géré différement :
httpd: HSTS
L’entête HSTS se modifie, non pas en déclarant une entête, comme pour les
autres, mais en utilisant tout simplement l’option hsts
(cf : hsts).
Elle se gère bien sûr dans le contexte de protocole HTTPS , via TLS .
Pour l’instant, nous n’aborderons pas ce sujet ; d’autant que je fais les présentations dans mon article de présentation d'httpd .
httpd: exemple
Code : httpd
server "domain.tld" {
listen on 127.0.0.1 port 80
listen on ::1 port 80
# enable hsts only if you use TLS for HTTPS
hsts {
max-age 63072000
preload
subdomains
}
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
location "/" {
directory index index.html
}
log {
access "domain.tld/access.log"
error "domain.tld/errors.log"
style forwarded
}
root "/htdocs/domain.tld/www"
}
httpd: log
Voici un exemple de log :
domain.tld 127.0.0.1 - - [06/May/2020:04:08:51 +0200] "GET / HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 66.249.79.202 -
domain.tld 127.0.0.1 - - [06/May/2020:09:48:36 +0200] "GET /robots.txt HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" 5.196.87.174 -
domain.tld 127.0.0.1 - - [06/May/2020:10:29:29 +0200] "GET / HTTP/1.1" 200 0 "" "Mozilla/5.0 (compatible; AhrefsBot/6.1; +http://ahrefs.com/robot/)" 54.36.148.31 -
Nous remarquons bien que l’adresse IP du client est précisé en fin de ligne.
C’est ce que permet le paramètre de style de journal forwarder
.
relayd
- Le fichier de configuration est
/etc/relayd.conf
, par défaut.
Dans les faits :
- Nous déclarons un protocole http en lui donnant un nom - le nom importe peu, mais est réutilisé plus tard, dans le contexte des déclarations de relais.
- les filtres de correspondance
match
pour créer les réponses d’entêtesheader
.- les deux premières déclarations sont nécessaires pour capturer les
valeurs serveurs suivantes afin de les rediriger correctement :
$SERVER_ADDR:$SERVER_PORT
pour l’optionX-Forwarded-By
,$REMOTE_ADDR
pour l’optionX-Forwarded-For
.
- les deux premières déclarations sont nécessaires pour capturer les
valeurs serveurs suivantes afin de les rediriger correctement :
- puis nous relaierons en paramétrant, dans les déclarations
relay
correspondantes :- l’option d’écoute
listen
, sur l’adresse IP public et le port www et, - nous ciblons le protocole http nommé afin que les règles sur les entêtes soient appliquées dans chacun des contextes de relais, et,
- redirigerons à l’aide de l’option
forward
vers l’interface de bouclage local, et le port désiré, correspondant à celui sur lequel écoute httpd.
- l’option d’écoute
relayd: Httpoxy
Certains des plus attentifs remarqueront dans l’exemple ci-dessous la déclaration de l’entête suivante :
match request header remove "Proxy"
Celle-ci est utile pour lutter contre la faille Httpoxy qui affecte les applications CGI, PHP, dans le contexte d’une connexion HTTP .
C’est reconnue comme étant la meilleure façon de bloquer cette faille. L’autre angle de protection efficace est de fournir des connexions HTTPS , qui apparemment ne sont pas assujetties à cette faille.
relayd: exemple
Code : relayd
ip4 = "ipv4_public_address"
ip6 = "ipv6_public_address"
http protocol "hw" {
match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
match request header remove "Proxy"
match response header set "Cache-Control" value "max-age=1814400"
match response header set "Content-Security-Policy" value "upgrade-insecure-requests; default-src https: 'self'"
match response header set "Permissions-Policy" value "fullscreen=(), geolocation=(), microphone()"
match response header set "Frame-Options" value "SAMEORIGIN"
match response header set "Referrer-Policy" value "strict-origin"
match response header set "Server" value "OpenBSD Relayd+httpd"
match response header set "X-Content-Type-Options" value "nosniff"
match response header set "X-Download-Options" value "noopen"
match response header set "X-Frame-Options" value "SAMEORIGIN"
match response header set "X-Powered-By" value "!"
match response header set "X-Robots-Tag" value "index, nofollow"
match response header set "X-Xss-Protection" value "1; mode=block"
tcp { nodelay, sack, socket buffer 65536, backlog 100 }
pass
}
relay "www" {
listen on $ip4 port 80
protocol hw
forward to 127.0.0.1 port 80
}
relay "www6" {
listen on $ip6 port 80
protocol hw
forward to ::1 port 80
}
Documentations
Manpages
Autres documentations
-
Pour en savoir plus sur les entêtes :
- Content-Security-Policy : CSP : Content Security Policy (header)
- Cross-origin Resource Sharing : CORS : Cross-origin Resource Sharing (header)
- Frame-Options : X-Frame-Options (header)
- HSTS : HSTS : HTTP Strict Transport Security (header)
- Referrer : Referrer (header)
- X-Content-Type-Options : X-Content-Type-Options (header)
- X-Frame-Options : X-Frame-Options (header)
- X-Xss-Protection : X-XSS-Protection (header)
-
Pour information, Xavier Cartron @prx propose une autre méthode - personnellement testé, non réussie.
-
ou la page du wiki de la communauté “OpenBSD Pour Tous” : "HTTPd : Comment gérer les entêtes HTTP"
-
Voici un exemple très complet, avec gestion TLS - en anglais