3-4-11-HAProxy高级功能与配置之https实现.md
haproxy代理https有两种方式 :
haproxy服务器本身提供ssl证书 , 后面的web服务器走正常的http需要编译
haproxy的时候支持ssl编译参数 :
#make TARGET=linux26 USE_OPENSSL=1 ADDLIB=-lz #ldd haproxy | grep ssl libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007fb0485e5000)配置说明
支持ssl会话
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE #crt 后证书文件为PEM格式 , 且同时包含证书和所有私钥 cat demo.crt demo.key > demo.pem把80端口的请求重向定443\
bind *:80 redirect scheme https if !{ ssl_fc }向后端传递用户请求的协议和端口(
frontend或backend)http_request set-header X-Forwarded-Port %[dst_port] http_request add-header X-Forwared-Proto https if { ssl_fc }配置文件示例
frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/servername.pem mode http option httpclose option forwardfor reqadd X-Forwarded-Proto:\ https default_backend web_server backend web_server mode http balance roundrobin cookie SERVERID insert indirect nocache server s1 192.168.1.150:80 check cookie s1 server s2 192.168.1.151:80 check cookie s2
注 : 这里的
pem文件是下面两个文件合并而成#cat servername.crt servername.key |tee servername.pemhaproxy服务器本身只提供代理 , 后面的web服务器走https(配置ssl证书)这种方式 ,
haproxy不需要重新编译支持ssl, 简单方便 , 只需要后面的web服务器配置好ssl即可。frontend https_frontend bind *:443 mode tcp default_backend web_server backend web_server mode tcp balance roundrobin stick-table type ip size 200k expire 30m stick on src server s1 192.168.1.150:443 server s2 192.168.1.151:443注 : 这种模式下
mode必须是tcp模式
1. 证书制作
# mkdir /usr/local/haproxy/certs
# cd /usr/local/haproxy/certs
# openssl genrsa -out haproxy.key 2048
# openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.magedu.net"
# cat haproxy.key haproxy.crt > haproxy.pem
# openssl x509 -in haproxy.pem -noout -text #查看证书
2. https配置示例
2.1 http跳转https
把所有请求http://http.ilanni.com的地址全部跳转为https//http.ilanni.com这个地址。
配置示例
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
uid 188
gid 188
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.1
option redispatch
retries 3
option redispatch
maxconn 2000
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen admin_stats
bind 0.0.0.0:1080
mode http
option httplog
maxconn 10
stats refresh 30s
stats uri /stats
stats auth admin:admin
stats hide-version
frontend weblb
bind *:80
acl is_http hdr_beg(host) http.ilanni.com
redirect scheme https if !{ ssl_fc }
bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
use_backend httpserver if is_http
backend httpserver
balance source
server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3配置说明
tune.ssl.default-dh-param 2048: 因为我们的SSL密钥使用的是2048bit加密 , 所以在此进行声明。acl is_http hdr_beg(host) http.ilanni.comredirect scheme https if !{ ssl_fc }bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
这三行表示把所有访问http.ilanni.com这个域名的请求 , 全部转发到https://http.ilanni.com这个连接。
2.2 http与https并存配置
haproxy要实现http和https并存的话 ,配置也很简单 , 只需要把haproxy分别监控不同的端口就行 , 配置文件如下
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen admin_stats
bind 0.0.0.0:1080
mode http
option httplog
maxconn 10
stats refresh 30s
stats uri /stats
stats auth admin:admin
stats hide-version
frontend weblb
bind *:80
acl is_http hdr_beg(host) http.ilanni.com
use_backend httpserver if is_http
backend httpserver
balance source
server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3
frontend weblb443
bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
acl is_443 hdr_beg(host) http.ilanni.com
use_backend httpserver443 if is_443
backend httpserver443
balance source
server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3#web server http
frontend web_server-http
bind 192.168.7.101:80
redirect scheme https if !{ ssl_fc }
mode http
use_backend web_host
#web server https
frontend web_server-https
bind 192.168.7.101:443 ssl crt /usr/local/haproxy/certs/haproxy.pem
mode http
use_backend web_host
backend default_host
mode http
server web1 192.168.7.102:80 check inter 2000 fall 3 rise 5
backend web_host
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server web1 192.168.7.103:80 check inter 2000 fall 3 rise 5
server web2 192.168.7.104:80 check inter 2000 fall 3 rise 5
在以上配置文件中 , 我们定义了两个前端 , 一个前端用于监听80端口 , 也就是http协议。另外一个前端监听443端口 , 也就是https协议。
此时haproxy会根据客户端请求的协议进行分发 , 如果发现客户端请求的是http协议 ,则把该请求分发到监听80端口的前端。如果发现客户端请求的是https协议 , 则把该请求分发到监听443端口的前端。如此就达到了haproxy让http和https并存的要求。
2.3 同台服务器不同域名之间的https与http配置
同台服务器不同域名之间的http和https配置比较复杂 , 第一需要监听两个端口 ,第二还要根据不同的域名进行分发。
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
uid 188
gid 188
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.1
option redispatch
retries 3
option redispatch
maxconn 2000
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen admin_stats
bind 0.0.0.0:1080
mode http
option httplog
maxconn 10
stats refresh 30s
stats uri /stats
stats auth admin:admin
stats hide-version
frontend weblb
bind *:80
acl is_haproxy hdr_beg(host) haproxy.ilanni.com
acl is_http hdr_beg(host) http.ilanni.com
redirect prefix https://http.ilanni.com if is_http
use_backend haproxyserver if is_haproxy
backend haproxyserver
balance source
server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3
frontend weblb443
bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
acl is_443 hdr_beg(host) http.ilanni.com
use_backend httpserver443 if is_443
backend httpserver443
balance source
server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3同台服务器不同域名之间的https与http配置 , 我们配置了两个前端一个用于监听80端口 , 并且根据不同的域名进行跳转。在80端口的规则中 , 如果客户端请求的是http.ilanni.com , 这个域名的话 , 则haproxy会把该请求直接跳转到https://http.ilanni.com。如果是haproxy.ilanni.com , 这个域名的话 , 则分发到后端的服务器。
另外一个前端用于监听443端口 , 用于分发客户端https://http.ilanni.com的请求。
同台服务器上访问haproxy.ilanni.com直接跳转到80端口 , 如果访问的是http.ilanni.com域名的话则跳转到https://http.ilanni.com 这个地址。
2.4 同台服务器多域名均使用https配置
要使同台服务器的两个设置多个域名都使用https协议的话 , 配置很简单。只需要在haproxy中启用各自的https配置即可。
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
uid 108
gid 116
daemon
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.1
option redispatch
retries 3
option redispatch
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen admin_stats
bind 0.0.0.0:1080
mode http
option httplog
maxconn 10
stats refresh 30s
stats uri /stats
stats auth admin:admin
stats hide-version
frontend web80
bind *:80
acl is_http hdr_beg(host) http.ilanni.com
redirect scheme https if !{ ssl_fc }
bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
acl is_haproxy hdr_beg(host) haproxy.ilanni.com
redirect scheme https if !{ ssl_fc }
bind *:443 ssl crt /etc/haproxy/ilanni.com.pem
use_backend httpserver if is_http
use_backend haproxyserver if is_haproxy
backend httpserver
balance source
server web1 127.0.0.1:6060 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3
backend haproxyserver
balance source
server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3