我有以下设置:
(internet) ---> [ pfSense Box ] /-> [ Apache / PHP server ] [running HAproxy] --+--> [ Apache / PHP server ] +--> [ Apache / PHP server ] \-> [ Apache / PHP server ]
对于HTTP请求这很好 ,请求分发到我的Apache服务器就好了。 对于SSL请求,我使用HAproxy使用TCP负载均衡来分发请求,但是由于HAproxy没有充当代理,没有添加X-Forwarded-For
HTTP标头,Apache / PHP服务器也没有不知道客户的真实IP地址。
所以,我在HAproxy前面添加了stunnel
,读取stunnel可以添加X-Forwarded-For
HTTP标头。 然而,我可以安装到pfSense中的软件包不会添加这个头文件,而且这显然会损害我使用KeepAlive请求的能力 ,这是我真正想保留的。 但是这个想法最大的问题是stunnel把HTTPS请求转换成普通的HTTP请求,所以PHP不知道SSL被启用并试图redirect到SSL站点。
如何使用HAproxy在多个SSL服务器之间进行负载均衡,使这些服务器都知道客户端的IP地址, 并知道SSL正在使用? 如果可能的话,我怎样才能在我的pfSense服务器上做到这一点?
或者我应该放弃所有这些,只使用nginx?
您不需要全部放弃,您可以在haproxy前面使用nginx进行SSL支持,保持所有的负载平衡configuration。 如果你不想要,你甚至不需要使用nginx的HTTP。 Nginx可以同时传递X-Forwarded-For和一个自定义标题,指示SSL正在使用(如果需要的话还有客户端证书信息)。 发送所需信息的Nginxconfiguration片段:
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;
只是为了logging,因为这个线程经常涉及到HAProxy + SSL,所以HAProxy自1.5-dev12开始支持双方的本地SSL。 因此,使用X-Forwarded-For,HTTP保持活动状态以及向服务器报告通过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 ... ...
我敢肯定,当你想出一些不同的东西的时候,但是现在至less有新的访问者会得到简单的解决scheme:-)
对于发现这个问题的其他人,我遵循了Ochoto的build议并使用了nginx。 以下是我在pfSense路由器上执行此操作的具体步骤:
使用pfsensenetworking界面,我安装了pfsense PfJailctl软件包和System> Packages下的“jail_template”软件包,这样我就可以创build一个FreeBSD jail,在这个jail下编译和安装pfsense系统上的nginx。
我在服务> Jails中为我的nginx服务器configuration了一个监狱,为新监狱提供了与运行HAproxy的虚拟IP别名相同的主机名和IP地址。 我将监狱绑定到WAN接口。 我使用默认的监狱模板,并启用unionfs而不是nullfs。
一旦监狱开始了,我就进入了pfsense箱子,然后跑去找监狱的号码。 然后我跑了jexec 1 sh
在监狱里面得到一个壳。 从那里我设置了BSD端口,并使用以下命令安装nginx:
portsnap extract portsnap fetch update cd /usr/ports/www/nginx make install clean
然后,我configurationnginx在端口443上侦听,并在端口80上传递所有请求到HAproxy,包括HTTP报头中的真实IP和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; } } }
然后,我修改了我的PHP应用程序来检测X-Forwarded-Proto
HTTP头:
function usingSSL() { return ( (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' )); }
所以最后的设置是:
(internet) ---> [ -> nginx -> haproxy -]--> (pool of apache servers) [ (pfSense server) ]
我的1.5-dev-17版本haproxy的configuration:
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
它使用ssl_fc
ACL。 请注意, option http-server-close
部分非常重要。
HAProxy不能在不使用原始TCP模式的情况下攻击SSL后端,而是丢失X-Forwarded-For
,但是,您可以使用监听通道为后端传输重新encryptionstream量。 丑,但。
我更喜欢Ochoto的方法,但需要注意:nginx是一个完美的负载均衡器, 如果你使用它,我会说使用它的一切。 代理您的传入HTTPS负载均衡的HTTPS后端 – 这样,没有必要自定义标头的SSL信息(除非你需要客户端证书)。
去年,我实施了一个解决scheme, 将HAProxy与pfSense整合在一起 ,以便利用HAProxy的所有function,并与pfSense保持良好的隔离。 所以这是生产环境的可行select。 SSL在HAProxy上终止 。 我使用ezjail和Ports Collection在pfSense的监狱里安装了HAProxy。 这样就很容易独立维护两个组件。 你可以安装你想要的任何版本。 我从1.5-dev13开始。 从那以后,它对我来说是完美的。 我已经在这里logging了整个事情。
在pfSense上安装HAProxy
威利,很感谢这么好的产品。