mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
fix(fail2ban): exempt SSH and panel ports from IP-limit ban (#4896)
The 3x-ipl action used iptables-allports, so a banned IP lost all TCP access including SSH and the panel, locking admins out (especially with dynamic-IP clients). The ban now blocks every TCP port except the SSH and panel ports via a multiport negation, derived at jail-creation time in both x-ui.sh and DockerEntrypoint.sh. This keeps IP-limit working for all current and future inbounds without per-port config.
This commit is contained in:
parent
14e2d4954a
commit
b1d079fc24
2 changed files with 28 additions and 4 deletions
|
|
@ -27,6 +27,16 @@ failregex = \[LIMIT_IP\]\s*Email\s*=\s*<F-USER>.+</F-USER>\s*\|\|\s*Disconnect
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Ports to exempt from the ban so an over-limit proxy client can never lock
|
||||||
|
# the administrator out of SSH or the panel. The ban still covers every other
|
||||||
|
# TCP port (including all Xray inbounds), so IP-limit keeps working for inbounds
|
||||||
|
# added later without regenerating these files.
|
||||||
|
SSH_PORTS=$(grep -oE '^[[:space:]]*Port[[:space:]]+[0-9]+' /etc/ssh/sshd_config 2>/dev/null | grep -oE '[0-9]+' | paste -sd, -)
|
||||||
|
[ -z "$SSH_PORTS" ] && SSH_PORTS="22"
|
||||||
|
PANEL_PORT=$(/app/x-ui setting -show true 2>/dev/null | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
|
EXEMPT_PORTS="$SSH_PORTS"
|
||||||
|
[ -n "$PANEL_PORT" ] && EXEMPT_PORTS="$EXEMPT_PORTS,$PANEL_PORT"
|
||||||
|
|
||||||
cat > /etc/fail2ban/action.d/3x-ipl.conf << EOF
|
cat > /etc/fail2ban/action.d/3x-ipl.conf << EOF
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
before = iptables-allports.conf
|
before = iptables-allports.conf
|
||||||
|
|
@ -42,16 +52,17 @@ actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name>
|
||||||
|
|
||||||
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
|
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
|
||||||
|
|
||||||
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
|
actionban = <iptables> -I f2b-<name> 1 -s <ip> -p <protocol> -m multiport ! --dports <exemptports> -j <blocktype>
|
||||||
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") BAN [Email] = <F-USER> [IP] = <ip> banned for <bantime> seconds." >> $LOG_FOLDER/3xipl-banned.log
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") BAN [Email] = <F-USER> [IP] = <ip> banned for <bantime> seconds." >> $LOG_FOLDER/3xipl-banned.log
|
||||||
|
|
||||||
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
|
actionunban = <iptables> -D f2b-<name> -s <ip> -p <protocol> -m multiport ! --dports <exemptports> -j <blocktype>
|
||||||
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> $LOG_FOLDER/3xipl-banned.log
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> $LOG_FOLDER/3xipl-banned.log
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
name = default
|
name = default
|
||||||
protocol = tcp
|
protocol = tcp
|
||||||
chain = INPUT
|
chain = INPUT
|
||||||
|
exemptports = $EXEMPT_PORTS
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
fail2ban-client -x start
|
fail2ban-client -x start
|
||||||
|
|
|
||||||
17
x-ui.sh
17
x-ui.sh
|
|
@ -2248,6 +2248,18 @@ failregex = \[LIMIT_IP\]\s*Email\s*=\s*<F-USER>.+</F-USER>\s*\|\|\s*Disconnect
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Ports to exempt from the ban so an over-limit proxy client can never lock
|
||||||
|
# the administrator out of SSH or the panel. The ban still covers every other
|
||||||
|
# TCP port (including all Xray inbounds), so IP-limit keeps working for inbounds
|
||||||
|
# added later without regenerating these files.
|
||||||
|
local ssh_ports
|
||||||
|
ssh_ports=$(grep -oP '^[[:space:]]*Port[[:space:]]+\K[0-9]+' /etc/ssh/sshd_config 2>/dev/null | paste -sd, -)
|
||||||
|
[[ -z "${ssh_ports}" ]] && ssh_ports="22"
|
||||||
|
local panel_port
|
||||||
|
panel_port=$(${xui_folder}/x-ui setting -show true 2>/dev/null | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
|
local exempt_ports="${ssh_ports}"
|
||||||
|
[[ -n "${panel_port}" ]] && exempt_ports="${exempt_ports},${panel_port}"
|
||||||
|
|
||||||
cat << EOF > /etc/fail2ban/action.d/3x-ipl.conf
|
cat << EOF > /etc/fail2ban/action.d/3x-ipl.conf
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
before = iptables-allports.conf
|
before = iptables-allports.conf
|
||||||
|
|
@ -2263,16 +2275,17 @@ actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name>
|
||||||
|
|
||||||
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
|
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'
|
||||||
|
|
||||||
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
|
actionban = <iptables> -I f2b-<name> 1 -s <ip> -p <protocol> -m multiport ! --dports <exemptports> -j <blocktype>
|
||||||
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") BAN [Email] = <F-USER> [IP] = <ip> banned for <bantime> seconds." >> ${iplimit_banned_log_path}
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") BAN [Email] = <F-USER> [IP] = <ip> banned for <bantime> seconds." >> ${iplimit_banned_log_path}
|
||||||
|
|
||||||
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
|
actionunban = <iptables> -D f2b-<name> -s <ip> -p <protocol> -m multiport ! --dports <exemptports> -j <blocktype>
|
||||||
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> ${iplimit_banned_log_path}
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> ${iplimit_banned_log_path}
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
name = default
|
name = default
|
||||||
protocol = tcp
|
protocol = tcp
|
||||||
chain = INPUT
|
chain = INPUT
|
||||||
|
exemptports = ${exempt_ports}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo -e "${green}Ip Limit jail files created with a bantime of ${bantime} minutes.${plain}"
|
echo -e "${green}Ip Limit jail files created with a bantime of ${bantime} minutes.${plain}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue