Forum Linux.général Réseau : Passer du HTTPS à un conteneur Docker

Posté par  (site web personnel) . Licence CC By‑SA.
0
10
oct.
2018

Bonjour,

Suite à mon problème que j'ai résolu grâce à ce post j'ai voulu passer à niveau supérieur, le https.

Du coup naturellement j'ai généré des certificats avec le script deshydrated dans le conteneur Docker et ensuite j'ai appliqué la même recette qu'en http côté Nginx (proxy)

  server {
    listen 443;
    server_name nextcloud.reynum.eu;

    location / {
      proxy_pass http://nextcloud.reynum.eu:6443;
      #proxy_redirect http://nextcloud.reynum.eu:6443/ https://nextcloud.reynum.eu;
      proxy_set_header Host $host;
    }
  }

Et du côté conteneur Docker et apache

Alias /nextcloud /var/www/nextcloud/
Alias /.well-known/acme-challenge /var/www/dehydrated

ServerName nextcloud.reynum.eu

<VirtualHost _default_:443>

        ServerAdmin reynum2@free.fr
        DocumentRoot /var/www/nextcloud/

        <Directory /var/www/nextcloud/>
                  Options +FollowSymlinks
                  AllowOverride All

                 <IfModule mod_dav.c>
                        Dav off
                 </IfModule>

                 SetEnv HOME /var/www/nextcloud
                 SetEnv HTTP_HOME /var/www/nextcloud

        </Directory>

        <Directory /var/www/dehydrated>
                Options None
                AllowOverride None

                # Apache 2.4
                <IfModule mod_authz_core.c>
                        Require all granted
                </IfModule>
        </Directory>

        SSLEngine on
        SSLCertificateFile /etc/dehydrated/certs/nextcloud.reynum.eu/fullchain.pem
        SSLCertificateKeyFile /etc/dehydrated/certs/nextcloud.reynum.eu/privkey.pem
        SSLProtocol all -SSLv2 -SSLv3
        SSLHonorCipherOrder on

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

Et là problème Firefox me répond.

An error occurred during a connection to nextcloud.reynum.eu. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG

Du coup j'ai testé plein de choses côté nginx et côté apache et rien n'y fait je n'arrive pas à faire du https, alors que je veux avoir les certificats dans le conteneur docker.

