Showing posts with label Tutorial. Show all posts
Showing posts with label Tutorial. Show all posts

Wednesday, January 21, 2015

Reverse SSH Tunnel on Linux

Reverse SSH is a technique that can be used to access systems (that are behind a firewall) from the outside world.
As you already know SSH is a network protocol that supports cryptographic communication between network nodes. Using this protocol, you can do a secure remote login, secure copy from/to a remote machine etc.

You’ll typically do the following to connect to a remote server securely using ssh command.
$ ssh [your-account-login]@[server-ip]

What is Reverse SSH?

SSH is very good tool to access remote machine or server securely. But, the problem arises when you try to connect to a remote server which is behind a firewall and this firewall denies any incoming connection or data transfer request that has no prior outgoing request. This means that only those connections would be allowed which are initiated by the remote server machine. This is a real problem for those who want to access this server machine remotely.
Reverse SSH provides a technique through which you can simulate a normal SSH to this remote server machine.
The main problem is that firewall is rejecting ssh connection that your machine is trying to establish with remote server machine. But you know that the same firewall will not have any problem with the connections originating from server machine. So, why not ask some one who is sitting behind the firewall to do something with which you can achieve your goal of remotely accessing the server. To do this we have to use ssh -R option.
This is the description of the ssh -R option from the man page:
-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.
So you can use ssh command, with -R option, (from server in our case) to connect to your machine, allocate a port there and make sure that any connection request on that port is forwarded to ssh port of the remote server.
Instead of your machine doing an ssh, the server machine does an ssh and through port forwarding makes sure that you can ssh back to server machine.

How to Create a Reverse SSH Tunnel?

Here is the command your friend sitting on remote server side should run on the server :
ssh -fN -R 7000:localhost:22 username@yourMachine-ipaddress
So this ssh connection request originating from remote server to your machine will make sure that any ssh connection request for port 7000 on your machine is forwarded to port 22 of remote server.
Now do an ssh connection request from your machine to your own machine at port 7000:
ssh username@localhost -p 7000
Here, though it may seem like you are doing ssh on localhost but your request would be forwarded to remote host. So, you should use your account ‘username’ on remote server and when prompted for password, enter the corresponding password.
This should clear most of the aspects related to reverse ssh technique. But, there is one catch. The catch is that you have to ask a friend of yours — who is sitting behind the firewall — to create an ssh connection first. This is not feasible every time.
To overcome this problem, what you can do is that you can set up a machine which is out of firewall (just like yours) in a way that it is always on. Lets call this machine as machine_z.
The benefit of machine_z is that you can once do this reverse ssh set up on it and leave it like this. At any point of time, when you need to login to remote machine, you can ssh into machine_z on a specified port (as shown earlier) and your connection request will be forwarded to remote server machine and Voila, you will be running commands on remote server.
On a related note, you can also setup no password SSH to connect to another server without entering the password.
Some settings that you need to configure on machine_z would include :
  • Make sure that the parameters TCPKeepAlive, ClientAliveInterval, ClientAliveCountMax and GatewayPorts are set to appropriate values. These parameters are found in /etc/sshd_config or /etc/ssh/sshd_config file
  • If you make some changes to above parameters, you should restart sshd daemon to reflect the changes.
  • Also, make sure that you run the first ssh command (that is executed from the remote server to machine_z) using nohup command so that this ssh session becomes immune to hangups which can happen when a user logs out.

SSH Tunneling on Linux, Unix or BSD Server to bypass NAT

How can I set encrypted tunnel between my desktop/laptop computer and server in a remote data center to bypass the limits in a network? How do I create a reverse SSH tunnel on Unix-like systems?

SSH tunnelling can be thought as a poor-man's-VPN. It is handy in situations where you would like to hide your traffic from any body who might be listening on the wire or eavsdropping. 

You can use such tunnel between your computer and your Unix/BSD/Linux server to bypass limits placed by a network or to bypass NAT, and more.

More about the Internet protocol, ports, tcp and udp

The Internet protocol is nothing but a set of rules for sending information between your desktop and the server on the Internet (or WAN or Lan). Each computer at least has one IP address. Each rule is like a language and in computer science you call it as a protocol. One can use protocols for communication over the Internet.

Common application protocol

For example, you can use HTTP (Hypertext Transfer Protocol) or HTTPS (Hypertext Transfer Protocol Secure) protocol to view images or download files from the Internet. You can use DNS (Domain Name System) protocol translates domain names such as www.cyberciti.biz, which can be easily memorized by humans, to the numerical IP addresses such as 75.126.153.206 and vice versa. You can use ssh (Secure Shell) for secure data communication, remote command-line login, remote command execution, and more.

