PYTHON脚本验证端口访问权限(支持多种格式)

# -*- coding: utf-8 -*-
import socket
import time
import sys
import os

def parse_ip_range(ip_range):

    ip_list = []
    
    try:
        if '-' in ip_range and ip_range.count('.') == 6:
            # Full IP range format: 192.168.1.1-192.168.1.5
            start_ip, end_ip = ip_range.split('-')
            start_parts = start_ip.split('.')
            end_parts = end_ip.split('.')
            
            if len(start_parts) == 4 and len(end_parts) == 4:
                if start_parts[0:3] == end_parts[0:3]:
                    start = int(start_parts[3])
                    end = int(end_parts[3])
                    base_ip = '.'.join(start_parts[0:3])
                    for i in range(start, end + 1):
                        ip_list.append("%s.%d" % (base_ip, i))
                else:
                    print("IP地址范围只能在最后一部分设置 '%s'" % ip_range)
            else:
                print("输入的IP地址范围格式不符合要求 '%s'" % ip_range)
                
        # Check if contains range or selector in last octet
        elif '-' in ip_range or '|' in ip_range:
            parts = ip_range.split('.')
            if len(parts) != 4:
                print("IP格式不正确 '%s'" % ip_range)
                return ip_list
                
            base_ip = parts[:3]
            last_part = parts[3]
            
            # Handle range and selection in last octet
            if '-' in last_part and '|' in last_part:
                # Format: 1-5|6|7
                range_part, select_part = last_part.split('|', 1)
                start_str, end_str = range_part.split('-')
                start = int(start_str)
                end = int(end_str)
                
                # Add range IPs
                for i in range(start, end + 1):
                    ip_list.append("%s.%s.%s.%s" % (base_ip[0], base_ip[1], base_ip[2], i))
                
                # Add selected IPs
                for select_ip in select_part.split('|'):
                    ip_list.append("%s.%s.%s.%s" % (base_ip[0], base_ip[1], base_ip[2], select_ip))
                    
            elif '-' in last_part:
                # Format: 1-5
                start_str, end_str = last_part.split('-')
                start = int(start_str)
                end = int(end_str)
                for i in range(start, end + 1):
                    ip_list.append("%s.%s.%s.%s" % (base_ip[0], base_ip[1], base_ip[2], i))
                    
            elif '|' in last_part:
                # Format: 1|3|5|7
                for select_ip in last_part.split('|'):
                    ip_list.append("%s.%s.%s.%s" % (base_ip[0], base_ip[1], base_ip[2], select_ip))
        else:
            # Single IP
            ip_list.append(ip_range)
            
    except Exception as e:
        print("IP地址格式错误'%s': %s" % (ip_range, e))
    
    return ip_list

def parse_port_range(port_part):

    port_list = []
    
    try:
        # Handle range and selection in ports
        if '-' in port_part and '|' in port_part:
            # Format: 80-90|91|92
            range_part, select_part = port_part.split('|', 1)
            start_str, end_str = range_part.split('-')
            start = int(start_str)
            end = int(end_str)
            
            # Add range ports
            for i in range(start, end + 1):
                port_list.append(i)
            
            # Add selected ports
            for select_port in select_part.split('|'):
                port_list.append(int(select_port))
                
        elif '-' in port_part:
            # Format: 80-90
            start_str, end_str = port_part.split('-')
            start = int(start_str)
            end = int(end_str)
            for i in range(start, end + 1):
                port_list.append(i)
                
        elif '|' in port_part:
            for select_port in port_part.split('|'):
                port_list.append(int(select_port))
        else:
            port_list.append(int(port_part))
            
    except Exception as e:
        print("端口格式错误 '%s': %s" % (port_part, e))
    
    return port_list

def parse_ip_port_line(line):

    results = []
    
    line = line.strip()
    if not line or line.startswith('#'):
        return results
    
    try:
        if ':' in line:
            if line.count(':') > 1:
                print("不支持IPv6格式 '%s'" % line)
                return results
            ip_part, port_part = line.rsplit(':', 1)
            
            port_list = parse_port_range(port_part)
        else:
            ip_part = line
            port_list = [80]  #如果没有输入端口, 默认80端口
        
        ip_list = parse_ip_range(ip_part)
        
        for ip in ip_list:
            for port in port_list:
                results.append((ip, port))
            
    except ValueError as e:
        print("第 '%s' 行格式解析错误: %s" % (line, e))
    except Exception as e:
        print("第 '%s' 行发生未知错误: %s" % (line, e))
    
    return results

