haproxy + stunnel + keep-alive?


10

ฉันต้องการวาง stunnel ไว้ด้านหน้า haproxy 1.4 เพื่อจัดการปริมาณการใช้ HTTPS ฉันยังต้องการ stunnel เพื่อเพิ่มส่วนหัวX-Forwarded-For สามารถทำได้โดยแพทช์ "stunnel-4.xx-xforwarded-for.diff" จากเว็บไซต์ haproxy

อย่างไรก็ตามคำอธิบายดังกล่าว:

โปรดทราบว่าแพทช์นี้ไม่สามารถทำงานได้กับ ...

คำถามของฉันคืออะไรในทางปฏิบัติสิ่งนี้สำหรับฉัน ฉันไม่แน่ใจ

  1. หากนี่เป็นเรื่องที่รักษาไว้ระหว่างกัน
    • ลูกค้าและ stunnel
    • stunnel และ haproxy
    • หรือเซิร์ฟเวอร์ haproxy และแบ็กเอนด์?
  2. สิ่งนี้มีความหมายอย่างไรต่อประสิทธิภาพการทำงาน: ถ้าฉันมี 100 ไอคอนบนหน้าเว็บเบราว์เซอร์จะต้องต่อรอง 100 การเชื่อมต่อ SSL เต็มรูปแบบหรือสามารถใช้การเชื่อมต่อ SSL อีกครั้งเพียงแค่สร้างการเชื่อมต่อ TCP ใหม่

คำตอบ:


12

นี่เป็นเรื่องเกี่ยวกับ HTTP keep-alive ซึ่งอนุญาตให้มีการร้องขอทรัพยากรหลายครั้งผ่านเซสชัน TCP เดียว (และด้วย SSL, เซสชัน SSL เดียว) สิ่งนี้มีความสำคัญอย่างยิ่งต่อประสิทธิภาพของไซต์ SSL เนื่องจากไม่มีการใช้งานแบบ handshake SSL จึงจำเป็นสำหรับแต่ละทรัพยากรที่ร้องขอ

ดังนั้นความกังวลที่นี่คือหนึ่งเซสชันการรักษาใหญ่จากไคลเอนต์ไปจนถึงเซิร์ฟเวอร์ส่วนหลัง มันเป็นสิ่งสำคัญสำหรับการทำงานและเป็นเรื่องของเซิร์ฟเวอร์ HTTP ที่ทันสมัย ​​แต่แพตช์นี้บอกว่ามันไม่รองรับ มาดูกันว่าทำไม ..


เซสชัน keep-alive เป็นเพียงการร้องขออีกครั้งหนึ่งหลังจากที่เซิร์ฟเวอร์เสร็จสิ้นการตอบสนองต่อการร้องขอหนึ่งเซิร์ฟเวอร์ไม่ได้ส่งFINแพ็คเก็ตที่จะจบเซสชัน TCP; ลูกค้าสามารถส่งส่วนหัวอีกชุดหนึ่งได้

เพื่อให้เข้าใจว่าแพทช์นั้นกำลังทำอะไรต่อไปนี้เป็นตัวอย่างของการสนทนาแบบต่อเนื่อง:

ลูกค้า:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

เซิร์ฟเวอร์:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

นี่คือจุดที่การเชื่อมต่อที่ไม่หยุดทำงานจะหยุดลง แต่ยังมีชีวิตอยู่ช่วยให้ลูกค้าเพียงแค่ยิงออกไปอีก:

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

สำหรับรหัสลูกค้าในการมอบฉันทะพร็อกซี่ย้อนกลับบางอย่างสามารถเพิ่มในX-Forwarded-Forส่วนหัวในแต่ละคำขอของลูกค้า ที่บอกเซิร์ฟเวอร์ upstream ว่าคำขอมาจากไหน (แทนทุกคำขอที่เริ่มต้นจาก IP พร็อกซีย้อนกลับ) เพื่อความมีสติในการบันทึกและความต้องการใช้งานอื่น ๆ

X-Forwarded-Forส่วนหัวจะต้องมีการฉีดเข้าไปในแต่ละคนและทุกคำขอทรัพยากรลูกค้าส่งผ่านการเชื่อมต่อแบบ keep-มีชีวิตอยู่ในขณะที่ส่วนหัวแบบเต็มจะถูกส่งไปในแต่ละครั้ง; การจัดการX-Forwarded-Forส่วนหัวและการแปลเป็นคำขอ IP "ของจริง" จะดำเนินการตามคำขอต่อไม่ใช่พื้นฐานต่อ TCP-keep-alive-session และเดี๋ยวก่อนอาจมีซอฟต์แวร์ reverse proxy ที่ยอดเยี่ยมที่ใช้เซสชันแบบ keep-alive หนึ่งครั้งเพื่อรับบริการจากลูกค้าหลาย ๆ คน

