mirror of
https://github.com/anten-ka/kaskad-pro.git
synced 2026-05-19 14:36:04 +00:00
Add TCP ping fallback for servers that block ICMP (XRay, VLESS, Reality)
Made-with: Cursor
This commit is contained in:
23
_ssh_debug.py
Normal file
23
_ssh_debug.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import paramiko, sys
|
||||||
|
|
||||||
|
host = "185.250.47.205"
|
||||||
|
user = "root"
|
||||||
|
pwd = "0i1sbf9NM36FkG5dFH"
|
||||||
|
|
||||||
|
def run(cmd, timeout=30):
|
||||||
|
ssh = paramiko.SSHClient()
|
||||||
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
ssh.connect(host, username=user, password=pwd, timeout=10)
|
||||||
|
stdin, stdout, stderr = ssh.exec_command(cmd, timeout=timeout)
|
||||||
|
out = stdout.read().decode(errors="replace")
|
||||||
|
err = stderr.read().decode(errors="replace")
|
||||||
|
rc = stdout.channel.recv_exit_status()
|
||||||
|
ssh.close()
|
||||||
|
return rc, out, err
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
cmd = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "echo ok"
|
||||||
|
rc, out, err = run(cmd)
|
||||||
|
if out: print(out, end="")
|
||||||
|
if err: print("STDERR:", err, end="")
|
||||||
|
print(f"\n[exit {rc}]")
|
||||||
58
_test_tcp_ping.py
Normal file
58
_test_tcp_ping.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import paramiko
|
||||||
|
|
||||||
|
host = "185.250.47.205"
|
||||||
|
user = "root"
|
||||||
|
pwd = "0i1sbf9NM36FkG5dFH"
|
||||||
|
|
||||||
|
test_script = """#!/bin/bash
|
||||||
|
tcp_ping() {
|
||||||
|
local ip="$1" port="$2" tout="${3:-3}"
|
||||||
|
local raw
|
||||||
|
raw=$(curl -so /dev/null -w '%{time_connect}' --max-time "$tout" --connect-timeout "$tout" "http://${ip}:${port}/" 2>/dev/null)
|
||||||
|
[ -z "$raw" ] && return 1
|
||||||
|
local ms
|
||||||
|
ms=$(awk "BEGIN {v=$raw*1000; if(v<0.5) exit 1; printf \\"%.2f\\", v}" 2>/dev/null) || return 1
|
||||||
|
echo "$ms"
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_ping() {
|
||||||
|
local ip="$1" tout="${2:-3}" port="${3:-}"
|
||||||
|
local ms
|
||||||
|
ms=$(ping -c 1 -W "$tout" "$ip" 2>/dev/null | sed -n 's/.*time=\\([0-9.]*\\).*/\\1/p')
|
||||||
|
if [ -n "$ms" ]; then echo "ICMP: ${ms}ms"; return 0; fi
|
||||||
|
[ -z "$port" ] && { echo "NO_PORT"; return 1; }
|
||||||
|
ms=$(tcp_ping "$ip" "$port" "$tout")
|
||||||
|
if [ -n "$ms" ]; then echo "TCP: ${ms}ms"; return 0; fi
|
||||||
|
echo "TIMEOUT"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "=== Test 1: ICMP to 8.8.8.8 ==="
|
||||||
|
smart_ping "8.8.8.8" 3
|
||||||
|
|
||||||
|
echo "=== Test 2: ICMP to 193.124.225.26 (no port) ==="
|
||||||
|
smart_ping "193.124.225.26" 3
|
||||||
|
|
||||||
|
echo "=== Test 3: smart_ping 193.124.225.26 TCP:443 ==="
|
||||||
|
smart_ping "193.124.225.26" 3 "443"
|
||||||
|
|
||||||
|
echo "=== Test 4: tcp_ping raw ==="
|
||||||
|
result=$(tcp_ping "193.124.225.26" "443" 3)
|
||||||
|
echo "result=$result rc=$?"
|
||||||
|
"""
|
||||||
|
|
||||||
|
ssh = paramiko.SSHClient()
|
||||||
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
ssh.connect(host, username=user, password=pwd, timeout=10)
|
||||||
|
|
||||||
|
sftp = ssh.open_sftp()
|
||||||
|
with sftp.file("/tmp/_kaskad_test.sh", "w") as f:
|
||||||
|
f.write(test_script)
|
||||||
|
sftp.close()
|
||||||
|
|
||||||
|
stdin, stdout, stderr = ssh.exec_command("bash /tmp/_kaskad_test.sh", timeout=30)
|
||||||
|
print(stdout.read().decode(errors="replace"))
|
||||||
|
err = stderr.read().decode(errors="replace")
|
||||||
|
if err:
|
||||||
|
print("STDERR:", err)
|
||||||
|
ssh.close()
|
||||||
45
install.sh
45
install.sh
@@ -261,7 +261,9 @@ probe_server_cli() {
|
|||||||
[ -n "$_RET_NOTE" ] && set_alias_note "$ip" "$_RET_NOTE"
|
[ -n "$_RET_NOTE" ] && set_alias_note "$ip" "$_RET_NOTE"
|
||||||
|
|
||||||
if [ ${#pings[@]} -eq 0 ]; then
|
if [ ${#pings[@]} -eq 0 ]; then
|
||||||
echo -e "${YELLOW}[WARN] Сервер не отвечает на ping.${NC}"
|
echo -e "${YELLOW}[WARN] Сервер не отвечает на ICMP ping.${NC}"
|
||||||
|
echo -e "${WHITE}(Это нормально для VLESS/XRay — ICMP часто заблокирован)${NC}"
|
||||||
|
echo -e "${WHITE}TCP-проверка будет доступна после добавления правила.${NC}"
|
||||||
read -p "Продолжить? (y/n): " ans
|
read -p "Продолжить? (y/n): " ans
|
||||||
[[ "$ans" != "y" ]] && return 1
|
[[ "$ans" != "y" ]] && return 1
|
||||||
fi
|
fi
|
||||||
@@ -403,6 +405,31 @@ get_target_ips() {
|
|||||||
get_rules_list | awk -F'|' '{split($3,a,":"); print a[1]}' | sort -u
|
get_rules_list | awk -F'|' '{split($3,a,":"); print a[1]}' | sort -u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_port_for_ip() {
|
||||||
|
local ip="$1"
|
||||||
|
get_rules_list | awk -F'|' -v ip="$ip" '{split($3,a,":"); if(a[1]==ip){print a[2]; exit}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp_ping() {
|
||||||
|
local ip="$1" port="$2" tout="${3:-3}"
|
||||||
|
local raw
|
||||||
|
raw=$(curl -so /dev/null -w '%{time_connect}' --max-time "$tout" --connect-timeout "$tout" "http://${ip}:${port}/" 2>/dev/null)
|
||||||
|
[ -z "$raw" ] && return 1
|
||||||
|
local ms
|
||||||
|
ms=$(awk "BEGIN {v=$raw*1000; if(v<0.5) exit 1; printf \"%.2f\", v}" 2>/dev/null) || return 1
|
||||||
|
echo "$ms"
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_ping() {
|
||||||
|
local ip="$1" tout="${2:-3}" port="${3:-}"
|
||||||
|
local ms
|
||||||
|
ms=$(ping -c 1 -W "$tout" "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
||||||
|
if [ -n "$ms" ]; then echo "$ms"; return 0; fi
|
||||||
|
[ -z "$port" ] && port=$(get_port_for_ip "$ip")
|
||||||
|
[ -z "$port" ] && return 1
|
||||||
|
tcp_ping "$ip" "$port" "$tout"
|
||||||
|
}
|
||||||
|
|
||||||
remove_rules_for_port() {
|
remove_rules_for_port() {
|
||||||
local proto="$1" in_port="$2"
|
local proto="$1" in_port="$2"
|
||||||
iptables -t nat -S PREROUTING 2>/dev/null | grep "DNAT" | grep -- "--dport ${in_port} " | grep -- "-p ${proto} " | while read -r rule; do
|
iptables -t nat -S PREROUTING 2>/dev/null | grep "DNAT" | grep -- "--dport ${in_port} " | grep -- "-p ${proto} " | while read -r rule; do
|
||||||
@@ -717,14 +744,18 @@ ping_live() {
|
|||||||
|
|
||||||
trap 'running=0' INT
|
trap 'running=0' INT
|
||||||
|
|
||||||
|
local _port; _port=$(get_port_for_ip "$ip")
|
||||||
|
local _mode="ICMP"
|
||||||
|
[ -n "$_port" ] && _mode="ICMP/TCP:${_port}"
|
||||||
|
|
||||||
while [ "$running" -eq 1 ]; do
|
while [ "$running" -eq 1 ]; do
|
||||||
local ms
|
local ms
|
||||||
ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
ms=$(smart_ping "$ip" 3 "${_port:-}")
|
||||||
((count++))
|
((count++))
|
||||||
|
|
||||||
clear
|
clear
|
||||||
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||||
echo -e "${CYAN} Live Ping: ${WHITE}$label${CYAN} [Ctrl+C — стоп]${NC}"
|
echo -e "${CYAN} Live Ping: ${WHITE}$label${CYAN} (${_mode}) [Ctrl+C — стоп]${NC}"
|
||||||
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||||
|
|
||||||
if [ -n "$ms" ]; then
|
if [ -n "$ms" ]; then
|
||||||
@@ -885,7 +916,7 @@ monitor_daemon() {
|
|||||||
[ -f "$ckf" ] && lc=$(cat "$ckf")
|
[ -f "$ckf" ] && lc=$(cat "$ckf")
|
||||||
if (( now - lc >= MON_INTERVAL )); then
|
if (( now - lc >= MON_INTERVAL )); then
|
||||||
echo "$now" > "$ckf"
|
echo "$now" > "$ckf"
|
||||||
local pr; pr=$(ping -c 1 -W 3 "$MON_IP" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
local pr; pr=$(smart_ping "$MON_IP" 3)
|
||||||
if [ -z "$pr" ]; then
|
if [ -z "$pr" ]; then
|
||||||
monitor_alert "$MON_IP" "TIMEOUT" "$MON_THRESHOLD" "$MON_COOLDOWN"
|
monitor_alert "$MON_IP" "TIMEOUT" "$MON_THRESHOLD" "$MON_COOLDOWN"
|
||||||
else
|
else
|
||||||
@@ -1204,7 +1235,7 @@ bot_handle_callback() {
|
|||||||
ps:*) local ip="${data#ps:}"; local lb; lb=$(fmt_ip_short "$ip")
|
ps:*) local ip="${data#ps:}"; local lb; lb=$(fmt_ip_short "$ip")
|
||||||
tg_edit "$chat_id" "$msg_id" "🏓 <b>$lb</b>\nРежим:" "$(kbd_ping_opts "$ip")" ;;
|
tg_edit "$chat_id" "$msg_id" "🏓 <b>$lb</b>\nРежим:" "$(kbd_ping_opts "$ip")" ;;
|
||||||
po:*) local ip="${data#po:}"; local lb; lb=$(fmt_ip_short "$ip")
|
po:*) local ip="${data#po:}"; local lb; lb=$(fmt_ip_short "$ip")
|
||||||
( local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
( local ms; ms=$(smart_ping "$ip" 3)
|
||||||
[ -n "$ms" ] && tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>${ms} ms</code>" "$(kbd_back)" > /dev/null \
|
[ -n "$ms" ] && tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>${ms} ms</code>" "$(kbd_back)" > /dev/null \
|
||||||
|| tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>timeout</code>" "$(kbd_back)" > /dev/null ) & ;;
|
|| tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>timeout</code>" "$(kbd_back)" > /dev/null ) & ;;
|
||||||
p10:*) local ip="${data#p10:}"; local lb; lb=$(fmt_ip_short "$ip")
|
p10:*) local ip="${data#p10:}"; local lb; lb=$(fmt_ip_short "$ip")
|
||||||
@@ -1212,7 +1243,7 @@ bot_handle_callback() {
|
|||||||
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
|
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
|
||||||
local -a res=(); local lost=0 txt=""
|
local -a res=(); local lost=0 txt=""
|
||||||
for n in $(seq 1 10); do
|
for n in $(seq 1 10); do
|
||||||
local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
local ms; ms=$(smart_ping "$ip" 3)
|
||||||
[ -n "$ms" ] && res+=("$ms") && txt+="#$n: ${ms}ms\n" || { ((lost++)); txt+="#$n: timeout\n"; }
|
[ -n "$ms" ] && res+=("$ms") && txt+="#$n: ${ms}ms\n" || { ((lost++)); txt+="#$n: timeout\n"; }
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
@@ -1226,7 +1257,7 @@ bot_handle_callback() {
|
|||||||
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
|
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
|
||||||
local -a res=(); local lost=0
|
local -a res=(); local lost=0
|
||||||
for n in $(seq 1 60); do
|
for n in $(seq 1 60); do
|
||||||
local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
|
local ms; ms=$(smart_ping "$ip" 3)
|
||||||
[ -n "$ms" ] && res+=("$ms") || ((lost++))
|
[ -n "$ms" ] && res+=("$ms") || ((lost++))
|
||||||
if (( n % 10 == 0 )) && [ -n "$mid" ]; then
|
if (( n % 10 == 0 )) && [ -n "$mid" ]; then
|
||||||
local p="🏓 <b>$lb</b>: ${n}/60с\nОК: ${#res[@]} | Lost: $lost"
|
local p="🏓 <b>$lb</b>: ${n}/60с\nОК: ${#res[@]} | Lost: $lost"
|
||||||
|
|||||||
Reference in New Issue
Block a user