def test_connection(ip, port, timeout=3):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        start_time = time.time()
        result = sock.connect_ex((ip, port))
        end_time = time.time()
        response_time = round((end_time - start_time) * 1000, 2)  #毫秒
        
        sock.close()
        
        if result == 0:
            return (ip, port, True, "连接成功", response_time)
        else:
            # Provide more descriptive error messages
            error_messages = {
                11: "网络不可达",
                110: "连接超时",
                111: "拒绝连接",
                113: "解析错误"
            }
            error_msg = error_messages.get(result, "错误码: %s" % result)
            return (ip, port, False, error_msg, response_time)
            
    except socket.timeout:
        return (ip, port, False, "超时", 0)
    except socket.gaierror as e:
        return (ip, port, False, "DNS解析错误: %s" % e, 0)
    except Exception as e:
        return (ip, port, False, "未知错误: %s" % e, 0)

def read_and_parse_ip_list(filename="IP_LIST.txt"):

    all_targets = []
    
    if not os.path.exists(filename):
        print("错误:文件 %s 不存在!" % filename)
        return []
    
    try:
        with open(filename, 'r') as file:
            for line_num, line in enumerate(file, 1):
                line = line.strip()
                if line and not line.startswith('#'):
                    targets = parse_ip_port_line(line)
                    all_targets.extend(targets)
                    if targets:
                        print("第%d行: '%s' -> %d 个目标" % (line_num, line, len(targets)))
                    else:
                        print("第%d行: '%s' -> 0 个目标 (处理失败)" % (line_num, line))
                    
    except IOError:
        print("读取文件失败 %s" % filename)
        return []
    except Exception as e:
        print("读取文件失败: %s" % e)
        return []
    
    return all_targets

def check_python_version():
    print("Python版本: %s" % sys.version)

def sequential_test(targets):
    successful = 0
    failed = 0
    
    for ip, port in targets:
        result_ip, result_port, success, message, response_time = test_connection(ip, port)
        
        if success:
            print("SUCCESS %s:%d - %s (用时: %sms)" % (result_ip, result_port, message, response_time))
            successful += 1
        else:
            print("FAILED  %s:%d - %s" % (result_ip, result_port, message))
            failed += 1
    
    return successful, failed

def main():
    check_python_version()
    print("\n读取IP文件列表...")
    targets = read_and_parse_ip_list("IP_LIST.txt")
    
    if not targets:
        print("IP地址或端口无效")
        return
    
    print("\n需要测试的IP数量是: %d" % len(targets))
    print("开始进行测试...\n")
    
    successful = 0
    failed = 0
    
    # Try to use concurrent.futures first (Python 3.x)
    try:
        from concurrent.futures import ThreadPoolExecutor, as_completed
        
        with ThreadPoolExecutor(max_workers=20) as executor:
            future_to_target = {}
            for ip, port in targets:
                future = executor.submit(test_connection, ip, port)
                future_to_target[future] = (ip, port)
            
            for future in as_completed(future_to_target):
                ip, port = future_to_target[future]
                try:
                    result_ip, result_port, success, message, response_time = future.result()
                    
                    if success:
                        print("SUCCESS %s:%d - %s (用时: %sms)" % (result_ip, result_port, message, response_time))
                        successful += 1
                    else:
                        print("FAILED  %s:%d - %s" % (result_ip, result_port, message))
                        failed += 1
                        
                except Exception as e:
                    print("ERROR %s:%d - 测试过程发生异常: %s" % (ip, port, e))
                    failed += 1
                    
    except ImportError:
        successful, failed = sequential_test(targets)
    
    # Output statistics
    print("\n" + "="*50)
    print("成功: %d" % successful)
    print("失败: %d" % failed)
    print("合计: %d" % len(targets))

if __name__ == "__main__":
    main()

 

# IP列表文件示例

# 单个IP+单个PORT
10.192.112.235:443

# 多个IP+多个PORT
10.192.112.235|236:22-23|33

# 混合格式
10.66.132.123-124|125:22-23|26

 

将IP列表文件 IP_LIST.txt 放在脚本同级目录下,使用命令运行

python telnet_script.py

 

posted @ 2025-10-27 16:15  吃吃吃大王  阅读(1)  评论(0)    收藏  举报