Si vous avez une solution, un conseil ?

  • # proxy et ssl

    Posté par  . Évalué à 3.

    je doute que tu puisses faire ce que tu decris,
    en effet le proxypass ne va pas simplement passer la requete au serveur suivant,

    il recoit la requete de ton firefox, fournit le certificat SSL du "proxy",
    puis interroge le serveur final (ton docker) en https.

    le firefox et le public n'ont aucune connaissance du certificat qui se trouve sur le docker.

    il te faudrait remonter le certificat au niveau du NGINX

    • [^] # Re: proxy et ssl

      Posté par  (site web personnel) . Évalué à 2. Dernière modification le 11 octobre 2018 à 08:22.

      il te faudrait remonter le certificat au niveau du NGINX

      Aïlle Aïlle Aïlle, c'est ce que je craignais.
      Merci pour la réponse

      kentoc'h mervel eget bezan saotred

      • [^] # Re: proxy et ssl

        Posté par  . Évalué à 4.

        Sinon, tu fais un proxy TCP au lieu de HTTP (mais tu n'aurais pas la notion des vhost).

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: proxy et ssl

          Posté par  (site web personnel) . Évalué à 2.

          Stop moi si je me trompe mais, ce que tu nommes vhost c'est la possibilité d'avoir plusieurs site dans des conteneurs séparés sur un seul serveur ?

          kentoc'h mervel eget bezan saotred

          • [^] # Re: proxy et ssl

            Posté par  . Évalué à 3.

            C'est le filtrage basé sur le nom d'hôte du header HTTP ou le SNI de TLS. Si tu fais la redirection au niveau TCP tout le trafic qui arrive sur le port en question sera envoyé au même endroit.

            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: proxy et ssl

            Posté par  . Évalué à 2.

            le vhost c'est le fait d'avoir plusieurs domaines et sites webs derriere la meme IP,
            c'est alors le nom DNS qui sert à orienter le client vers le bon dossier (au sein d'une machine) ou dans ton cas vers le bon docker.

            tu peux aussi faire du vhost dans le docker, mais cela n'a pas de sens.

            sinon, comme proposer, tu peux faire du proxy TCP, c'est alors un renvoi direct du port 443 de l'IP 'publique' vers le docker qui va avec, et comme tu ne connais pas le nom de domaine, tu ne peux pas heberger plusieurs services sur le port 443.

            • [^] # Re: proxy et ssl

              Posté par  (site web personnel) . Évalué à 2.

              tu ne peux pas heberger plusieurs services sur le port 443.

              Du coup ça ne correspond pas à mon besoin.

              kentoc'h mervel eget bezan saotred

              • [^] # Re: proxy et ssl

                Posté par  . Évalué à 3. Dernière modification le 11 octobre 2018 à 15:45.

                tu ne peux pas heberger plusieurs services sur le port 443.

                Du coup ça ne correspond pas à mon besoin.

                donc il te reste à heberger les certificats sur le reverse proxy de la machine principal,

                c'est alors ce proxy qui va repondre à tes clients, et parler (en clair ou en chiffré) à des dockers

                et c'est par les fonctionnalités SNI qui vont ouvrir le flux, voir quel DNS est demandé, que le routage vers le bon docker va se faire

                ton client ne verra jamais ton docker, mais uniquement ton reverse proxy et son certificat SSL

  • # Le plus simple en effet

    Posté par  . Évalué à 2.

    Serait d'utiliser ton frontal nginx pour la partie certificats/SSL ça sera nettement plus simple et tu pourras gérer des domaines wildcards.

    Tu peux laisser en https ton backend d'autant plus qu'nginx ne râle pas sur les backend avec des certificats non signés.

  • # Faisable, mais pas avec nginx en front

    Posté par  (site web personnel) . Évalué à 3. Dernière modification le 11 octobre 2018 à 11:40.

    Ce que tu veut faire est faisable, mais pas en mettant un proxy http devant un site https, la negotiation HTTPS commence avant même que le premier octet de communication du protocole http ne s'etablisse.

    Tu as deux options:
    1 gérer le https et le certificat sur un proxy http/https standard
    2 utiliser un proxy tcp

    Sachant que la négociation https (ssl plus précisement) nécessite en théorie de fournir un certificat "à l'aveugle" (ie sans savoir quel est le site demandé par le navigateur) l'option permettant le plus de support client est un proxy tcp sur une IP dédiée.

    Comme cette solution devient in-envisageable rapidement, notamment vis-a-vis de la réduction des IP, on a rajouter le "SNI": en gros le navigateur lors de l'établissement de la session ssl envoi le nom du site voulu, ce qui permet d'utiliser plusieurs certificats sur une seule IP, cela ouvre la voie à deux techniques:
    * un proxy HTTPS qui gère plusieurs domaines et certificats (nginx,apache,traefik,haproxy)
    * un proxy TCP qui inspecte le SNI, et route le trafic sur un autre logiciel (haproxy, peut-etre d'autres)

    Perso, ayant un serveur avec une seule IPv4 et plusieurs IPv6 j'ai choisi la solution d'utiliser haproxy en proxy pour IPv4 et des accès directs en IPv6, du coup pour le https j'ai mis en place haproxy en inspecteur SNI, qui renvoi sur les webserveurs des jails, en rajoutant son entete ProxyProtocol pour garder les IP sources

    # https routing on SNI (https isn't handled by haproxy to allow one ssl configration v4/v6)
    frontend https-in
        bind <ip>:443
        tcp-request inspect-delay 5s
        tcp-request content accept if { req_ssl_hello_type 1 }
    
        ## figure out which one to use
        use_backend jblog-sni if { req_ssl_sni -i blog.example.com }
        use_backend jcloud-sni if { req_ssl_sni -i cloud.example.com }
        use_backend imap-sni if { req_ssl_sni -i imap.example.com }
    
        default_backend jblog-sni
    
    backend jcloud-sni
        acl clienthello req_ssl_hello_type 1
        acl serverhello rep_ssl_hello_type 2
    
        tcp-request inspect-delay 5s
        tcp-request content accept if clienthello
    
        tcp-response content accept if serverhello
        server jcloud <ip priv jail>:443 maxconn 32 send-proxy
    

    Exemple de configuration nginx:

    server {
        listen       <ip priv jail>:443      ssl http2 proxy_protocol;
        listen       [ <ipv6 jail> ]:443 ssl http2;
    
        server_name cloud.example.com;
    
        # Set the client remote address to the one sent in the X_FORWARDED_FOR header from trusted addresses.
        set_real_ip_from                <ip priv haproxy>;
        real_ip_header                  proxy_protocol;
        real_ip_recursive               on;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers                 ECDHE;
        ssl_prefer_server_ciphers   on;
        ssl_ecdh_curve              secp384r1;
        ...
    }
    

    Après selon la configuration, un outil comme traefik dont la config se gère dynamiquement en relation avec la solution de conteneurs et qui gère LE nativement peut être une bien meilleure idée

    PS: faire du docker pour faire du docker …

  • # nginx-proxy

    Posté par  (site web personnel) . Évalué à 1.

    Bonsoir,

    As tu regardé du coté de :

    https://github.com/jwilder/nginx-proxy

    et

    https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion/

    C'est l'idéal pour héberger de multiple applications docker avec du SSL

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.