How to replace a Stunnel with a Haproxy - haproxy

I try to replace an existing Stunnel configuration
sslVersion = TLSv1.2
ciphers = AES256-SHA:AES128-SHA:RC4-SHA:RC4-MD5
CAfile = acs.pem
output = stunnel.log
debug = 7
[CONF1]
verify = 2
cert = conf1.pem
key = conf1.key
accept = 0.0.0.0:<port_conf1>
local = <hostname>
protocol = connect
protocolHost = <target dnsname>:443
connect = <haproxy to go outside>:<port>
client = yes
with an Haproxy
does it possible ?
If no i would like to understand why please :-).
Thanks
I tried without succes
frontend front_wtf
bind *:<port_conf1>
option httplog
stats enable
mode http
default_backend back_conf1
backend back_conf1
mode http
stats enable
http-request set-header Host <target dnsname>
http-request set-header X-Port 443
server conf1 <haproxy to go outside>:<port> ssl ca-file ./acs.pem crt ./conf1.pem.key

Related

HAProxy: omiting auth for URI not working

I need to be able to omit authentication for a specific URI using haproxy but using the following config file is not working. When accessing whatever.server/app/my-app, I still get asked to provide login credentials.
global
maxconn 4096
daemon
userlist myUsers
user someUser insecure-password somePass
defaults
mode http
log 127.0.0.1 local1 debug
option httplog
frontend all
bind 0.0.0.0:80
timeout client 86400000
default_backend www_backend
acl is_websocket hdr(Upgrade) -i WebSocket
acl is_webapp path_beg /app
acl is_my_app path_beg /app/my-app
acl auth_ok http_auth(myUsers)
http-request auth unless auth_ok or is_websocket or is_my_app
use_backend webapp_backend if is_webapp
backend www_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
option httpclose
timeout server 1800000
timeout connect 4000
server server1 localhost:81 weight 1 maxconn 1024 check
backend webapp_backend
balance roundrobin
option forwardfor # This sets X-Forwarded-For
option httpclose
timeout server 1800000
timeout connect 4000
server server1 localhost:8800 weight 1 maxconn 1024 check
I'm using haproxy v1.4
EDIT
Also tried
http-request allow if is_my_app
http-request auth unless auth_ok or is_websocket
but it's allowing all URLs without authentication
Acls can be negated as mentioned here https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.2
acl url_static path_beg /app/my-app
acl AuthOkay_Web http_auth(myUsers)
http-request auth realm AuthYourself if !isOptions !url_static !AuthOkay_Web
Also explained at https://serverfault.com/a/874742/297275

HAProxy frontend rule matching order

