Installer un reverse-proxy sécurisé

Publié le 15/06/2021

Linux/Debian, Domotique, Sécurité

A l'aide d'un Raspberry Pi, nous allons créer un Reverse Proxy afin d'accéder de manière sécurisée à notre serveur domotique, nos caméras, notre NAS, etc...

Il s'agit d'un moyen efficace et sécurisé d'offrir un accès aux services d'un réseau interne au travers d'une passerelle offrant un cryptage SSL.

Ainsi, contrairement au Proxy classique qui permet à un utilisateur d'accéder au réseau internet, le proxy inverse (reverse proxy) permet d'accéder au réseau interne depuis internet.

Par contre, afin d'être sure que seule les personnes autorisées pourront accéder aux services, on les identifiera avec un certificat généré par le reverse-proxy et protégé par mot de passe.


Grâce à cette installation, vous pourrez accéder en toute sécurité à vos serveurs domotiques, imprimantes 3D, caméras de sécurité, NAS, caméras IP, etc... depuis internet.


Prérequis

Paramétrage de la Box internet

Rendez-vous dans votre box et ajoutez votre raspberry en tant que DMZ.
Ainsi, tout le trafic internet qui tentera de se connecter à votre réseau internet sera redirigé vers la passerelle.
Il est également possible de ne rediriger que les ports TCP 433 et 80.

Matériel nécessaire

  • Un raspberry pi de n'importe quelle version devrait suffire, mais je recommande tout de même d'utiliser au moins un Raspberry Pi 2.
    Et c'est presque tout...
  • Un cable réseau
    Le wifi peut fonctionner mais ce n'est pas idéale et ça peut représenter une faille dans la sécurité...
  • Clavier, souris, écran...
    Mais pas obligatoire, car on peut accéder au système vi SSH.

Installation et Configuration

Commençons par installer le serveur web :

sudo apt-get install apache2

Création des certificats

Certificats serveur

On crée le fichier de configuration de base :

nano openssl.cnf

Collez-y le contenu suivant :


[ req ]
default_md = sha1
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
countryName = Country
countryName_default = FR
countryName_min = 2
countryName_max = 2
localityName = Locality
localityName_default = France
organizationName = Organization
organizationName_default = reverse_proxy
commonName = Common Name
commonName_default = nom.de.domaine.fr
commonName_max = 64

