Déploiement d'un serveur httpd(8) sous OpenBSD 6.0 avec PHP/MYSQL/SSL et sécurisation via PacketFilter
This article is available in english here
Depuis la version 5.7, OpenBSD intègre sa propre solution de serveur http nommée httpd(8). Cette version est actuellement assez mature afin d’héberger de façon pérenne ses applications Web.
Nous détaillerons ici la mise en place des briques logicielles courantes associées à un serveur http ainsi que leur sécurisation.
Configuration basique et lancement d’httpd(8) :
On commence par créer le fichier de configuration :
# touch /etc/httpd.conf
On édite le fichier afin d’y intégrer notre configuration de base :
# vi /etc/httpd.conf
Voici la configuration de base que nous allons détailler. J’ai mis en place des variables assez explicites afin de comprendre l’étendue des possibilités en terme de configuration.
domaine_de_lina="lina.cagedmonster.net"
bind_adress="egress"
server "domaine_de_lina" {
listen on $bind_adress port 80
}
Dans le cas présent, egress correspond tout simplement au groupe des interfaces réseau gérant les routes par défaut. N’ayant pas spécifié d’emplacement dédié aux pages à servir, l’emplacement par défaut est situé dans : /var/www/htdocs/
On crée une page de test rapide :
# echo "Page de test" > /var/www/htdocs/index.html
On teste notre configuration :
# httpd -n configuration OK
On active httpd au lancement du serveur :
# rcctl enable httpd
On lance httpd et on va consulter sa page http://IP/ ou http://URL/
# rcctl start httpd
Installation et configuration d’un environnement PHP et MySQL associés à httpd :
Nous allons passer par le système de packages d’OpenBSD, vérifiez que les informations contenues dans /etc/pkg.conf soient exactes.
# pkg_add php-mysql mariadb-server
# ln -sf /etc/php-5.6.sample/mysql.ini /etc/php-5.6/mysql.ini
On active le service PHP au démarrage :
# rcctl enable php56_fpm
On lance le service PHP :
# rcctl start php56_fpm
php56_fpm(ok)
Configuration de MySQL :
# /usr/local/bin/mysql_install_db
Activation de MySQL au démarrage :
# rcctl enable mysqld
Lancement de MySQL :
# rcctl start mysqld
Fin de la configuration de MySQL :
# /usr/local/bin/mysql_secure_installation
Enter current password for root (enter for none): [ENTRER]
Set root password? [Y/n] Y
New password: PASS
Re-enter new password: PASS
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
Il est temps de configurer httpd afin d’y intégrer la gestion de PHP :
domaine_de_lina="lina.cagedmonster.net"
bind_adress="egress"
server "domaine_de_lina" {
listen on $bind_adress port 80
directory {index "index.php" }
location "/*.php" { fastcgi socket "/run/php-fpm.sock" }
}
On teste notre configuration :
# httpd -n
configuration OK
On crée notre page PHP de test :
# echo "<?php phpinfo(); ?>" > /var/www/htdocs/index.php
On relance httpd et on teste à l’emplacement http://IP/ ou http://URL/
# rcctl restart httpd
Vous devriez obtenir quelque chose d’équivalent :
Il est temps à présent de mettre en place du SSL :
Il y deux méthodes visant à obtenir un certificat SSL.
- Auto-générer son certificat (qui ne sera pas validé par une autorité reconnue).
- Passer par une autorité telle que LetsEncrypt utilisant Certbot pour générer votre certificat. Auquel cas je vous laisserai le soin de consulter cette page.
Nous allons nous concentrer sur la première.
Génération du certificat :
# openssl genrsa -out /etc/ssl/private/server.key
Generating RSA private key, 2048 bit long modulus ...............................................................+++ ..........+++ e is 65537 (0x10001)
# openssl req -new -x509 -key /etc/ssl/private/server.key -out /etc/ssl/server.crt -days 3650
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:FR
State or Province Name (full name) []:SomeWhere
Locality Name (eg, city) []:Deauville
Organization Name (eg, company) []:CagedMonster
Organizational Unit Name (eg, section) []:CGM
Common Name (eg, fully qualified host name) []:lina.cagedmonster.net
Email Address []:[adresse masquée]
Modification de la configuration de notre httpd :
domaine_de_lina="lina.cagedmonster.net"
bind_adress="egress"
server "domaine_de_lina" {
listen on $bind_adress port 80
listen on $bind_adress tls port 443
directory {index "index.php" }
location "/*.php" { fastcgi socket "/run/php-fpm.sock" }
tls { certificate "/etc/ssl/server.crt" key "/etc/ssl/private/server.key" }
}
Comme à l’accoutumée, vérification de la configuration, restart du serveur et consultation à l’adresse **https://**IP/ ou **https://**URL/ :
# httpd -n
configuration OK
# rcctl restart httpd
httpd(ok)
A présent, nous allons configurer httpd afin que toutes les requêtes http soient redirigées en https automatiquement. Voici la configuration associée :
domaine_de_lina="lina.cagedmonster.net"
bind_adress="egress"
server $domaine_de_lina {
listen on $bind_adress port 80 block return 301 "https://$SERVER_NAME$REQUEST_URI"
}
server "domaine_de_lina" {
listen on $bind_adress tls port 443 directory {index "index.php" }
location "/*.php" { fastcgi socket "/run/php-fpm.sock" }
tls { certificate "/etc/ssl/server.crt" key "/etc/ssl/private/server.key" }
}
Même procédure, on teste notre configuration, on relance et cette fois ci nous allons visiter notre adresse en http://IP/ ou http://URL/ afin de tester si la redirection est effectuée automatiquement.
# httpd -n && rcctl restart httpd
configuration OK
httpd(ok)
Nous avons à présent un service httpd configuré avec PHP / MySQL / SSL et redirigeant les requêtes http:// vers https://
Dernier point, la sécurisation de votre service httpd avec Packet Filter (pf) :
Dans le cas où vous aimeriez mettre en ligne un CMS (WordPress, Drupal, etc.), il est fort probable que vous subissiez des tentatives de bruteforce sur le système de Login ce qui en plus de remplir vos logs risque de consommer des ressources serveur inutiles.
Voici une configuration adaptée comprenant un maximum de connexions de 100 et un nombre de requêtes maximum de 30 requêtes toutes les 15 secondes :
# vi /etc/pf.conf
pass quick proto tcp from any to any port 80 \
flags S/SA keep state \
(max-src-conn 100, max-src-conn-rate 30/15, \
verload <bruteforce> flush global)
pass quick proto tcp from any to any port 443 \
flags S/SA keep state \
(max-src-conn 100, max-src-conn-rate 30/15, \
overload <bruteforce> flush global)
Reste à recharger la configuration :
# pfctl -f /etc/pf.conf
Il vous est également possible de consulter les adresses bannies :
# pfctl -t bruteforce -T show
Pour supprimer une adresse :
# pfctl -t bruteforce -T delete <IP>
Pour que les adresses bannies expirent au bout d’un temps donné (une heure dans ce cas précis) :
# pfctl -t bruteforce -T expire 3600
Besoin d’aide ?