Files
dock/03
2025-11-05 23:26:35 +08:00

324 lines
9.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 显示标题
echo -e "${CYAN}"
echo "================================================"
echo " 网络连接诊断工具 v2.0"
echo "================================================"
echo -e "${NC}"
# 函数:检查命令是否存在
check_command() {
if command -v "$1" &> /dev/null; then
return 0
else
return 1
fi
}
# 函数:显示帮助信息
show_help() {
echo -e "${YELLOW}使用说明:${NC}"
echo "1. 本工具用于测试网络连接和端口状态"
echo "2. 支持IP地址和域名测试"
echo "3. 可以测试多个端口"
echo "4. 包含详细的连接状态分析"
echo ""
}
# 函数输入IP/域名
input_target() {
while true; do
echo -e "${BLUE}请输入要测试的目标IP地址或域名${NC}"
read -p "目标地址: " TARGET
if [ -z "$TARGET" ]; then
echo -e "${RED}错误:目标地址不能为空!${NC}"
continue
fi
# 简单验证格式
if [[ "$TARGET" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || [[ "$TARGET" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
break
else
echo -e "${RED}错误请输入有效的IP地址或域名${NC}"
fi
done
}
# 函数:输入端口
input_ports() {
echo -e "${BLUE}请输入要测试的端口(多个端口用空格分隔):${NC}"
read -p "端口: " PORTS_INPUT
if [ -z "$PORTS_INPUT" ]; then
echo -e "${YELLOW}警告:未输入端口,使用默认端口 25555${NC}"
PORTS=("25555")
else
# 将输入的端口转换为数组
PORTS=($PORTS_INPUT)
fi
}
# 函数Ping测试
ping_test() {
echo -e "\n${PURPLE}=== Ping 连通性测试 ===${NC}"
echo -e "目标: ${YELLOW}$TARGET${NC}"
if ping -c 4 -W 2 "$TARGET" &> /dev/null; then
echo -e "${GREEN}✓ Ping 测试成功 - 网络连通正常${NC}"
PING_RESULT=$(ping -c 4 -W 2 "$TARGET" | grep -E "packets transmitted|min/avg/max" 2>/dev/null || echo "Ping 成功但无法解析详细结果")
echo "$PING_RESULT"
return 0
else
echo -e "${RED}✗ Ping 测试失败 - 网络不通${NC}"
return 1
fi
}
# 函数TCP连接测试主要测试方法
tcp_connection_test() {
local port=$1
echo -e "\n${PURPLE}=== 端口 $port 测试 ===${NC}"
# 测试1: TCP 连接测试(主要方法)
echo -e "${CYAN}[测试1] TCP 连接测试...${NC}"
if timeout 3 bash -c "echo > /dev/tcp/$TARGET/$port" 2>/dev/null; then
echo -e "${GREEN}✓ TCP 测试 - 端口 $port 开放${NC}"
TCP_RESULT=0
else
echo -e "${RED}✗ TCP 测试 - 端口 $port 关闭或无法连接${NC}"
TCP_RESULT=1
fi
# 测试2: 使用 curl 测试 HTTP/HTTPS 端口(如果适用)
if [[ $port -eq 80 || $port -eq 443 || $port -eq 8080 || $port -eq 8443 ]]; then
echo -e "${CYAN}[测试2] HTTP/HTTPS 服务检测...${NC}"
if check_command curl; then
local protocol="http"
if [[ $port -eq 443 || $port -eq 8443 ]]; then
protocol="https"
fi
if timeout 5 curl -s -I "${protocol}://${TARGET}:${port}" &> /dev/null; then
echo -e "${GREEN}✓ HTTP/HTTPS 服务在端口 $port 运行正常${NC}"
else
echo -e "${YELLOW}⚠ 端口 $port 可能不是 HTTP/HTTPS 服务或服务无响应${NC}"
fi
else
echo -e "${YELLOW}⚠ curl 命令未安装跳过HTTP测试${NC}"
fi
fi
# 测试3: 使用 nc 如果可用
if check_command nc; then
echo -e "${CYAN}[测试3] NC 端口扫描...${NC}"
if nc -zv -w 3 "$TARGET" "$port" &> /dev/null; then
echo -e "${GREEN}✓ NC 测试 - 端口 $port 开放${NC}"
else
echo -e "${RED}✗ NC 测试 - 端口 $port 关闭${NC}"
fi
else
echo -e "${YELLOW}⚠ NC 命令未安装跳过NC测试${NC}"
fi
# 测试4: 使用 telnet 如果可用
if check_command telnet; then
echo -e "${CYAN}[测试4] Telnet 测试...${NC}"
if timeout 3 telnet "$TARGET" "$port" 2>&1 | grep -q "Connected"; then
echo -e "${GREEN}✓ Telnet 测试 - 端口 $port 可连接${NC}"
else
echo -e "${RED}✗ Telnet 测试 - 端口 $port 无法连接${NC}"
fi
else
echo -e "${YELLOW}⚠ Telnet 命令未安装跳过Telnet测试${NC}"
fi
return $TCP_RESULT
}
# 函数DNS解析测试
dns_test() {
echo -e "\n${PURPLE}=== DNS 解析测试 ===${NC}"
if [[ "$TARGET" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo -e "${CYAN}检测到域名进行DNS解析...${NC}"
if check_command nslookup; then
if nslookup "$TARGET" &> /dev/null; then
echo -e "${GREEN}✓ DNS 解析成功${NC}"
nslookup "$TARGET" | grep -A 10 "Name:" | head -10
else
echo -e "${RED}✗ DNS 解析失败${NC}"
fi
elif check_command dig; then
if dig "$TARGET" +short &> /dev/null; then
echo -e "${GREEN}✓ DNS 解析成功${NC}"
dig "$TARGET" +short
else
echo -e "${RED}✗ DNS 解析失败${NC}"
fi
else
echo -e "${YELLOW}⚠ DNS 查询工具未安装跳过DNS测试${NC}"
fi
else
echo -e "${CYAN}检测到IP地址跳过DNS解析测试${NC}"
fi
}
# 函数:路由跟踪
trace_route() {
echo -e "\n${PURPLE}=== 路由跟踪测试 ===${NC}"
echo -e "${YELLOW}是否进行路由跟踪?(y/n, 可能需要较长时间)${NC}"
read -p "选择: " DO_TRACE
if [[ "$DO_TRACE" == "y" || "$DO_TRACE" == "Y" ]]; then
if check_command traceroute; then
echo -e "${CYAN}开始路由跟踪...${NC}"
traceroute -m 15 "$TARGET"
elif check_command tracepath; then
echo -e "${CYAN}开始路由跟踪 (使用 tracepath)...${NC}"
tracepath "$TARGET"
else
echo -e "${YELLOW}⚠ 路由跟踪命令未安装${NC}"
fi
fi
}
# 函数:生成测试报告
generate_report() {
echo -e "\n${PURPLE}=== 测试报告 ===${NC}"
echo -e "测试时间: $(date)"
echo -e "目标地址: ${YELLOW}$TARGET${NC}"
echo -e "测试端口: ${YELLOW}${PORTS[*]}${NC}"
# 汇总结果
echo -e "\n${CYAN}汇总结果:${NC}"
if ping -c 1 -W 2 "$TARGET" &> /dev/null; then
echo -e "${GREEN}● 网络连通性: 正常${NC}"
else
echo -e "${RED}● 网络连通性: 异常${NC}"
fi
echo -e "● 端口状态:"
for port in "${PORTS[@]}"; do
if timeout 2 bash -c "echo > /dev/tcp/$TARGET/$port" 2>/dev/null; then
echo -e " 端口 $port: ${GREEN}开放${NC}"
else
echo -e " 端口 $port: ${RED}关闭${NC}"
fi
done
# 给出建议
echo -e "\n${CYAN}建议:${NC}"
local all_ports_closed=true
for port in "${PORTS[@]}"; do
if timeout 2 bash -c "echo > /dev/tcp/$TARGET/$port" 2>/dev/null; then
all_ports_closed=false
break
fi
done
if ! ping -c 1 -W 2 "$TARGET" &> /dev/null; then
echo -e "${RED}● 目标主机无法访问,请检查网络连接或目标地址${NC}"
elif [ "$all_ports_closed" = true ]; then
echo -e "${YELLOW}● 所有测试端口均关闭,可能的原因:${NC}"
echo -e " - 目标服务未运行"
echo -e " - 防火墙阻止了连接"
echo -e " - 目标主机拒绝了连接"
else
echo -e "${GREEN}● 网络连接正常,部分端口可访问${NC}"
fi
}
# 主函数
main() {
# 显示帮助信息
show_help
# 获取用户输入
input_target
input_ports
echo -e "\n${GREEN}开始网络诊断测试...${NC}"
echo -e "目标: ${YELLOW}$TARGET${NC}"
echo -e "端口: ${YELLOW}${PORTS[*]}${NC}"
echo ""
# 执行各项测试
dns_test
ping_test
ping_result=$?
# 如果ping不通询问是否继续
if [ $ping_result -ne 0 ]; then
echo -e "\n${YELLOW}警告: Ping 测试失败,目标可能无法访问${NC}"
echo -e "${YELLOW}是否继续端口测试?(y/n)${NC}"
read -p "选择: " CONTINUE
if [[ "$CONTINUE" != "y" && "$CONTINUE" != "Y" ]]; then
echo -e "${RED}测试终止${NC}"
exit 1
fi
fi
# 端口测试
for port in "${PORTS[@]}"; do
tcp_connection_test "$port"
done
# 路由跟踪
trace_route
# 生成报告
generate_report
echo -e "\n${GREEN}网络诊断完成!${NC}"
}
# 检查必要命令(简化版)
check_requirements() {
local missing=()
# 只检查最基础的命令
for cmd in ping timeout; do
if ! command -v "$cmd" &> /dev/null; then
missing+=("$cmd")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo -e "${RED}错误: 缺少必要的命令: ${missing[*]}${NC}"
echo -e "${YELLOW}请安装缺少的命令后重新运行脚本${NC}"
exit 1
fi
# 检查可选命令并提示
echo -e "${CYAN}检测可选工具...${NC}"
for cmd in nc telnet curl nslookup dig traceroute tracepath; do
if ! command -v "$cmd" &> /dev/null; then
echo -e "${YELLOW}⚠ 可选工具 '$cmd' 未安装,相关测试将跳过${NC}"
else
echo -e "${GREEN}✓ 工具 '$cmd' 可用${NC}"
fi
done
echo ""
}
# 脚本入口
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
# 检查系统要求
check_requirements
# 运行主程序
main