[ certauth ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
crlDistributionPoints = @crl

[ server ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
nsCertType = server
crlDistributionPoints = @crl

[ client ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = clientAuth
nsCertType = client
crlDistributionPoints = @crl

[ crl ]
URI=ca.crl

Puis on génère le certificat auto-signé de l’autorité de certification :

openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer
Generating a RSA private key
..............................................................................................................................................................................................+++++
....................+++++
writing new private key to 'ca.key'
-----
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 [FR]:
Locality [France]:
Organization [Reverse_proxy]:
Common Name []:nom.de.domaine.fr

Vous devez indiquer dans le Common Name le nom de domaine ou l'adresse IP de votre box.

Ensuite on crée la clé serveur :

openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
............................+++++
...........................................................................................................................................................................................+++++
e is 65537 (0x010001)

Puis, on effectue une demande de signature de certificat :

openssl req -config ./openssl.cnf -new -key server.key -out server.req de magdiblog dont j'ai corrigé les erreurs.


For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country [FR]:
Locality [France]:
Organization [Reverse_proxy]:
Common Name []:nom.de.domaine.fr

Enfin, signons la CSR avec le certificat de l’autorité de certification pour obtenir le certificat serveur :

openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 3650 -outform PEM -out server.cer Signature ok subject=C = FR, L = France, O = Reverse_proxy, CN = nom.de.domaine.fr Getting CA Private Key

Et supprimons server.req devenu inutile :

rm server.req

Certificats client

On génère une nouvelle clé par client :

openssl genrsa -out client1.key 2048
openssl genrsa -out client2.key 2048
openssl genrsa -out client3.key 2048

Generating RSA private key, 2048 bit long modulus (2 primes)
.+++++
.....................+++++
e is 65537 (0x010001)

Puis le CSR :

openssl req -config ./openssl.cnf -new -key client.key -out client.req
openssl req -config ./openssl.cnf -new -key client2.key -out client2.req
openssl req -config ./openssl.cnf -new -key client3.key -out client3.req

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 [FR]:
Locality [France]:
Organization [Reverse_proxy]:
Common Name []:nom.de.domaine.fr

Que l'on signe numériquement :

openssl x509 -req -in client1.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 3650 -outform PEM -out client1.cer
openssl x509 -req -in client2.req -CA ca.cer -CAkey ca.key -set_serial 102 -extfile openssl.cnf -extensions client -days 3650 -outform PEM -out client2.cer
openssl x509 -req -in client3.req -CA ca.cer -CAkey ca.key -set_serial 103 -extfile openssl.cnf -extensions client -days 3650 -outform PEM -out client3.cer

Signature ok
subject=C = FR, L = France, O = Reverse_proxy, CN = nom.de.domaine.fr
Getting CA Private Key
A noter :

Le certificat serveur possède le numéro 100 et le premier client 101. Incrémentez ce nombre pour chaque nouvel utilisateur.

Enfin, pour pouvoir être utilisé dans un navigateur web, on convertit la clé et le certificat en un fichier pkcs12 :

openssl pkcs12 -export -inkey client1.key -in client1.cer -out client1.p12
openssl pkcs12 -export -inkey client2.key -in client2.cer -out client2.p12
openssl pkcs12 -export -inkey client3.key -in client3.cer -out client3.p12

Enter Export Password:
Verifying - Enter Export Password:

Choisissez un mot de passe, pour sécuriser vos certificats.
Celui-ci sera demandé quand vous l'installerez dans votre navigateur ou votre smartphone.

On supprime l'inutile :

rm client1.req client2.req client3.req

Paramétrage du seveur apache et du reverse-proxy

sudo nano /etc/apache2/sites-enabled/000-default.conf

Remplaçons son contenu par :


<VirtualHost *:443>

# activation https
SSLEngine on
#certificat serveur
SSLCertificateFile /home/pi/server.cer
#clé du serveur
SSLCertificateKeyFile /home/pi/server.key
#force le serveur à vérifier le certificat client
SSLVerifyClient require
#le certificat client doit être signé par la même autorité de certification
SSLVerifyDepth 1
#certificat de l'autorité de certification
SSLCACertificateFile /home/pi/ca.cer
#désactive les requêtes proxy
ProxyRequests off

# Domoticz
ProxyPass "/domoticz/" "http://192.168.1.102/"
ProxyPassReverse "/domoticz/" "http://192.168.1.102/"

# MotionEye
ProxyPass /motioneye/ http://192.168.1.100:7856/
ProxyPassReverse /motioneye/ http://192.168.1.100:7856/

# Nextcloud
ProxyPass "/nextcloud/" "http://192.168.1.100/"
ProxyPassReverse "/nextcloud/" "http://192.168.1.100/"

# Octoprint
ProxyPass "/nextcloud/" "http://192.168.1.150/"
ProxyPassReverse "/nextcloud/" "http://192.168.1.150/"

# serveur web perso
ProxyPass "/" "http://192.168.1.101/"
ProxyPassReverse "/" "http://192.168.1.101/"

<Proxy *>
Order allow,deny
allow from all
</Proxy>

LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/rproxy_error.log
CustomLog ${APACHE_LOG_DIR}/rproxy_access.log combined
</VirtualHost>

Ensuite, on active le service SSL :

sudo a2enmod ssl

et on redémarre le serveur apache :

sudo systemctl restart apache2

Paramétrages particuliers :

Cette section n'est pas terminée, j'ajouterais des éléments au fur et à mesure de mes découvertes.

Il n'est pas possible de faire passer du https à travers le reverse proxy.
Pour un service comme Nextcloud (installé via snap), il faut utiliser la commande suivante :

nextcloud.disable-https
Desactivating HTTPS... done
Restarting apache... done

Sécurité

Paramétrage du pare-feu

Création d'un script pour iptable :

sudo nano /etc/init.d/firewall.sh

Insérez-y le code suivant :


#! /bin/bash

### BEGIN INIT INFO
# Provides: firewall
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Gateway firewall script
# Description: Enable service provided by daemon.
### END INIT INFO

tables_start()
{
iptables -N INPUT_LOG_ACCEPT
iptables -A INPUT_LOG_ACCEPT -j LOG --log-prefix "INPUT_ACCEPT -> "
iptables -A INPUT_LOG_ACCEPT -j ACCEPT

iptables -N INPUT_LOG_DROP
iptables -A INPUT_LOG_DROP -j LOG --log-prefix "INPUT_DROP -> "
iptables -A INPUT_LOG_DROP -j DROP

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT # accepte toutes les connexions en provenance du réseau local
iptables -A INPUT -p tcp --dport 433 -j INPUT_LOG_ACCEPT # on n'accepte que les connexions sur les port 433/TCP depuis l'extérieur
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state NEW,INVALID -j INPUT_LOG_DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A OUTPUT -j ACCEPT
}

tables_clear()
{
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
}

tables_stop()
{
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -j REJECT
iptables -A OUTPUT -j REJECT
iptables -A FORWARD -j REJECT
}

tables_usage()
{
echo "usage: $0 [ start | stop | clear ]"
}

case "$1" in
stop)
echo " Stoping firewall ..."
tables_clear
tables_stop
exit 0
;;
clear)
tables_clear
exit 0
;;
start)
echo " Starting firewall ..."
tables_clear
tables_start
exit 0
;;

