Docker Nginx 安装 Stream 代理 SSH 端口

前言

最近常和Nginx打交道,就诞生了编写Nginx专栏的想法;另一方面则是博客也荒废好长时间了,想要拾起来,重新出发啦。

预计在五月前会更新完我目前关于Nginx专栏相关的博客,后续的话,则需要看情况和时间去更新更多使用的博客啦。

上一次写博客还是在参与年终总结的活动,要是说写技术文的话,那需要追溯到7月前的 关于 Spring Integration 你知道多少,包含集成MQTT案例讲述及源码

停更了较为漫长的一段时间吧,从去年心里开始蹦出换工作的想法,一直到入职新的公司,再一直到现在,写博客的频率就较低了,可以说人同时也进入了一种较为迷茫的状态,有种茫茫然活着的感受吧。

一开始动手敲下文字,就不可避免想要说些自己无人可以诉说的话,那些别人听去可能觉得矫情又或者觉得无语的话,只好通过这种方式来表达啦。

说回文章本身吧,这个通过 Nginx 代理 SSH 端口的需求,严格说起来是我自己折腾的。

项目单位上有一台服务器,外部访问是通过公网IP做端口映射来实现的,而一些服务是没有映射端口的,只能够先通过远程软件连接到项目单位的主机,再通过ssh连接到服务器,去查看日志。(这就非常折磨人啊)

项目单位上不允许直接映射22端口,我才想了这个的,但是即使通过其他端口映射,也一定要做好安全防护,白名单等,以免出现安全问题

一、Nginx常见使用方式

可能大部分朋友听到Nginx时,所能想到的使用方式大致就是:

1、nginx实现反向代理

2、实现动静分离

3、nginx部署vue项目

4、nginx解决跨域问题

5、nginx配置ssl证书

等等,当然还有一些其他的使用方式,但上述列出来的都是较为常见的,可能也有很多朋友接触过。

实话实说,在我没遇上我自己这个需求时,我根本没想过要使用 Nginx 来实现 ssh 的代理,也根本不知道 Nginx 可以实现 ssh 的代理。

补充:

上面所有列出来的使用方式都是使用Nginx来实现七层代理(也有叫七层负载均衡),而实现ssh的代理,则是要实现四层代理(也有叫七层负载均衡的),Nginx本身并不直接支持tcp的代理,需要借助扩展模块来进行实现。

二、七层负载均衡和四层负载均衡

最后还是决定写一下这个章节啦,可以更详细的知道 nginx 在此时的作用。

七层负载均衡

七层代理主要工作于OSI模型的应用层,应用层主要用来处理消息内容的。比如,HTTP便是常见的七层协议。

七层负载均衡服务器起到了反向代理的作用,Client端要先与七层负载均衡设备三次握手建立TCP连接,把要访问的报文信息发送给七层负载均衡。

七层负载均衡器基于消息中内容( 比如URL或者cookie中的信息 )来做出负载均衡的决定。之后,七层负载均衡器建立一个新的TCP连接来选择上游服务并向这个服务发出请求。

使用七层负载均衡的设备经常被用于反向代理

比如我们常常使用Nginx来代理单体的Java服务,比如类似下面这种常见配置:

bash 复制代码
location /spider {
    proxy_redirect off;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://192.168.1.28:6790/spider;
}

看完配置文件,应该可以更好的理解这句"七层负载均衡器基于消息中内容( 比如URL或者cookie中的信息 )来做出负载均衡的决定"的话了吧

四层负载均衡

四层代理主要工作于OSI模型中的传输层,传输层主要处理消息的传递,而不管消息的内容。TCP就是常见的四层协议。

四层负载均衡只针对由上游服务发送和接收的网络包,而并不检查包内的具体内容是什么。 四层负载均衡可以通过检查TCP流中的前几个包,从而决定是否限制路由。

因此,四层负载均衡的核心就是IP+端口层面的负载均衡,不涉及具体的报文内容。

