HAProxy mengalihkan http ke https (ssl)

100

Saya menggunakan HAProxy untuk load balancing dan hanya ingin situs saya mendukung https. Karenanya, saya ingin mengalihkan semua permintaan di port 80 ke port 443.

Bagaimana saya melakukan ini?

Edit: Kami ingin mengalihkan ke url yang sama di https, menjaga parameter kueri. Jadi, http://foo.com/bar akan dialihkan ke https://foo.com/bar

Jon Chu
sumber

Jawaban:

141

Saya menemukan ini menjadi bantuan terbesar :

Gunakan HAProxy 1.5 atau yang lebih baru, dan cukup tambahkan baris berikut ke konfigurasi frontend:

redirect scheme https code 301 if !{ ssl_fc }
Jay Taylor
sumber
20
Untuk menambah ini, dari jawaban User2966600 di bawah, dengan 301 ditambahkan, gunakan ini untuk mengalihkan ke https hanya untuk domain tertentu:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Quentin Skousen
1
Itu berhasil. Meskipun tidak bekerja tanpa 'kode 301'. Terima kasih atas pembaruannya.
deej
7
Sebuah setara sintaks untuk jawaban yang diberikan akan seperti ini: http-request redirect scheme https code 301 if !{ ssl_fc }. Dokumentasi untuk http redirection di ALOHA HAProxy 7.0 bahkan menyebutkan bahwa " sintaks kedua direktif itu sama, yang mengatakan, redirect sekarang dianggap sebagai legacy dan konfigurasi harus pindah ke bentuk http-request redirect ". Saya menyimpulkan, tanpa sepenuhnya yakin, bahwa penjelasan yang sama berlaku untuk rilis terbaru dari versi open source HAProxy.
rodolfojcj
Terima kasih untuk balasan Anda. Bisakah Anda memperluas untuk menjelaskan di mana kami harus menambahkan baris ini? Di bagian depan / backend / default / global / ..?
realtebo
Saya biasanya menempatkannya di dalam frontend, tetapi pengalihan hanyalah sebuah header, jadi saya berharap pengalihan dapat dipicu hingga header respons telah dikirim. Saya ingin tahu apakah ini dapat berfungsi di kedua lokasi, mungkin harus mencobanya.
Jay Taylor
68

Saya tidak memiliki reputasi yang cukup untuk mengomentari jawaban sebelumnya, jadi saya memposting jawaban baru untuk melengkapi jawaban Jay Taylor. Pada dasarnya jawabannya akan melakukan pengalihan, meskipun pengalihan implisit, artinya akan mengeluarkan 302 (pengalihan sementara), tetapi karena pertanyaan tersebut menginformasikan bahwa seluruh situs web akan disajikan sebagai https, maka pengalihan yang sesuai haruslah 301 (pengalihan permanen ).

redirect scheme https code 301 if !{ ssl_fc }

Tampaknya ada perubahan kecil, tetapi dampaknya mungkin besar bergantung pada situs web, dengan pengalihan permanen kami memberi tahu browser bahwa seharusnya tidak lagi mencari versi http sejak awal (menghindari pengalihan di masa mendatang) - penghemat waktu untuk https situs. Ini juga membantu dengan SEO, tetapi tidak membagi jus tautan Anda.

Marcos Abreu
sumber
42

Untuk mengarahkan semua lalu lintas:

redirect scheme https if !{ ssl_fc }

Untuk mengalihkan satu url (Jika ada beberapa frontend / backend)

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

pengguna2966600
sumber
1
Terima kasih, kondisi "hanya pada host tertentu" adalah yang saya cari!
Quentin Skousen
Bolehkah Anda menunjukkan contoh praktis dari opsi kedua?
RicarHincapie
16

Menurut http://parsnips.net/haproxy-http-to-https-redirect/ , semudah mengonfigurasi haproxy.cfg Anda untuk memuat ikuti.

#---------------------------------------------------------------------
# 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
sumber
7
Jadi itu akan mengarahkan semuanya ke foo.bar.com . Idealnya, kami ingin foo.bar.com/baz dialihkan ke foo.bar.com/baz . Kami juga membutuhkan parameter kueri.
Jon Chu
@JonChu memunculkan kasus penggunaan yang valid, ini hanya solusi parsial.
Jay Taylor
3
Alih-alih menggunakan lokasi pengalihan, coba alihkan awalan https: //foo.bar.com. Ini akan membantu dengan kasus penggunaan yang disebutkan Jon Chu.
xangxiong
16

Cara terjamin terbaik untuk mengalihkan semua http ke https adalah:

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

Ini sedikit lebih menarik menggunakan 'kode 301 ′, tetapi mungkin juga memberi tahu klien bahwa ini permanen. Bagian 'mode http' tidak penting dengan konfigurasi default, tetapi tidak ada salahnya. Jika Anda memiliki mode tcpdi bagian default (seperti yang saya lakukan), maka itu perlu.

Maitreya
sumber
10

Sedikit variasi dari solusi user2966600 ...

Untuk mengalihkan semua kecuali satu URL (Jika ada beberapa frontend / backend):

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

Seperti yang dikatakan Jay Taylor, HAProxy 1.5-dev memiliki redirect schemearahan konfigurasi, yang menyelesaikan apa yang Anda butuhkan.

Namun, jika Anda tidak dapat menggunakan 1.5, dan jika Anda siap untuk mengompilasi HAProxy dari sumber, saya mem-backport redirect schemefungsionalitasnya sehingga berfungsi di 1.4. Anda bisa mendapatkan patchnya di sini: http://marc.info/?l=haproxy&m=138456233430692&w=2

berkarat
sumber
2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com
sanyi
sumber
1

Di versi HAProxy yang lebih baru, disarankan untuk digunakan

http-request redirect scheme https if !{ ssl_fc }

untuk mengarahkan lalu lintas http ke https.

Orang itu
sumber
0

Jika Anda ingin menulis ulang url, Anda harus mengubah virtualhost situs Anda dengan menambahkan baris ini:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

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

Tetapi, jika Anda ingin mengalihkan semua permintaan Anda pada port 80 ke port 443 server web di belakang proxy, Anda dapat mencoba contoh conf ini di haproxy.cfg Anda:

##########
# 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

Saya harap ini membantu Anda

Datar
sumber
0

Mengapa Anda tidak menggunakan ACL untuk membedakan lalu lintas? di atas kepalaku:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Ini melampaui apa yang dijawab oleh Matthew Brown.

Lihat ha docs , cari hal-hal seperti hdr_dom dan di bawah ini untuk menemukan lebih banyak opsi ACL. Ada banyak pilihan.

Glenn Plas
sumber
0

Tambahkan ini ke konfigurasi frontend HAProxy:

acl http      ssl_fc,not
http-request redirect scheme https if http

HAProxy - Mengalihkan Permintaan HTTP

Nick Tsai
sumber
0

Bisa dilakukan seperti ini -

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

Semua lalu lintas yang masuk ke http akan dialihkan ke https

chandan
sumber
0

pernyataan pengalihan adalah warisan

gunakan http-request redirect sebagai gantinya

acl http      ssl_fc,not
http-request redirect scheme https if http
Amir Jalali
sumber
0

Secara sederhana:

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
sumber