-h|--help)
tables_usage
exit 0
;;
*)
tables_clear
tables_start
exit 0
;;
esac

exit 1

On rend exécutable le script et on le lance au démarrage :

chmod 755 /etc/init.d/firewall.sh
cd /etc/init.d
update-rc.d firewall.sh defaults

Conclusion

Ce genre d'installation n'est pas à la portée de tout le monde, toutefois, le jeux en vaux la chandelle, car elle offre une bonne sécurité aux services hébergés à domicile.

Pour écrire cet article, je me suis inspiré de celui de magdiblog dont j'ai corrigé les erreurs.

Articles qui peuvent vous intéresser

Publié le 16/09/2020

Sécurité, Raspberry Pi

Ouvrir un accès sécurisé vers un réseau interne

A l'aide d'un Raspberry Pi, nous allons créer un Reverse Proxy.

Il s'agit d'un moyen efficace et sécurisé d'offrir un accès aux services d'un réseau interne au travers d'une passerelle offrant un cryptage SSL.

Ainsi, contrairement au Proxy classique qui permet à un utilisateur d'accéder au réseau internet, le proxy inverse (reverse proxy) permet d'accéder au réseau interne depuis internet.

Ainsi, vous pourrez accéder à vos serveurs domotiques, imprimantes 3D, caméras de sécurité, NAS, caméras IP, etc... depuis internet.


Lire la suite...
Publié le 4/01/2021

Linux/Debian, Raspberry Pi

Sauvegarder automatiquement la carte SD d'un Raspberry Pi

Pour sauvegarder le système d'un raspberry pi, c'est facile...
Eteignez-le, retirez la carte SD et faites une copie de son contenu avec WinDiskImager par exemple

C'est peut-être facile, mas cette méthode est lourde et nécessite d'éteindre le Pi.

Hors, ces micro-ordinateurs sont souvent utilisés en tant que serveur, et un serveur, ben c'est mieux de ne pas avoir à l'éteindre.

Je vais donc vous présenter une méthode pour sauvegarder le contenu d'une carte SD de Raspberry pi à distance via le réseau.


Lire la suite...
Publié le 26/01/2021

Sécurité

Protégez vos SMS avec Signal Messagerie Privée

Envoyer des SMS cryptés grâce à Signal Messagerie Privée

Signal Messagerie Privée est une application de messagerie quelque peu particulière.

Cette application, qui peut remplacer l'application de SMS par défaut de votre téléphone Android, est capable d'envoyer des messages cryptés via le réseau Internet.
Il est également possible d'y envoyer et recevoir des SMS classiques non cryptés mais si les deux utilisateurs utilisent Signal, les messages seront cryptés.


Lire la suite...
En poursuivant votre navigation sur ce site, vous acceptez l’utilisation de cookies à des fins de mesure d'audience. Fermer