图片 13

SSH隧道应用, 突破网络限制

让AWS虚机访问公司内网资源(SSH反向代理),aws虚机

SSH隧道应用, 突破网络限制

一:squid服务概述

背景说明

今天我要将AWS虚机升级到beta版本并进行一些测试。

由于beta版本只在公司内网提供,因此我需要将升级用的文件手动拷贝到AWS虚机中。原始的方法,很容易理解:

然而这就遇到一个问题,因为镜像文件有4.2GB大小,传输过程不仅占用带宽资源,而且还会浪费很多时间。

图片 1文章配图:
静安寺 摄影: 怡文圣美

 
Squid
cache(简称为Squid)是一个流行的自由软件(GNU通用公共许可证)的代理服务器和Web缓存服务器。Squid有广泛的用途,从作为网页服务器的前置cache服务器缓存相关请求来提高Web服务器的速度,到为一组人共享网络资源而缓存万维网,域名系统和其他网络搜索,到通过过滤流量帮助网络安全,到局域网通过代理上网。Squid主要设计用于在Unix一类系统运行。

研究过程

文/怡文圣美

代理服务器是介于 Internet
和内网计算机之间的联系桥梁,他的功能就是代替内网计算机去访问互联网信息。使用代理服务器,可以有效的节约IP资源,多台内网计算机可以通过同一个IP访问Internet。目前大部分企业都是通过代理服务器为企业内部员工提供上网服务。

方案1【被舍弃】

解决办法我首先想到将目录http://download.eng.pek2.redhat.com/pub/rhel/rel-eng/RHEL-7.4-20170621.0/compose/Server/x86_64/debug/tree/拷贝到虚机上,然后用它来做YUM源进行升级。但我很快就发现自己并不能确定哪些package是升级所需要的,因此只能上传全部的文件,这样做并不能有效解决问题。

这篇文章可以帮你解决下面三个问题:

端口: 3128

方案2【被舍弃】

其次,我想到在AWS虚机上安装客户端,通过VPN方式访问内网资源。这样做当然是可行的,只是openvpn配置起来需要将证书拷来拷去,这使我担心潜在的安全问题,也担心后续会过多地占用VPN服务器资源,因此这个想法只能作罢。

  1. 不能直连服务器, 要先登陆跳板机, 造成客户端工具无法连接服务器.
  2. 服务器没有公网IP, 且只允许公司IP访问,
    要在家里操作要先远程桌面到工作机再登陆服务器, 速度很慢又不稳定.
    你有一台公网服务器, 希望能借它牵线搭桥.
  3. 用最简单的办法为服务器增加代理功能.

二:实验安装

方案3【被舍弃】

后来,我想到了一个办法,将公司内网的HTTP代理服务器,用反向连接的方式,共享给AWS虚机,用到的命令大概会是这样:

ssh -R 8080:squid.corp.redhat.com:3128 -i ~/.pem/ap-northeast-1-cheshi.pem [email protected]13-113-60-192.ap-northeast-1.compute.amazonaws.com

这样做应该是最简单的方案了,但是它还有一个小问题,所有流量都要去公司代理服务器上绕一圈,数据通路看起来会是这样的:

AWS虚机 <=> MyHost(内网主机) <=> ProxyServer(内网代理服务器) <=> FileServer(内网更新服务器)

浪费资源是一方面,更重要的是如果更新量很大,过多地占用了公司代理服务器的资源,有可能会被IT部门审计出来。

一. SSH隧道技术

要解决本文开头的三个问题, 最佳方案肯定是ssh隧道. 什么是ssh隧道呢?
请参考阮一峰老师写的SSH原理与运用:远程操作与端口转发.

阮一峰老师说到, ssh隧道有三种类型,
正好可以用来解决文章开头提到的三个问题. 这三个类型是:

  1. 本地端口转发.
  2. 远程端口转发.
  3. 绑定本地端口.

ssh隧道使用命令就可以创建, 工作中我们有先进的工具辅助,
可以为你省去不少麻烦, 比如你手头肯定会有的SecureCRT, 或者XShell.

1:安装squid:

方案4【被采纳】

于是,我将这个方案进行了一些改进。我直接将MyHost做成了ProxyServer,并将代理服务器端口映射到AWS虚机中,这样就不会过多地占用公司服务器的资源,速度也应该会快一些。此时的数据通路会是这样的:

