HAProxy Source IP Alias Problem [Solved]
-
tldr; HAproxy trying to use an alias as source IP filter. Alias (7 hosts) resolved correctly in pfSense, HAProxy config file looks good, but HAProxy src file created for alias is empty
I configured an alias called infoddns in pfSense latest stable (2.4.x) that consists of 7 hosts. The hosts are configured as FQDNs that are all updated using ddns. mysub1.mydom.info, mysub2.mydom.info, etc.
When I look at Diagnostics/Tables, infoddns is there and the correctly resolved IP addresses are listed in the table.
I used that alias name as the value for a front end ACL of type "Source IP matches IP or Alias". When I look at the generated HAProxy config, all looks correct:
acl infoacl src -f /var/etc/haproxy/ipalias_infoddns.lstIf I add the ACL to an action, those IPs (and all IPs) are blocked and return a 503.
When I look at the file /var/etc/haproxy/ipalias_infoddns.lst it is only 2 bytes long and contains no IPs.
It seems that everything is set up correctly, but the resolved alias IPs are never written to the HAProxy acl src file. I have re-started HAProxy and rebooted pfSense with no change.
It's likely that I missed some configuration step, but I'm stumped at the moment. Suggestions would be appreciated.
Jerry
-
Not missing a step.. just that haproxy isn't going to resolve the names in a list to IP's, so the 'alias support' is limited to fixed IP's and subnets a.t.m.. It could be possible i suppose to resolve a list of names to IP's by the package when reloading the config, but when a dns record changes it wouldn't take effect until the config is reloaded.. so really it would still be of limited use.
-
Thanks PiBa.
Is it possible to read the contents of a pfSense table from a shell script? If so, I could simply run a cron job to read the table contents which is being resolved correctly and write the HAProxy src file which is being configured correctly, but not populated.
-
Your cron job would be to late if its going to edit the file as it is only read on haproxy startup..
There might still be a possibility though, if you manage to read the ip's from pfSense.
pfctl -t bogons -T show
And then add them to the haproxy in memory list.
/usr/local/pkg/haproxy/haproxy_socket.sh add acl /var/etc/haproxy/ipalias_infoddns.lst 1.2.3.4/31
-
That works perfectly! Thanks very much for your help.
-
Here's the script I added to cron. There might be more efficient / better ways to do it, but this works for my case with a fairly small number of IPs in the alias.
#!/bin/sh
Update an HAProxy acl with ddns addresses from a pfsense table
#Edit this value to match pfSense alias name
ALIASNAME="infoddns"#Force update on first run - acl will be empty after restart
/usr/local/pkg/haproxy/haproxy_socket.sh show acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst" > "/tmp/${ALIASNAME}-acl"
rc=wc -l < "/tmp/${ALIASNAME}-acl" | awk '{print $1}'
if [ $rc -lt 2 ]; then echo "X" > "/tmp/${ALIASNAME}-cur"; fi#Dump the alias table to a temp file
pfctl -t ${ALIASNAME} -T show > "/tmp/${ALIASNAME}-new"#Check new alias table against current
diff "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur" >/dev/null 2>&1#If no change, just exit
rc=$?; if [ $rc == 0 ]; then exit 0; fi#Clear current acl
/usr/local/pkg/haproxy/haproxy_socket.sh clear acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst"#read each alias table line and add to HAproxy acl IP values
while read -r line; do
/usr/local/pkg/haproxy/haproxy_socket.sh add acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst ${line}/31"
done < "/tmp/${ALIASNAME}-new"#Set current alias file to the updated values
mv "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur"exit 0
-
@piba can you please be a little elaborate on how to do this?
-
This post is deleted! -
@jafath
Thank you for the providing this handy script.I had to make minor changes in order for it to work.
For anyone who might need it:#!/bin/sh #Edit this value to match pfSense alias name ALIASNAME="infodns" #Force update on first run - acl will be empty after restart /usr/local/pkg/haproxy/haproxy_socket.sh show acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst" > "/tmp/${ALIASNAME}-acl" rc=$(wc -l < "/tmp/${ALIASNAME}-acl" | awk '{print $1}') if [ "$rc" -lt 2 ]; then echo "X" > "/tmp/${ALIASNAME}-cur"; fi #Dump the alias table to a temp file pfctl -t ${ALIASNAME} -T show > "/tmp/${ALIASNAME}-new" #Check new alias table against current diff "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur" >/dev/null 2>&1 #If no change, just exit rc=$?; if [ $rc == 0 ]; then exit 0; fi #Clear current acl /usr/local/pkg/haproxy/haproxy_socket.sh clear acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst" #read each alias table line and add to HAproxy acl IP values while read -r line; do /usr/local/pkg/haproxy/haproxy_socket.sh add acl "/var/etc/haproxy/ipalias_${ALIASNAME}.lst ${line}/32" done < "/tmp/${ALIASNAME}-new" #Set current alias file to the updated values mv "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur" #Optional Log to syslog # logger Haproxy acl for ALIASNAME updated successfully via the update script exit 0
Place it some where in pfsense (e.g /usr/customScripts/update-haproxy-ALIASNAME.sh), then add a cron entry that points to this script.
-
@jafath said in HAProxy Source IP Alias Problem [Solved]:
/usr/local/pkg/haproxy/haproxy_socket.sh add acl
I'm a bit late to the party...
When checking this feature request: https://redmine.pfsense.org/issues/9793 I would say it's possible, checking the GitHub merge request you can see it should be able to parse ip table aliases.I'm on 2.5.2 but do not have those entries in /usr/local/pkg/haproxy/haproxy.inc and I'm not sure if it's in 2.6 or not.
Anyone any idea?
Using the haproxy_socket.sh add acl approach works, but it's a time-consuming loop for 14k ip table lists from pfBlockerNG and I don't know ACME decides to restart HAProxy when generating new certificates.
Gr,
L -
@cukal I was looking for the same thing, and can se that it is only in the devel version urltable is added: haproxy-devel
-
I was beating my head against this the past few days, finally figured out using an alias with FQDNs was not actually working. The script above was a good starting point, but I have a new version that is more robust. Hopefully helpful to someone else! One more improvement I will make eventually is to support multiple aliases. I wanted to use the socket wrapper script, but it generated additional cruft on the first output line so I just used the socket directly. I also did not know why the original used /31 as a mask so I removed that.
#! /bin/sh #Edit this value to match pfSense alias name ALIASNAME="Foreman_Clients" SOCKET=/tmp/haproxy.socket #Pull current ACL from haproxy (normalize and sort by IP) echo "show acl /var/etc/haproxy/ipalias_${ALIASNAME}.lst" | nc -U $SOCKET | sed '/^$/d' | awk '{print $2}' | sort -V > "/tmp/${ALIASNAME}-cur" #Dump alias values to a temp file (normalize and sort by IP) pfctl -t ${ALIASNAME} -T show | sort -V > "/tmp/${ALIASNAME}-new" #Check new alias values against current (ignore whitespace) diff -w "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur" >/dev/null 2>&1 && exit 0 #Clear current acl echo "clear acl /var/etc/haproxy/ipalias_${ALIASNAME}.lst" | nc -U $SOCKET #Populate haproxy ACL with alias values while read -r line; do echo "add acl /var/etc/haproxy/ipalias_${ALIASNAME}.lst ${line}" | nc -U $SOCKET done < "/tmp/${ALIASNAME}-new" #Remember current alias contents for next run mv "/tmp/${ALIASNAME}-new" "/tmp/${ALIASNAME}-cur" exit 0
-
@ciscoqid thank you very much, your script solved my problem...