1、Haproxy的https实现
这里的环境是接着前面文章的环境来的,也就是在上面修改一下其配置文件来实现。
haproxy可以实现https的功能,从用户到haproxy为https,从haproxy到后端服务器是使用的http来通信,但基于性能的考虑,在生产中都是把证书放到后端服务器上比如nginx上面。
#配置HAProxy支持https协议,支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥
cat demo.key demo.crt > 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 }
1.1、制作自签名证书
root@haproxy:~# mkdir /etc/haproxy/certs && cd $_
root@haproxy:/etc/haproxy/certs# openssl req -new -x509 -newkey rsa:2048 -subj "/CN=www.stars.com" -keyout www.stars.org.key -nodes -days 365 -out www.stars.org.crt
root@haproxy:/etc/haproxy/certs# ls
www.stars.org.crt www.stars.org.key
root@haproxy:/etc/haproxy/certs# cat www.stars.org.key www.stars.org.crt > www.stars.org.pem
root@haproxy:/etc/haproxy/certs# ls
www.stars.org.crt www.stars.org.key www.stars.org.pem
#查看证书内容
root@haproxy:/etc/haproxy/certs# openssl x509 -in www.stars.org.pem -noout -text
1.2、haproxy中的https的配置
#首先配置一下haproxy日志,在生产中不推荐开启,这里为了测试开起一下,开启日志会影响性能。
root@haproxy:~# vim /etc/haproxy/haproxy.cfg
#在global配置项定义:
log 127.0.0.1 local2 info
#在配置一下其他配置
root@haproxy:~# vim /etc/haproxy/conf.d/zg_web_80.cfg
frontend zg_web_80
bind 10.0.0.100:80
bind 10.0.0.100:443 ssl crt /etc/haproxy/certs/www.stars.org.pem
redirect scheme https if !{ ssl_fc }
http-request set-header X-forwarded-Port %[dst_port]
http-request add-header X-forwarded-Proto https if { ssl_fc }
mode http
log global
option httplog
acl web_domain hdr_dom(host) -i www.stars.org
default_backend web_hosts
balance roundrobin
backend web_hosts
mode http
server 10.0.0.101 10.0.0.101:80 weight 1 check inter 3000 fall 2 rise 5
server 10.0.0.102 10.0.0.102:80 weight 1 check inter 3000 fall 2 rise 5
#配置完后重启一下haproxy服务
root@haproxy:~# systemctl restart haproxy.service
#配置一下rsyslog配置文件:
root@haproxy:~# vim /etc/rsyslog.conf
# provides UDP syslog reception #默认下面两个是注释掉的,把注释去掉。
module(load="imudp")
input(type="imudp" port="514")
root@haproxy:~# vim /etc/rsyslog.d/50-default.conf
#在配置文件中加入下面配置
local2.* /var/log/haproxy.log
#配置完后重启一下rsyslog服务
root@haproxy:~# systemctl restart rsyslog.service
#验证端口
root@haproxy:~# ss -tnl | grep 10.0.0.100
LISTEN 0 20480 10.0.0.100:443 0.0.0.0:*
LISTEN 0 20480 10.0.0.100:80 0.0.0.0:*
1.3、准备以下后端服务配置
两个服务器的操作是一样的。
root@web1:~# vim install_all_nginx.sh
#!/bin/bash
SRC_DIR=/usr/local/src
NGINX_URL=http://nginx.org/download/
NGINX_FILE=nginx-1.18.0
TAR=.tar.gz
NGINX_INSTALL_DIR=/apps/nginx
CPUS=`lscpu | awk '/^CPU\(s\)/{print $2}'`
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
os_type () {
awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release
}
os_version () {
awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release
}
check () {
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}${TAR} ];then
color "相关文件已准备好" 0
else
color '开始下载 nginx 源码包' 0
wget ${NGINX_URL}${NGINX_FILE}${TAR}
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}${TAR}文件失败" 1; exit; }
fi
}
install () {
color "开始安装 nginx" 0
if id nginx &> /dev/null;then
color "nginx 用户已存在" 1
else
useradd -s /sbin/nologin -r nginx
color "创建 nginx 用户" 0
fi
color "开始安装 nginx 依赖包" 0
if [ `os_type` == "CentOS" -a `os_version` == '8' ] ;then
yum -y -q install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ `os_type` == "CentOS" -a `os_version` == '7' ];then
yum -y -q install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
else
apt update &> /dev/null
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev &> /dev/null
fi
cd $SRC_DIR
tar xf ${NGINX_FILE}${TAR}
NGINX_DIR=`echo ${NGINX_FILE}${TAR}| sed -nr 's/^(.*[0-9]).*/\1/p'`
cd ${NGINX_DIR}
./configure --prefix=${NGINX_INSTALL_DIR} --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
make -j $CPUS && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
LimitNOFILE=100000
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "nginx 启动失败,退出!" 1 ; exit; }
color "nginx 安装完成" 0
}
check
install
root@web1:~# scp install_all_nginx.sh 10.0.0.102: #传到另一个后端服务器
#运行脚本安装nginx
root@web1:~# bash install_all_nginx.sh
root@web1:~# echo "Welcome to `hostname -I` test page" > /apps/nginx/html/index.html
#修改服务器的默认日志格式
root@web1:~# vim /apps/nginx/conf/nginx.conf
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,' #总的处理时间
'"upstreamtime":"$upstream_response_time",' #后端应用服务器处理时间
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log /apps/nginx/logs/access_json.log access_json;
#编辑完后查看语法是否有问题
root@web1:~# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
root@web1:~# nginx -s reload #重新加载配置文件
root@web1:~# ls /apps/nginx/logs/
access_json.log access.log error.log nginx.pid
1.4、验证haproxy的https是否成功
root@node4:~# curl -IkL http://www.stars.org
HTTP/1.1 302 Found
content-length: 0
location: https://www.stars.org/
cache-control: no-cache
HTTP/1.1 200 OK
server: nginx
date: Mon, 11 Jul 2022 11:06:36 GMT
content-type: text/html
content-length: 33
last-modified: Mon, 11 Jul 2022 10:34:56 GMT
etag: "62cbfcd0-21"
accept-ranges: bytes
root@node4:~# curl -Ik https://www.stars.org
HTTP/1.1 200 OK
server: nginx
date: Mon, 11 Jul 2022 11:06:49 GMT
content-type: text/html
content-length: 33
last-modified: Mon, 11 Jul 2022 10:38:34 GMT
etag: "62cbfdaa-21"
accept-ranges: bytes
#查看一下后端服务的访问日志
root@web1:~# tail -f /apps/nginx/logs/access_json.log
{"@timestamp":"2022-07-11T19:06:36+08:00","host":"10.0.0.101", "clientip":"10.0.0.100", "size":0, "responsetime":0.000, "upstreamtime":"-", "upstreamhost":"-", "http_host":"www.stars.org", "uri":"/index.html", "xff":"10.0.0.103","referer":"-", "tcp_xff":"-", "http_user_agent":"curl/7.58.0", "status":"200"}
{"@timestamp":"2022-07-11T19:08:35+08:00","host":"10.0.0.101", "clientip":"10.0.0.100", "size":0, "responsetime":0.000, "upstreamtime":"-", "upstreamhost":"-", "http_host":"www.stars.org", "uri":"/index.html", "xff":"10.0.0.103","referer":"-", "tcp_xff":"-", "http_user_agent":"curl/7.58.0", "status":"200"}
{"@timestamp":"2022-07-11T19:08:37+08:00","host":"10.0.0.101", "clientip":"10.0.0.100", "size":0, "responsetime":0.000, "upstreamtime":"-", "upstreamhost":"-", "http_host":"www.stars.org", "uri":"/index.html", "xff":"10.0.0.103","referer":"-", "tcp_xff":"-", "http_user_agent":"curl/7.58.0", "status":"200"}
1.5、在浏览器中访问测试
在回到后端服务器上查看一下刚刚访问的日志