AWS虚机 <=> MyHost(内网主机即代理服务器) <=> FileServer(内网更新服务器)

下面是我的实现步骤。

二. 使用隧道绕过跳板机

用通俗的话讲, 这里的隧道在做这么一件事: 服务器A上有个程序,
监听3306端口,
存在一台服务器B分别和你的工作机以及服务器A的网络相通,
你在服务器A和服务器B上都有登陆权限,
隧道可以帮你把服务器A的3306端口映射到服务器B或者你的工作机上,
连接映射后的3306端口就等同于连接服务器A的3306端口.

工作中, 公司IT部为保证服务器安全, 工作机和服务器A之间的网络是不通的,
需要借助充当跳板机角色的服务器B. 你需要先ssh到服务器B, 再ssh到服务器A.
这对控制台下的一般管理还算能接受,
但对于不得不借助客户端工具的任务就无法实施了. 所以, 使用隧道,
把服务器A的3306端口映射到本地, 客户端工具中修改地址为localhost:3306,
客户端工具就能正常连接服务器A了.

使用工具创建隧道前先确保已将服务器B的ssh公钥上传至服务器A,
如果不明白我说的是什么,
请参考阮一峰老师写的SSH原理与运用:远程登录的第五节: 公钥登录

这里以XShell为例, SecureCRT类似. 打开服务器B的连接属性,
有一个被”特意”加粗显示的菜单叫隧道, 右边大红框中展示的是已经建立的,
点击”添加”按钮添加新隧道.

图片 2连接属性->隧道

类型选择Local , 源主机一栏填写你想映射到哪里,
侦听端口填写映射后的端口, 这里填写localhost3306,
代表映射到本的3306端口. 目标主机为服务器A的IP, 目标端口为3306,
意思是把服务器A的3306端口映射到本地. 确定后就添加了一条映射规则,
以后只要打开这个连接, 这条映射规则就会生效.

图片 3配置隧道

查看菜单里的”隧道窗格”可以显示当前会话所建立的隧道(转义规则标签)以及当前有哪些隧道正在通信(渠道标签).

图片 4查看隧道状态

有些客户端工具也自带隧道功能, 比较常见的就是各种数据库连接工具,
如HeidiSQL, MySQL Workbench, Navicat等等

图片 5数据库客户端配置隧道

总结: 有了ssh隧道后,
任意被跳板机”挡住”的服务器端口都可以映射到本地或者你能直连的服务器上.

[root@xuegod63
~]# yum install squid -y

搭建代理服务

ProxyServer我用的是Squid,它是一款开源软件,配置十分简单,几乎不用修改任何配置就可以拿来当HTTP代理服务器用。首先,登录MyHost并执行:

[[email protected]1-202 ~]# yum install -y squid
[[email protected]1-202 ~]# squid -z  # 初始化数据库
[[email protected]1-202 ~]# systemctl start squid.service

三. 使用反向隧道绕过防火墙

这里的反向隧道应用于这样一种场景: 公司服务器A位于内网, 没有公网IP,
只能被公司IP的电脑登陆. 你有一台公网服务器C,
可以被家中电脑和服务器A主动连接.

利用反向隧道可以让服务器C成为连通家中电脑和公司服务器A的桥梁.
使用反向隧道的大致步骤为:

  1. 在公司登陆服务器A, 和服务器C之间建立反向隧道,
  2. 在家里登录服务器C,
  3. 连接反向隧道从而登陆服务器A.

可以发现服务器A是主动连接服务器C的,
这就顺利突破了公司防火墙和没有公网IP的限制. 这就是反向的含义.

具体的步骤是先用公司的工作机登陆服务器A执行命令:

ssh -R 7000:localhost22 root@ServerC_IP

含义是登陆服务器C后, 将本地的22端口映射到服务器C的7000端口上.
这时候不能退出, 不能关电脑, 不能断网络.
待你回到家后用家中电脑登陆服务器C, 执行:

netstat -lpn | grep 7000

会发现一个被打开的7000端口, 这就是隧道了. 该端口等同于服务器A的22端口,
你执行下面命令就可以登陆服务器A了:

ssh user@localhost -p 7000

工作机上如果退出服务器C的登陆, 隧道就会被关闭,
所以这种方案也只能适合工作机可以长时间不关的人.

读者可能会发现XShell的连接属性->隧道->添加->类型下拉框中有一个选项叫Remote
, 这种类型对应的也是反向隧道. 但笔者用这种方式建立的隧道无法使用,
既没有报错,
也没有成功映射端口.有知道这个选项到底干嘛用的请一定要告诉我哦 OO~.

总结: 在知道反向隧道之前,
你登录公司服务器的方法可能是先远程桌面到工作机, 再登陆公司服务器,
这之间可能还要先登录跳板机, 受远程桌面和网络质量的影响,
这样2次跳板后到达服务器的操作感受会很糟糕. 现在只需要跳转1次,
关键是省去了远程桌面, 操作流畅度会大大提高.

2:配置文件位置:

反向映射端口(Reverse SSH tunnel)

我需要将本地的3128端口(也就是Squid服务的默认端口)映射到AWS虚机的8080端口,让虚机可以直接使用这个代理服务器。用到的命令是:

# ssh反向映射端口
ssh -R [服务器IP或省略]:[服务器端口]:[客户端能访问的IP]:[客户端能访问的IP的端口] [登陆服务器的用户名@服务器IP] -p [服务器ssh服务端口(默认22)]

换成我的情况,我需要使用下面这样的命令:

[[email protected]1-202 ~]# ssh -R 8080:127.0.0.1:3128 -i ~/.pem/ap-northeast-1-cheshi.pem -l ec2-user ec2-13-113-60-192.ap-northeast-1.compute.amazonaws.com
Last login: Wed Jul  5 05:00:34 2017 from 119.254.120.66
[[email protected]172-31-2-249 ~]$ 

这样的命令会同时打开一个到服务器(也就是AWS虚机)的console,在这个console连通的时候,代理服务器都是有效的,关闭这个console后,端口映射也就终止了。如果你想在不打开console的情况下使端口映射生效,你可以在上述命令中添加-Nf选项。

[[email protected]1-202 ~]# ssh -Nf -R 8080:127.0.0.1:3128 -i ~/.pem/ap-northeast-1-cheshi.pem -l ec2-user ec2-52-193-95-192.ap-northeast-1.compute.amazonaws.com
[[email protected]1-202 ~]# ps -ef | grep "ssh -Nf"
root     25126     1  0 13:10 ?        00:00:00 ssh -Nf -R 8080:127.0.0.1:3128 -i /root/.pem/ap-northeast-1-cheshi.pem -l ec2-user ec2-52-193-95-192.ap-northeast-1.compute.amazonaws.com
root     25176 16347  0 13:16 pts/0    00:00:00 grep --color=auto ssh -Nf
[[email protected]1-202 ~]# 

扩展阅读:使用ssh正向连接、反向连接、做socks代理的方法

注意:使用-Nf选项建立tunnel有可能使你在将来忘记它的存在。为此,出于安全考虑,我建议你使用不带-Nf选项的“阅后即焚”的连接方式。

四. 使用代理隧道搭建代理服务器

阮一峰老是在SSH原理与运用:远程操作与端口转发中说的绑定本地端口类型指的就是代理隧道,
这点可以从XShell的连接属性->隧道->添加->类型->Dynamic
就可以看出:

图片 6配置代理隧道

这样的隧道建立后, localhost:8080就是代理服务器地址了,
代理的网络环境就是会话所连接的服务器网络.

这种隧道非常适合用来调试线上系统. 比如采用分布式部署的应用, 从公网访问,
均衡负载会随机分配一台主机响应, 想要调试指定的一台主机怎么办?
你可以在均衡负载机上建立代理隧道, 浏览器中配置均衡负载为代理服务器,
浏览器地址栏输入主机的内网IP就可以访问指定的主机了.

总结: 虽然Linux安装ss5不难, 但在公司的服务器上安装就不妥了.
这种基于ssh的ss5代理方式比较轻量级, 无需在服务器上安装什么,
打开关闭很容易, 不相关人也无法使用, 简单又安全.

完.

[root@xuegod63
~]# ls /etc/squid/squid.conf

在虚机中使用yum

