ติดตั้ง haproxy บน ubuntu server 16.04
บันทึกนี้ปรับปรุงล่าสุดเมื่อวันที่ 13-09-2561
ดูแลโดย WIBOON
- haproxy นำมาใช้ทำเป็น reverse proxy สำหรับ web server
- haproxy สามารถนำมาใช้ทำ load balance ในระดับ layer 4 และ layer 7 ได้
- haproxy ทำ load balance layer 4 ต้้งค่า mode tcp
- haproxy ทำ load balance layer 7 ต้้งค่า mode http
- haproxy ทำ load balance layer 7 ต้้งค่า mode http และทำ SSL Termination ร่วมด้วย เพื่อให้เป็น https สำหรับ backend server โดยที่ไม่ต้องติดตั้ง SSL เพิ่ม
ขั้นตอน
1. ติดตั้งโปรแกรม haproxy
sudo apt update sudo apt install haproxy
2. ตั้งค่า
sudo vi /etc/default/haproxy ENABLED=1
3. restart service
sudo service haproxy restart sudo service haproxy status
4. ให้ restart service rsyslog เพื่อให้เกิด haproxy.log
sudo service rsyslog restart
5. เก็บสำรองไฟล์ haproxy.cfg ไว้ด้วย
cd /etc/haproxy; sudo cp haproxy.cfg haproxy.cfg.orig
[ตัวอย่างการแก้ไขค่าคอนฟิกใน haproxy.cfg ]
เช่น นำ haproxy ไปใช้กับ wordpress และ apache2 web server
1. แก้ไขไฟล์ haproxy.cfg ด้วยเอดิเตอร์ vi หรือ nano ก็ได้
sudo vi /etc/haproxy/haproxy.cfg
นำท่อนข้างล่างนี้ต่อท้ายไฟล์ haproxy.cfg
เพิ่มต่อท้ายในชุด defaults
option forwardfor option http-server-close
แล้วตามด้วยท่อนนี้ เพื่อใช้ http port 80/tcp
frontend www-http bind *:80 reqadd X-Forwarded-Proto:\ http default_backend wordpress-backend
แล้วตามด้วยท่อนนี้ เพื่อใช้ https port 443/tcp (SSL Termination with haproxy)
frontend www-https bind *:443 ssl crt /etc/ssl/private/my.pem reqadd X-Forwarded-Proto:\ https default_backend wordpress-backend
แล้วตามด้วยท่อนนี้
backend wordpress-backend balance roundrobin redirect scheme https if !{ ssl_fc } server wordpress1 10.0.0.52:80 check server wordpress2 10.0.0.53:80 check
2. restart service haproxy ด้วยคำสั่ง
sudo service haproxy restart
3. แก้ไข wordpress wp-config.php
เพิ่มท่อนนี้ก่อนบรรทัด /* That's all, stop editing! Happy blogging. */
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { $_SERVER['HTTPS'] = 'on'; $_SERVER['SERVER_PORT'] = 443; } /* That's all, stop editing! Happy blogging. */
4. แก้ไข LogFormat ของ apache2 ให้รับ X-Forwarded-For ด้วยเอดิเตอร์ vi หรือ nano ก็ได้
sudo vi /etc/apache2/apache2.conf
แก้ไขดังนี้
#LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
5. restart service apache2 ด้วยคำสั่ง
sudo service apache2 restart
หมายเหตุ หากเราจะทำ Joomla site ก็ใช้วิธีการเดียวกันกับที่อธิบายไปในการทำ wordpress site แค่ไปเพิ่มบรรทัดในไฟล์ configuration.php แบบนี้
<?php if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on'; class JConfig { /* default datas */
[ตัวอย่างการตั้งค่าด้วย acl ของ haproxy.cfg]
สมมติว่าเว็บไซต์เรามีชื่อเริ่มต้นว่า myweb เช่น myweb.mydomain และ tblog1.mydomain เป็นต้น เราเขียนได้ 2 แบบ ดังนี้
แบบที่ 1 ใช้ acl ระบุว่าชื่อขึ้นต้นด้วย myweb
frontend www-http bind *:80 mode http acl host_myweb hdr_beg(host) -i myweb use_backend myweb-backend if host_myweb default_backend wordpress-backend backend myweb-backend mode http balance roundrobin option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost server myweb 10.0.0.51:80 check backend wordpress-backend mode http balance roundrobin option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost server wordpress1 10.0.0.52:80 check server wordpress2 10.0.0.53:80 check
แบบที่ 2 ใช้ acl ระบุว่าชื่อขึ้นต้นด้วย tblog1 และ tblog2
frontend www-http bind *:80 mode http acl host_tblog1 hdr_beg(host) -i tblog1 use_backend tblog1-backend if host_tblog1 acl host_tblog2 hdr_beg(host) -i tblog2 use_backend tblog2-backend if host_tblog2 default_backend server-backend backend tblog1-backend mode http balance roundrobin option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost server wordpress1 10.0.0.52:80 check server wordpress2 10.0.0.53:80 check backend tblog2-backend mode http balance roundrobin option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost server wordpress1 10.0.0.52:80 check server wordpress2 10.0.0.53:80 check backend server-backend mode http balance roundrobin option forwardfor http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost server myweb 10.0.0.51:80 check
เพิ่มเติม HTTP Headers เกี่ยวกับ security ให้ใส่ก่อนบรรทัด server myweb 10.0.0.51:80 check
http-response set-header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
http-response set-header X-Frame-Options "SAMEORIGIN"
http-response set-header X-XSS-Protection "1; mode=block"
http-response set-header X-Content-Type-Options "nosniff"
http-response set-header Expect-CT "max-age=3600"
http-response set-header Referrer-Policy "no-referrer-when-downgrade"
http-response set-header Feature-Policy "accelerometer 'none'; camera 'none'; geolocation 'none';
gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'"
อ่านเพิ่มเติม
- ติดตั้ง ssl-cert บน ubuntu 16.04 server
- https://www.digitalocean.com/community/tutorial_series/load-balancing-wordpress-with-haproxy
- https://feliciano.tech/blog/running-wordpress-behind-an-sslhttps-terminating-proxy/
- https://serverfault.com/questions/331079/haproxy-and-forwarding-client-ip-address-to-servers
- https://gist.github.com/ajaegers/7eda2eadffbc1bbcf12f