Skip to main content

HAProxy

Setup​

Installation​

การติดตั้ง HAProxy ลงใน linux server สามารถติดตั้งได้โดยการใช้คำสั่ง apt install

sudo apt install haproxy -y

Check version​

เนื่องจากความต่างกันของ version จะส่งผลถึง parameter หรือ syntax ในตัวไฟล์ configuration อย่างไรก็ตาม แนะนำให้ตรวจสอบอีกครั้งกับ HAProxy Documentation

haproxy -v

Configuration​

Editing HAProxy configuration file​

ไฟล์ configuration จะถูกจัดเก็บอยู่ที่ directory /etc/haproxy/haproxy.cfg สามาถเข้าถึงไฟล์ได้โดยการใช้คำสั่งแก้ไขไฟล์เช่น nano หรือ vi หรือ cat

ไฟล์ haproxy.cfg ตือไฟล์ที่จะเก็บค่าที่เราตั้งค่าให้กับตัว proxy ไปใช้ ดังนั้นการตั้งค่าทั้งหมดจะถูกแก้ไขที่นี่

sudo nano /etc/haproxy/haproxy.cfg
tip

เครื่องมือ nano สามารถ save โดยกดปุ่ม ++ctrl+x++ และ ++enter++


ตัวอย่างไฟล์ haproxy.cfg​

การตั้งค่าจะมีด้วยกัน 3 ส่วนหลัก ๆ ได้แก่ ตั้งค่า SSL Certificate, ตั้งค่า frontend และ ตั้งค่า backend

Normal deployment​

สำหรับการ deployment แบบปกติไม่ต้องทำ reverse-proxy สามารถใช้ไฟล์ดังนี้

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon

ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
log global
mode http
option httplog
option dontlognull
timeout connect 30000
timeout client 30000
timeout server 50000
timeout tunnel 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

frontend all
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/PSU240722.pem

reqadd X-Forwarded-Proto:\ https if { ssl_fc }
reqadd X-Forwarded-Port:\ 443 if { ssl_fc }
reqadd X-Forwarded-Proto:\ http if !{ ssl_fc }
reqadd X-Forwarded-Port:\ 80 if !{ ssl_fc }

redirect scheme https code 301 if !{ ssl_fc }

use_backend [backend-name] if { hdr(host) -i [your-domain-name] }

backend [backend-name]
option redispatch
option httpclose
option forwardfor
balance roundrobin
server [server-name] [port ที่ deploy service เช่น 0.0.0.0:8080] check-ssl verify none
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-XSS-Protection 1
http-response set-header Content-Security-Policy "img-src 'self' data: code.jquery.com www.gstatic.com wordpress.org ps.w.org s.w.org piwik.psu.ac.th www.google-analytics.com secure.gravatar.com"
http-response set-header Strict-Transport-Security max-age=31536000
http-response set-header Referrer-Policy no-referrer-when-downgrade
http-response set-header Feature-Policy "accelerometer 'none'"
info

เปลี่ยน reqadd เป็น http-request add-header

haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon

ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
log global
mode http
option httplog
option dontlognull
timeout connect 30000
timeout client 30000
timeout server 50000
timeout tunnel 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

frontend all
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/star.in.pem

acl is_https ssl_fc
http-request add-header X-Forwarded-Proto: https if is_https
http-request add-header X-Forwarded-Port: 443 if is_https
http-request add-header X-Forwarded-Proto: http if !is_https
http-request add-header X-Forwarded-Port: 80 if !is_https
redirect scheme https code 301 if !is_https

use_backend [backend-name] if { hdr(host) -i [your-domain-name] }

backend [backend-name]
option redispatch
option httpclose
option forwardfor
balance roundrobin
server [server-name] [port ที่ deploy service เช่น 0.0.0.0:8080] check-ssl verify none
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-XSS-Protection 1
http-response set-header Content-Security-Policy "img-src 'self' data: code.jquery.com www.gstatic.com wordpress.org ps.w.org > #http-response set-header X-Content-Type-Options nosniff
http-response set-header Strict-Transport-Security max-age=31536000
http-response set-header Referrer-Policy no-referrer-when-downgrade
http-response set-header Feature-Policy "accelerometer 'none'"
info
ไฟล์ certificate .pem

