HAProxy redirigeant http vers https (ssl)

99

J'utilise HAProxy pour l'équilibrage de charge et je souhaite uniquement que mon site prenne en charge https. Ainsi, j'aimerais rediriger toutes les demandes sur le port 80 vers le port 443.

Comment ferais-je ça?

Edit: Nous aimerions rediriger vers la même URL sur https, en préservant les paramètres de requête. Ainsi, http://foo.com/bar redirigerait vers https://foo.com/bar

Jon Chu
la source

Réponses:

137

J'ai trouvé que c'était la plus grande aide :

Utilisez HAProxy 1.5 ou plus récent, et ajoutez simplement la ligne suivante à la configuration du frontend:

redirect scheme https code 301 if !{ ssl_fc }
Jay Taylor
la source
20
Pour ajouter à cela, à partir de la réponse de User2966600 ci-dessous, avec 301 ajouté, utilisez ceci pour rediriger vers https uniquement pour un domaine spécifique:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Quentin Skousen
1
Ça a marché. Bien que cela ne fonctionne pas sans «code 301». Merci pour la mise à jour.
deej
7
Serait comme une syntaxe équivalente à la réponse donnée à ceci: http-request redirect scheme https code 301 if !{ ssl_fc }. La documentation pour la redirection http dans ALOHA HAProxy 7.0 mentionne même que " la syntaxe des deux directives est la même, cela dit, la redirection est maintenant considérée comme héritée et les configurations doivent passer au formulaire de redirection de requête http ". J'en déduis, sans être totalement sûr, que la même explication s'applique aux nouvelles versions de la version open source de HAProxy.
rodolfojcj
Merci pour votre réponse. Pourriez-vous développer pour expliquer où devons-nous ajouter cette ligne? Dans le frontend / backend / default / global / ..?
realtebo
Je le place généralement à l'intérieur du frontend, mais les redirections ne sont qu'un en-tête, donc je m'attendrais à ce qu'une redirection puisse être déclenchée jusqu'à ce que les en-têtes de réponse aient été envoyés. Je voudrais savoir si cela peut fonctionner dans les deux endroits, je devrai peut-être essayer.
Jay Taylor
68

Je n'ai pas assez de réputation pour commenter une réponse précédente, donc je poste une nouvelle réponse pour compléter la réponse de Jay Taylor. Fondamentalement, sa réponse fera la redirection, une redirection implicite cependant, ce qui signifie qu'elle émettra une 302 (redirection temporaire), mais puisque la question informe que l'ensemble du site Web sera servi en https, alors la redirection appropriée devrait être une 301 (redirection permanente ).

redirect scheme https code 301 if !{ ssl_fc }

Cela semble un petit changement, mais l'impact peut être énorme en fonction du site Web, avec une redirection permanente, nous informons le navigateur qu'il ne devrait plus chercher la version http dès le début (en évitant les futures redirections) - un gain de temps pour https des sites. Cela aide également au référencement, mais ne divise pas le jus de vos liens.

Marcos Abreu
la source
41

Pour rediriger tout le trafic:

redirect scheme https if !{ ssl_fc }

Pour rediriger une seule URL (en cas de frontend / backend multiple)

redirect scheme https if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }

user2966600
la source
1
Merci, la condition "uniquement sur un hôte spécifique" était exactement ce que je recherchais!
Quentin Skousen
Pouvez-vous s'il vous plaît montrer un exemple pratique de la deuxième option, s'il vous plaît?
RicarHincapie
16

Selon http://parsnips.net/haproxy-http-to-https-redirect/, il devrait être aussi simple que de configurer votre haproxy.cfg pour qu'il contienne les éléments suivants.

#---------------------------------------------------------------------
# Redirect to secured
#---------------------------------------------------------------------
frontend unsecured *:80
    redirect location https://foo.bar.com

#---------------------------------------------------------------------
# frontend secured
#---------------------------------------------------------------------
frontend  secured *:443
   mode  tcp
   default_backend      app

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    mode  tcp
    balance roundrobin
    server  app1 127.0.0.1:5001 check
    server  app2 127.0.0.1:5002 check
    server  app3 127.0.0.1:5003 check
    server  app4 127.0.0.1:5004 check