比如下面这个就是我编写的代理ssh端口的配置文件:

bash 复制代码
stream {
        allow 111.11.11.11;
        deny all;
        proxy_timeout 1d;
        proxy_connect_timeout 30;

        upstream ssh-proxy {
          server 192.168.1.19:22;
        }
        server {
          listen 9999 ;
          proxy_pass ssh-proxy;
        }
}

在这个配置文件中可以看出,nginx 只是监听了 9999 端口,有消息的话,就将它传递给 proxy_pass 指定的服务中去。即只受IP+端口的影响,不受消息体的影响。

三、Docker Nginx 安装 Stream 模块

Nginx 本身并没有直接开启四层代理,需要在编译的时候安装指定的模块来实现。

nginx-1.9.0 发布,该版本增加了stream 模块用于一般的TCP 代理和负载均衡,ngx_stream_core_module 这个模块在1.90版本后将被启用。但是并不会默认安装, 需要在编译时通过指定 --with-stream 参数来激活这个模块。

Stream 模块使得 Nginx 可以像 TCP/UDP 代理一样工作,并且支持负载均衡、反向代理、SSL 加密等功能。后续将介绍如何在 Docker 容器中安装并配置 Nginx 的 Stream 模块。

前置环境:docker

我在ubuntu上直接编译过不少程序,mqtt、nginx、opencv、zlm等等,实话实说,非必要,真一点也不建议在宿主机上编译什么程序,因为你不知道要踩多少坑....

对如何直接在ubuntu上编译Nginx感兴趣的话 ,点赞过三十,我到时候更一篇如何在ubuntu宿主机上编译nginx的博客,哈哈哈

不过我更建议使用Docker来实现这些操作,一方面是资源隔离,另外一方面是docker真的方便,认识大部分开发者,感觉都有使用到Docker。

后续的话,需要一点点docker相关的知识,如果都不行的话,至少得安装好docker,然后跟着贴命令就好。

docker 安装命令

bash 复制代码
sudo apt update
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
 
sudo apt install docker-ce
#到此安装完成, 可以输入 sudo docker --version 或者 sudo docker run hello-world 测试是否安装成功

#如果您想免sudo进入docker的话, 直接输入以下命令,亲测:

sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp - docker
#注意:最后一步是必须的,否则因为 groups 命令获取到的是缓存的组信息,刚添加的组信息未能生效,所以 docker images 执行时同样有错。
# 如果还是不行请尝试
sudo chmod o+rw /var/run/docker.sock

3.1、编写 Dockerfile 文件

编写Dockerfile的作用是制作镜像,这方面的知识可能需要大家去了解docker的简单概念,不再赘述了。

dockerfile 复制代码
FROM nginx:latest

RUN apt-get update && apt-get install -y \
    build-essential \
    libpcre3-dev \
    zlib1g-dev \
    wget

WORKDIR /usr/src/nginx

RUN wget https://nginx.org/download/nginx-1.22.1.tar.gz \
    && tar -xzvf nginx-1.22.1.tar.gz

WORKDIR /usr/src/nginx/nginx-1.22.1

RUN ./configure --with-stream && make && make install

ADD nginx.conf /etc/nginx/nginx.conf

RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 9888
STOPSIGNAL SIGTERM
CMD ["nginx","-g","daemon off;"]

比较重要的就这一句了,在编译nginx的时候,编译时通过指定 --with-stream 参数来让nginx实现tcp四层负载均衡。

bash 复制代码
RUN ./configure --with-stream && make && make install

3.2、Nginx 配置文件

将 nginx.conf 配置文件置于和Dockerfile 同一个目录下。

bash 复制代码
user root;
worker_processes 1;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid  /var/run/nginx.pid;

events
{
    use epoll;
    worker_connections 1024;
}

