ssh tunnel可以在加密的通道上传输未加密的通讯。其一大功效就是翻墙,很多公司都只开放了80端口,如果你和家里的ssh server 建立了ssh tunnel, 那你就可以把本地的某端口映射到外网的某服务器的某一不准访问的端口
端口映射有三种方式
- Local port forwarding
- Remote port forwarding
- Dynamic port forwarding
Tunnelling with Local port forwarding
比如公司不让上yahoo.com,那可以使用以下命令
1
| ssh -L 9001:yahoo.com:80 home |
此时公司的ssh client将连到家里的ssh server, 通常是端口22,如果不是就用 -p 来指定, 公司电脑将监听本地的9001端口,通过公司和家里的电脑建立的 ssh tunnel, 家里的电脑会去连接yahoo.com的80端口,所以此时你只要访问 http://localhost:9001 就可以上yahoo网站了
这种用法的格式是
这种用法的格式是
1
| ssh -L < local -port-to-listen>:<remote-host>:<remote-port> <gateway> |
举例1, 如果你想用vnc连家里电脑
1
| ssh -L 5900:localhost:5900 home |
显然 如果你公司已经给你机器装了vnc,那你左边那个5900得随便换一个别的。中间的localhost指的是相对家里而言的,所以他是家里的电脑本身(如果家里的ssh server在路由器上,那这里的localhost可以换成你的ddns域名,然后在路由器上映射5900到你的电脑上)
举例2,如果你想访问一台不能直接ssh的电脑,但是家里的电脑可以,那你可以先建ssh tunnel到家里的电脑,在此已有通道基础上再ssh到目的地
首先
1
| ssh -L 9001:banned:22 home |
然后
1
| ssh -p 9001 localhost |
Reverse Tunnelling with remote port forwarding
现在假设你想在家里连回公司,当然你可以用vpn,但是作为一个屌丝小职员,公司是不会给你vpn帐号的。
前一个例子里ssh tunnel 是从公司里的防火墙后的电脑发起的,因为从外面进来的通讯被组织了 但是从里面出去的通讯是允许的。而现在client端是在家里的,-R可以指定反向tunnel
1
| ssh -R 9001:intra-site.com:80 home |
这行运行完之后,访问家里的电脑的9001端口就相当于 访问公司内网地址 intra-site.com
以上方法都是 要访问一个站就加一条,下面是自动方法
Dynamic Port Forwarding
这种方法可以只用一个端口,把所有的通讯转向家里的电脑,此时公司的电脑会建立一个 SOCKS proxy,只要把浏览器或其他软件如qq的代理服务器里填入相应的SOCKS proxy就可以了(填localhost 9001)
ssh -D 9001 home
待续
SSH Tunneling Explained
How does reverse SSH tunneling work?
Bypassing corporate firewall with reverse ssh port forwarding
SSH Tunneling Explained
How does reverse SSH tunneling work?
Bypassing corporate firewall with reverse ssh port forwarding
本来下面的连接是适用于路由器的情况,但是我现在的tomato默认的dropbear的ssh client不支持 -D 参数,可以自己装optware然后装openssh,好麻烦,我没有实验,我准备直接在pc机上装openssh,这样简单些…当然pc得一直开着….
Using SSH as a reverse tunnel。
Using SSH as a reverse tunnel。
----------------
SSH Tunneling Explained
Recently I wanted to set up a remote desktop sharing session from home pc to my laptop. While going through the set up guide I came across ssh tunneling. Even though there are many articles on the subject still it took me a considerable amount of googling, some experimenting and couple of Wireshark sessions to grasp what’s going under the hood. Most of the guides were incomplete in terms of explaining the concept which left me desiring for a good article on the subject with some explanatory illustrations. So I decided to write it my self. So here goes…
Introduction
A SSH tunnel consists of an encrypted tunnel created through a SSH protocol
connection. A SSH tunnel can be used to transfer unencrypted traffic over a
network through an encrypted channel. For example we can use a ssh tunnel to
securely transfer files between a FTP server and a client even though the FTP
protocol itself is not encrypted. SSH tunnels also provide a means to bypass firewalls that prohibits or filter certain internet services. For example an organization will block certain sites using their proxy filter. But users may not wish to have their web traffic
monitored or blocked by the organization proxy filter. If users can connect to
an external SSH server, they can create a SSH tunnel to forward a given port on
their local machine to port 80 on remote web-server via the external SSH
server. I will describe this scenario in detail in a little while.
connection. A SSH tunnel can be used to transfer unencrypted traffic over a
network through an encrypted channel. For example we can use a ssh tunnel to
securely transfer files between a FTP server and a client even though the FTP
protocol itself is not encrypted. SSH tunnels also provide a means to bypass firewalls that prohibits or filter certain internet services. For example an organization will block certain sites using their proxy filter. But users may not wish to have their web traffic
monitored or blocked by the organization proxy filter. If users can connect to
an external SSH server, they can create a SSH tunnel to forward a given port on
their local machine to port 80 on remote web-server via the external SSH
server. I will describe this scenario in detail in a little while.
To set up a SSH tunnel a given port of one machine needs to be forwarded (of
which I am going to talk about in a little while) to a port in the other
machine which will be the other end of the tunnel. Once the SSH tunnel has been
established, the user can connect to earlier specified port at first machine to
access the network service.
which I am going to talk about in a little while) to a port in the other
machine which will be the other end of the tunnel. Once the SSH tunnel has been
established, the user can connect to earlier specified port at first machine to
access the network service.
Port Forwarding
SSH tunnels can be created in several ways using different kinds of port forwarding
mechanisms. Ports can be forwarded in three ways.
mechanisms. Ports can be forwarded in three ways.
- Local port forwarding
- Remote port forwarding
- Dynamic port forwarding
I didn’t explain what port forwarding is. I found Wikipedia’s definition more explanatory.
Port forwarding or port mapping is a name given to the combined technique of
- translating the address and/or port number of a packet to a new destination
- possibly accepting such packet(s) in a packet filter(firewall)
- forwarding the packet according to the routing table.
Here the first technique will be used in creating an SSH tunnel. When a client application connects to the local port (local endpoint) of the SSH tunnel and transfer data these data will be forwarded to the remote end by translating the host and port values to that of the remote end of the channel.
So with that let’s see how SSH tunnels can be created using forwarded ports with an examples.
Tunnelling with Local port forwarding
Let’s say that yahoo.com is being blocked using a proxy filter in the University.
(For the sake of this example. . Cannot think any valid reason why yahoo would be blocked). A SSH tunnel can be used to bypass this restriction. Let’s name my machine at the university as ‘work’ and my home machine as ‘home’. ‘home’ needs to have a public IP for this to work. And I am running a SSH server on my home machine. Following diagram illustrates the scenario.
(For the sake of this example. . Cannot think any valid reason why yahoo would be blocked). A SSH tunnel can be used to bypass this restriction. Let’s name my machine at the university as ‘work’ and my home machine as ‘home’. ‘home’ needs to have a public IP for this to work. And I am running a SSH server on my home machine. Following diagram illustrates the scenario.
To create the SSH tunnel execute following from ‘work’ machine.
1
| ssh -L 9001:yahoo.com:80 home |
The ‘L’ switch indicates that a local port forward is need to be created. The switch syntax is as follows.
1
| -L < local-port-to-listen >:< remote-host >:< remote-port > |
Now the SSH client at ‘work’ will connect to SSH server running at ‘home’ (usually running at port 22) binding port 9001 of ‘work’ to listen for local requests thus creating a SSH tunnel between ‘home’ and ‘work’. At the ‘home’ end it will create a connection to ‘yahoo.com’ at port 80. So ‘work’ doesn’t need to know how to connect to yahoo.com. Only ‘home’ needs to worry about that. The channel between ‘work’ and ‘home’ will be encrypted while the connection between ‘home’ and ‘yahoo.com’ will be unencrypted.
Now it is possible to browse yahoo.com by visiting http://localhost:9001 in the web browser at ‘work’ computer. The ‘home’ computer will act as a gateway which would accept requests from ‘work’ machine and fetch data and tunnelling it back. So the syntax of the full command would be as follows.
1
| ssh -L < local-port-to-listen >:< remote-host >:< remote-port > < gateway > |
The image below describes the scenario.
Here the ‘host’ to ‘yahoo.com’ connection is only made when browser makes the
request not at the tunnel setup time.
request not at the tunnel setup time.
It is also possible to specify a port in the ‘home’ computer itself instead of
connecting to an external host. This is useful if I were to set up a VNC session
between ‘work’ and ‘home’. Then the command line would be as follows.
connecting to an external host. This is useful if I were to set up a VNC session
between ‘work’ and ‘home’. Then the command line would be as follows.
1
| ssh -L 5900:localhost:5900 home (Executed from 'work') |
So here what does localhost refer to? Is it the ‘work’ since the command line is executed from ‘work’? Turns out that it is not. As explained earlier is relative to the gateway (‘home’ in this case) , not the machine from where the tunnel is initiated. So this will make a connection to port 5900 of the ‘home’ computer where the VNC client would be listening in.
The created tunnel can be used to transfer all kinds of data not limited to web browsing sessions. We can also tunnel SSH sessions from this as well. Let’s assume there is another computer (‘banned’) to which we need to SSH from within University but the SSH access is being blocked. It is possible to tunnel a SSH session to this host using a local port forward. The setup would look like this.
As can be seen now the transferred data between ‘work’ and ‘banned’ are encrypted end to end. For this we need to create a local port forward as follows.
1
| ssh -L 9001:banned:22 home |
Now we need to create a SSH session to local port 9001 from where the session
will get tunneled to ‘banned’ via ‘home’ computer.
will get tunneled to ‘banned’ via ‘home’ computer.
1
| ssh -p 9001 localhost |
With that let’s move on to next type of SSH tunnelling method, reverse tunnelling.
Reverse Tunnelling with remote port forwarding
Let’s say it is required to connect to an internal university website from home.
The university firewall is blocking all incoming traffic. How can we connect from ‘home’ to internal network so that we can browse the internal site? A VPN setup is a good candidate here. However for this example let’s assume we don’t have this facility. Enter SSH reverse tunnelling..
The university firewall is blocking all incoming traffic. How can we connect from ‘home’ to internal network so that we can browse the internal site? A VPN setup is a good candidate here. However for this example let’s assume we don’t have this facility. Enter SSH reverse tunnelling..
As in the earlier case we will initiate the tunnel from ‘work’ computer behind the firewall. This is possible since only incoming traffic is blocking and outgoing traffic is allowed. However instead of the earlier case the client will now be at the ‘home’ computer. Instead of -L option we now define -R which specifies
a reverse tunnel need to be created.
a reverse tunnel need to be created.
1
| ssh -R 9001:intra-site.com:80 home (Executed from 'work') |
Once executed the SSH client at ‘work’ will connect to SSH server running at home creating a SSH channel. Then the server will bind port 9001 on ‘home’ machine to listen for incoming requests which would subsequently be routed through the created SSH channel between ‘home’ and ‘work’. Now it’s possible to browse the internal site
by visiting http://localhost:9001 in ‘home’ web browser. The ‘work’ will then create a connection to intra-site and relay back the response to ‘home’ via the created SSH channel.
by visiting http://localhost:9001 in ‘home’ web browser. The ‘work’ will then create a connection to intra-site and relay back the response to ‘home’ via the created SSH channel.
As nice all of these would be still you need to create another tunnel if you need to connect to another site in both cases. Wouldn’t it be nice if it is possible to proxy traffic to any site using the SSH channel created? That’s what dynamic port forwarding is all about.
Dynamic Port Forwarding
Dynamic port forwarding allows to configure one local port for tunnelling data to all remote destinations. However to utilize this the client application connecting to local port should send their traffic using the SOCKS protocol. At the client side of the tunnel a SOCKS proxy would be created and the application (eg. browser) uses the SOCKS protocol to specify where the traffic should be sent when it leaves the other end of the ssh tunnel.
1
| ssh -D 9001 home (Executed from 'work') |
Here SSH will create a SOCKS proxy listening in for connections at local port
9001 and upon receiving a request would route the traffic via SSH channel
created between ‘work’ and ‘home’. For this it is required to configure the
browser to point to the SOCKS proxy at port 9001 at localhost。
9001 and upon receiving a request would route the traffic via SSH channel
created between ‘work’ and ‘home’. For this it is required to configure the
browser to point to the SOCKS proxy at port 9001 at localhost。
from https://chamibuddhika.wordpress.com/2012/03/21/ssh-tunnelling-explained/
--------------
80
78
|
As I understand this, firewalls (assuming default settings) deny all incoming traffic that has no prior corresponding outgoing traffic.
Based on Reversing an ssh connection and SSH Tunneling Made Easy, reverse SSH tunneling can be used to get around pesky firewall restrictions.
I would like to execute shell commands on a remote machine. The remote machine has its own firewall and is behind an additional firewall (router). It has an IP address like 192.168.1.126 (or something similar). I am not behind a firewall and I know the remote machine's IP address as seen from the Internet (not the 192.168.... address). Additionally, I can ask someone to execute
ssh (something) as root on the remote machine first.
Could anyone explain me, step by step, how reverse SSH tunneling works to get around the firewalls (local and remote machines' firewalls and the additional firewall between them)?
What is the role of the switches (-R, -f, -L, -N)?
--------------
Bypassing corporate firewall with reverse ssh port forwarding
Probably lots of you are behind some sort of very restrictive corporate firewall. Unable to access your office pc from home because of firewall policies. In normal cases this scenario is more than welcomed. No outsiders should be allowed to access internal parts of secure network! Ideally companies will setup secure VPN access thus allowing its employees to access their work computers and do some work remotely. What if you aren't one of the lucky ones having such option? You desperately need to access your office pc?
The problem
As shown on the picture above, we have our office PC behind very restrictive corporate firewall connected to Internet. Firewall will not allow any traffic originating from Internet to internal network except previously initiated traffic. Meaning you can contact remote hosts on Internet from your office PC and they can respond, but remote computers can't initiate connection to your office PC. This is of course huge problem if you have to access your work materials on office PC from your home. Additionally corporate firewall will only allow certain traffic from your office PC to remote hosts. Meaning you can only establish FTP, SSH, HTTP, POP3... communications, all other ports are blocked. So how can you access your office PC? One way is to setup corporate VPN access allowing secure connections to internal network. Another method is to setup a port forwarding on corporate firewall so it redirects certain ports to your office PC. But if you don't have the means to accomplish any of this then the only way to do it is to use ssh tunnels and reverse port forwarding.
The solution
So if we can only contact remote hosts on certain ports, the solution would be to contact remote hosts via allowed port and piggyback the connection on already established link. Something like shown on the picture above. Fortunately we can do this with ssh, all we need to do is met some requirements.
Real life example
I will assume that home PC is connected via dynamically assigned IP address. First thing you will need to make sure you have ssh server installed on your home PC and it should be accessible from Internet. If you have some NAT routers, be sure to forward port 22 to your home PC. Secondly you will need to setup a dyndns account so you can connect to your home PC regardless of IP address changes. Now the goal will be to connect to ssh server on our office PC. so the port in question will be 22 if you wish to forward another port change it in your configuration accordingly. For the purpose of this example i will name my home PC: bhome.dyndns.com office computer name will be bwork.office.com bwork computer uses private IP range of 192.168.0.0/24 with address 192.168.0.100 So if the firewall is preventing outside connections to our bwork computer we must initiate connection from it. We can do this with simple ssh command:
ssh -R 2210:localhost:22 bhome.dyndns.com
So what just happened here? We are initiating ssh connection "ssh" with reverse port forwarding option "-R" which will then open listening port "2210:" who is going to be forwarded back to localhost's port ":22" and all this will happen on remote computer "bhome.dyndns.com". This connection represents the green line in the diagram above, and it's a legit connection as far as corporate firewall is concerned. So if we now open up a terminal on bhome computer, and type in:
ssh -p 2210 localhost
we will try to connect to localhost (bhome.dyndns.com) on port 2210. Since that port is setuped by remote ssh connection it will tunnel the request back via that link to the bwork.office.comcomputer. This is the red line on the diagram above. Looking from firewall's perspective it's a legit traffic, since it is responding traffic on already initiated link from bwork computer.
Real life example 2
What if your home computer is not always on-line? Or perhaps you wish to access your office computer from multiple locations? For this you will have to have some dedicated server or VPS outside the corporate firewall. So to accomplish this we will use the same command as previously, only this time we will open up a reverse ssh tunnel to remote server or VPS. For the purpose of this example we will name the server bserver.outside.com with IP 89.xxx.xx.4
ssh -R 2210:localhost:22 bserver.outside.com
again this will open up reverse ssh tunnel to the machine 89.xxx.xx.4 (bserver.outside.com). So when we login to the server and issue the command:
ssh -p 2210 localhost
we will end up with bwork computer's ssh login prompt.
Can I use this previously established reverse ssh tunnel to the server to directly connect to my office computer?
Of course, but some slight modifications are required. By default ssh tunnels only bind to local address, and can be accessible only locally. Meaning, in the example above, you can't just type:
ssh -p 2210 bserver.outside.com
on your home PC and be connected to your office PC If you run:
netstat -ntl
on bserver you will see that the port 2210 is only listening on 127.0.0.1 IP address. To get it listen on interface connected to Internet we must enable GatewayPorts option in ssh server's configuration. By default GatewayPorts are disabled in sshd, we can simply enable them:
nano /etc/ssh/sshd_config
then add:
GatewayPorts clientspecified
save the file and restart sshd:
/etc/init.d/ssh restart
we could have just enable GatewayPorts by typing On instead of clientspecified, that would route any ssh tunnel to network interface. This way we can control which tunnel will be accessible from outside, and on which interface. So if we initiate reverse ssh tunnel like this:
ssh -R 89.xxx.xx.4:2210:localhost:22 bserver.outside.com
we will have bserver listening on port 2210 on network interface bound to ip 89.xxx.xx.4 and forwarding all traffic via established tunnel to bwork computer. If you omit the 89.xxx.xx.4 address from the command above server will again listen on port 2210 only on local loopback interface. If you have multiple network interfaces on server be sure to select the one you can connect to. So now when we run:
ssh -p 2210 bserver.outside.com
from our home PC we will initiate ssh connection on port 2210 towards server bserver.outside.com (blue line). Server will then forward that traffic to office PC (red line) via the previously established reverse ssh tunnel (gren line). Of course you will have to open up port 2210 on server's firewall to be able to connect.
Some more fun with reverse tunnels.
But i have a printer behind that corporate firewall. How can i connect to it? Easy... remember the first example? the command ssh -R is taking 5 arguments of which 4 are mandatory
ssh -R [bind_address:]port:host:hostport
bind_address is the network address on which port will be listening, and forwarded to host(connected to network from which reverse tunnel originated) on hostport. so if we issue the command like this on our bwork pc:
ssh -R 89.xxx.xx.4:2211:192.168.0.10:631 bserver.outside.com
we will get something like this: so again we have previously established reverse ssh tunnel listening on port 2210 to channel the ssh connection towards office PC. Now with this new command we established the reverse ssh tunnel (yellow line) towards bserver which will listen for incoming connections on port 2211. When the home pc makes a data connection to port 2211 on bserver (brown line) it is then forwarded to office PC (black line) which is then redirected towards office printer at address 192.168.0.10 on port 631 (violet line). Remember, all this traffic is passing trough corporate firewall as legit traffic, even if the illustration perhaps shows otherwise.
Automating the task
So by now we should have covered the basics on how to bypass corporate firewall in order to get to your office computer and network equipment. Now ssh -R isn't really practical, it consumes one terminal, and as soon as it shuts down there is no tunnel and no outside connectivity for that matter. The easiest thing to do is putting a cron job that will connect to remote server if the connection fails, office computer reboots etc. First of all generate ssh keys, and add them to ssh-agent so that script won't ask you for remote server's password all the time. Next we will add two extra parameters to our command -N and -f so that the connection goes into the background. the command will look like:
ssh -N -f -R [bind_address:]port:host:hostport
next we need a shell script that will be triggered by the cron. For this example we will use the Real life example 2.
#!/bin/sh COMMAND="ssh -N -f -R 89.xxx.xx.4:2210:localhost:22 bserver.outside.com" pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND
now edit this code so it suits your needs, and save it in your home dir as reverse_ssh_tunnel.sh Now we need to add a crontab entry which will trigger this script every 5 minutes.
crontab -e
and add:
*/5 * * * * /bin/sh /home/username/reverse_ssh_tunnel.sh
If you are connecting to different user name on remote server you can edit your commands so they look like: ssh -R [bind_address]:port:host:host_port username@remote_host
|