Jos*_*osh 20 ssl load-balancing haproxy pfsense
我有以下设置:
(internet) ---> [ pfSense Box ] /-> [ Apache / PHP server ]
[running HAproxy] --+--> [ Apache / PHP server ]
+--> [ Apache / PHP server ]
\-> [ Apache / PHP server ]
Run Code Online (Sandbox Code Playgroud)
对于 HTTP 请求,这很好用,请求被分发到我的 Apache 服务器就好了。对于 SSL 请求,我让 HAproxy 使用 TCP 负载平衡分发请求,但是它可以工作,因为 HAproxy 没有充当代理,它没有添加X-Forwarded-ForHTTP 标头,并且 Apache/PHP 服务器不知道客户端的真实IP地址。
所以,我stunnel在HAproxy前面加了,读到stunnel可以加X-Forwarded-ForHTTP头。但是,我可以安装到 pfSense 中的包没有添加这个标头......而且,这显然会扼杀我使用 KeepAlive requests 的能力,我真的很想保留它。但是扼杀了这个想法的最大问题是 stunnel 将 HTTPS 请求转换为普通的 HTTP 请求,所以 PHP 不知道 SSL 已启用并试图重定向到 SSL 站点。
如何使用 HAproxy 在多个 SSL 服务器之间进行负载平衡,让这些服务器既知道客户端的 IP 地址又知道 SSL 正在使用中?如果可能的话,我如何在我的 pfSense 服务器上做到这一点?
还是我应该放弃这一切而只使用 nginx?
Wil*_*eau 39
只是为了记录,因为这个线程经常被提到关于 HAProxy + SSL,HAProxy 从 1.5-dev12 开始确实支持双方的原生 SSL。因此,拥有 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
http-request set-header X-Forwarded-Proto https if { ssl_fc }
server srv1 1.1.1.1:80 check ...
...
Run Code Online (Sandbox Code Playgroud)
我相信当你想出不同的东西时,但至少新访客现在会得到简单的解决方案:-)
Och*_*oto 16
你不需要全部放弃,你可以在 haproxy 前面使用 nginx 来支持 SSL,保持你所有的负载平衡配置。如果您不想,您甚至不需要将 nginx 用于 HTTP。Nginx 可以传递 X-Forwarded-For 和指示 SSL 正在使用的自定义标头(如果需要,还可以传递客户端证书信息)。发送所需信息的 Nginx 配置片段:
proxy_set_header SCHEME $scheme; # http/https
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header CLIENT_CERT $ssl_client_raw_cert;
Run Code Online (Sandbox Code Playgroud)
Jos*_*osh 12
对于发现这个问题的其他人,我遵循了 Ochoto 的建议并使用了 nginx。这是我用来在我的 pfSense 路由器上完成这项工作的具体步骤:
使用 pfsense Web 界面,我在System > Packages下安装了 pfsense PfJailctl 包和“jail_template”包,这样我就可以创建一个 FreeBSD jail,在该监狱下在 pfsense 系统上编译和安装 nginx。
我在Services > Jails下为我的 nginx 服务器配置了一个 jail ,为新的 jail 提供与运行 HAproxy 的虚拟 IP 别名相同的主机名和 IP 地址。我将监狱绑定到 WAN 接口。我使用了默认的 jail 模板并启用了 unionfs 而不是 nullfs。
监狱启动后,我通过 SSH 连接到 pfsense 框并跑去jls寻找监狱的号码。然后我跑去jexec 1 sh监狱里拿一个炮弹。从那里我设置了 BSD 端口并使用以下方法安装了 nginx:
portsnap extract
portsnap fetch update
cd /usr/ports/www/nginx
make install clean
Run Code Online (Sandbox Code Playgroud)然后我将 nginx 配置为侦听端口 443,并将所有请求传递到端口 80 上的 HAproxy,包括真实 IP 和 HTTP 标头中的 SSL 状态。我的usr/local/etc/nginx/nginx.conf样子:
worker_processes 1;
events {
worker_connections 2048;
}
http {
upstream haproxy {
server 209.59.186.35:80;
}
server {
listen 443;
server_name my.host.name default_server;
ssl on;
ssl_certificate my.crt;
ssl_certificate_key my.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://haproxy;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
}
Run Code Online (Sandbox Code Playgroud)然后我修改了我的 PHP 应用程序以检测X-Forwarded-ProtoHTTP 标头:
function usingSSL()
{
return (
(isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' )
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' ));
}
Run Code Online (Sandbox Code Playgroud)所以最后的设置是:
(internet) ---> [ -> nginx -> haproxy -]--> (pool of apache servers)
[ (pfSense server) ]
Run Code Online (Sandbox Code Playgroud)
我对 1.5-dev-17 版本的 haproxy 的配置:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#chroot /usr/share/haproxy
user haproxy
group haproxy
daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
retries 3
option redispatch
fullconn 1000
maxconn 1000
timeout queue 600s
timeout connect 5s
timeout client 600s
timeout server 600s
frontend http-in
bind *:80
bind *:443 ssl crt /usr/local/etc/ssl/certs
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
default_backend varnish-ha
option forwardfor
backend varnish-ha
server hafront1 10.1.69.1:6081 minconn 100 maxqueue 10000
Run Code Online (Sandbox Code Playgroud)
它使用ssl_fcACL。请注意,该option http-server-close部分非常重要。
HAProxy 不能在不使用原始 TCP 模式的情况下访问 SSL 后端,丢失X-Forwarded-For,但是,您可能会使用后端传输的侦听通道重新加密流量。不过丑。
我更喜欢 Ochoto 的方法,但有一个警告:nginx 是一个功能完善的负载均衡器;如果你正在使用它,我会说把它用于一切。将传入的 HTTPS 代理到负载平衡的 HTTPS 后端 - 这样,就不需要 SSL 信息的自定义标头(除非您确实需要客户端证书)。
| 归档时间: |
|
| 查看次数: |
81110 次 |
| 最近记录: |