HAProxy với SNI và các Cài đặt SSL khác nhau


9

Tôi có HAProxy cho hai trang web của mình, một trong số đó là công khai và một trang riêng tư.

www.mysite.com private.mysite.com

Atm, tôi đang sử dụng haproxy như thế này:

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3
  mode http
  acl domain_www     hdr_beg(host) -i www.
  acl domain_private hdr_beg(host) -i private.
  acl path_ghost     path_beg         /ghost/
  acl clientcert     ssl_c_used

  redirect location https://www.example.com if path_ghost !clientcert
  redirect location https://www.example.com if !domain_www !clientcert

  use_backend bknd_private if domain_private
  use_backend bknd_www     if domain_www

  default_backend bknd_www

Điều này nên làm là yêu cầu chứng chỉ ứng dụng khách (tùy chọn) và tiến hành. Nếu tên miền không phải là www.example.com và khách truy cập không thể cung cấp chứng chỉ phù hợp hoặc đường dẫn là / ghost / và khách truy cập không thể cung cấp chứng chỉ phù hợp, thì nên chuyển hướng đến https://www.example.com

Cho đến nay, điều này hoạt động tốt. Tuy nhiên, tôi đã nhận được khiếu nại của người dùng Mac khi duyệt trang web của tôi với Safari rằng họ cứ bị yêu cầu chứng nhận khi duyệt trên https://www.example.com/ trong khi đó, Firefox chỉ hỏi khi duyệt https: //private.example .com / hoặc https://www.example.com/ghost/ .

Rõ ràng đó là cách Safari hoạt động nên tôi không thể khắc phục điều đó. Ý tưởng của tôi là sử dụng SNI để phân chia giữa các tiền tuyến khác nhau

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem no-sslv3

frontend private_https
  bind *.443 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3

Tất nhiên điều đó không hiệu quả vì

a. Tôi không thể có hai giao diện nghe trên cổng 443 chỉ với một IP công khai b. Tôi chưa tìm thấy cách nào để nói "use_frontend if domain_www" hoặc đại loại như thế. (Chỉ use_backend hoặc use-server)

Tôi cũng đã thử làm điều đó với ba máy chủ haproxy

frontend haproxy-sni
bind *:443 ssl crt /etc/mycert.pem no-sslv3
mode tcp

tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }

acl domain_www ssl_fc_sni_end -i www.example.com

use-server server1 haproxy-private.lan  if !domain_www
use-server server2 haproxy-public.lan   if domain_www

Điều này hoạt động, vấn đề ở đây là haproxy-private yêu cầu chứng chỉ ứng dụng khách, nhưng yêu cầu không đến được trình duyệt. Bằng cách nào đó haproxy-sni bỏ yêu cầu.

Ngoài ra, bây giờ tôi có ba máy chủ haproxy không mong muốn (mặc dù là một tùy chọn khả thi nếu tôi không thể tìm ra giải pháp tốt hơn).

Tốt nhất là tôi muốn một cái gì đó như thế này (tạo thành .. không biết các tùy chọn thực sự)

frontend mysite_https
  bind *.443 ssl crt /etc/mycert.pem no-sslv3
  mode http

  acl domain_www     hdr_beg(host) -i www.
  acl domain_private hdr_beg(host) -i private.
  acl path_ghost     path_beg         /ghost/

  ssl_options ca-file /etc/myca.pem verify optional if !www_domain          # made up!
  ssl_options ca-file /etc/myca.pem verify optional if !path_ghost          # made up!

  acl clientcert     ssl_c_used

  redirect location https://www.example.com if path_ghost !clientcert
  redirect location https://www.example.com if !domain_www !clientcert
  ...

Tôi hy vọng ai đó có thể giúp tôi với điều này ...

Câu trả lời:


13

Tôi đã tìm thấy một giải pháp cho vấn đề này, đó là không yêu cầu máy chủ hoặc dịch vụ bổ sung. Tôi không hoàn toàn chắc chắn nếu điều này không sinh ra vấn đề mới mặc dù. Đối với tôi nó dường như làm việc ngay bây giờ.

Cách tôi đã làm là tạo một lối vào cho mỗi tên miền yêu cầu cài đặt ssl khác nhau. Sau đó, tôi đặt tùy chọn liên kết của các giao diện đó thành các cổng cao (chúng không thể truy cập được từ công chúng!).