Matthew Brown
la source
7
Cela redirigerait donc tout vers foo.bar.com . Idéalement, nous aimerions que foo.bar.com/baz redirige vers foo.bar.com/baz . Nous avons également besoin de paramètres de requête.
Jon Chu
@JonChu soulève un cas d'utilisation valide, ce n'est qu'une solution partielle.
Jay Taylor
3
Au lieu d'utiliser l'emplacement de redirection, essayez plutôt le préfixe de redirection https: //foo.bar.com. Cela devrait aider avec le cas d'utilisation mentionné par Jon Chu.
xangxiong
16

Le meilleur moyen garanti de rediriger tout http vers https est:

frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

C'est un peu plus sophistiqué en utilisant le 'code 301', mais cela pourrait aussi bien faire savoir au client que c'est permanent. La partie «mode http» n'est pas essentielle avec la configuration par défaut, mais ne peut pas nuire. Si vous avez mode tcpdans la section par défaut (comme je l'ai fait), alors c'est nécessaire.

Maitreya
la source
10

Une légère variation de la solution de user2966600 ...

Pour tout rediriger sauf une seule URL (en cas de frontend / backend multiple):

redirect scheme https if !{ hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Josh Currier
la source
4

Comme Jay Taylor l'a dit, HAProxy 1.5-dev a la redirect schemedirective de configuration, qui accomplit exactement ce dont vous avez besoin.

Cependant, si vous ne parvenez pas à utiliser la version 1.5 et si vous êtes prêt à compiler HAProxy à partir des sources, j'ai rétroporté la redirect schemefonctionnalité pour qu'elle fonctionne dans la version 1.4. Vous pouvez obtenir le correctif ici: http://marc.info/?l=haproxy&m=138456233430692&w=2

rouillé
la source
2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com
sanyi
la source
1

Dans les versions plus récentes de HAProxy, il est recommandé d'utiliser

http-request redirect scheme https if !{ ssl_fc }

pour rediriger le trafic http vers https.

Ce mec
la source
0

Si vous souhaitez réécrire l'url, vous devez modifier l'hôte virtuel de votre site en ajoutant ces lignes:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

### Rewrite http:// => https://
RewriteCond %{SERVER_PORT} 80$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,NC,L]

Mais, si vous souhaitez rediriger toutes vos requêtes sur le port 80 vers le port 443 des serveurs web derrière le proxy, vous pouvez essayer cet exemple de conf sur votre haproxy.cfg:

##########
# Global #
##########
global
    maxconn 100
    spread-checks 50
    daemon
    nbproc 4

############
# Defaults #
############
defaults
    maxconn 100
    log global
    mode http
    option dontlognull
    retries 3
    contimeout 60000
    clitimeout 60000
    srvtimeout 60000

#####################
# Frontend: HTTP-IN #
#####################
frontend http-in
    bind *:80
    option logasap
    option httplog
    option httpclose
    log global
    default_backend sslwebserver

#########################
# Backend: SSLWEBSERVER #
#########################
backend sslwebserver
    option httplog
    option forwardfor
    option abortonclose
    log global
    balance roundrobin
    # Server List
    server sslws01 webserver01:443 check
    server sslws02 webserver02:443 check
    server sslws03 webserver03:443 check

J'espère que cela vous aidera

Plat
la source
0

Pourquoi n'utilisez-vous pas les ACL pour distinguer le trafic? au sommet de ma tête:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Cela s'ajoute à ce que Matthew Brown a répondu.

Consultez les documents ha , recherchez des éléments tels que hdr_dom et ci-dessous pour trouver plus d'options ACL. Il y a beaucoup de choix.

Glenn Plas
la source
0

Peut être fait comme ça -

  frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

Tout trafic atteignant http sera redirigé vers https

Chandan
la source
0

instruction de redirection est héritée

utilisez plutôt la redirection de requête http

acl http      ssl_fc,not
http-request redirect scheme https if http
1AmirJalali
la source
0

Simplement:

frontend incoming_requsts
        bind *:80
        bind *:443 ssl crt *path_to_cert*.**pem**
        **http-request redirect scheme https unless { ssl_fc }**
        default_backend k8s_nodes
Badr Fennane
la source