• # Faisable, mais pas avec nginx en front

    Posté par (site web personnel) . En réponse au message Réseau : Passer du HTTPS à un conteneur Docker. É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 ...