Files
Denozordec 2671e90d20
Docker / build (push) Successful in 31s
Init Commit
2026-03-23 17:31:26 +07:00

94 lines
2.5 KiB
Bash

#!/bin/bash
# Вызывается из socat EXEC; в окружении есть SOCAT_PEERADDR.
set -uo pipefail
STATUS_FILE="${STATUS_FILE:-/var/www/cfb/status.html}"
ALLOW="${STATUS_HTTP_ALLOW_IPS:-}"
ip_to_int() {
local a b c d IFS=.
read -r a b c d <<<"$1"
[[ -n "$d" ]] || return 1
echo $(((a << 24) | (b << 16) | (c << 8) | d))
}
ipv4_in_cidr() {
local ip="$1" cidr="$2" base masklen ipn basen mask
[[ "$cidr" =~ ^([0-9]{1,3}(\.[0-9]{1,3}){3})/([0-9]{1,2})$ ]] || return 1
base="${BASH_REMATCH[1]}"
masklen="${BASH_REMATCH[3]}"
(( masklen >= 0 && masklen <= 32 )) || return 1
(( masklen == 0 )) && return 0
ipn=$(ip_to_int "$ip") || return 1
basen=$(ip_to_int "$base") || return 1
(( masklen == 32 )) && { [[ "$ip" == "$base" ]]; return; }
mask=$(( (0xFFFFFFFF << (32 - masklen)) & 0xFFFFFFFF ))
(( (ipn & mask) == (basen & mask) ))
}
extract_peer_ip() {
local raw="${SOCAT_PEERADDR:-}"
[[ -n "$raw" ]] || { echo ""; return 1; }
if [[ "$raw" == \[*\]* ]]; then
local inner="${raw#\[}"
echo "${inner%%\]*}"
return 0
fi
if [[ "$raw" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}:[0-9]+$ ]]; then
echo "${raw%:*}"
return 0
fi
echo "$raw"
}
allowed_ip() {
local peer="$1" entry trimmed
[[ -n "$peer" ]] || return 1
IFS=',' read -ra _entries <<<"$ALLOW"
for entry in "${_entries[@]}"; do
trimmed="${entry#"${entry%%[![:space:]]*}"}"
trimmed="${trimmed%"${trimmed##*[![:space:]]}"}"
[[ -n "$trimmed" ]] || continue
if [[ "$trimmed" == */* ]]; then
if [[ "$peer" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; then
ipv4_in_cidr "$peer" "$trimmed" && return 0
fi
continue
fi
[[ "$peer" == "$trimmed" ]] && return 0
done
return 1
}
# Считать минимальный HTTP-запрос
while IFS= read -r line; do
line="${line%$'\r'}"
[[ -z "$line" ]] && break
done
peer_ip=$(extract_peer_ip)
hdr_ok=$'HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n'
hdr_denied=$'HTTP/1.0 403 Forbidden\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\nForbidden\r\n'
if [[ -z "${ALLOW// }" ]]; then
# только loopback — на всякий случай
if [[ "$peer_ip" != "127.0.0.1" && "$peer_ip" != "::1" ]]; then
printf '%b' "$hdr_denied"
exit 0
fi
else
if ! allowed_ip "$peer_ip"; then
printf '%b' "$hdr_denied"
exit 0
fi
fi
printf '%b' "$hdr_ok"
if [[ -r "$STATUS_FILE" ]]; then
cat "$STATUS_FILE"
else
printf '%s\n' '<!DOCTYPE html><html><body><p>status pending</p></body></html>'
fi