global log 127.0.0.1 local2 debug maxconn 2000 user haproxy group haproxy ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ssl-default-bind-ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 #ssl good practise taken from: https://www.haproxy.com/documentation/aloha/12-5/traffic-management/lb-layer7/tls/ #ssl ciphers level intermediate (compatible with almost everything) taken from: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended-configurations defaults log global mode http option httplog option dontlognull retries 3 option redispatch timeout connect 5000 timeout client 10000 timeout server 10000 log-format "GMT:%T frontend:%f/%H/%fi:%fp backend:%b client:%ci:%cp xforwardedfor:%[capture.req.hdr(3)] headers:%hr statuscode:%ST request:%r" frontend www-https mode http option http-buffer-request declare capture request len 40000 capture request header User-Agent len 512 capture request header Host len 512 capture request header X-Forwarded-For len 512 capture request header X-Forwarded-Proto len 512 capture request header X-Host len 512 capture request header Forwarded len 512 capture request header Via len 512 log /dev/log local2 debug http-response set-header X-Frame-Options DENY http-response set-header X-Content-Type-Options nosniff http-response set-header Cache-Control "max-age=0, no-cache, no-store, must-revalidate" bind :::443 v4v6 ssl crt /etc/letsencrypt/live/haproxy.pem http-request add-header X-Forwarded-Proto https # modify the paths below to match your c2 channel acl path_stage1 path -m beg /s1 acl path_cs path -m beg /cs # stager - enable only if you know what you are doing #acl path_cs path_reg ^/[0-z][0-z][0-z][0-z]$ use_backend c2_stage1_https if path_stage1 use_backend c2_cobaltstrike_https if path_cobaltstrike default_backend decoy-www timeout client 1m frontend www-http mode http option http-buffer-request declare capture request len 40000 capture request header User-Agent len 512 capture request header Host len 512 capture request header X-Forwarded-For len 512 capture request header X-Forwarded-Proto len 512 capture request header X-Host len 512 capture request header Forwarded len 512 capture request header Via len 512 log /dev/log local2 debug http-response set-header X-Frame-Options DENY http-response set-header X-Content-Type-Options nosniff http-response set-header Cache-Control "max-age=0, no-cache, no-store, must-revalidate" bind :::80 v4v6 http-request add-header X-Forwarded-Proto http # modify the paths below to match your c2 channel acl path_stage1 path -m beg /s1 acl path_cs path -m beg /cs # stager - enable only if you know what you are doing #acl path_cs path_reg ^/[0-z][0-z][0-z][0-z]$ default_backend decoy-www timeout client 1m # backend names should start with decoy, c2 or alarm for redelk to understand and act upon backend decoy-www mode http http-request set-header Host 127.0.0.1 server 127.0.0.1 127.0.0.1:80 backend c2_cobaltstrike_https # Insert X-Forwarded-For header to have Cobalt Strike display the proper IP address of target. Uncomment if you want this functionality # Remark: when using Domain Fronting/CDNs, this needs to be commented out as Cobalt Strike does not understand a double inserted X-Forwarded-For header: it will display the IP of the CDN endpoint #option forwardfor server teamserver $$IP_OF_YOUR_C2SERVER:443 check ssl verify none backend c2_cobaltstrike_http #option forwardfor server teamserver $$IP_OF_YOUR_C2SERVER:80 backend c2_stage1 server c2server $$IP_OF_YOUR_C2SERVER:11081