http
{
    include mime.types;
    default_type application/octet-stream;

    sendfile on;
    #aio on;
    directio 512;
    output_buffers 1 128k;
    log_not_found off;
    keepalive_timeout 65;
    server_tokens off;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    gzip on;
    gzip_comp_level 6;
    gzip_min_length 1k;
    gzip_buffers 4 8k;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript application/json;

    log_format main '{'
        '"@level": "info",'
        '"@remote": "$remote_addr",'
        '"@forwarded": "$http_x_forwarded_for",'
        '"@server": "$server_addr",'
        '"@hostname": "$host",'
        '"@timestamp": "$time_iso8601",'
        '"@spend":"$request_time",'
        '"@request": {'
            '"@protocol": "$scheme",'
                '"@host": "$host",'
                '"@path": "$request",'
                '"@header": {'
                    '"@User-Agent": "$http_user_agent"'
               '}'
       '},'
       '"@response": {'
           '"@statusCode": "$status"'
       '}'
    '}';

    fastcgi_intercept_errors on;
    server_names_hash_max_size 4096;

    include /etc/nginx/conf.d/*.conf;
}
stream {
        allow 111.11.11.11;
        deny all;
        proxy_timeout 1d;
        proxy_connect_timeout 30;

        upstream ssh-proxy {
          server 192.168.1.1:22;
        }
        server {
          listen 9888 ;
          proxy_pass ssh-proxy;
        }
}

主要是添加了 Stream 模块,注意 Stream 模块是同 http 模块同级的,而并非在 Http 模块之下。

allow是白名单的配置,只允许公司网络的网络出口可以进行ssh连接。

deny 是拒绝其他全部连接。

这里同样也可以做负载均衡的

bash 复制代码
   upstream ssh-proxy {
      server 192.168.1.1:22;
      server 192.168.1.1:23;
    }

但我这个场景并没有什么意义,我就没有演示了,其他我暂时还木有想到很好的场景,如果大家有什么好的场景也可以说一说,讨论一下。

3.3、制作镜像

bash 复制代码
docker build -t nginx-stream .

参数:-t 是用于指定镜像的名称,最后的小数点是表示Dockfile所在的当前目录,当文件名不再叫Dockerfile时,则需要添加 -f 来指定 Dockerfile 文件

3.4、运行容器

bash 复制代码
docker run -d -p 9888:9888 --name nginx-stream nginx-stream

3.5、测试Stream模块

看看是否可以通过我们代理的端口来实现ssh连接

测试前记得要先打开防火墙,如果是云服务器,请记得开放端口,否则无法访问。

通过代理的端口去实现ssh连接

写到这里,我都不知道怎么去贴这个测试的图,看日志,日志中啥也没有,展示端口,也没有端口展示,没啥用。

后语

有问题的话,大家可以留言,或者私信,我都会在第一时间进行回复。

文中如有不对或不足之处,还请各位指正,非常感谢。

如果你持续对我,或者是对本系列相关的文章感兴趣,可以关注同名微信公众号《宁在春》,后续我会在第一时间将相关博客更新到公众号中。

非常感谢你的阅读,有所收获的话,还望不要吝啬赞和评论,不得不说,我想要获取一些坚持去写的动力,哈哈哈

读到最后,那就祝大家周末愉快啦~

春夏之际,与友踏青,我想应该是个非常不错的事情吧,大家可以试一试哦~

说的就是你,别卷了!!!

相关推荐
Marst Code几秒前
(Django)初步使用
后端·python·django
代码之光_19807 分钟前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端
编程老船长20 分钟前
第26章 Java操作Mongodb实现数据持久化
数据库·后端·mongodb
IT果果日记41 分钟前
DataX+Crontab实现多任务顺序定时同步
后端
姜学迁2 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健2 小时前
MQTT--Java整合EMQX
后端
北极小狐3 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
tangdou3690986553 小时前
Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)
docker·容器
tangdou3690986553 小时前
两种方案手把手教你多种服务器使用tinyproxy搭建http代理
运维·后端·自动化运维
【D'accumulation】3 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端