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

浏览 4.9k

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
创作不易,留下一份鼓励
宗兆伟

暂无个人介绍

关注



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

按点赞数排序

按时间排序

点个赞,火钳刘明
赞同

1

回复举报

发表于2020-05-27 14:01



回复阿尔巴
回复
关于作者
宗兆伟
这家伙很懒还未留下介绍~
3
文章
1
问答
1
粉丝
相关文章
NginxRestrictAccessModuleAmoduletorestrictaccesstoaserver/locationusingthehostnameofremotehost,basedonNginxaccessmodule.ThismoduleisnotdistributedwiththeNginxsource.See theinstallationinstructions.ConfigurationAnexample:pidlogs/nginx.pid; error_loglogs/nginx-main_error.logdebug; #DevelopmentMode #master_processoff; #daemonoff; worker_processes1; worker_rlimit_core500M; working_directory/tmp; debug_point
点赞 1
浏览 3.9k
启用FastCGI缓存编辑必须启用缓存的虚拟主机配置文件。nano/etc/nginx/sites-enabled/vhost将以下行添加到server{}指令之外的文件顶部:fastcgi_cache_path/etc/nginx/cachelevels=1:2keys_zone=MYAPP:100minactive=60m;fastcgi_cache_key"𝑠𝑐ℎ𝑒𝑚𝑒schemerequest_methodℎ𝑜𝑠𝑡hostrequest_uri";“fastcgi_cache_path”指令指定缓存(/etc/nginx/cache)的位置,其大小(100m),内存区域名称(MYAPP),子目录级别和非活动定时器。位置可以在硬盘上的任何地方;但是,大小必须小于您的服务器的RAM+交换,否则你会收到一个错误,“无法分配内存”。如果缓存在“inactive”选项指定的特定时间内没有被访问(这里为60分钟),Nginx将删除它。“fastcgi_cache_key”指令指定如何哈希缓存文件名。Nginx基于此指令使用MD5加密访问的文件。在location~.
点赞 1
浏览 3.6k
公开课资料下载感谢您参加> 课程演讲稿下载:1月27日:NGINX服务网格解决方案2月24日:k8s应用安全的威胁和防护3月24日:NGINXController之API管理解决方案nginx.org.cn>NGINX 官方微信群GINX公开课
点赞 0
浏览 5k