代理、ssh隧道那些事

版权声明:本文为博主原创文章,未经博主允许不得转载。如有疑问,请在下方评论或邮件本人,本人邮箱: [email protected] https://blog.csdn.net/u013332124/article/details/84309221

一、各种代理术语介绍

在工作中,我们会和各种各样的代理打交道,比如利用nginx做请求转发、用shadowsocks翻墙,一些抓包软包也用了代理。之前虽然知道代理的意思,但是对涉及代理各个专业术语并没有很清晰的认识,今天就专门整理一下这些知识。

正向代理

比如由于墙的原因,我们大陆用户访问不了谷歌,这时我们就可以设置代理,通过把请求发向代理服务器,让代理服务器来帮我们获取数据并返回给我们。这种方式就是正向代理。在正向代理中,我们的目的是要访问谷歌,但是需要通过代理服务器来访问。shadowsocks就是一个很好的例子。

反向代理

和正向代理不同,用户访问代理时甚至不知道自己访问的是一个代理,用户直接把这个代理的地址当成一个服务访问,但是这个服务在接收用户的请求会将请求转发到其他的服务上获取响应,然后再返回给用户。比如nginx,我们访问nginx暴露的一个端口,但是并不会知道nginx把请求转发到了哪里,我们也不关心这个,只要nginx能把我们想要的数据返回给我们就可以了,这就是反向代理。

透明代理

透明代理和正向代理比较像,也是通过代理去访问某个服务。但是,和正向代理不同的是,用户不需要去专门设置代理。典型的例子就是操作系统的防火墙,防火墙会拦截所有用的请求然后判断哪些需要拦截,哪些直接放行。也就是说,用户的请求是先经过防火墙然后再到达目标服务器,这时候防火墙就可以理解为是一个透明代理。对于用户来说,完全感知不到防火墙的存在,因为这个代理对用户来说是透明的。

二、ssh隧道

对于ssh,我们平常都用来连接服务器,但是其实ssh的功能远不止如此。利用ssh提供的隧道功能,我们可以实现各种各样的代理功能。

ssh支持3种形式的隧道,下面介绍一下这三种隧道

1. -D 动态隧道

通过 -D 参数,我们可以实现一个简单的代理服务器。

命令格式

ssh -D [bind_address:]port root@服务器ip

在平常,我们的电脑是无法访问谷歌的,但是现在我们手上有一台服务器A可以访问谷歌。现在我们就可以通过ssh -D来让服务器A变成一个代理服务器,从而让我们的电脑可以访问谷歌。

# 绑定本地的8080端口,后面发往8080端口的请求都会通过ssh隧道发给服务器A,由服务器Alain进行请求后再将响应返回给我们
ssh -D 127.0.0.1:8080 root@服务器A的ip

之后我们需要设置一下浏览器的代理,地址使用127.0.0.1:8080。之后浏览器的请求都会走向8080端口,到8080端口后,经过ssh隧道发向服务器A,服务器把这个请求发往目标服务器,之后拿到响应内容后返回给我们。整个过程就是一个正向代理的过程。

ssh的这个功能和shadowsocks的工作流程基本一样,但是笔者简单测试了下,使用ssh隧道构建的代理服务器无论是性能还是稳定性都远不如shadowsocks。具体的原因笔者也没有很深入的去研究,不过可能这就是ssh动态隧道很少被人使用的原因吧。

2. -L 本地隧道

本地隧道也叫正向隧道,通过本地隧道,我们可以让目标服务器将我们本地的端口转发到具体其他地址的端口。

命令格式

ssh -L [bind_address:]port:host:hostport root@服务器ip

假设我们现在有个内网服务器A上有一个进程占用8080端口,我们的电脑要访问内网服务器只能通过跳板机,也就是服务器B来访问。这时候我们要在本地访问服务器A上那个8080的进程要怎么做呢?ssh就可以帮我们做到

# 监听了本地的8888端口,所有发往8888端口的请求都会发给服务器B,服务器B再将请求发给 '服务器A的ip:8080',之后拿到响应后返回
# 前面的127.0.0.1可以不填,不填的话默认就是绑定在127.0.0.1上面
ssh -L [127.0.0.1:]8888:服务器A的ip:8080 root@服务器B的ip

执行了上面的命令后,我们就可以直接通过127.0.0.1:8888就可以访问服务器A上的那个8080的进程。本地隧道建立后,所有发往127.0.0.1:8888地址的请求都会通过隧道发给服务器B,然后服务器B帮我们把请求发给配置好的服务器A的ip:8080,之后拿到请求返回给我们。

为了更好的理解本地隧道的工作原理,我们再模拟一个场景。假设我们现在可以直接访问服务器A的网络,但是A的8080端口并不对外开放,我们只能通过ssh协议登陆服务器。这时候应该怎么配置ssh隧道来访问8080端口呢?

# 那个'127.0.0.1:8080'配置的是服务器A要转发的地址,以服务器A的角度来看,要访问的就是127.0.0.1的8080端口
ssh -L [127.0.0.1:]8888:127.0.0.1:8080 root@服务器A的ip

看到上面的配置,如果不知道本地隧道的转发原理的可能会比较懵。