来到AWS虚机中,添加YUM源,并为其设置代理服务器(http://127.0.0.1:8080/)。

[[email protected]172-31-10-95 ~]$ cat /etc/yum.repos.d/rhel7u4.repo
[rhel7u4-debug]
name=rhel7u4-debug
baseurl=http://download.eng.pek2.redhat.com/pub/rhel/rel-eng/RHEL-7.4-20170621.0/compose/Server/x86_64/os
enabled=1
gpgcheck=0
proxy=http://127.0.0.1:8080/
[[email protected]172-31-10-95 ~]$ 

备注:因为有代理服务器在,所以这里的baseurl可以直接填写MyHost可以访问的任何一台更新服务器。

然后,就可以通过YUM源进行更新了:

[[email protected]172-31-10-95 ~]$ sudo yum update --enablerepo=rhel7u4-debug
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
Resolving Dependencies
--> Running transaction check
---> Package NetworkManager.x86_64 1:1.8.0-0.4.rc3.el7 will be updated
---> Package NetworkManager.x86_64 1:1.8.0-9.el7 will be an update
......
Complete!
[[email protected]172-31-10-95 ~]$ 

备注:如果没有设置代理服务器,或者代理服务器的连接有问题(通常是由于MyHost上的防火墙所致),就会收到"Could not resolve host: download.eng.pek2.redhat.com; Name or service not known"的消息。

3:启动服务

在虚机中使用wget

搭建代理服务器的好处多多,比如可以通过wget下载:

[[email protected]172-31-10-95 ~]$ export http_proxy=http://127.0.0.1:8080/
[[email protected]172-31-10-95 ~]$ wget http://download.eng.bos.redhat.com/brewroot/packages/cloud-init/0.7.9/4.el7/x86_64/cloud-init-0.7.9-4.el7.x86_64.rpm
......
Saving to: ‘cloud-init-0.7.9-4.el7.x86_64.rpm’

100%[=================================================================>] 633,112      349KB/s   in 1.8s   

2017-07-05 02:17:51 (349 KB/s) - ‘cloud-init-0.7.9-4.el7.x86_64.rpm’ saved [633112/633112]

[[email protected]172-31-10-95 ~]$ 

[root@xuegod63
~]# /etc/init.d/squid start

在虚机中使用更多工具

除此之外,还有很多工具支持使用代理服务器,当然你需要经过适当的配置,这里就不再展开叙述了。

扩展阅读:Linux设置代理

[root@xuegod63
~]# netstat -antup | grep 3128

防火墙设置及功能调试

通过firewall-cmd可以很容易地为Squid服务添加防火墙规则:

[[email protected]1-202 ~]# firewall-cmd --get-default-zone 
FedoraServer
[[email protected]1-202 ~]# firewall-cmd --add-service=squid
success
[[email protected]1-202 ~]# firewall-cmd --list-services
ssh dhcpv6-client cockpit squid
[[email protected]1-202 ~]# 

调试和排错时,可以使用nmap这个工具,它可以列出某台主机对外开放的端口及对应的服务。

在MyHost上,我们应该可以看到3128/tcp端口被打开,对应的服务是squid-http

[[email protected]1-202 ~]# nmap localhost

Starting Nmap 7.40 ( https://nmap.org ) at 2017-07-05 12:31 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000050s latency).
Other addresses for localhost (not scanned): ::1
Not shown: 995 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
111/tcp  open  rpcbind
2049/tcp open  nfs
3128/tcp open  squid-http
9090/tcp open  zeus-admin

Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds
[[email protected]1-202 ~]# 

而在AWS虚机中,我们也应该可以看到8080/tcp端口被打开:

[[email protected]172-31-2-249 ~]$ nmap localhost

Starting Nmap 6.40 ( http://nmap.org ) at 2017-07-05 04:33 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00034s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 997 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
[[email protected]172-31-2-249 ~]$ 

此时,还可以进一步使用nc命令验证8080/tcp端口的服务状态,这里不再赘述。

tcp
       0      0 0.0.0.0:3128       0.0.0.0:*     LISTEN    
4376/(squid)

结束语

相信大家已经看到,ssh是个非常强大的命令,但无论是哪种连接方式,对于服务器和整个内网而言,它都不会隐藏你的真实身份,因此你仍然需要为自己的行为负责,不要去做一些违反公司政策的事情。

另外,你需要考虑一些安全问题。由于ssh提供了安全的连接,而内网又在防火墙的保护之中,因此你唯一需要关心的问题是——你所连接的服务器存在安全隐患吗?举例来说,如果你将代理服务器的端口映射到了一台具有弱口令的外网主机,而攻破这台主机的黑客,就有可能通过映射端口访问到一些内网资源,造成泄密事件的发生。好在AWS的虚机默认情况下都安全得很,我能够提醒你的是:不要允许密码登录并保管好你的证书

总而言之,技术本身是没有善恶的,但使用者要对自己的行为负责,也要对整个网络的安全负责。

[root@xuegod63
~]# chkconfig squid on

参考文献

[root@xuegod63
~]# chkconfig –list squid

squid
         0:关闭1:关闭2:启用3:启用4:启用5:启用6:关闭

4:服务启动失败的解决方法

[root@xuegod63
~]# vim /etc/hosts

192.168.10.20
squid_A.tarena.com  sxueod63

[root@xuegod63
~]#  squid -z    #初始化缓存                  

2014/03/12
14:06:39| Creating Swap Directories

[root@xuegod63
~]# /etc/init.d/squid start

三:实战举例

根据实现的方式不同,代理服务可以分为正向代理和反向代理,正向代理包括传统代理和透明代理,这两种代理服务完成的工作相差不多。

第一块:正向代理

1:正向传统代理服务器:

在客户端使用的时候需要在web游览器中进行设置,来指定服务器的端口和地址,这种代理主要是针对局域网访问internet的时候用的比较广泛,但由于客户端需要进行设置,所以这种并不是最常用的。

1)加速原理:

图片 7 

代理服务器的功能是代替网络用户去访问网络信息,并把获得的信息返回给用户,其工作步骤大致如下:

(1)
客户机向代理服务器发起访问互联网的请求

(2)
代理服务器收到请求后检查请求是否被允许,如果允许将会进行下一步处理,否则丢弃该请求。

(3)
代理服务器先查找本地缓存中是否有客户机请求的数据���如果有则直接返回给客户端,否则继续下一步。

(4)
如果没有找到数据缓存,则代替客户机在互联网上发起请求。

(5)
接到请求回应后复制一份到缓存中,然后返回给客户机

1)实验拓扑

图片 8 

2)实验需求:

搭建squid代理服务器,使内网主机xuegod64:192.168.2.2
,能够通过xuegod63上的squid代理服务器加速上网。

3)实验环境

配置xuegod63网络:   eth0:
192.168.1.63  添加eth1,配置IP:192.168.2.1  vmnet4

配置xuegod64网络:  
添加eth0,配置IP:192.168.2.2 网关: 192.168.2.1     vmnet4

4)实验步骤

xuegod63配置:

[root@xuegod63
~]# vim /etc/squid/squid.conf

改: #http_access
deny all

 为: http_access
allow all          //允许所有用户使用它作为代理

5)启动服务

[root@xuegod63
~]# service squid restart

[root@xuegod63
~]# chkconfig squid on

6)配置xuegod64
客户端

 
 在浏览器里指定代理服务器的ip地址(192.168.2.1)和端口号(3128)。

 

图片 9

图片 10

 

 图片 11

7)测试:

图片 12 

#在xuegod64上的浏览器中打开www.163.com可以访问,但是当ping www.163.com ping是不通的

图片 13

#在xuegod64上的浏览器中打开192.168.1.1
 可以访问到当前的路由器,并且找到了当前的
主机是匿名主机的IP地址是192.168.1.63
 而不是xuegod64上的IP地址。这样xuegod63就是一个代理服务器了,客户端(xuegod63)通过代理服务器(xuegod64)访问到网络,而客户端本身自己是不能访问网络的。

 

 2:正向透明代理服务器:

提供与传统代理相同的服务,但不需要用户进行设置,而是通过默认路由和防火墙的重定向功能,在整个过程中用户不知道其中的过程,所以称之为透明代理。使用透明代理时网页游览器访问网站时的域名解析请求优先发给DNS服务进行解析。透明代理必须在linux操作系统的防火墙上进行操作。操作上不是很灵活。