Saturday, April 28, 2012

How to do SSH Tunneling (Port Forwarding) - Screen-cast

In this post we will see how ssh works?, what is SSH tunneling? what is important of ssh tunnels and how to setup the ssh tunnel.
When SSH server is installed in machine then by default its allowed ssh tunneling.

SSH Tunneling (Port Forwarding)
Tunneling is the concept to encapsulate the network protocol to another protocol. here we put into SSH. so all network communication are encrypted. It also called Port Forwarding. because in ssh tunneling we are going to bind one local port. so what are the packet we are going to send that particular port, all packets are transparently encrypt and delivered to remote system.

What is the need for SSH Tunneling?

     SSH is enough to administrate the remote system. its not enough to access the all services which are available in remote system.
let i describe in the following scenario,

now lets consider the scenario, System ( is my system its connected to internet and server its called PrivateServer (  machine have two Ethernet interfaces. one is connected to Internet. and another is connected to local network. Intranet ( machine is part of  sub network.

Note : here i mentioned local system( and remote system( are looking like local sub-net IP address. For VM purpose i used these IP address. But reality is it should be any public IP address.

Important Note : SSH Server daemon service is running in port 22 in all these three system and firewall is allowed to connect these system using SSH client.

now System ( can communicate to PrivateServer (, because both system are connected to internet directly. But System ( can't communicate to Intranet ( machine, because from System ( perspective is non route able IP address. is not public IP address, its local IP address. so we can't route the packets directly.

Now the situation like that from System( i want to access the Intranet ( machine. without modifying IP tables, redirect, like tools/services in intermediate (or) target machine. Because i m not sys-admin, so i don't have root privilege. 

One of the possible solution is first use ssh to log in into PrivateServer( and then again (nested) log in  to Intranet( Yes its good idea, its works, now i can remotely administrate the Intranet( but if Intranet( offer some services like VNC, Apache httpd, smtp, pop3, squid proxy then how we can access these services from System(

here its not strictly Intranet( offer these service, it may be sub net any one of the machine can offer these services. Even in sub-net have one intranet-website. how we can access these site from System( machine Firefox?

The solution is SSH Tunneling or SSH Port Forwarding

How SSH Works

            In terminal when we type ssh [email protected]  then terminal application invoke the ssh client, ssh client connect to's SSH server in port 22. then both client and server exchange the identity,  public keys, cipher suite information and create one shell process in server side. then secure channel is established between client and server. then future all commands from 192.168.101 are go through this secure channel to server ( and execute the command and the response are come back in same secure channel. 

For example after establish ssh, i will issue the ls command. the ls command goes to SSH client then that command encapsulate and encrypted then send to server. Server decrypt and extract the command and execute the command in shell (which is created when ssh is established), the output of ls command is not printed in shell. Its redirect the output to SSH client in same secure channel and follow the same procedure (encapsulate and encrypt) . and finally Terminal application shows the output of ls command.

I think here all command is encoded to Base64 encoding before send to server and before encrypt. (But i am not sure)

here very important note that SSH is not disturb  the port other than 22 (or which port ssh server is running).

SSH Tunneling
      SSH can work many channel's simultaneously. In normal case we use shell channel. But now we are going to use data channel. so base concept is, in machine ssh client bind one port and establish secure connection with server ( and create one data channel and shell channel. (we can omit shell channel using -N option in ssh command).

Now In system machine ( any application send data to that port (which one ssh client is bind), then ssh client transparently receive the data and encrypt and sent to server machine. In server  ( receive and decrypt it and make the local call. (we discuss later)

SSH Tunneling types
SSH offers three types of tunneling 
  • Dynamic Tunneling (SOCKS Proxy)
  • Local Port Forwarding
  • Remote Port Forwarding

Dynamic Tunneling 

   Command :            ssh     -D 8080     [email protected]

here -D 8080 is mention SOCKS v5 Proxy bind 8080 port in client side

         Now ssh client in machine create one SOCKS proxy server in client side and bind one local port.then connect to remote machine and establish secure channel.

 Now all client application like Firefox, chrome,... need to configure the proxy setting  to SOCKS proxy server localhost and port number. (check video for reference below the post)

Note : consider server ( and Intranet ( both machines run Apache httpd server and bind port 80

After configuration is completes,
in Firefox now type http://localhost/ , we know that in client machine ( there is no service is running in port 80. but when we hit enter in browser, we can see the website of server machine (

How we can access server website using http://localhost/ in client machine?
we configure the proxy in browser. so browser send all HTTP request (even localhost anf to port 8080, here SOCKS proxy is running in that port. Then socks proxy server packs our HTTP request to ssh client and encrypt and send to server. Server decrypt and extract the HTTP Request. Now in server side the HTTP request http://localhost/ is point to server machine itself. so server invoke the request. If any service is running in port 80, is called and response is send back to client using same secure channel. so browser shows server webpage in client side.

We know that from client machine ( , the IP address is non routable. but now if we issue in Firefox browser, its shows the Apache server webpage.

Advantage :
  • One proxy server is enough to access the all services of remote machine and its sub-net services
  • We need to configure the Proxy settings in client application, If application doesn't support the proxy then we can't access the service.

Local Port Forwarding 

Command :        ssh       -L  8000:localhost:80     [email protected]

here syntax is   -L   <local port> : <remote hostname> : <remote service port>

so when we execute the command, its bind port 8000 in client side. now what are request send to port 6000 its redirect to ssh client, then encrypt and send to server machine. now server directly delivered the data to port 80.

In dynamic tunnel, server checks the packet and decide where we need to send the packet, for example http://localhost/ then its send to 80, smtp then send to 25. But in local port it always send to single port which one we mention during setup the local port forwarding <remote hostname> : <remote service port>

this time in Firefox no need to configure the proxy, clear the proxy(if its present)
and type in address bar  http://localhost:8000/
then HTTP request is going to local port 8000, then its redirect and send to server. server directly send to port 80. (Its based on <remote hostname> : <remote service port>, here now localhost:80)

If u want to access the machine http service then we need to setup new local port forwarding.
we can't use prior port forwarding. because old one always pointing to localhost:80.

Command :             ssh   -L  8000:   [email protected]

now client side local port 8000 is redirected to machine via

In Firefox using http://localhost:8080/ we can access the machine http service.

(For further reference check the video below. in video i show the how to access remote desktop using VNC)

  • no need to configure the proxy setting
  • Each service we need to setup different local port forwarding, (i.e for example, 2 port forwarding is needed to get and http services)

Remote Port Forwarding

Remote port forwarding is same like local port forwarding. but this time we need to set the port forwarding in server side(, not client side

Command :        ssh    -R 8000:localhost:80       [email protected]
here very important changes is from server we going to connect client, so  [email protected] here its not 102.

when we execute this command its connect to client and create 8000 port in client side(not server side).
as usual client use its local port 8000 to connect server. like local port forwarding.

Why Remote Port Forwarding is Important?
    Its rarely used, when we worked the machine. that machine is inside the NAT. so from outside no one can access it. that kind of situation physically access the machine and connect back to our client system ( using remote port forward. then from client machine we can access the services.(Its seems to be little bit confusing, but its simple)

In Windows Machine
   In windows machine if want to run ssh server then there is lots of ssh servers are available WinSSHD freeSSHd, openssh. If we want only ssh client then we can use Putty.

suppose in System( i am using Windows then how we access the ssh tunneling.

open the putty and type the host [email protected] and select Connection->SSH->Tunnels (see the image), then type 8080 in source port and select Dynamic, if u want dynamic tunnel (Its equal to -D 8080 in command option)

If we want local port forwarding then put any unused port 6000 in source port and destination is localhost:80 and select Local. (Its equal to -L 6000:localhost:80)

If u want to access machine  the remote desktop then make local port forward (check above image) and Destination is here 5900 is the port used by vnc server. then using any vnc client (here i used tightvnc client) to connect ur local port 6000
so mention localhost::6000,   here we need to mention double colon ::, because in vnc client port no is specified in this manner. (Check the video )

Bypass Firewall
                 This SSH Tunnel concept can be use to bypass firewall. lets consider the scenario. In server side its enable firewall and some service are running and these services are can access through localhost or same machine. but u can't access through remote machine. because firewall block the all the port except ssh port (22).

this kind of situation we use tunnel and almost all services can be accessed from outside. because firewall is rule based. In firewall perspective all traffic is goes through port 22. so its allowed. but internally we made tunnel and access all services.

How to prevent SSH Tunnel
      Open the ssh server config file /etc/ssh/sshd_config  then set the parameter
AllowTcpForwarding no
then restart ssh service. then they not allow the ssh tunnel service, but still we can access ssh shell service.

But in ssh man page they clearly mentioned

" Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. "
so still we can use use ssh tunnel even though  we set AllowTcpForwarding no. (I will show in my next post)

I hope everything is clear. If any misunderstanding please let me know.

Screen cast (Watch in HD)


Comments Welcomed

Tuesday, April 24, 2012

How to compile kernel step by step

Recently I compiled the latest kernel by manually for just fun. so i logged my experience here. I show the step by step to the compilation process. I followed the this reference for compile the kernel.

Why Need to compile the Kernel?
  • Some time some software or modules expected that some kernel flags needed to set while compile (build) the kernel. This kind of scenario we need to rebuild the kernel with specified configuration flags are set.
  • When new kernel is released,  compile the new kernel and install in our system. But this is not recommend way to install the system. so use our distribution(Ubuntu, red-hat release )  kernel update.

Check your Linux kernel version
        In Linux system use uname -r or cat /proc/version to find the current kernel version
Linux Kernel Version
here is current system kernel version

Step 1 : Download the latest kernel
 Goto website and get the latest version of the kernel source. i will get 3.3.3


and extract the source code.
tar xf linux-3.3.3.tar.bz2
cd linux-3.3.3
in linux-3.3.3 folder contain lots of files and folders. some folders are use following purpose

arch - this folder shows the what are the architecture port the Linux
crypto- contain cryptography implementations like AES, DES
drivers-  all device drivers modules (IDE, SCSI, Ethernet device, Wireless)
fs- all file-system implementation code (ext4, FAT, NTFS)
net - all network protocol implementations (IPv4, IPv6, tcp, 802.11)

Step 2 : make the configuration file
  While compile the kernel source code, we need configuration file. that configuration file contain lots of variable to help to understand what are the modules we need to compile.

For x86 specific kernel variable check this reference 

using make command we can build the configuration, but this command is interactive, its ask more than 1000 question about enable or disable the particular module, like which file-system r u want and IP-Tables related modules like SIP components (state-full inspection firewall).

so the best way is copy the current Linux config file. its stored in /boot/config-<version>.
cp /boot/config-      .config 

now we got old configuration. now we change/add new configuration settings.
for this purpose therse is lots of options are avialable

make help       ==>Provides the help

There is GUI option is also available

make   menuconfig          ==> this provides Text based GUI Configuration

here load the old config file and add/change the settings then save the config file.

make   gconfig      ==> this provides GTK 2 based GUI Configuration for GNOME

for this we need to install libgtk2.0-dev, libglad2-dev through apt-get install

make   xconfig      ==> this provides QT based GUI Configuration for KDE

for this we need qt-dev tools

Using any one of the above method modify the configuration.

Step 3 : Compile the Kernel
        There are two ways to compile the kernel

  • Generic way (lots of steps)
  • Debian specific way (simple, Use make-kpkg tool)

Step 3.1 : Generic Way

      Step 3.1.1 Compile the Kernel and its modules

       above code is take 1 to 2 hours depending on system performance. In this step it compile the kernel and store the kernel in binary form to arch/x86/boot/bzImage file
then based on kernel headers it will compile the kernel  modules (device driver, file-system, network,...)
and generate .ko files. ko means kernel object. These modules also called Loadable Kernel Modules (LKM).

   Step 3.1.2 Install Kernel modules

     make  modules_install
     This step copy the all kernel modules (*.ko) to /lib/modules/<version>/kernel/   folder.

       Step 3.1.3 Install Kernel 

       make  install
      This step copy the the kenel from arch/x86/boot/bzImage to /boot folder and copy the .config file to /boot/config-<latest-version> and generate the file.

      Step 3.1.4 Create Initramfs file
     up to now kernel and its modules are compiled and installed. when next boot up time we need to choose latest kernel. so we need to prepare the boot-loader and its support files. When system turns on, after bios and boot loader load the kernel to main memory and mount initial dummy file system as a root file system of system. this initial file system have necessary drivers for disk hardware (SCSI or IDE) and mount the correct file system as a root file system.

so we need to create initramfs file using update-initramfs or mkinitfs tool

     update-initramfs -c -k 3.3.3
here 3.3.3 is new kernel version.

   Step 3.1.5  Update GRUB bootloader
  the last step is update the boot loader here i m using GRUB boot-loader.

this command automatically probe the kernels in /boot folder and add the entries in its configuration file, grub.cfg

now restart the system , we will see the new kernel is added in boot loader entries. then choose new kernel in boot loader.

now open the terminal and issue uname -r command, its shows the  current kernel version.

Step 3.2 : Debian specific way Way

              In Debian system's (Ubuntu, Linux Mint,..) there is one tool "make-kpkg" is available to automate the kernel compilation process.

to install the make-kpkg, use apt-get
sudo apt-get install    kernel-package    libncurses5-dev

this one line command is compile the kernel and its modules and make the binary form in deb file.
make-kpkg --initrd --append-to-version=-ramki    kernel_image     kernel_headers

this one line make the kernel and its headers with custom suffix -ramki
--initrd specify that make initramfs disk file
kernel_image option to make the kernel and its modules
kernel_headers option to make all header files of the kernel. (optional)

the final output is its create 2 DEB files.

Install the Deb files
      Install the deb file is simple. use dpkg tool like normal installation in Debian system
dpkg -i kernel_image-ramki-i386.deb

while executing this line install the kernel to /boot folder. install the modules in /lib/modules folder and create the initramfs file and update the grub like generic way. all the above operation is happen automatically.

then in optional case we can install the kernel_headers-ramki-i386.deb file.

why need the kernel headers are important?
       kernel_image is enough to run the system. but when we need to install drivers, for example we need to install the new driver in Linux  that time while compile the driver, that time need the kernel headers.

In my system its works fine. i tested in VM also.


Comments Welcomed