轉自:https://yq.aliyun.com/articles/8469
ssh是一個非常棒的工具, 不但能建立動態轉發, 例如chrome的Switchy插件用到的就是這個技術.
http://blog.163.com/digoal@126/blog/static/163877040201141821810103/
還能建立TCP的轉發隧道, 例如我以前寫過的關於使用ssh 隧道加密和加速WAN傳輸的幾個例子.
http://blog.163.com/digoal@126/blog/static/163877040201342383123592/
http://blog.163.com/digoal@126/blog/static/16387704020115294425540/
上面的例子可以理解為正向的TCP端口轉發代理(如local$ ssh -L 7001:1.1.1.1:1000 remote_A), 即本地服務器local建立和遠程服務器的SSH連接, 本地監聽一個端口7001, 連接本地的監聽端口7001相當於"通過遠程服務器remote_A訪問指定的IP 1.1.1.1和PORT 1000".
這種方法適用於本地網絡中其他服務器想訪問遠程的服務器, 但是其他服務器沒有直接訪問遠程服務器的權限, 通過本地網絡中有權限的服務器做端口轉發的場景.
還有一種應用場景是這樣的, 本地網絡環境中沒有任何一台服務器可以直接訪問遠程服務器, 但是遠程服務器可以反過來訪問本地的某台服務器(或者本地可以訪問到的某台服務器), 這樣的話也能實現本地服務器去訪問遠程服務器的目的. 這就是反向代理.
實際的應用場景如,
或者說A和B無法相互訪問,但是A能訪問C,B也能訪問C。怎么通過C讓AB能相互訪問?
.1. 家里的網絡是動態撥號網絡, 沒有固定IP, 如果想在上班的時候控制家里的電腦怎么辦呢? 如果公司有一台服務器是可以在家撥號過去訪問的, 那么你可以在家里的電腦上建立和這台公司服務器的反向代理, 到公司后, 就可以連接這台服務器上的反向代理(監聽)來連接家里的電腦了.
.2. 有的客戶可能不希望提供VPN給你去訪問他們的服務器, 但是又需要得到你的遠程協助, 怎么辦呢?
你可以提供一台服務器讓客戶主動來訪問你的服務器, 客戶建立這樣的反向代理, 然后你通過這個反向代理來連接客戶開放的端口如VNC桌面共享, 進行遠程協助. (這種方法比QQ遠程協助是更安全的, 因為客戶和這台服務器之間的數據時加密的, QQ遠程協助畢竟有一定的風險存在.)
以下是反向代理的圖例, 如圖1 :
箭頭表示允許訪問的方向, 也就是說Server C可以訪問Server A和Server B以及Client A.
而Client B和Client C可以訪問Client A.
我們的目的是要讓Client 可以訪問Server. 這里就要用到SSH的反向端口轉發, 或遠程端口轉發.
反向代理應用場景.
例如, 以下虛線表示Client C最終要訪問Server A的22端口.
實現的步驟
1. Client A需要修改一下sshd_config, 開啟GatewayPorts, 這樣才能監聽回環地址以外的地址, 如0.0.0.0, 這樣的話其他服務器才能訪問到這個端口.
2. Server C建立和Client A的反向端口轉發, 讓Client A在0.0.0.0上監聽7001端口, 訪問這個端口的數據轉發到IP_SA的22端口.
ssh -CqTfnN -R 0.0.0.0:7001:IP_SA:22 IP_CA
其實再深層次一點, 因為client c和server a已經可以建立ssh了, 那么通過client c和server a建立反向代理, Server A也可以訪問Client c. 這樣需要經過了多層ssh隧道( IP_CA->IP_SC, IP_SA->IP_CC )
這種反向代理的用法很容易應用到實際的場景中, 例如前面提到的 :
有的客戶可能不希望提供VPN給你去訪問他們的服務器, 但是又需要得到你的遠程協助, 怎么辦呢?
你可以提供一台服務器讓客戶主動來訪問你的服務器, 客戶建立這樣的反向代理, 然后你通過這個反向代理來連接客戶開放的端口如VNC桌面共享, 進行遠程協助.
如圖 :
Public A是一台公用主機, 可以被客戶和服務提供商同時訪問.
當客戶需要遠程協助時.
1. 客戶在SERVER C上開啟一個VNC server
2. 客戶將需要遠程協助的窗口先登錄好, 例如某些內網服務器(SERVER A , SERVER B)的telnet或ssh終端. 以供服務提供商使用.
3. 客戶在SERVER C主動建立和這台公用主機的反向代理, 將端口轉發到server c的vnc監聽端口.
4. 服務提供商使用VNC客戶端連接這台公共服務器的SSH代理監聽端口, 相當於連接到了server c的vnc server. 以提供遠程協助.
5. 客戶可以在server c上觀看, 錄像, 控制這個VNC會話等.
下面來舉個例子 :
場景 :
家里有一台WINDOWS服務器, 通過VPN撥號到公司網絡.
WINDOWS服務器上跑了兩個VMWARE的虛擬機, 分別是FreeBSD和CentOS.
公司有1台主機172.16.3.150, 安裝了CentOS,
撥號后, 家里的虛擬機FreeBSD可以訪問172.16.3.150.
現在要讓公司的其他服務器如172.16.3.167可以訪問到家里的192.168.198.129虛擬機.
簡單步驟.
.1. 撥號, 略
.2. 172.16.3.150上需要修改sshd_config.
[root@db-172-16-3-150 ~]# vi /etc/ssh/sshd_config GatewayPorts yes [root@db-172-16-3-150 ~]# service sshd reload Reloading sshd: [ OK ]
.3. 通過虛擬機192.168.198.130連接到172.16.3.150開啟反向端口代理. (如果130不是LINUX是WINDOWS, 也可以用securecrt類似的軟件進行代理配置.)
root@digoal:~ # ssh -CqTfnN -R 0.0.0.0:7001:192.168.198.129:22 172.16.3.150 root@172.16.3.150's password:
.4. 在172.16.3.150上可以看到這個監聽.
[root@db-172-16-3-150 ~]# netstat -anp|grep 7001 tcp 0 0 0.0.0.0:7001 0.0.0.0:* LISTEN 2392/sshd tcp 0 0 :::7001 :::* LISTEN 2392/sshd
.5. 現在到172.16.3.167上連接172.16.3.150的7001端口.
[root@db5 ~]# ifconfig
bond0 Link encap:Ethernet HWaddr 00:23:7D:A3:F0:4E inet addr:172.16.3.176 Bcast:172.16.3.255 Mask:255.255.255.0 inet6 addr: fe80::223:7dff:fea3:f04e/64 Scope:Link UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1 RX packets:200422824 errors:0 dropped:0 overruns:0 frame:0 TX packets:16849618 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:23012276676 (21.4 GiB) TX bytes:3567071726 (3.3 GiB) [root@db5 ~]# ping 172.16.3.150 PING 172.16.3.150 (172.16.3.150) 56(84) bytes of data. 64 bytes from 172.16.3.150: icmp_seq=1 ttl=64 time=0.337 ms --- 172.16.3.150 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.337/0.337/0.337/0.000 ms [root@db5 ~]# ssh -p 7001 172.16.3.150 Password for root@digoal.org: root@digoal:~ # ifconfig em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM> ether 00:0c:29:c0:4b:65 inet 192.168.198.129 netmask 0xffffff00 broadcast 192.168.198.255 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect (1000baseT <full-duplex>) status: active
到這里反向代理的測試完成.
接下來我們看看如何在反向代理的基礎上, 再做一層反向代理.
例如我要在172.16.3.167建立和192.168.198.129的反向代理, 讓192.168.198.130通過192.168.198.129來訪問172.16.3.150.
.1. 首先要修改192.168.198.129的sshd_config
root@digoal:~ # vi /etc/ssh/sshd_config GatewayPorts yes root@digoal:~ # service sshd reload Performing sanity check on sshd configuration. root@digoal:~ # exit logout Connection to 172.16.3.150 closed.
.2. 在172.16.3.167建立和192.168.198.129的反向代理
[root@db5 ~]# ssh -CqTfnN -p 7001 -R 0.0.0.0:7001:172.16.3.150:22 172.16.3.150 Password for root@digoal.org:
.3. 在192.168.198.129上查看監聽.
root@digoal:~ # netstat -AaLnSTW Current listen queue sizes (qlen/incqlen/maxqlen) Tcpcb Proto Listen Local Address fffff800076ce800 tcp4 0/0/128 *.7001
.4. 在192.168.198.130上通過192.168.198.129:7001來訪問172.16.3.150:22.
[root@digoal ~]# ssh -p 7001 192.168.198.129 The authenticity of host '[192.168.198.129]:7001 ([192.168.198.129]:7001)' can't be established. RSA key fingerprint is 01:0b:96:e1:a8:be:a3:a3:69:a4:0a:11:5d:2a:6f:c2. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.198.129]:7001' (RSA) to the list of known hosts. root@192.168.198.129's password: Last login: Sat Jun 14 18:20:23 2014 from 10.0.0.60 [root@db-172-16-3-150 ~]#
[注意]
.1. 當使用vncserver共享桌面時, 有幾點需要注意, 需要使用或勾選Shared connection選項, 否則一個連上來, 其他的就會斷掉.
.2. 使用vncserver共享桌面, 只要把5901端口共享出來就可以了.
例如
在172.16.3.150建立和172.16.3.221的反向隧道, 代理VNCSERVER端口的反向轉發.
# ssh -CqTfnN -p 22 -R 0.0.0.0:5901:172.16.3.150:5901 172.16.3.221
這個使用的是172.16.3.221:5901來代理172.16.3.150:5901
在172.16.3.150開啟一個vncserver, 讓A主機可以連到這個vncserver.
在A主機開啟一個vncviewer, 並打開共享連接, 連接到172.16.3.150:5901
在B主機開啟一個vncviewer, 並打開共享連接, 連接到172.16.3.221:5901
最終, A變成了監控機, B是操作方.
B的操作, A可以在VNCVIEWER觀看到.
使用完成后, 斷開172.16.3.150和172.16.3.221的連接即可, 或者關閉172.16.3.150的vncserver服務即可. vncserver -kill :?.
.3. 如果是跨廣域網的隧道, 中間經過的某些網絡設備可能會有會話空閑自動斷開機制, 為了確保隧道不會被這種機制自動干掉, 我們可以設置一下SSH連接的心跳.
# sysctl -w net.ipv4.tcp_keepalive_time=30 net.ipv4.tcp_keepalive_time = 30 # ssh -CqTfnN -o TCPKeepAlive=yes -o ServerAliveInterval=10 -o ServerAliveCountMax=10 -p 22 -R 0.0.0.0:5901:172.16.3.150:5901 目標IP
現在TCP的心跳時間縮短了, 空閑會自動發送TCP心跳包.
[root@150 ~]# netstat -anpo|grep ssh tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2699/sshd off (0.00/0/0) tcp 0 0 172.16.3.150:62230 目標IP:22 ESTABLISHED 21721/ssh keepalive (21.48/0/0)
.4. 如果目標機的5901端口監聽被占用了, 可以換個端口, 那么使用vncviewer或者其他客戶端連接時, 需要使用::port指定端口.
例如172.16.3.150::6666
.5. 考慮到跨廣域網的帶寬有限問題, vncserver啟動時, 最好設置一下位寬, 因為大多數操作不需要那么好的色彩, 例如 :
# vncserver :1 -geometry 1200x700 -depth 8 -cc 3
初次配置時, 輸入密碼
# vi ~/.vnc/xstartup #twm & gnome-session & # vncserver -kill :1 # vncserver :1 -geometry 1200x700 -depth 8 -cc 3
參考
man vncserver
[參考]
.1. http://blog.163.com/digoal@126/blog/static/163877040201141821810103/
.2. http://blog.163.com/digoal@126/blog/static/16387704020115294425540/
.3. http://blog.163.com/digoal@126/blog/static/163877040201342383123592/
.4. man ssh
-R [bind_address:]port:host:hostport
Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side. This works by allocating a socket to listen to port on the remote side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to host port hostport from the local machine. Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square braces or using an alternative syntax: [bind_address/]host/port/hostport. By default, the listening socket on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server’s GatewayPorts option is enabled (see sshd_config(5)). If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to the client at run time.
.5.
linux 通過ssh代理上網
本網段上網需計費,想到通過另一網段的linux服務器做代理免費上網
前提是你有那台linux主機的帳戶
然后打開終端輸入
ssh -qTfnN -D 7070 user@host
說明: user是你的帳號,host指對方linux主機的ip
-q Quiet mode. 安靜模式,忽略一切對話和錯誤提示。
-T Disable pseudo-tty allocation. 不占用 shell 了。 -f Requests ssh to go to background just before command execution. 后台運行,並推薦加上 -n 參數。 -n Redirects stdin from /dev/null (actually, prevents reading from stdin). -f 推薦的,不加這條參數應該也行。 -N Do not execute a remote command. 不執行遠程命令,專為端口轉發度身打造。
然后在瀏覽器中
如果是firefox:安裝autoproxy插件,在代理中選擇SSH -D即可。默認情況下的配置就是7070端口,所以可以不用修改配置,否則在首選項中更改服務器設置。
如果是Chrome:安裝proxy switchy擴展,添加Proxy Profile,在右側的socks host中輸入127.0.0.1和7070,下方選中socks v5,保存,然后切換至該profile即可。