1. 程式人生 > >讓AWS虛機訪問公司內網資源(SSH反向代理)

讓AWS虛機訪問公司內網資源(SSH反向代理)

背景說明

今天我要將AWS虛機升級到beta版本並進行一些測試。

由於beta版本只在公司內網提供,因此我需要將升級用的檔案手動拷貝到AWS虛機中。原始的方法,很容易理解:

  1. 用AWS上能找到的最新版本AMI啟動一個虛機。
  2. 將映象檔案RHEL-7.4-20170621.0-Server-x86_64-dvd1.iso拷貝到這個虛機中。
  3. Mount這個映象檔案,並以此建立YUM源。
  4. 執行yum update操作完成更新。

然而這就遇到一個問題,因為映象檔案有4.2GB大小,傳輸過程不僅佔用頻寬資源,而且還會浪費很多時間。

研究過程

方案1【被捨棄】

解決辦法我首先想到將目錄http://download.intranet.shadowman.com/paths/RHEL-7.4-20170621.0/compose/Server/x86_64/debug/tree/拷貝到虛機上,然後用它來做YUM源進行升級。但我很快就發現自己並不能確定哪些package是升級所需要的,因此只能上傳全部的檔案,這樣做並不能有效解決問題。

方案2【被捨棄】

其次,我想到在AWS虛機上安裝客戶端,通過VPN方式訪問內網資源。這樣做當然是可行的,只是openvpn配置起來需要將證書拷來拷去,這使我擔心潛在的安全問題,也擔心後續會過多地佔用VPN伺服器資源,因此這個想法只能作罷。

方案3【被捨棄】

後來,我想到了一個辦法,將公司內網的HTTP代理伺服器,用反向連線的方式,共享給AWS虛機,用到的命令大概會是這樣:

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

這樣做應該是最簡單的方案了,但是它還有一個小問題,所有流量都要去公司代理伺服器上繞一圈,資料通路看起來會是這樣的:

AWS虛機 <=> MyHost(內網主機) <=> ProxyServer(內網代理伺服器) <=> FileServer(內網更新伺服器)

浪費資源是一方面,更重要的是如果更新量很大,過多地佔用了公司代理伺服器的資源,有可能會被IT部門審計出來。

方案4【被採納】

於是,我將這個方案進行了一些改進。我直接將MyHost做成了ProxyServer,並將代理伺服器埠對映到AWS虛機中,這樣就不會過多地佔用公司伺服器的資源,速度也應該會快一些。此時的資料通路會是這樣的:

AWS虛機 <=> MyHost(內網主機即代理伺服器) <=> FileServer(內網更新伺服器)

下面是我的實現步驟。

搭建代理服務

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

反向對映埠(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/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/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/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選項的“閱後即焚”的連線方式。

在虛機中使用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.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/
[[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.intranet.shadowman.com; Name or service not known"的訊息。

在虛機中使用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.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]

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

在虛機中使用更多工具

除此之外,還有很多工具支援使用代理伺服器,當然你需要經過適當的配置,這裡就不再展開敘述了。

擴充套件閱讀:Linux設定代理

防火牆設定及功能除錯

通過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埠的服務狀態,這裡不再贅述。

基於方案4的指令碼

這個指令碼執行在內網主機上,使用內網repo資源升級AWS上的虛擬機器:
https://github.com/SCHEN2015/virt-utils/tree/master/aws_vm_upgrade

結束語

相信大家已經看到,ssh是個非常強大的命令,但無論是哪種連線方式,對於伺服器和整個內網而言,它都不會隱藏你的真實身份,因此你仍然需要為自己的行為負責,不要去做一些違反公司政策的事情。

另外,你需要考慮一些安全問題。由於ssh提供了安全的連線,而內網又在防火牆的保護之中,因此你唯一需要關心的問題是——你所連線的伺服器存在安全隱患嗎?舉例來說,如果你將代理伺服器的埠對映到了一臺具有弱口令的外網主機,而攻破這臺主機的黑客,就有可能通過對映埠訪問到一些內網資源,造成洩密事件的發生。好在AWS的虛機預設情況下都安全得很,我能夠提醒你的是:不要允許密碼登入並保管好你的證書

總而言之,技術本身是沒有善惡的,但使用者要對自己的行為負責,也要對整個網路的安全負責。

參考文獻

  1. 使用ssh正向連線、反向連線、做socks代理的方法 http://blog.csdn.net/linsanhua/article/details/17360369
  2. Centos下搭建Squid代理伺服器詳細教程 http://www.tuicool.com/articles/IJzeAv2
  3. Linux設定代理 http://www.361way.com/linux-proxy/4184.html
  4. FirewallD/zh-cn - FedoraProject https://fedoraproject.org/w/index.php?title=FirewallD/zh-cn