I have a haproxy configuration as follows. (haproxy 1.7) We want to catch all OPTIONS request and respond directly to them instead of routing the requests to backends (which have basic auth enabled).
This was working fine when we developed it but now it seems to not be matching the rules in order (not sure what we have/haven't done which has caused this):
global
log 127.0.0.1 local1
tune.ssl.default-dh-param 2048
lua-load /etc/haproxy/cors.lua
stats socket /var/run/haproxy.sock mode 400
# Default certificate and key directories
ca-base /etc/ssl/private
crt-base /etc/ssl/private
# User lists used to enforce HTTP Basic Authentication
userlist ul_100123-2ovt9rsu
user app1 password $6$lCjf6VnWhI$kcjmpWdV.odeYf4psUhcVKs49ZtPk3MDhg5wtLNUx658A3EWdDHJQqs9xCD1d.7zG05M2nwOxdkC6o/MSpifv0
userlist ul_100123-9uvsclqr
user app1 password $6$DlcLoDMMu$wDm3O0W1eiQuk8gI.GmpzI1.jbBf.UYQ.KM73nHa1tGZJNfzkDpVnLUhh7v7C9yPHB1oo0cRrFnfOdeyAf/eU1
# Front-end for public services which have SSL termination at the router.
frontend term
bind *:443 accept-proxy ssl no-sslv3 crt router/fred-external.pem crt router/fred-external.ace.pem crt router
reqadd X-Forwarded-Proto:\ https
rspidel ^(Server|X-Powered-By):
option forwardfor
mode http
http-request use-service lua.cors-response if METH_OPTIONS { req.hdr(origin) -m found }
acl host_match_100123-2ovt9rsu ssl_fc_sni -i 2ovt9rsu.fredurl.com
use_backend b_term_100123-2ovt9rsu if host_match_100123-2ovt9rsu
......
If I curl -X OPTIONS to 2ovt9rsu.fredurl.com it matches the 2nd rule and forwards me to the b_term_100123-2ovt9rsu backend which then fails as I haven't provided auth creds.
If I curl -X OPTIONS to Anything.fredurl.com it matches the first http-request and responds with the cors response as expected.
Why does the 2ovt9rsu.fredurl.com not match the first http-request rule and then return the cors-response?
In the logs we can see
Nov 7 18:24:09 localhost haproxy[37302]: 94.45.23.22:49853 [07/Nov/2017:18:24:09.807] term~ b_term_100123-2ovt9rsu/<lua.cors-response> -1/-1/-1/-1/73 401 249 - - PR-- 0/0/0/0/3 0/0 "OPTIONS / HTTP/1.1"
when the request gets forwarded to the backend
http-request gets executed before use_backend, the config looks good to me, have you set origin header when you curl ?

HAProxy redirect requests from one port to another

I'm using HAProxy version 1.6.
How would I modify the config to redirect requests from:
localhost:8081/myapp
to:
localhost:8111/myapp
Thanks!
frontend weblb
bind *:8081
acl if is_seller url_beg /myapp
use_backend sellerserver if is_seller
backend sellerserver
balance source
server web1 127.0.0.1:8111 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3
You could try using replace-value on the Host header:
http-request replace-value Host localhost:8081 localhost:8111
Which is nice because it also supports regexes:
http-request replace-value Host (.*):8081 \1:8111
something like :
listen weblb xxx.xxx.xxx.xxx:8081
balance leastconn
mode http
server web1 127.0.0.1:8111

haproxy sni ssl_fc_has_sni always 0

I am trying to create an SNI based frontend/backend setup in HAProxy. It seems that ssl_fc_has_sni is always evaluating to 0 in my log and I haven't been able to figure out why.
This is a simplified version of the config I've been testing with:
global
user haproxy
group haproxy
daemon
log /dev/log local0
defaults
timeout connect 5s
timeout client 30s
timeout server 30s
timeout tunnel 1h
log-format frontend:%f\ %b/%s\ client_ip:%Ci\ client_port:%Cp\ SSL_version:%sslv\ SSL_cypher:%sslc\ SNI:%[ssl_fc_has_sni]\ %ts
frontend public_ssl
bind :443
log global
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend be_sni if { ssl_fc_has_sni }
default_backend be_no_sni
backend be_sni
server fe_sni 127.0.0.1:10444 weight 1 send-proxy
frontend fe_sni
#terminate with a cert that matches the sni host
bind 127.0.0.1:10444 ssl crt /mycertdir/certs accept-proxy no-sslv3
default_backend be_default
frontend fe_no_sni
#terminate with a generic cert
bind 127.0.0.1:10443 ssl crt /myothercertdir/default_pub_keys.pem accept-proxy no-sslv3
default_backend be_default
# backend for when sni does not exist, or ssl term needs to happen on the edge
backend be_no_sni
server fe_no_sni 127.0.0.1:10443 weight 1 send-proxy
backend be_default
mode http
option forwardfor
option http-pretend-keepalive
server the_backend 127.0.0.1:8080
Other items of note:
haproxy -vv shows OpenSSL library supports SNI : yes
I am running haproxy version 1.5.9 on fedora 20 through vagrant
the log always shows SNI:0 haproxy[17807]: frontend:public_ssl be_no_sni/fe_no_sni client_ip:<ip> client_port:42285 SSL_version:- SSL_cypher:- SNI:0 --
I'm testing with openssl s_client -servername www.example.com -connect <ip>:443.
I feel like I'm missing something obvious since there is no ssl version, cypher, or sni.
Looks like ssl_fc_has_sni is meant to be used post termination. Checking for the existence of the SNI host can be accomplished with:
frontend public_ssl
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend be_sni if { req.ssl_sni -m found }
default_backend be_no_sni

HaProxy (cannot bind socket, select test failed)

Hello everyone,
Im working about an high availbility project, I had to put in production an haproxy for some applications. Everything was ok after some basics tests but I had some errors and cant fix it. Does someone have some ideas ?
here is the test
# /usr/sbin/haproxy -d -f /etc/haproxy/haproxy.cfg
Available polling systems :
sepoll : pref=400, test result OK
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result FAILED
Total: 4 (3 usable), will use sepoll.
Using sepoll() as the polling mechanism.
[ALERT] 174/160258 (22038) : Starting proxy mysql: cannot bind socket
[ALERT] 174/160258 (22038) : Starting proxy http: cannot bind socket
There is my file haproxy.cfg
global
log 127.0.0.1 local0 notice
user haproxy
group haproxy
maxconn 32000
ulimit-n 65536
defaults
log global
option dontlognull
retries 2
timeout connect 3000
timeout server 5000
timeout client 5000
option redispatch
listen mysql
bind *:3306
mode tcp
option tcplog
balance roundrobin
option mysql-check user haproxy_check
server mysql1 10.83.83.167:3306 check
server mysql2 10.83.83.168:3306 check
server mysql3 10.83.83.169:3306 check
listen http
mode http
bind *:80
stats enable
stats uri /stats
stats auth admin:HaProxy2014
acl app1_cluster_acl hdr_beg(host) -i app1
acl app2_cluster_acl hdr_beg(host) -i app2
acl mysql_cluster_acl hdr_beg(host) -i mysql
use_backend app1_cluster if app1_cluster_acl
use_backend app2_cluster if app2_cluster_acl
use_backend mysql_cluster if mysql_cluster_acl
backend app1_cluster
mode http
cookie SERVERID insert indirect nocache
option forwardfor header X-Real-IP
option http-server-close
option httplog
balance roundrobin
server serv1 10.83.83.203:80 check cookie serv1
server serv2 10.83.83.204:80 check cookie serv2
backend app2_cluster
mode http
cookie SERVERID insert indirect nocache
option forwardfor header X-Real-IP
option http-server-close
option httplog
balance roundrobin
server serv1 10.83.83.187:80 check cookie serv1
server serv2 10.83.83.188:80 check cookie serv2
backend mysql_cluster
mode http
cookie SERVERID insert indirect nocache
option forwardfor header X-Real-IP
option http-server-close
option httplog
balance roundrobin
server mysql1 10.83.83.167:80 check cookie serv1
server mysql2 10.83.83.168:80 check cookie serv2
server mysql3 10.83.83.169:80 check cookie serv2
I get the same error if there is already a mysql or http service running on my load balancer in addition to ruuning on the back ends.
For example if nginx/apache is already running on my load balancer.
$ netstat -anp | grep ":80"
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN 3646/nginx
And i try to start my load balancer with bind *:80 i get a similar error.
$ haproxy -d -f /etc/haproxy/haproxy.cfg
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result FAILED
Total: 3 (2 usable), will use epoll.
Using epoll() as the polling mechanism.
[ALERT] 195/001456 (1903) : Starting frontend www: cannot bind socket [0.0.0.0:80]
If you need to have a mysql or http instance listening on 127.0.0.1 then you can specify the ip of another interface in the bind call.
bind: 10.0.0.20:80
With the latest version of haproxy you can now even use variables.
bind ${LB1}:80
And export these from the haproxy startup script or /etc/default/haproxy
export LB1="10.0.0.20"
Otherwise perhaps there is an issue with your haproxy startup scripts.