SSH通道提供了强大的转发功能,比如端口转发,动态端口转发,X11转发等。
端口转发包含client to server(C2S)和Server to client(S2C)两种(这里的server指安装了SSH server的机器,client指安装了SSH客户端的机器)。
端口转发的命令在Client的机器上执行,C2S的命令格式如下:
ssh -L localport:host:hostport user@ssh_server
Client的localport的所有连接都被加密传输到ssh server,然后转发到host的hostport 进程。
S2C的命令格式如下:
ssh -R localport:host:hostport user@ssh_server
ssh server的localport的所有连接都被加密传输到client,然后转发到host的hostport 进程。
例一:
两个局域网之间安全传输数据。假设有两个局域网A和B
A:192.168.0.0 255.255.255.0/普通用户局域网Client1,Client2,…
B:192.168.1.0 255.255.255.0/服务器局域网Server1,Server2,…
A网和B网需要在广域网中安全的传输数据。那么可以采用采用如下的方案:
在 A网和B网中各选择一台机器,分别叫做ClientX,ServerX(需要有外网IP,可以被ClientX访问),在ClientX上安装SSH client, 在ServerX上安装SSH server. 在ClientX上设置一个SSH的C2S端口转发,所有的Client的访问都通过ClientX建立的通道。
ssh -L port:ServerY:port user@ServerX
这样的一个设置,如果以前访问的是ServerY:port,那么现在client只需要访问ClientX:port例子就可以达到同样的效果,并且数据通过ClientX到ServerX都加密了。
例二:
在家里怎么访问公司局域网中机器。
比 如公司有一台机器A(hostA),开启了telnet服务(假设用默认端口23),我在家里想访问。首先需要在公司找到一台外网可以访问的机器 B(hostB),B肯定会有两个地址,一个是和A在同一局域网中地址,另外一个是外网地址。在B上安装SSH server,并设置对应的账户。然后在自己的机器上安装SSH Client.最后设置端口转发。
ssh -L localport:hostA:23 user@HostB
那么你就可以使用telnet 127.0.0.1 localportl 来访问HostA的telnet服务,并且数据在你的机器与HostB之间的加密的。
除 了端口转发之外,SSH还有动态端口转发(Dynamic port forwarding). 动态端口转发中SSH client相当于是SOCKS代理服务器。SSH client在一个固定的端口比如1080监听,充当一个SOCKS代理服务器,应用程序使用SOCKS代理。所有的请求都通过SSH Client的这个代理.
SSH Client通过动态端口转发将每个请求先自动的转发到SSH Server,然后SSH Server转发到请求目标。
命令格式如下:
ssh -D localport user@ssh_server
这个命令将在本地建立一个SOCKS的代理服务器,所有的代理请求都安全传输到ssh_server上。
例子:
这种方式在浏览器中使用比较多,这里就以浏览器为例。
假设有一个SSH Server在美国,你在上面申请了一个SSH的账户。那么你可以通过设置SSH动态端口转发使得你浏览器的所有请求都加密传输到到这台SSH服务器,然后再通过这台SSH Server来访问对应的资源。
首先需要设置SSH动态端口转发,然后在浏览器中设置代理服务器就可以。这就是一种常见的翻墙方式。
SSH的X11转发提供了窗口转发的功能。其命令格式如下;
ssh -X user@ssh_server
这 样连接上ssh_server后,在ssh_server运行一个窗口程序,这个窗口就可以在自己的机器上显示。这时候,你不用自己设置DISPLAY变 量。你使用-X选项的时候,SSH Server自动为你设置了。如果你的机器上没有X11 Server的话,需要安装一个X11 Server(比如xmanager或者X-Deep/32)才能够正确的显示。x11转发如果不考虑安全因素,可以使用VNC,因为窗口的数据都需要加 密,速度可能是一个问题。当然也可以把VNC和SSH结合使用,先设置安全通道,然后在安全通道上使用VNC.
SSH提供的转发功能,其本质都是一样的,就是把数据安全的从一台机器转发到另外一台机器。端口转发只对固定的端口的数据转发,动态端口转发可以对任意的端口数据转发,X11转发的是图形窗口.
--------------------------------------------------------------
使用OpenSSH在Linux上实现安全网络通道
RSA key fingerprint is d2:af:9e:c7:52:97:d2:55:e8:3e:83:a4:eb:98:a1:b6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘192.168.1.3′ (RSA) to the list of known hosts.
------------------------------------------
利用SSH通道共享上网,(linux,mac)没有上网客户端(锐捷)的解决方法
只要你有能上网的机器,在局域网内(一定要能互相访问,否则很难实现)就可以共享上网。当然这样的方法很多,简单的例如利用windows自身的NAT地址转换,双网卡来共享,通过ccproxy之类的软件架设代理服务器或者网关之类的,等等。但是如果网络条件恶劣,上网客户端有诸多限制,例如电信拨号,限制只能一台上网,例如锐捷,除了限制单台电脑上网外,还限制不能多网卡,不能开启代理服务器(包括http,socks代理),这样的时候上述简单方法都无效。这个时候就可以利用SSH的通道技术在需要上网的机器和能上网的机器之间建立加密的安全通道(SSH通道)来上网。
(这里强烈鄙视锐捷,我难道为了上网还要装 windows?windows客户端版本在升级,linux下就一直不升级而且不能用,BSD,mac下更是没有。而且windows下兼容性奇差,这 也限制那也限制,我无线网卡也是双网卡?这些技术真是恶心死了,专门为学校教育网研发的把。学校大概也为了显示水平,linux下客户端版本也限制。强烈 BS这样的行为!恶心死了。这里介绍的方法就是我在linux不能上网的情况下弄出来的)
不清楚SSH是什么?看这里:
这里把能上网的机器成为服务器,需要连接上网的机器叫客户机。
客户机和外界的通信过程:客户机信息 <–> 客户机某个端口(如7070)<–> SSH通道 <–> 主机的端口( SSH服务器端口22)<–> 外界
这里SSH服务器就成为一个socks5代理服务器了。只要支持socks5的软件都可以轻松上网,如firefox,不支持socks5的稍微麻烦一点。
- 什么是socks5?和socks4,http代理有何不同?
具体表现在SOCKS4只能代理TCP协议,而 SOCKS5什么协议都可以代理,而QQ使用的是UDP协议,所以它不能使用SOCKS4代理,而象国外的ICQ使用比UDP协议安全的TCP协议,所以就可以使用SOCKS4代理。说上面一些无非是介绍大概过程和适用环境。废话说完了,下面是过程以及解释:
那SOCKS代理和HTTP代理有什么不同?从上文我们知道SOCKS工作在会话层上,而HTTP工作在应用层上,Socks代理只是简单地传递数 据包,而不必关心是何种应用协议(比如FTP、HTTP和NNTP请求),所以Socks代理服务器比应用层代理服务器要快得多。
条件
- 网段:192.168.0.1-192.168.0.255
- 网关:192.168.0.1
- 能上网机器:192.168.0.2 装的xp (我这里是其实是虚拟机)
- 需要上网的机器:192.168.0.10和192.168.0.11 装的archlinux和ubuntu (真实机器,有一台是虚拟机的主机)
- 附加条件:一定能互相访问,互相能ping通,比如在一个交换机或者路由下,而不是通过网关,例如锐捷的网关是不会让互相能访问的
- 先在服务器上安装一个SSH服务器,这里因为windows机器能上网的比较多,以xp为例。服务器端推荐F-Secure SSH Server,客户端可以用F-Secure SSH Client,(还可以是sshwindows),google一下教程很多。此处省略。Windows平台SSH服务器架设攻略(图)
- 建立好服务端,启动(如果失败,就查看日志),用SSH客户端连接测试(登陆帐号和密码就是xp的用户帐号和密码,也就是远程登陆了xp)。
- (如果服务端是*nux或者mac的,支持的更加好,应该是自带了类似工具,如openssh,相关资料更多,SSH本身就是为*nix设计用来远程安全管理的。)
- 但是此时没有通道,此处以linux下操作为例,如果只是自己使用,利用ssh这个命令足够。
ssh端口转发命令介绍
ssh的三个强大的端口转发命令:
ssh -C -f -N -g -L listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -R listen_port:DST_Host:DST_port user@Tunnel_Host
ssh -C -f -N -g -D listen_port user@Tunnel_Host
-f Fork into background after authentication.
后台认证用户/密码,通常和-N连用,不用登录到远程主机。 -p port Connect to this port. Server must be on the same port.
被登录的ssd服务器的sshd服务端口。
-L port:host:hostport
将 本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-R port:host:hostport
将 远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
-D port
指 定一个本地机器”动态的”应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
-C Enable compression.
压缩数据传输。
-N Do not execute a shell or command.
不执行脚本或命令,通常与-f连用。
-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接
- 如果需要共享通道给别人用的,我没找到ssh的相关参数,如果你知道的请告诉一下我哦。我是用putty(跨平台,windows下也有)实现的。需要选上connection-SSH-Tunnels选项卡里面最上面的一项[Local ports accept connections from other hosts],别人共享通道的,省掉上面这一步
- 在 firefox里设置socks 5代理为192.168.0.10:7070,应该就可以访问ip地址了。不过此时没有办法解析DNS,也就是输入域名是没有办法访问的。这里有只是针对 火狐的一个方法:about:config里面network.proxy.socks_remote_dns设置为true,这样就会利用socks5 主机解析域名而不通过本机设置的DNS
Tor 这个东西,我已经用了蛮久了,以前也有写过一些相关的文章。这么久以来,一直用Tor+TorCP+ Privoxy的组合,TorCP是Tor的控制面板程序,执行后在后台调用Tor,就不会出现那个DOS窗口了。而又由于IE和Firefox都不支持 sock4a(当时是这么以为的),所以使用Privoxy把Tor提供的sock4a代理端口9050转换为HTTP代理端口8118,然后在IE或 Firefox里设置HTTP代理地址为localhost:8118。
今天在研究Firefox时,在about:config里发现了一项network.proxy.socks_remote_dns,翻译成中文 就是网络.代理.socks远程DNS。看字面上的意思是说让socks代理使用远程DNS,这不就是Tor所要求的sock4a协议吗?以前看一篇文章 说过,sock4a和sock4的区别就在于:使用sock4协议,浏览器要自行进行DNS解析,而使用sock4a协议,浏览器不进行DNS解析,直接 将URL传给socks代理,由代理服务器做DNS解析。Tor作为一个通过SSL加密传输来访问网络的软件,为了避免DNS解析被封锁,所以要求浏览器 使用sock4a协议连接。以前还专门上Google查过,IE是铁定不支持sock4a,Firefox呢,查了半天也没查到有说支持sock4a的。 Firefox直接连Tor也提示协议不对,所以一直用着Privoxy做转换。
于是立刻做了个试验:修改socks代理为Tor的端口localhost:9050,随便访问了糍粑的网站,在Tor窗口里立即看到了那条熟悉的信息:
Apr 09 09:35:29.812 [Warn] Your application (using socks4 on port 80) is giving Tor only an IP address. Applications that do DNS resolves themselves may leak information. Consider using Socks4A (e.g. via privoxy or socat) instead.
然后将network.proxy.socks_remote_dns项修改为true,F5刷新页面,居然打开了糍粑的网站,Tor也没有报错。哈哈,看来Firefox是支持sock4a的,这下可以把Privoxy抛弃掉,直接用Firefox搭配Tor了。
其余的自身支持socks5的程序,linux下的如xchat,pidgin都可以正常使用。
- 不支持socks5的或者不支持代理的就不行了。这个时候需要一个代理的跳板,可以让几乎所有程序可以使用网络。linux下用tsocks(transparent socks)。windows下用scokscap之类软件。
tsocks设置:sudo $EDITOR /etc/tsocks.conf #此处$EDITOR为你的编辑器,root权限,后面的文件没有则新建
内容类似下面的:
# This is the configuration for libtsocks (transparent socks) for use
# with tor, which is providing a socks server on port 9050 by default.
#
# See tsocks.conf(5) and torify(1) manpages. server = 192.168.0.10 #这里是建立代理的机器,就是和服务器建立通道的机器,如果是建立代理的本机也可以写127.0.0.1
server_type = 5 #这里是代理类型,socks5当然写5
server_port = 7070 #端口
# We specify local as 127.0.0.0 – 127.191.255.255 because the
# Tor MAPADDRESS virtual IP range is the rest of net 127.
local = 192.168.0.0/255.255.255.0 #这里一定要设置一下你的网段,不然tsocks会提示不是本地网
#local = 192.168.0.0/255.255.255.0
测试一下:tsocks wget ip #(此处仍然不能解析DNS,所以可以用一个网站的ip试试看)。如果成功,恭喜,离胜利不远了。在需要访问网络的程序前面加上tsocks就ok了。
比如:
archlinux的更新:sudo tsocks pacman -Syu
ubuntu的更新:sudo tsocks apt-get update
- 剩 下的就是DNS了,也要建立一个本地DNS服务器。如果架设一个真正的DNS服务器就有些小题大做了,只是需要一个能解析DNS的服务。这里推荐 treewalk,本来一般是用来给本机建立DNS缓存的,但是它很大一个功能就是DNS服务器,正好符合这里要求。它也可以设置直接转发DNS,而不用 缓存DNS。
在主机上安装treewalk,安装就不多说了,没有需要解释的,安装完成重起会自动修改主机DNS服务器地址,自己启动服务。至此你已经可以比较正常的上网了。锐捷之类的客户短也不可能检测到。不过有个缺点,QQ没有办法是用,原谅我现在才说,我一开始也不知道,要怪就怪QQ只能UDP协议,而SSH貌似是TCP协议.
配置方面:
需要修改
$systemdir$\system32\dns\named.conf找到
acl “private” { 127.0.0.0/24; };添加你需要生效的网段。如
acl “private” { 127.0.0.0/24; 192.168.0.1/24; };然后找到:
listen-on port 53 { 127.0.0.1; };添加你需要的ip。如
listen-on port 53 { 192.168.0.2; 192.168.0.10; 192.168.0.11; 127.0.0.1; };然后重新启动twdns服务。可以在cmd下输入net stop twdns 然后 net start twdns
注意:
然后再把你的客户机的DNS服务器也更改为服务器的ip。192.168.0.2
- 此文件根据你自己情况修改,我是修改了这两处生效了就没有再更改了,网上有说前一个地方的,有说后一个地方的。
- 不要忘记”;”
- 重起服务才能生效
此时,在客户机测试一下,ping http://www.baidu.com 如果成功解析了域名,那么就成功了。
--------------------------------
SSH PortForwarding
Introduction
Types of Port Forwarding
Warning:
Filtering and monitoring is usually implemented for a reason. Even if
you don't agree with that reason, your IT department might not take
kindly to you flouting their rules.
|
- Local port forwarding: connections from the SSH client are forwarded via the SSH server, then to a destination server
- Remote port forwarding: connections from the SSH server are forwarded via the SSH client, then to a destination server
- Dynamic port forwarding: connections from various programs are forwarded via the SSH client, then via the SSH server, and finally to several destination servers
Local Port Forwarding
ssh -L 8080:www.ubuntuforums.org:80 <host>
ssh -L 8080:www.ubuntuforums.org:80 -L 12345:ubuntu.com:80 <host>
ssh -L 5900:localhost:5900 <host>
Remote Port Forwarding
ssh -R 5900:localhost:5900 guest@joes-pc
Dynamic Port Forwarding
ssh -C -D 1080 laptop
- go to Edit -> Preferences -> Advanced -> Network -> Connection -> Settings...
- check "Manual proxy configuration"
- make sure "Use this proxy server for all protocols" is cleared
- clear "HTTP Proxy", "SSL Proxy", "FTP Proxy", and "Gopher Proxy" fields
- enter "127.0.0.1" for "SOCKS Host"
- enter "1080" (or whatever port you chose) for Port.
- Type in about:config in the Firefox address bar
- Find the key called "network.proxy.socks_remote_dns" and set it to true
Forwarding GUI Programs
Single Applications
ssh -X laptop
firefox &
ssh -f -T -X laptop firefox
ssh -fTXC joe@laptop firefox
Nested Windows
Port Forwarding Explained
Troubleshooting
bind: Address already in use channel_setup_fwd_listener: cannot listen to port: <port number> Could not request local forwarding.
grep Forwarding /etc/ssh/sshd_config
X11Forwarding no AllowTcpForwarding nothen forwarding is disabled on your server. See the SSH configuration page for more information。
from https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding
----------------------------------------------------------------------------------------
SSH Tunneling with -L
how to forward a remote webserver to my localhost using ssh.The syntax is simple:
ssh -L localport:localhost:remoteport remoteserver
.Let me explain this in a bit more detail.
Say you’re running a webserver/service on a local or remote VM and you want to debug it locally since the VM is headless and you want to see your work in a browser. Use ssh -L. My dev machine set up is a headless CentOS VM, which is configured to be as similar to my production VM as possible. In order for me to run my code and test things out, I need to view it locally in my browser, with ssh -L I can.
Breaking it out it looks like this:
- localhost = my windows desktop
- remote server = a VM running inside VirtualBox (on my desktop)
- local port: 80
- remote port: 80
ssh -f -N -L 80:localhost:80 dev-vm
will do the following:- -f = fork process into backgroundi
- -N = don't run any commands remotely (w/o this -f will complain)
- -L = bind the remote and local port to a secure channel
Now it is great that I can see a webpage, but in my little application I’m doing a few API calls on to a server on ports that aren’t open on my firewall. Oh me oh my, how will I ever get anything done? I could call up my hosting provider and tell them to open up a port here and there, but at home I have a dynamic IP and I don’t want to start poking holes in the firewall rules.
A better option is to tunnel through my remote VM at my hosting provider, which has access to the ports I need, and access the services I need from there. Now you may be thinking, “well you really shouldn’t subvert the security measures put in place by blocking those ports” that is a valid point. However, I believe it is better to use only what you need to get the job done. One way in – one way out, through the single, secure remote VM at the hosting provider.
To illustrate a working example, let’s take this scenario: script.sh is making two calls to an API on Server A, one call goes to port 8000, the other 8443. To your dismay, both of these ports are blocked on your local network. Further, these two ports are also blocked from any traffic not coming from sanctioned IPs. Luckily, your work server, Server B is allowed to interface with Server A, and you can ssh into Server B. Problem solved, see ASCII art below for explaination.
ssh -f -N -L 8000:serverA:8000 -L 8443:serverA:8443 serverB
- L = localhost
- A = serverA
- B = serverB
<—-8000/8443—– B <—-8000/8443—– A
Now, there is one nuance which is what hung me up for a bit. Notice in my first example I was doing
80:localhost:80 dev-vm
. That bound a remote web server to
my localhost’s port 80. This situation is tunneling traffic on my localhost’s
8000/8443 ports to another ‘liberated’ machine, which does not have the ports
blocked. So, what are really saying is, any request locally to Server A
on port 8000 or 8443 must go through Server B. To get this to work properly, we
need to modify our /etc/hosts file.In this final step, we will tell our hosts file to take any request to Server A, and forward it to our localhost (127.0.0.1). So in your hosts file, add or modify the following line:
127.0.0.1 localhost
to:
127.0.0.1 localhost serverA
This will route all requests to Server A through the correct ports on Server B.
That’s all for now, next post I’ll go into my local VM set up in some detail. It may be helpful for those of you out there that are forced to use Windows at work and want to replicate your production environment locally.
P.S. I switched over to my laptop…typing on the iPad isn’t so great when you want to keep speed. Maybe it will be better if I do it with my wireless keyboard.
UPDATE: fixed syntax on compound ssh command – replaced ‘serverB’ in the middle with -L.
-------------------------------------------------------------------------------------------
配置ssh的无密码登录
# ssh-keygen -t rsassh虽然无须再输入用户密码,但如果你在生成key pair时,设置了私钥的passphrase,那么仍然要输入私钥的passphrase,这和输入ssh用户的密码一样麻烦,幸好托ibm的福,大牛Daniel Robbins为我们介绍了使用ssh-agent和keychain免去输入密码之烦的方法,不过应该不适用于我们这样经常需要开关机的情况,所以,只好回到第一步,生成一对没有passphrase的密钥来用,虽然安全性下降了些,倒是非常方便。
安全建议
- 如果条件允许,使用带有passphrase的密钥,配合ssh-agent和keychain使用。
- 如果需要从不同的计算机登录服务器,最好使用不一样的密钥对。
- 记得定期更换密钥对,切记。
参考
- AdvancedOpenSSH
- 通用线程: OpenSSH 密钥管理,第 1 部分 – 理解 RSA/DSA 认证
- 通用线程: OpenSSH 密钥管理,第 2 部分 – 介绍 ssh-agent 和 keychain
- RSA/DSA authentication on SSH
--------------------------------------------------
ssh通过http proxy或者socks proxy连接服务器
直接上命令:
# http代理
ssh -o ProxyCommand="nc -X connect -x 127.0.0.1:3128 %h %p" root@<server_ip>
# socks代理
ssh -o ProxyCommand="nc -X 5 -x 127.0.0.1:1080 %h %p" root@<server_ip>
说明:
nc命令的常用参数:
-X是指定代理协议
4是socks4协议
5是socks5协议
-x是指定代理服务器和端口[代理服务器:端口]
默认socks使用1080
HTTPS使用3128