ไฟล์ certificate .pem สามารถขอได้จากผู้ดูแลระบบเครือข่าย ไฟล์ certificate จะมี expire date หรือวันหมดอายุ กรุณาตรวจสอบก่อนติดตั้งและเปลี่ยนก่อนจะครบวันหมดอายุ

Meaning of configuration file​

บรรทัดความหมายสิ่งที่จะต้องทำ
1-13ส่วนของการประกาศตัวแปร global-
15-30ค่า default ที่จะถูกใช้ในทุกๆ frontend-
32-43การกำหนด frontend จะเป็นส่วนที่บอกว่าจะมีการใช้ port ไหนบ้าง, ไฟล์ SSL Certificate สำหรับการใช้งาน https, การกำหนดให้บังคับใช้ https เท่านั้น ถ้ามีการเข้าผ่าน http จะถูก redirect ไปยัง https โดยอัตโนมัติ และการประกาศใช้ backend ถ้ามีการผ่านของเงื่อนไข domain nameบรรทัดที่ 34 => แก้ไขที่อยู่ของไฟล์ certificate , บรรทัดที่ 43 => แก้ไขชื่อของ backend และ domain name ภายในการตรวจสอบเงื่อนไข hdr(host) -i {your-domain-name}
45+การกำหนด backend จะเป็นส่วนที่จะกำหนดว่ามี server หรือ container กี่ตัว ที่อยู่ที่ ip address ไหนบ้าง และจะกำหนดว่าจะส่งค่าอะไรไปให้ service ที่ run อยู่ข้างหลังผ่าน request header และหากมีมากกว่า 1 server จะทำการ load balance แบบ roundrobinบรรทัดที่ 50 => แก้ไข server-name เป็นชื่อ สามารถใช้ชื่ออะไรก็ได้ให้สื่อถึง service นั้นๆ สามารถมีได้มากกว่า 1 server

Reverse-proxy deployment​

สำหรับการ deployment แบบ reverse-proxy ให้แก้ไขส่วนของ backend โดยการเพิ่ม 2 บรรทัดดังนี้

haproxy.cfg
...

backend [backend-name]
option redispatch
option httpclose
option forwardfor
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:[your-domain-name]
server [server-name] [localhost address:port ที่ deploy service เช่น 127.0.0.1:8080]
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-XSS-Protection 1
http-response set-header Content-Security-Policy "img-src 'self' data: code.jquery.com www.gstatic.com wordpress.org ps.w.org > #http-response set-header X-Content-Type-Options nosniff
http-response set-header Strict-Transport-Security max-age=31536000
http-response set-header Referrer-Policy no-referrer-when-downgrade
http-response set-header Feature-Policy "accelerometer 'none'"

ในบรรทัดที่ 9 ไม่ต้องใส่ check-ssl verify none แล้วเนื่องจากเป็นการใช้งานผ่าน http


Validate and Applying​

Validating configuration file​

ตรวจสอบความถูกต้องของการตั้งค่า proxy ก่อนจะสั่ง restart เพื่อ apply ค่าไปใช้จริง

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

Restart HAProxy to apply configuration​

หลังจากแก้ไขเสร็จสิ้น ค่า configuration จะไม่ถูกนำไปใช้ทันทีเนื่องจาก HAProxy ได้มีการ load ไฟล์ไปอ่านตั้งแต่ตอน start service แล้ว ดังนั้นการ apply ค่าชุดใหม่จะต้องใช้คำสั่ง restart service หรือ systemctl restart

sudo systemctl restart haproxy

ณ ขั้นตอนนี้ ไฟล์ configuration ที่ถูกแก้จะถูก compile ถ้ามีส่วนที่ error จะต้องกลับไปแก้ไข โดยสามารถดู logs การ complie ได้จากคำสั่ง

sudo journalctl -xeu haproxy.service
ข้อควรระวัง

การแก้ไข proxy จะส่งผลต่อการใช้งาน ณ ขณะนั้น ไม่ควรแก้ไขระหว่างมีการใช้งานของผู้ใช้ หาก proxy ไม่สามารถ start ได้ ผู้ใช้ก็จะไม่สามารถเข้าถึง container ภายในได้

Trobleshooting HAProxy

การแก้ไขปัญหาเพิ่มเติมอ่านต่อได้ที่ How To Troubleshoot Common HAProxy Errors


Uninstall HAProxy

HAProxy สามารถลบออกได้โดยการใช้คำสั่ง purge

sudo apt purge haproxy -y