You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Pymodbus的StartTcpServer设置IP访问限制?

限制Pymodbus TCP服务器的客户端IP访问

Pymodbus本身没有直接提供IP白名单/访问列表的配置选项,但可以通过自定义服务器的连接处理逻辑来实现这个功能。以下是针对不同后端的实现方案:

方案1:基于同步TCP服务器(默认后端)

如果你的代码使用的是Pymodbus默认的同步TCP服务器,可以继承ModbusTcpServer类,重写连接处理方法添加IP校验:

from pymodbus.server.sync import ModbusTcpServer
from pymodbus.datastore import ModbusSlaveContext, ModbusSequentialDataBlock, ModbusServerContext

# 定义允许访问的IP白名单
ALLOWED_IPS = {"192.168.1.100", "127.0.0.1"}

class RestrictedModbusTcpServer(ModbusTcpServer):
    def handle_accepted(self, sock, addr):
        client_ip = addr[0]
        # 检查客户端IP是否在白名单内
        if client_ip not in ALLOWED_IPS:
            print(f"拒绝来自未授权IP {client_ip} 的连接")
            sock.close()
            return
        # 允许连接,调用父类的处理逻辑
        super().handle_accepted(sock, addr)

# 初始化数据存储
store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [0]*100))
context = ModbusServerContext(slaves=store, single=True)

debug = True
port = 502

if debug:
    print('pymobus in debug')
    from pymodbus import pymodbus_apply_logging_config
    pymodbus_apply_logging_config("DEBUG")

# 启动自定义的受限服务器
try:
    print(f'Starting ModbusTCP server at port {port}.')
    server = RestrictedModbusTcpServer(context=context, address=("0.0.0.0", port))
    server.serve_forever()
except KeyboardInterrupt:
    server.shutdown()

方案2:基于AsyncIO后端(推荐,适用于新版Pymodbus)

如果使用Pymodbus的AsyncIO后端,需要自定义ModbusTcpProtocol来实现IP过滤:

from pymodbus.server.async_io import ModbusTcpServer, ModbusTcpProtocol
from pymodbus.datastore import ModbusSlaveContext, ModbusSequentialDataBlock, ModbusServerContext
import asyncio

ALLOWED_IPS = {"192.168.1.100", "127.0.0.1"}

class RestrictedModbusTcpProtocol(ModbusTcpProtocol):
    def connection_made(self, transport):
        client_ip = transport.get_extra_info('peername')[0]
        if client_ip not in ALLOWED_IPS:
            print(f"拒绝来自未授权IP {client_ip} 的连接")
            transport.close()
            return
        super().connection_made(transport)

# 初始化数据存储
store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [0]*100))
context = ModbusServerContext(slaves=store, single=True)

debug = True
port = 502

if debug:
    print('pymobus in debug')
    from pymodbus import pymodbus_apply_logging_config
    pymodbus_apply_logging_config("DEBUG")

# 启动AsyncIO服务器
async def run_server():
    print(f'Starting ModbusTCP server at port {port}.')
    server = await ModbusTcpServer.from_context(
        context,
        protocol_class=RestrictedModbusTcpProtocol,
        address=("0.0.0.0", port)
    )
    await server.serve_forever()

try:
    asyncio.run(run_server())
except KeyboardInterrupt:
    pass

关键说明

  • 可根据需求修改ALLOWED_IPS集合,添加允许访问的客户端IP地址
  • 未授权IP的连接会被直接关闭,服务器不会处理其任何请求
  • 如果需要IP段匹配这类复杂规则,可以用ipaddress模块扩展校验逻辑,示例:
    import ipaddress
    def is_allowed(ip):
        return ipaddress.ip_address(ip) in ipaddress.ip_network("192.168.1.0/24")
    
    之后在连接校验时调用该函数替代直接的集合判断即可。

内容的提问来源于stack exchange,提问作者kpankhurst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:45:00