นี่คือที่แพทช์นี้ล้มเหลว


โปรแกรมแก้ไขที่ไซต์นั้นเฝ้าดูบัฟเฟอร์ของเซสชัน TCP สำหรับการสิ้นสุดของส่วนหัว HTTP ชุดแรกในสตรีมและฉีดส่วนหัวใหม่ลงในสตรีมหลังจากสิ้นสุดส่วนหัวชุดแรกนั้น หลังจากเสร็จสิ้นแล้วจะพิจารณาX-Forwarded-Forงานที่ทำเสร็จและหยุดสแกนเพื่อสิ้นสุดส่วนหัวชุดใหม่ วิธีนี้ไม่มีการรับรู้ถึงส่วนหัวในอนาคตทั้งหมดที่เข้ามาทางคำขอที่ตามมา

โทษพวกเขาไม่ได้จริงๆ stunnel ไม่ได้ถูกสร้างขึ้นเพื่อทำการจัดการและแปลเนื้อหาของสตรีม

ผลกระทบที่จะเกิดขึ้นกับระบบของคุณคือคำขอแรกของสตรีมแบบ keep-alive จะได้รับการX-Forwarded-Forฉีดส่วนหัวอย่างถูกต้องและคำขอต่อมาทั้งหมดจะทำงานได้ดี - แต่จะไม่มีส่วนหัว

เว้นแต่จะมีแพทช์การฉีดเฮดเดอร์อื่นที่สามารถจัดการคำขอของลูกค้าได้หลายรายการต่อการเชื่อมต่อ (หรือรับอันนี้ tweaked ด้วยความช่วยเหลือของเพื่อนของเราที่ Stack Overflow) คุณอาจต้องดูตัวเลือกอื่น ๆ สำหรับการยกเลิก SSL


1
คำตอบที่ยอดเยี่ยมขอบคุณ เตือนฉันว่าทำไมจึงเป็นความคิดที่ดีที่จะถามคำถามที่นี่
Chris Lercher

1
เพื่ออนุญาตให้มีการฉีดเฮดเดอร์แบบ Keep-alive โดยต้องมีความสามารถในการพูด HTTP เกือบทั้งหมดซึ่งจะเป็นงานจำนวนมาก ที่กล่าวว่าคุณยังสามารถใช้โปรโตคอล PROXY ของ HAproxy (ซึ่งต้องใช้แพตช์สำหรับ stunnel หรือแกนสลับ) ฉีดส่วนหัวใน HAproxy ดูเอกสารสำหรับข้อมูลเพิ่มเติม (จากแคชของ Google เนื่องจากไซต์ HAproxy ดูเหมือนว่าจะถูกปิด ATM บางส่วน)
Holger เพียง

5

STunnel 4.45 แก้ไขสิ่งนี้อย่างถูกต้องโดยใช้ความสามารถใหม่ (พร็อกซีโปรโตคอล) ที่มาพร้อมกับ HAProxy 1.15

นอกจากนี้ยังแก้ไขปัญหาของ Patch ก่อนหน้าและ Keep Alive


3

คล้ายกับสิ่งที่ฉันโพสต์ในเธรดอื่น HAProxy รองรับ SSL พื้นเมืองทั้งสองด้านตั้งแต่ 1.5-dev12 ดังนั้นการมี X-Forwarded-For, HTTP Keep-alive รวมถึงส่วนหัวที่บอกเซิร์ฟเวอร์ว่าการเชื่อมต่อที่ทำผ่าน SSL นั้นเรียบง่ายดังต่อไปนี้:

listen front
    bind :80
    bind :443 ssl crt /etc/haproxy/haproxy.pem
    mode http
    option http-server-close
    option forwardfor
    reqadd X-Forwarded-Proto:\ https if { is_ssl }
    server srv1 1.1.1.1:80 check ...
    ...

มันง่ายกว่าการ stunnel patching และดีกว่าการปล่อยให้มีชีวิต


คุณอาจต้องการใช้ ssl_fc แทน is_ssl
josch

2

การขยายคำตอบที่ดีเลิศจาก Shane คุณสามารถใช้ Nginx เป็น SSL terminator ที่ด้านหน้า HAproxy มันจัดการอย่างถูกต้องรักษาชีวิตระหว่างไคลเอนต์และ nginx ซึ่งเป็นด้านที่มีความสำคัญแฝงมากที่สุดและทำให้การเชื่อมต่อใหม่เพื่อแบ็กเอนด์สำหรับการร้องขอของลูกค้าแต่ละคนส่ง X-FORWARDED-FOR ในแต่ละคน


1
อย่างไรก็ตามหากคุณต้องการ websockets ดังนั้น nginx จะไม่ทำงาน
w00t

นอกจากนี้ยังรองรับแคชเซสชัน SSL
3molo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.