今天我要将AWS虚机升级到beta版本并进行一些测试。
由于beta版本只在公司内网提供,因此我需要将升级用的文件手动拷贝到AWS虚机中。原始的方法,很容易理解:
RHEL-7.4-20170621.0-Server-x86_64-dvd1.iso
拷贝到这个虚机中。yum update
操作完成更新。然而这就遇到一个问题,因为镜像文件有4.2GB大小,传输过程不仅占用带宽资源,而且还会浪费很多时间。
解决办法我首先想到将目录http://download.intranet.shadowman.com/paths/RHEL-7.4-20170621.0/compose/Server/x86_64/debug/tree/
拷贝到虚机上,然后用它来做YUM源进行升级。但我很快就发现自己并不能确定哪些package是升级所需要的,因此只能上传全部的文件,这样做并不能有效解决问题。
其次,我想到在AWS虚机上安装客户端,通过VPN方式访问内网资源。这样做当然是可行的,只是open配置起来需要将证书拷来拷去,这使我担心潜在的安全问题,也担心后续会过多地占用VPN服务器资源,因此这个想法只能作罢。
后来,我想到了一个办法,将公司内网的HTTP代理服务器,用反向连接的方式,共享给AWS虚机,用到的命令大概会是这样:
ssh -R 8080:squid.intranet.shadowman.com:3128 -i ~/.pem/cheshi.pem ec2-user@ec2-13-113-60-192.ap-northeast-1.compute.amazonaws.com
这样做应该是最简单的方案了,但是它还有一个小问题,所有流量都要去公司代理服务器上绕一圈,数据通路看起来会是这样的:
AWS虚机 <=> MyHost(内网主机) <=> ProxyServer(内网代理服务器) <=> FileServer(内网更新服务器)
浪费资源是一方面,更重要的是如果更新量很大,过多地占用了公司代理服务器的资源,有可能会被IT部门审计出来。
于是,我将这个方案进行了一些改进。我直接将MyHost做成了ProxyServer,并将代理服务器端口映射到AWS虚机中,这样就不会过多地占用公司服务器的资源,速度也应该会快一些。此时的数据通路会是这样的:
AWS虚机 <=> MyHost(内网主机即代理服务器) <=> FileServer(内网更新服务器)
下面是我的实现步骤。
ProxyServer我用的是Squid,它是一款开源软件,配置十分简单,几乎不用修改任何配置就可以拿来当HTTP代理服务器用。首先,登录MyHost并执行:
[root@dhcp-1-202 ~]# yum install -y squid
[root@dhcp-1-202 ~]# squid -z # 初始化数据库
[root@dhcp-1-202 ~]# systemctl start squid.service
我需要将本地的3128
端口(也就是Squid服务的默认端口)映射到AWS虚机的8080
端口,让虚机可以直接使用这个代理服务器。用到的命令是:
# ssh反向映射端口
ssh -R [服务器IP或省略]:[服务器端口]:[客户端能访问的IP]:[客户端能访问的IP的端口] [登陆服务器的用户名@服务器IP] -p [服务器ssh服务端口(默认22)]
换成我的情况,我需要使用下面这样的命令:
[root@dhcp-1-202 ~]# ssh -R 8080:127.0.0.1:3128 -i ~/.pem/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
[ec2-user@ip-172-31-2-249 ~]$
这样的命令会同时打开一个到服务器(也就是AWS虚机)的console,在这个console连通的时候,代理服务器都是有效的,关闭这个console后,端口映射也就终止了。如果你想在不打开console的情况下使端口映射生效,你可以在上述命令中添加-Nf
选项。
[root@dhcp-1-202 ~]# ssh -Nf -R 8080:127.0.0.1:3128 -i ~/.pem/cheshi.pem -l ec2-user ec2-52-193-95-192.ap-northeast-1.compute.amazonaws.com
[root@dhcp-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/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
[root@dhcp-1-202 ~]#
扩展阅读:使用ssh正向连接、反向连接、做socks代理的方法
注意:使用-Nf
选项建立tunnel有可能使你在将来忘记它的存在。为此,出于安全考虑,我建议你使用不带-Nf
选项的“阅后即焚”的连接方式。
来到AWS虚机中,添加YUM源,并为其设置代理服务器(http://127.0.0.1:8080/
)。
[ec2-user@ip-172-31-10-95 ~]$ cat /etc/yum.repos.d/rhel7u4.repo
[rhel7u4-debug]
name=rhel7u4-debug
baseurl=http://download.intranet.shadowman.com/paths/RHEL-7.4-20170621.0/compose/Server/x86_64/os
enabled=1
gpgcheck=0
proxy=http://127.0.0.1:8080/
[ec2-user@ip-172-31-10-95 ~]$
备注:因为有代理服务器在,所以这里的baseurl
可以直接填写MyHost可以访问的任何一台更新服务器。
然后,就可以通过YUM源进行更新了:
[ec2-user@ip-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!
[ec2-user@ip-172-31-10-95 ~]$
备注:如果没有设置代理服务器,或者代理服务器的连接有问题(通常是由于MyHost上的防火墙所致),就会收到"Could not resolve host: download.intranet.shadowman.com; Name or service not known"
的消息。
搭建代理服务器的好处多多,比如可以通过wget
下载:
[ec2-user@ip-172-31-10-95 ~]$ export http_proxy=http://127.0.0.1:8080/
[ec2-user@ip-172-31-10-95 ~]$ wget http://download.intranet.shadowman.com/paths/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]
[ec2-user@ip-172-31-10-95 ~]$
除此之外,还有很多工具支持使用代理服务器,当然你需要经过适当的配置,这里就不再展开叙述了。
扩展阅读:Linux设置代理
通过firewall-cmd
可以很容易地为Squid服务添加防火墙规则:
[root@dhcp-1-202 ~]# firewall-cmd --get-default-zone
FedoraServer
[root@dhcp-1-202 ~]# firewall-cmd --add-service=squid
success
[root@dhcp-1-202 ~]# firewall-cmd --list-services
ssh dhcpv6-client cockpit squid
[root@dhcp-1-202 ~]#
调试和排错时,可以使用nmap
这个工具,它可以列出某台主机对外开放的端口及对应的服务。
在MyHost上,我们应该可以看到3128/tcp
端口被打开,对应的服务是squid-http
:
[root@dhcp-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
[root@dhcp-1-202 ~]#
而在AWS虚机中,我们也应该可以看到8080/tcp
端口被打开:
[ec2-user@ip-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
[ec2-user@ip-172-31-2-249 ~]$
此时,还可以进一步使用nc
命令验证8080/tcp
端口的服务状态,这里不再赘述。
这个脚本运行在内网主机上,使用内网repo资源升级AWS上的虚拟机:
https://github.com/SCHEN2015/virt-utils/tree/master/aws_vm_upgrade
相信大家已经看到,ssh
是个非常强大的命令,但无论是哪种连接方式,对于服务器和整个内网而言,它都不会隐藏你的真实身份,因此你仍然需要为自己的行为负责,不要去做一些违反公司政策的事情。
另外,你需要考虑一些安全问题。由于ssh
提供了安全的连接,而内网又在防火墙的保护之中,因此你唯一需要关心的问题是——你所连接的服务器存在安全隐患吗?举例来说,如果你将代理服务器的端口映射到了一台具有弱口令的外网主机,而攻破这台主机的黑客,就有可能通过映射端口访问到一些内网资源,造成泄密事件的发生。好在AWS的虚机默认情况下都安全得很,我能够提醒你的是:不要允许密码登录并保管好你的证书。
总而言之,技术本身是没有善恶的,但使用者要对自己的行为负责,也要对整个网络的安全负责。