Evilham
c33d99ee12
This is backwards compatible with what is already used internally @ungleich, but adds on top of that the ability to customise ports and, most importantly, it adds PROXY protocol support.
155 lines
3.4 KiB
Bash
155 lines
3.4 KiB
Bash
#!/bin/sh -eu
|
|
|
|
__package haproxy
|
|
require="__package/haproxy" __start_on_boot haproxy
|
|
|
|
tmpdir="$__object/files"
|
|
mkdir "$tmpdir"
|
|
configtmp="$__object/files/haproxy.cfg"
|
|
|
|
os=$(cat "$__global/explorer/os")
|
|
case $os in
|
|
freebsd)
|
|
CONFIG_FILE="/usr/local/etc/haproxy.conf"
|
|
cat <<EOF > "$configtmp"
|
|
global
|
|
maxconn 4000
|
|
user nobody
|
|
group nogroup
|
|
daemon
|
|
|
|
EOF
|
|
|
|
;;
|
|
*)
|
|
CONFIG_FILE="/etc/haproxy/haproxy.cfg"
|
|
cat <<EOF > "$configtmp"
|
|
global
|
|
log [::1] local2
|
|
chroot /var/lib/haproxy
|
|
pidfile /var/run/haproxy.pid
|
|
maxconn 4000
|
|
user haproxy
|
|
group haproxy
|
|
daemon
|
|
|
|
# turn on stats unix socket
|
|
stats socket /var/lib/haproxy/stats
|
|
|
|
EOF
|
|
;;
|
|
esac
|
|
|
|
cat <<EOF >> "$configtmp"
|
|
defaults
|
|
retries 3
|
|
log global
|
|
timeout http-request 10s
|
|
timeout queue 1m
|
|
timeout connect 10s
|
|
timeout client 1m
|
|
timeout server 1m
|
|
timeout http-keep-alive 10s
|
|
timeout check 10s
|
|
EOF
|
|
|
|
dig_cmd="$(command -v dig || true)"
|
|
get_ip() {
|
|
# Usage: get_ip (ipv4|ipv6) NAME
|
|
# uses "dig" if available, else fallback to "host"
|
|
case $1 in
|
|
ipv4)
|
|
if [ -n "${dig_cmd}" ]; then
|
|
${dig_cmd} +short A "$2"
|
|
else
|
|
host -t A "$2" | cut -d ' ' -f 4 | grep -v 'found:'
|
|
fi
|
|
;;
|
|
ipv6)
|
|
if [ -n "${dig_cmd}" ]; then
|
|
${dig_cmd} +short AAAA "$2"
|
|
else
|
|
host -t AAAA "$2" | cut -d ' ' -f 5 | grep -v 'NXDOMAIN'
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
PROTOCOLS="$(cat "$__object/parameter/protocol")"
|
|
|
|
for proxy in v4proxy v6proxy; do
|
|
param=$__object/parameter/$proxy
|
|
# no backend? skip generating code
|
|
if [ ! -f "$param" ]; then
|
|
continue
|
|
fi
|
|
|
|
# turn backend name into bind parameter: v4backend -> ipv4@
|
|
bind=$(echo $proxy | sed -e 's/^/ip/' -e 's/proxy//')
|
|
|
|
case $bind in
|
|
ipv4)
|
|
backendproto=ipv6
|
|
;;
|
|
ipv6)
|
|
backendproto=ipv4
|
|
;;
|
|
esac
|
|
|
|
for proto in ${PROTOCOLS}; do
|
|
# Add protocol "header"
|
|
printf "\n# %s %s \n" "${bind}" "${proto}" >> "$configtmp"
|
|
|
|
sed -e "s/BIND/$bind/" \
|
|
-e "s/\(frontend[[:space:]].*\)/\1$bind/" \
|
|
-e "s/\(backend[[:space:]].*\)/\\1$bind/" \
|
|
"$__type/files/$proto" >> "$configtmp"
|
|
|
|
while read -r hostdefinition; do
|
|
if echo "$hostdefinition" | grep -qE '^proxy:'; then
|
|
# Proxy protocol was requested
|
|
host="$(echo "$hostdefinition" | sed -E 's/^proxy:([^:]+).*$/\1/')"
|
|
send_proxy=" send-proxy"
|
|
else
|
|
# Just use tcp proxy mode
|
|
host="$hostdefinition"
|
|
send_proxy=""
|
|
fi
|
|
if echo "$hostdefinition" | grep -qE ":${proto}="; then
|
|
# Use custom port definition if requested
|
|
port="$(echo "$hostdefinition" | sed -E "s/^(.*:)?${proto}=([0-9]+).*$/:\2/")"
|
|
else
|
|
# Else use the default
|
|
port=""
|
|
fi
|
|
servername=$host
|
|
|
|
res=$(get_ip "$bind" "$servername")
|
|
|
|
if [ -z "$res" ]; then
|
|
echo "$servername does not resolve - aborting config" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Treat protocols without TLS+SNI specially
|
|
if [ "$proto" = http ]; then
|
|
echo " use-server $servername if { hdr(host) -i $host }" >> "$configtmp"
|
|
else
|
|
echo " use-server $servername if { req_ssl_sni -i $host }" >> "$configtmp"
|
|
fi
|
|
|
|
# Create the "server" itself.
|
|
# Note that port and send_proxy will be empty unless
|
|
# they were requested by the type user
|
|
echo " server $servername ${backendproto}@${host}${port}${send_proxy}" >> "$configtmp"
|
|
|
|
done < "$param"
|
|
done
|
|
done
|
|
|
|
# Create config file
|
|
require="__package/haproxy" __file ${CONFIG_FILE} --source "$configtmp" --mode 0644
|
|
|
|
require="__file${CONFIG_FILE}" __check_messages "haproxy_reload" \
|
|
--pattern "^__file${CONFIG_FILE}" \
|
|
--execute "service haproxy reload || service haproxy restart"
|