Our sample setup

                        ///////////
                       //Internet//
                       ////////////
                            |
     +---------------+      |       +-------------+
     | Unix/Linux    |      |       | Linux/Unix  |
     | Server with   +------+-------+ OSX/*BSD    |
     | OpenSSH SSHD  |              | Client      |
     +---------------+              +-------------+
       randomhost.net            client1.cyberciti.biz
     75.126.153.206                  192.168.1.42
                               (loopback interface 127.0.0.1)
Where,
  • randomhost.net - You have an accounts on this Linux/Unix based server.
  • client1.cyberciti.biz - Your private desktop/laptop computer that you use to connect to server1.cyberciti.biz server. You need to use loopback interface with the IP address 127.0.0.1. Only apps installed on the desktop such as browser, irc client, email client and more have access to 127.0.0.1.

Example: SSH tunnel for an IRC client

A tunnel between local port 8888 on the local interface (IP 127.0.0.1) and the IRC server at irc.freenode.net, bound to a remote machine's port 6667. You are going connect to it using the loopback interface:
                        ///////////
                       //Internet//
                       ////////////
                            |
     +---------------+      |       +-------------+
     | Unix/Linux    |      |       | Linux/Unix  |
     | Server with   +------+-------+ OSX/*BSD    |
+----+ OpenSSH SSHD  |              | Client      |
|    +---------------+              +-------------+
|      randomhost.net            client1.cyberciti.biz
|    75.126.153.206                  192.168.1.42
|                              (loopback interface 127.0.0.1:8888) <=== SSH client
|
|       +-----------------------+
+-------+ irc.freenode.net:6667 |
        +-----------------------+
If you login to your shell account with: ssh myuser@randomhost.net for SSH tunnelling you have to add additional arguments. It goes like this:
 
ssh -L 8888:irc.freenode.net:6667 myuser@randomhost.net
 
If the server/shell account you are using to tunnel through is listening on a different port, for example 2745, it would be written like this:
 
ssh -p2745 -L8888:irc.freenode.net:6667 myuser@randomhost.net
 
This will open a tunnel between your computer to irc.freenode.net through your shell account on randomhost.net. All traffic will go through your shell account box as encrypted SSH traffic before reaching irc.freenode.net. Your computer now acts like a irc server listening to port 8888. Replace it with any ports you want above 1024 to avoid conflict.
To connect to your local port as if it's irc server. On irssi this would be:
  /server 127.0.0.1 8888
This will also apply for any other irc clients such as X-Chat. Use 127.0.0.1/8888 for server name and you are good to go. Other fields remain the same.

Howto setup a reverse SSH tunnel

In a scenario where a machine is behind NAT or company firewall a normal SSH tunnel won't work. To overcome this, we have to make use of reverse SSH tunnel. To achieve this, you need an internet reachable box along with the machine behind NAT/firewall. During this guide we will call the machine behind NAT/firewall a NATbox and internet reachable machine an OPENbox.
For reverse SSH Tunnel, there are basically three ports involved. One is the SSH port of workstation, we use it forward the reverse tunnel port into it. The second, is the reverse tunnel port which gets forwarded to workstation's SSH port. The third, is the SSH port of the public box, we need that port to SSH into public box.
From outside if you use public box's SSH port, you log in to that box. If you use reverse tunnel port you get forwarded to workstation. You must be careful about usernames when doing this.
public box ip + public box SSH port + public box username -> access to public box
public box ip + reverse tunnel port + workstation username -> access to workstation
To establish reverse tunnel from workstation, you will use:
public box ip + public box SSH port + public box username 
And setup the reverse tunnel on a different random port and forward it to local SSH port.
To further protect the SSH daemon, you can implement port knocking where the SSH port is blocked by default and when you send special packets the port is opened for you. You can have the SSH port opened for certain IPs.

Example

So, let us consider, OPENbox is listening to SSH on port 1234. Type following on NATbox:
 
ssh -p1234 -R 5555:localhost:22 openboxuser@OPENbox.example.com
 
This will initiate a connection from behind the NATd/firewalled box to the publicly reachable box listeing to SSH on port 1234. Once the connection is established it will create a reverse tunnel at port 22 for the remote party to connect and get in. Type the following command on OPENbox:
 
ssh  -p5555 natboxuser@localhost
 
Since the NATd/firewalled box has an established connection to OPENbox, the tunnel will go through the same channel. In addition, type the following from anywhere else to access NATbox which will tunnel the traffic through OPENbox:
 
ssh -p5555 natboxuser@OPENbox
 
This requires an additional setup on the OpenSSHD server, add the lines to/etc/ssh/sshd_config
 GatewayPorts yes
Save and close the file. Make sure you restart/reload the SSHD on the remote server.

Summary

The syntax is as follows to access remote server port without modifying firewall settings:
 ## Syntax ##
ssh -f -L {local-port}:localhost:{remote-server-port} user@remote.server-name-here.org
 
# Use port 8888 on the localhost to connect to port 4444 on host foo for user bar and run in the background#
# Use port 8888 for your apps such as firefox, xchat, and more #
ssh -D 8888 -f -C -q -N -p 4444 foo@bar &
 
Where,
  1. -f : Requests ssh to go to background just before command execution.
  2. -L port : Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.
  3. -p port : Port to connect to on the remote host.
  4. -R : Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.
  5. -D port: Specifies a local "dynamic" application-level port forwarding.
  6. -C : Requests compression of all data. This is useful for speeding up connection.
  7. -q : Quiet mode. Causes most warning and diagnostic messages to be suppressed.
  8. -N: Do not execute a remote command. This is useful for just for warding ports.
For more information see man pages: ssh(1)sshd_config(5)ssh_config(5).

Make your Raspberry PI a Web Cam Server

The Raspberry PI is perfectly equipped to turn your USB based web cam into a fully functional IP web cam that you can have lots of fun with, from there you could use tools such as Python to make your project more unique, im having a go at counting passing traffic.
If your wanting to something a bit more simple you could just have a web cam that can be access from anywhere with an internet connection, which is what you will end up with at the end of this guide.
Your shopping list…
  • Raspberry Pi with an OS installed – Amazon US
  • USB Powered Hub – Amazon US
    • Important; This one worked for me, however it’s not worked for others, you will find this is the case with a lot of the powered USB hubs, research before buying.
    • We need a hub because the camera’s draw more power than the Raspberry Pi can actually provide, you see the same with some keyboards and USB dongles.
  • Web Cam
    • PS3 Eye Toy –  Amazon US
    • Microsoft HD –  Amazon US
You could also look at an external power back and WiFi if you want to make it mobile, a few people have put these in a garden or somewhere without a static power/network source.
1. Get the software ready
Ok so I am going to assume that you have a working PI on some kind of LAN with internet access, the next step as always is to update your PI ensuring you have the latest software and drivers installed.
?
1
2
sudo apt-get update
sudo apt-get upgrade
Now we need to install the software, we are going to be using a great little application called Motion, this will do a few things for us including accessing the USB cam, getting the images, and streaming them via a built in web server. As the name suggests it will also track and trigger events on motion been detected in the video frames (more on that later).
?
1
sudo apt-get install motion
2. Plug in your web cam
So now the software is on there it’s time to plug in the web cam and ensure that everything is working, ensuring that you plug it into the powered hub, and then into the PI. Otherwise the webcam will not get enough power to turn on.
When plugged in type the “lsusb” command, you should see a line there with your web cam manufacture, that proves that you have the basic connectivity working.
?
1
2
3
4
lsusb
....
Bus 001 Device 002: ID 04ea:1142 Microsoft Corp.
....
3. Configure the software
?
1
sudo nano /etc/motion/motion.conf
In here there are a few basic changes that you need to perform:
  • Daemon = OFF to ON
  • webcam_localhost = ON to OFF
You can change other settings but it’s recommend you don’t take more than 2 frames, and you been the default frame pixel size, for stability.
4. Start the software
To ensure that the motion service will actually start as a daemon we need to change another configuration setting, so enter the following:
sudo nano /etc/default/motion
Then change the value “start_motion_daemon=no” to “yes”
Finally you can start the motion service to stream the web cam images
?
1
sudo service motion start

http://192.168.0.100:8081
Then after about 30 seconds browse to the new web interface, which should be at the below URL (where 192.168.0.100 is your Raspberry PI’s IP address)
5. Final Tweeks
Web Port
You could change the web interface port to 80 (from the default 8081), so that you can just browse to the IP address without having to put :8081 at the end, it’s really simple to do, just:
?
1
sudo nano /etc/motion/motion.conf
And then change “webcam_port 8081″ to “webcam_port 80″, save the file, and restart the motion service.
?
1
sudo service motion restart
Port Forwarding
Final suggestion is enable port forwarding on your home broadband router to the Raspberry PI on port 80, that will mean you can access the web cam from anywhere in the world. There are too many routers in the word to explain how to do it here, but I am sure you will find some help on Google, if not please just leave a comment.
Warning; If you give it internet access via port forwarding this does take up quite a bit of bandwidth, and anyone can see your webcam feed, so only show what you want people to see.