Tôi đã tạo một giao diện nghe khác trên cổng: 443 để phân chia lưu lượng dựa trên SNI và đặt các máy chủ phụ trợ thành 127.0.0.1:high-port.

Bằng cách này, tôi đã tạo ra một vòng lặp trong haproxy

[incoming]->[haproxy:443]->[haproxy:7000]->[www.intern.lan]
[incoming]->[haproxy:443]->[haproxy:8000]->[private.intern.lan]

Đây là phần cấu hình.

frontend frnd_snipt                                             # Frontend_SNI-PassThrough (snipt)
  bind *:443                                                    # Do not use bind *:8443 ssl crt etc....!
  option tcplog
  mode tcp 

  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 } 

  acl subdomain_is_www   req_ssl_sni -i www.example.com
  acl subdomain_is_www   req_ssl_sni -i example.com
  acl subdomain_is_private req_ssl_sni -i private.example.com

  use_backend bknd_snipt_private if subdomain_is_private
  use_backend bknd_snipt_www  if subdomain_is_www

backend bknd_snipt_www
  mode tcp                                              # tcp mode must match the frontend mode - already set as default in [global]
  server snipt-www 127.0.0.1:7000                       # run without "check", otherwise haproxy checks itself all the time!

backend bknd_snipt_private
  mode tcp     
  server snipt-private 127.0.0.1:8000                   # also, don't add "ssl" when in tcp mode. "ssl" is an http mode option (result in "NO-SRV" when set in tcp)

##### NORMAL HAPROXY PART #####
frontend www_example_com                                # this frontend can be in tcp or http mode...
  bind *:7000 ssl crt /etc/mycert.pem no-sslv3          # www. frontend with normal https
  mode http
  option httplog


frontend private_example_com
  bind *:8000 ssl crt /etc/mycert.pem ca-file /etc/myca.pem verify optional no-sslv3        # private. frontend with client certificate request.
  mode http
  option httplog
  ... # whatever you have in your frontend

Nếu bất cứ ai có suy nghĩ về điều này, hoặc bất kỳ ý tưởng tại sao điều này có thể là một ý tưởng tồi xin vui lòng cho tôi biết. Nó hoạt động, nhưng tôi tự hỏi tại sao use_frontend không phải là một tùy chọn. Có lẽ bởi vì đó là điều không nên làm vì bất cứ lý do gì.


Ý tưởng tốt. Tôi cũng không thể tìm thấy tài liệu về thiết lập này. Hiệu suất có giống với vòng lặp HAProxy này không?
JB. Với Monica.

Xin lỗi, tôi không biết nó hoạt động như thế nào vì A: đã không sử dụng nó lâu (vì các bộ lọc ip nguồn), B: không có trang web lưu lượng truy cập cao, nơi tối ưu hóa hiệu suất sẽ thú vị hơn ...
mohrphium

Tôi chỉ đặt apache2 trước haproxy, hoạt động nhưng khá ngu ngốc vì một điểm thất bại trước cụm hapeoxy và (tôi nghĩ) tắc nghẽn hiệu suất (tôi nghĩ rằng hap nhanh hơn ap2, không có dữ liệu thực sự trên mặc dù vậy.)
mohrphium 24/08/2015

3

các phiên bản gần đây của haproxy hỗ trợ một cài đặt được gọi là crt-listcho phép bạn chỉ định các cài đặt TLS khác nhau dựa trên chứng chỉ phù hợp

bạn có thể sử dụng nó như thế này:

haproxy.conf:

frontend https
    mode http
    bind *:443 ssl crt-list /etc/haproxy/crt-list.conf ca-file ca.pem

    use_backend test if { ssl_fc_sni -i test.area.example.org }
    use_backend private if { ssl_fc_sni -i private.example.org }
    default_backend www

crt-list.conf:

www.pem [verify none]
www.pem [verify required] *.area.example.org
private.pem [verify required]

thêm thông tin: https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1-crt-list

lưu ý về bảo mật: luôn khớp tên máy chủ (nhạy cảm) của bạn với SNI ssl_fc_sni, không phải tên máy chủ HTTP. Nếu không, kẻ tấn công có thể bỏ qua chứng chỉ ứng dụng khách của bạn bằng cách gửi TLS SNI www.example.orgnhưng đặt tên máy chủ HTTP thành private.example.org!


OP đang sử dụng cùng một chứng chỉ cho cả hai. Câu hỏi là nhiều hơn về các ca-filethiết lập khác nhau .
gre_gor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.