前面的[127.0.0.1:]8888配置了要监听的地址端口。接着127.0.0.1:8080我们可以理解为只是配置一个地址,来告诉远程的服务器等会要把请求发到哪个地址。我们现在是把服务器A来当代理服务器,也就是服务器A接收到隧道传过来的请求后,就直接把对应的配置127.0.0.1:8080拿到,往这个地址转发。因此,后面那个配的是目标服务器要访问的地址。

可以看出,本地隧道玩的是反向代理。

3. -R 远程隧道 —— 内网穿透

远程隧道,也可以称为反向隧道。通过远程隧道,我们可以实现内网穿透。

命令格式:

ssh -R [bind_address:]port:host:hostport root@服务器ip
# bind_address 表示远程服务器绑定的ip地址。不过经笔者测试,这个参数好像并没有什么用,无论填什么都不会改变监听地址
# port 远程服务器要监听的端口
# host 要转发的ip地址。后面会在本地去访问这个ip
# hostport 要转发的端口

由于ipv4资源的紧缺,我们上网分配到的ip一般都是内网ip,由于是内网ip,其他局域网以外的服务器就没办法访问到我们的电脑了。

如果我们在自己的电脑上部署了一个网站,想要其他人可以访问到,就需要用到内网穿透的功能。用ssh的隧道加一个有公网ip的服务器,我们就可以实现内网穿透。

假设我们本地部署了一个网站,占用端口8080,手上有一个服务器A,我们可以这么配置:

# 在服务器A上面监听一个8888的端口,之后只要有人访问端口8888,ssh将会将请求经过隧道发送给我们的电脑上
# 之后我们的电脑就把请求发给配置好的地址 '127.0.0.1:8080'上,然后把响应内容返回给调用者。
ssh -R 8888:127.0.0.1:8080 root@服务器A

这个和本地隧道其实就是反过来的关系。访问者把请求发到远程服务器,然后远程服务器把请求转发到本地,本地通过配置好的地址去转发请求,最后返回结果。也就是说,后面配置的’127.0.0.1:8080’是以本地电脑的身份去访问的,所以可以实现内网穿透。

显然,远程隧道也是属于反向代理的一种。

使用远程隧道时要注意,一般云服务器上的ssh服务默认是禁止做远程隧道转发的。当我们执行上诉命令时,它会只绑定自己的回环ip 127.0.0.1,这样外部的访问就无法访问到我们绑定的端口了,就不能达到内网穿透的功能了。

通过编辑sshd的配置文件我们可以将ip绑定到0.0.0.0上,使所有人都可以访问这个端口。

vim /etc/ssh/sshd_config
# 将对应的配置项 GatewayPorts 的值修改成 yes
GatewayPorts yes

4. ssh的一些其他技巧

既然说到ssh了,这里再介绍一些ssh的使用姿势。

在我们使用-R、-D、-L这些参数打隧道的同时,会登录到远程服务器,退出服务器则会关闭这个隧道。如果我们只是想打隧道而不打算登录服务器的话,命令我们可以这么写:

# -A 开启认证代理连接转发功能
# -C 表示对所有的输入输出都压缩,使用的是gzip压缩
# -N 表示不执行远程指令
# -f 表示后台执行ssh指令,一般 Nf 一起使用就可以不登录远程服务器了
# -L 表示建立本地隧道
ssh -A -CNfL 8888:127.0.0.1:8080 root@目标服务器

上面的命令执行后将会在后台执行,而不会登陆上服务器。我们可以通过ps -ef|grep ssh命令找到对应的进程id。不过ssh也会有超时时间,超过一定时间ssh隧道也会自动断掉。

登陆内网机器时,无需通过跳板机登陆

我们登陆公司的服务器时,经常需要先登陆跳板机后才能登陆指定的服务器,这样操作起来就很麻烦。其实通过设置ssh的代理,我们可以直接一个命令登陆上目标服务器。

在用户目录的.ssh下新建一个配置文件config,如果有则不用创建。

在配置文件最后添加以下内容:

# 如果你的私钥需要密码,配置上这个就不用一直输入密码了
AddKeysToAgent yes

# 定义跳板机的相关信息
host jump
user kongtrio
port 指定ssh到跳板机的端口
hostname 跳板机ip
#forwardagent yes
identityfile ~/.ssh/id_rsa

# 定义之后要输入的命令格式
host *.jump
user yjb1
port 跳板机要去连你的目标服务器的端口
proxycommand ssh -W $(echo %h | sed -e "s/.jump$//"):%p jump

# 下面这个配置保证长时间不操作终端时,不会和服务器断开
ServerAliveInterval 60

配置好上面的config文件之后,只要输入命令ssh 192.168.0.1.jump就可以登录上我们的服务器了。原理大概就是ssh匹配到host是以’.jump’结尾了,就使用配置的proxycommand进行连接。之后通过跳板机做代理直接连接上目标服务器。

不仅登陆不用通过跳板机,传输文件也不用经过跳板机了:

# 一个命令就能传输文件了,不用再scp到跳板机,然后再去跳板机scp到目标机器
scp file 192.168.0.1.gw:/home/user/

猜你喜欢

转载自blog.csdn.net/u013332124/article/details/84309221