点赞
评论
收藏
分享
举报
NGINX+NJS应用场景之 PASV模式下FTP ALG协议支持
发表于2020-05-20 15:07

浏览 1.6k

NJS旨在成为NGINX的通用脚本框架。

NJS允许用户用脚本的方式给复杂业务场景下的流量负载添加处理逻辑。

它是扩展NGINX 应用的一把利刃。

 

编者注:

            文本所涉及源码均可通过访问以下github 代码仓库获得。

f5devcentral/nginx-njs-usecases  https://github.com/f5devcentral/nginx-njs-usecases

一、关于FTP ALG

关于FTP ALG 的相关概念可以从以下链接查阅:

 

https://www.juniper.net/documentation/en_US/junos/topics/topic-map/security-ftp-alg.html

 

在FTP 被动(PASSIVE)传输模式中:

PASV命令请求服务器侦听一个端口,这个端口不是服务器默认数据端口,而是服务器自定的一个端口。服务器开启此端口后等待连接。对PASV命令的响应包括服务器的主机和监听端口地址。

 

对于FTP 服务器在内网的情况,被动模式下,FTP 服务器告知客户端等待连接的主机和端口信息,不能是本机信息,而应该是网络边界上客户端可以连接到的端口信息。否则客户端就不能主动连接FTP服务器的数据端口。

但是很多情况下FTP服务器并不知道边界网关的信息。这时就会用到ALG(Application Layer Gateway),在FTP服务器给出PASV命令响应后,由边界路由器修改此响应中的主机和端口信息。以便让客户端顺利的连接到网关,网关负责再将数据传输转给后端FTP服务器。

大多数的路由协议中都支持ALG协议。所以FTP服务器可以以被动模式运行在网络内部。

 

二、NGINX + NJS 实现

1.部署及设计

本文给大家展示的是如何使用NGINX 和NJS 实现 ALG协议简单支持,即FTP服务器不可见,由NGINX代理FTP服务器的控制和数据链路。

 

下图是示例的部署环境,可以看出。

FTP服务器运行在Docker Cluster内部,运行于被动模式,并不暴露任何端口供外界连接,只是让Docker Cluster内的其他container访问21 和20000。前面通过NGINX做反向代理。用户可以访问它的8101端口进行数据链路控制,也可以访问8080端口做数据传输。


在被动模式下MYFTP告诉FTP客户端去连接127. 0.0.1:20000,但是这个连接显然是不能建立的。NGINX完成对PASV指令的响应的修改。报文中127.0. 0.1:20000被改成了172.100.0.106:8080。如下图所示:

 

之后的传输中FTP客户端去连接NGINX,NGINX负责把数据传输代理到后端的FTP服务器。

 

数据传输效果,如下图所示:

 

2.NJS实现

 

a)我们先看下NGINX 配置文件:

配置部分较为简单,我们监听了两个端口21, 和8080, 分别用于控制流和数据流传输。

控制流中我们使用ftp_controller 对数据流中的PASV响应做处理。

数据流中我们将数据代理到上游,上游的端口使用js_set来决定。这里是把端口20000参数化了。

“ proxy_download_rate 1k;” 是为了演示多连接同时存在情况下的异常报错。

 

b)再看下NJS代码实现部分:

 

在 ftp_controller中,我们注册一个上行过滤函数:

“s.on('upload', function(data, flags){”

 

该函数会检查从客户端过来的数据包内容,如果发现有PASV指令,则会注册一个下行过滤函数:

“s.on('download', handle_pasv);”

 

这个函数会检查从服务器端传给客户端的数据流,根据FTP控制协议,PASV指令的响应格式为:“/227 .*\(.*\)/”。

 

如果发现由此内容,就将括号中的内容替换成NGINX的地址和端口。

“function get_pasv_conn(s, ipaddr, port)”负责生成连接信息字符串。

注意在处理完毕后及时调用s.off 可以减少NJS对数据流的无用处理消耗。

 

至此,我们就可以实时监控并修改控制流中的PASV指令及响应,同时监听并代理数据流。

 

总结:

NJS ngx_stream_js_module 提供给我们对流操作的能力,通过s.on s.off 可以挂载对数据流的处理钩子。

修改后,TCP层的数据校验和不需要我们去考虑,kernel TCP协议栈帮我们完成。

 







已修改于2023-03-08 02:06
创作不易,留下一份鼓励
宗兆伟

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
宗兆伟
这家伙很懒还未留下介绍~
3
文章
1
问答
1
粉丝
相关文章