OTP Knocker
Implement "portknocking" in HAproxy by using OTP-Codes.
How it works
HAProxy will hold a table in memory of all IPs that are successfully authenticated.
When trying to access the protected backend, HAProxy will deny your request unless your IP is marked as "whitelisted".
While using the authentication backend, HAProxy will wait for the backend server to send a specific response header to inform HAProxy that the authentication was successful.
HAProxy configuraton
frontend http
bind *:80
bind *:443 ssl crt-list /etc/haproxy/certs/all.txt alpn h2,http/1.1 # Change this to point to your SSL certificates
use_backend otpknocker if { ssl_fc_sni knock.example.com }
use_backend secretStuff if { ssl_fc_sni secret.example.com }
backend secretStuff
http-request track-sc0 src table table-ip-whitelist if TRUE # We might not need this line.
acl authenticated src_get_gpc0(table-ip-whitelist) gt 0 # Create an ACL that's only true once the IP is authenticated
http-request deny if !authenticated # Deny the request unless the IP is authenticated
server mysecretBackendServer 10.10.10.55:80 # Add your backend servers here
backend table-ip-whitelist # This backend only exists to hold the stick table
stick-table type ip size 1m expire 86400s store gpc0 # Change 86400s to the expiration of whitelisted IPs
backend otpknocker
server otpknocker 192.168.5.10:8000 # Put the IP and Port of the python app here
http-request track-sc0 src table table-ip-whitelist
http-response sc-inc-gpc0(0) if { res.hdr(Authentication-Success) -m str "true" } # Once the app return the Authentication-Success header, the client IP will be whitelisted
OTP Knocker configuration
OTP Knocker can run in a Docker container. A Dockerfile
and docker-compose.yaml
is included.
The OTP-Secret needs to be injected as OTP_SECRET
environment variable. A sample value is provided but should be changed before usage!