LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C#实现Windows系统远程桌面3389端口来访者IP地址检测并强制断开不在白名单的非法连接

admin
2025年3月13日 12:17 本文热度 91

​以下是一个C#实现的解决方案,用于C#实现Windows系统远程桌面3389端口来访者IP地址检测,并强制断开不在白名单的非法IP地址连接,支持IPv4和IPv6地址判断,如果是IPv6地址则直接强制断开

using System;

using System.Collections.Generic;

using System.Net;

using System.Net.NetworkInformation;

using System.Net.Sockets;

using System.Runtime.InteropServices;


namespace TcpConnectionMonitor

{

    public class TcpConnectionManager

    {

        // IPv4连接结构体

        [StructLayout(LayoutKind.Sequential)]

        public struct MIB_TCPROW

        {

            public uint dwState;

            public uint dwLocalAddr;

            public uint dwLocalPort;

            public uint dwRemoteAddr;

            public uint dwRemotePort;

        }


        // IPv6连接结构体

        [StructLayout(LayoutKind.Sequential)]

        public struct MIB_TCP6ROW

        {

            public uint dwState;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]

            public byte[] localAddr;

            public uint localScopeId;

            public uint localPort;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]

            public byte[] remoteAddr;

            public uint remoteScopeId;

            public uint remotePort;

        }


        [DllImport("iphlpapi.dll", SetLastError = true)]

        public static extern int SetTcpEntry(ref MIB_TCPROW pTcpRow);


        [DllImport("iphlpapi.dll", SetLastError = true)]

        public static extern int SetTcpEntry6(ref MIB_TCP6ROW pTcp6Row);


        public static void DisconnectNonWhitelistedConnections(int targetPort, HashSet<string> whiteList)

        {

            IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();

            TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();


            foreach (TcpConnectionInformation connection in connections)

            {

                if (connection.LocalEndPoint.Port == targetPort)

                {

                    IPAddress remoteAddress = connection.RemoteEndPoint.Address;

                    string remoteIp = remoteAddress.ToString();


                    // 处理IPv6连接

                    if (remoteAddress.AddressFamily == AddressFamily.InterNetworkV6)

                    {

                        try

                        {

                            MIB_TCP6ROW row6 = new MIB_TCP6ROW

                            {

                                dwState = 12, // DELETE_TCB

                                localAddr = connection.LocalEndPoint.Address.GetAddressBytes(),

                                localPort = (uint)IPAddress.HostToNetworkOrder((short)connection.LocalEndPoint.Port),

                                remoteAddr = remoteAddress.GetAddressBytes(),

                                remotePort = (uint)IPAddress.HostToNetworkOrder((short)connection.RemoteEndPoint.Port),

                                localScopeId = 0,

                                remoteScopeId = 0

                            };


                            int result = SetTcpEntry6(ref row6);

                            Console.WriteLine(result == 0 ? 

                                $"已断开IPv6连接:{remoteIp}" : 

                                $"IPv6断开失败(错误码:{result}):{remoteIp}");

                        }

                        catch (Exception ex)

                        {

                            Console.WriteLine($"处理IPv6连接时出错:{ex.Message}");

                        }

                    }

                    // 处理IPv4连接

                    else if (!whiteList.Contains(remoteIp))

                    {

                        try

                        {

                            MIB_TCPROW row = new MIB_TCPROW

                            {

                                dwState = 12,

                                dwLocalAddr = BitConverter.ToUInt32(connection.LocalEndPoint.Address.GetAddressBytes(), 0),

                                dwLocalPort = (uint)IPAddress.HostToNetworkOrder((short)connection.LocalEndPoint.Port),

                                dwRemoteAddr = BitConverter.ToUInt32(remoteAddress.GetAddressBytes(), 0),

                                dwRemotePort = (uint)IPAddress.HostToNetworkOrder((short)connection.RemoteEndPoint.Port)

                            };


                            int result = SetTcpEntry(ref row);

                            Console.WriteLine(result == 0 ? 

                                $"已断开IPv4连接:{remoteIp}" : 

                                $"IPv4断开失败(错误码:{result}):{remoteIp}");

                        }

                        catch (Exception ex)

                        {

                            Console.WriteLine($"处理IPv4连接时出错:{ex.Message}");

                        }

                    }

                }

            }

        }

    }


    class Program

    {

        static void Main(string[] args)

        {

            HashSet<string> whiteList = new HashSet<string>

            {

                "192.168.1.100",

                "10.0.0.5"

            };


            try

            {

                TcpConnectionManager.DisconnectNonWhitelistedConnections(3389, whiteList);

            }

            catch (Exception ex)

            {

                Console.WriteLine($"运行时错误:{ex.Message}");

            }

        }

    }

}

  1. 双协议支持

    • 新增MIB_TCP6ROW结构体处理IPv6连接

    • 添加SetTcpEntry6 API调用接口

  2. 智能检测逻辑

if (remoteAddress.AddressFamily == AddressFamily.InterNetworkV6)

{

    // 强制断开所有IPv6连接

}

else if (!whiteList.Contains(remoteIp))

{

    // 处理非白名单IPv4连接

}

  1. 增强的错误处理

    • 分离IPv4/IPv6的错误日志

    • 明确显示操作结果和错误码

使用注意事项:

  1. 需要先添加System.Net.NetworkInformation引用

  2. 白名单IP需根据实际情况修改

  3. 测试前建议改用非关键端口进行验证

  4. 生产环境应考虑添加日志记录和异常处理

  1. 权限要求

    • 程序需要以管理员权限运行,否则无法修改TCP连接表。

    • 需要启用IPv6支持的操作系统

  2. 端口范围

    • 支持同时监控IPv4和IPv6的3389端口

    • 自动过滤其他端口流量

  3. 网络字节序

    • 自动处理IPv6地址的128位字节转换

    • 正确转换端口号的网络字节序

  4. 结构体转换

    1. 使用MIB_TCPROW结构体与Windows API交互

    2. IP地址和端口需要转换为网络字节序

  5. 白名单检查:直接使用HashSet进行快速查找

  6. 日志输出

    • 明确区分IPv4/IPv6操作结果

    • 显示API调用的详细错误码

该版本实现了对IPv6连接的主动断开功能,同时优化了以下方面:

  1. 使用更精确的地址族检测逻辑

  2. 改进结构体字段的初始化方式

  3. 增强网络字节序转换的可靠性

  4. 提供更详细的运行时反馈信息

对于无法处理的连接类型(如IPv6连接在旧系统上的兼容性问题),程序会通过错误码反馈具体故障原因。

此代码会实时检测所有连接到3389端口的TCP连接,并自动断开非白名单IP的连接,有效增强RDP服务的安全性。

其他注意事项:

1、HashSet 白名单地址维护方法参见:http://29753.oa22.cn

2、Windows系统的远程桌面端口是允许更改的,所以更稳妥的做法是要先读取Windows系统远程桌面的服务端口,以下是获取远程桌面服务端口的代码:

string PortNumber = "";

RegistryKey localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);

//远程桌面端口,判断操作系统版本(64位\32位)打开注册表项

try

{

    RegistryKey rk_Winlogon = localKey.OpenSubKey(@"System\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\Tcp", true);

    if (rk_Winlogon != null)

    {

        foreach (string vname in rk_Winlogon.GetValueNames())

        {

            if (vname == "PortNumber")

            {

                PortNumber = rk_Winlogon.GetValue("PortNumber").ToString();

                break;

            }

        }

        rk_Winlogon.Close();

    }

}

catch (Exception) { }


该文章在 2025/3/13 12:46:51 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved