range内核端口数据转发模块

原创
01/04 16:18
阅读数 68

NGINX 向云原生演进,All in OpenNJet 


range 端口转发模块

1.1 需求

在很多时候,比如流量劫持、ftp被动模式代理等功能需要能够支持流量端口转发。比如需要将10000到11000端口范围的所有流量都统一转到12000端口上,然后在12000端口上接收所有的报文进行后续处理。

1.2 依赖

该功能的实现依赖于iptables,如果通过rpm包安装,则自动为privilege进程为root启动

如果是普通用户启动,需要对opennjet设置setuid权限

setcap cap_setuid=eip /home/njet/sbin/njet

1.3 指令设计

Syntax

range type={tcp|udp}  src_ports={port1:port2}  dst_port={dst_port}

 

如果默认iptables path/usr/sbin/iptables 如果系统iptables路径不是这个,需要指定使用如下指令

range iptables_path={iptables_path};

Default

-

Context

Core,  支持配置多条

参数说明:

参数

类型

必填

默认值

说明

type

string

tcp

[tcp|udp], 指明是tcp还是udp数据,默认tcp

src_ports

string

-

 

支持单端口或者端口范围,格式如下:

端口范围(冒号分隔):     11000:12000

一个端口:       11000

dst_port

int

-

目标端口

iptables_path

 

string

 

/usr/sbin/iptables

 

这个根据系统而定,调用system执行的时候可能会出现找不到iptables错误,这个时候需要看看对应系统的iptables path,然后设置一下这个参数

 

如果配置多条range指令,则以最后一个明确指定的iptables_path为准

配置示例(tcp为例):

  • 将发往本机端口为11000到12000范围的数据,转发到13000端口:

range type=tcp src_ports=11000:12000  dst_port=13000

  • 将发往本机端口为11000,转发到13000端口:

range type=tcp src_ports=11000  dst_port=13000

  • 设置iptables path为/usr/sbin/iptables

range iptables_path=/usr/sbin/iptables;

1.4 实现方案

本功能的实现借助于iptables规则,通过range指令解析参数,然后生成对应的iptables规则下发。

range指令支持配置多条规则

模块init的时候会根据规则生成iptables规则

模块exit的时候会将规则进行删除

所有的规则都会放到自定义iptables链 OPENNJET上

1.5 测试

1.5.1 配置示例

njet.conf 配置里配置两条range指令

...

load_module modules/njt_range_module.so;      #加载range模块
...

user nobody;

events {
    worker_connections  1024;
}
error_log         logs/error_privilege.log info;



#配置两条range指令
range type=tcp src_ports=11000:12000 dst_port=13000;
range type=tcp src_ports=10000 dst_port=14000;

#默认路径为/usr/sbin/iptables, 如果系统路径不一致需要调用该指令设置下路径
range iptables_path=/usr/sbin/iptables;

http {
    access_log        logs/access_privilege.log combined;

    include           mime.types;

    server {
      ...
    }

}


cluster_name helper;
node_name node1;

1.5.2 测试结果

启动OpenNJet

查询系统iptables 规则:

启动OpenNJet

重新查询iptables规则,发现两条规则生效

reload重启后

重新查询,发现两条规则还在

停止OpenNJet

重新查询,两条规则删除

2. 命令式 API 动态配置端口转发规则

2.1 需求:

能够通过api接口查询全量的range 配置规则

能够通过api增加或者删除一条range配置规则

根据type、src_ports、dst_port三个字段来确定一条规则

2.2 配置

ctrl控制面配置:

...
 load_module modules/njt_http_range_api_module.so;   #load range api module
 ...
    server {
        listen       8081;
       
        location /range {
            dyn_range_api;      #
配置range api开关
        }
    }
...

2.3 动态API

查询:

GET  http://192.168.40.136:8081/range

{
  "ranges": [
    {
      "type": "tcp",
      "src_ports": "11000:12000",
      "dst_port": 10001
    },
    {
      "type": "tcp",
      "src_ports": "10000",
      "dst_port": 14000
    }
  ]
}

PUT  http://192.168.40.136:8081/range

#添加一条规则
{
    "action": "add",
    "type": "tcp",
    "src_ports": "11000:13000",
    "dst_port": 10001
}

#删除一条规则
{
    "action": "del",
    "type": "tcp",
    "src_ports": "11000:13000",
    "dst_port": 10001
}

 

参数

类型

必填

默认值

说明

action

string

-

[add|del]

type

string

-

[tcp|udp], 指明是tcp还是udp数据

src_ports

string

-

 

支持单端口或者端口范围,格式如下:

端口范围(冒号分隔):     11000:12000

一个端口:       11000

dst_port

int

-

目标端口

return:

{
    "code": 0,         #0
表示成功,   非0 表示失败
    "msg": "success"
}

错误码

code

msg

描述

 

0

success

成功

 

2

-

内存分配失败相关的一些错误信息

 

4

rule is not found

删除一个不存在的规则

 

4

rule has exist

添加一个已经存在的规则

 

4

其他错误

 

 

2.4 swagger访问

可以通过doc模块提供的swagger界面操作

http://192.168.40.136:8081/doc/swagger/

2.5 测试

通过swagger页面进行api测试

初始状态get 查询配置

查询iptables

通过swagger页面添加一个规则

再次 查询配置和iptables

reload后再次查询,动态添加的配置和iptables都存在刚才动态添加的配置

Stop OpenNJet后,iptables规则消失

OpenNJet 最早是基于 NGINX1.19 基础 fork 并独立演进,具有高性能、稳定、易扩展的特点,同时也解决了 NGINX 长期存在的难于动态配置、管理功能影响业务等问题。 邮件组 官网

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部