环境搭建
目的
在更新nginx upstream pool时,一般方案是更新nginx配置文件,然后reload nginx, 在nginx繁忙时会导致worker process长久处于shutdowning, 并且频繁的upstram可能导致nginx芭比Q。
所以我们这里需要解决的问题就是怎么不reload就能实现修改nginx配置。
以下环境搭建是基于Ubuntu的。
下载tar包
到官方下载tar包 http://tengine.taobao.org/download.html
这里下载最新的2.3.3
wget http://tengine.taobao.org/download/tengine-2.2.3.tar.gz运行环境检测脚本,安装nginx依赖库(pcre、openssl、zlib)
提前安装需要的依赖(也可以先运行configure,根据缺少的逐步安装)
apt-get install gcc -y
apt-get install libpcre3 libpcre3-dev -y
apt-get install openssl libssl-dev -y
apt-get install zlib1g-dev -y解压tar包后进入目录,运行目录下的configure文件
此时如果系统缺少必要的组件,会报错。我们只需要根据报错信息进行解决即可。(如图,代表缺少gcc)

这里要求gcc,所以我们先安装安装。
安装完毕后再次执行,发现新的报错。

根据报错进行安装,这里是缺少PCRE,再次运行,缺少openssl,继续安装。

此时再次运行,缺少zlib库,再次下载。

最后没有报错了,环境检查没问题。如下图,是安装的默认参数。
这里jemalloc是内存优化的,需要的就装,不需要的就不管。

这里给上jemalloc的安装操作(根据需求决定是否要加),首先下载jemalloc,然后进行解压即可,其他不需要操作,到后面的时候再操
wget https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2
tar -jxvf jemalloc-5.2.1.tar.bz2 安装tengine
到这里正式开始安装。安装完成后,会在/usr/local/nginx下看到tengine的安装文件(默认情况下,如果没设置了configure —prefix=/xx/xx的话)
./configure --prefix=/usr/local/tengine --without-http_upstream_keepalive_module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-stream --with-http_realip_module --add-module=./modules/ngx_http_upstream_*
PS:如果需要加jemalloc的话,加上参数(后面的是解压的路径) —with-jemalloc=~/jemalloc-5.2.1/
然后就可以编译了,完成后就会在前面我们设置的安装目录下找到服务。
make && make install
这里就其实和nginx一样,只是这里没有注册成服务,所以需要到安装目录下去执行二进制文件,当然我们也可以把他cp到 /usr/local/sbin上就可以了。
/usr/local/nginx/sbin/nginx -V 
/usr/local/nginx/sbin/nginx # 启动nginx,不需要参数此时访问80端口即可看到如下界面


配置
略,就和nginx一样。
dyups动态更新upstream
为了针对nginx不能动态修改配置文件这一痛点,dyups应运而生,这个模块能够实现动态修改配置。他的原理其实就是相当于把一个配置文件给加到了动态内存中,然后通过web进行管控从而实现动态修改。
PS:因为我在前面build的时候加入了upstream模块,所以直接用就行。
如图,这里就是在8000端口监听了dyups的控制端,然后我们就可以通过访问这个端口从而对内存中的conf文件进行修改了。
下面的配置实现的功能就是一个将流量根据upstream转发的配置

使用allow和deny可以设置这个接口允许访问的ip

那么upstream是什么呢?在配置文件中他长这样,如果我们设置了如下的配置,那么对于上述的转发配置,我们的host如果是hots1,流量就反代到8088端口。如果host是host2,则反代到对应的下面那个端口。

那么我们怎么动态更新这个upstream呢?前面也讲了,dyups通过监听一个端口实现对内存中的一个upstream配置文件修改,因此我们只需要调用这个web接口即可。
GET方法(读)
- /detail #获取全部upstream的详细信息
- /list #获取upstream的列表
- /upstream/
#查询指定upstream的信息
POST方法(写)
- /upstream/
#修改upstream的信息(如果不存在这个upstream,则增加)
DELETE方法(删除)
- /upstream/
#删除这个upstream
查看当前upstream的细节。 GET方法

修改指定upstream (如果没这个name,就会增加,有就会修改)

删除指定upstream

效果展示
这里,我们本地docker开启了两个不同的服务,接着我们尝试通过不同的域名来实现访问这两个服务。

这里我们想要的结果是动态修改配置,使得访问 host1则能到达50001,访问host2到达50002 .
因此我们只需要加两个upstream即可。
如图,向dyups管理端发送如下两个数据包即可完成添加upstream。
curl -d "server 127.0.0.1:50001;" 192.168.5.179:8000/upstream/1.aaa.com #对应的curl命令

此时访问1.aaa.com和2.aaa.com即可达成目的。
题外话,使用nginx做隧道
Q:既然nginx是个反代服务器,那么是不是也能够实现其他协议的隧道代理功能呢。
A:nginx本身只是web服务器,在默认情况下是不支持其他协议的反代的。但nginx在1.9.0开始,新增了一个stream模块,可以用来实现其他协议的转发、代理和负载。
查看是否存在stream模块
stream模块默认情况下是不会编译到nginx中的,所以在编译nginx的时候需要带上参数 —with-stream
nginx -V #查看nginx的详细信息,看是否存在stream模块
使用steam进行端口映射(反代)
这里我们选择让nginx反代内网的一个22端口
只需要在nginx配置文件中添加stream键值(和event、http同级)即可。
如下配置的意识是在nginx监听本地3389端口,把这个端口的流量给代理到upstream aaa上,而
aaa的目标又是内网的一个ssh端口
因此这里最终结果就是访问nginx服务器的3389等价于访问内网的ssh了。

使用nginx做socket隧道(正向代理)
A
,那么我们肯定不想止步于此,我们想让nginx在渗透周期中做更多的事情,比如做socket隧道?Q
,nginx本身不支持,需要第三方模块。但是我找到的两个第三方模块在编译的时候都报错了。只能说结局待定了。