SSH linux how to kill an idle or innactive connection

Sometimes when you're disconnected abruptly from a remote server like if your network connection gets dropped, you can be left with a ghost or inactive SSH session.

This can become pretty annoying when you're doing some SSH port redirection since you will not be able to bind to a given port since the ghost connection is still using that port, and you might end up with error messages such as the following :

debug1: Local connections to LOCALHOST:21521 forwarded to remote address localhost:21521
debug1: Local forwarding listening on 127.0.0.1 port 21521.
bind: Address already in use
debug1: Local forwarding listen

Now there are a few ways of dealing with this issue, the one I prefer is a 3 step operation :

1.Check who is connected to the server

This step is actually optional but it allows you to check which user is currently connected to the server and prevent accidentally destroying another user's session (or at least warning him that you will do it ;) )

To check who's connected to the server you can run the w command. the w command shows who is logged in to the system and what they are doing.

So go ahead and run the following command on your prompt :

   [ufasoli]> w

You should see an output similar to this one

 20:16:14 up 132 days,  3:38,  2 users,  load average: 0.04, 0.03, 0.00
USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0     20:07    0.00s  0.02s  0.00s w
root     pts/1     20:09    6:17   0.02s  0.02s -bash

Here you can identify your user with the WHAT column as it indicates what the user is doing (invoking the command w in our case) /

2.Display the running processes

By using the pstree command with the -p to show process identification numbers (PIDs)

Go ahead and run the following command :

[ufasoli]> pstree -p

pstree displays the processes (i.e., executing instances of programs) on the system in the form of a tree diagram so when running the above command you should have an output similar to the one below :

init(1)─┬─cron(8865)
        ├─cupsd(2385)
        ├─oracle(2063)
        ├─oracle(2065)
        ├─oracle(2067)
        ├─oracle(2069)
        ├─oracle(2176)
        ├─oracle(2180)
        ├─oracle(12830)
        ├─scsi_eh_1(226)
        ├─scsi_eh_2(232)
        ├─scsi_eh_3(236)
        ├─slpd(2136)
        ├─sshd(2411)─┬─sshd(12840)───bash(12842)───pstree(12908)
        │            └─sshd(12887)───bash(12889)
        ├─sshd(14276)
        ├─syslogd(2035)
        └─tnslsnr(3917)


3.Kill the unwanted process

In our case the unwanted session has the PID 12287 as it's the session without the pstree command that we've just issued.

You can now kill the unwanted PID (just be careful not to kill a colleagues session ;) ):

   [ufasoli]> kill -1 12887

Once the session is killed you should be able to bind to the previously occupied port

Running a spring boot application with maven

On the last 2 part tutorial that I published recently on Spring boot :Spring boot and spring data (part 1) and Spring boot and spring data (part 2) I said that when using pure maven (not the groovy approach) you needed to either package the project and then run the JAR manually or use the maven mojo exec plugin (which I preferred)

But as often after playing a bit more with it I realized that there is an even simpler solution and that is using the run goal of the spring-boot maven plugin

So you can simply run your spring-boot project by executing the following goal on your console/IDE


 mvn spring-boot:run

Spring boot and spring data jpa tutorial - A sample application using spring 4.0 spring boot and JPA (part 2/2)

This is the second part of the Spring boot and spring data jpa tutorial - A sample application using spring 4.0 spring boot and JPA

At the end of the tutorial I promised you that we will be removing one of the steps when running the application, that is merge the package and run in a maven command and make him do the work

5.- Making maven run the JAR directly

We're going to make maven run the runnable JAR for us after it has been packaged, for this purpose we're going to use one of org.codehaus.mojo maven plugins



....

        
            
                org.springframework.boot
                spring-boot-maven-plugin
            

            
                org.codehaus.mojo
                exec-maven-plugin
                1.2.1
                
                    com.ufasoli.tutorials.spring.boot.HelloWorldApp
                
            
        
    
...

So what's happening here ? :

  • By adding the exec plugin to the build section of our pom.xml and providing a mainClass when we run the appropriate maven goals the application will be packaged and run directly from maven

You can try this by running :

    mvn clean package exec:java

By running this on your console the application will be packaged and run directly using maven

Now let's add some more interesting stuff to our app

6.- Adding Spring Data and JPA support

We're now going to add some Spring Data and JPA support to our app.

The first thing you need to do is add the additional spring boot starter module (spring-boot-starter-data-jpa) to your maven dependencies and since we will be using an embedded HSQL database the dependency for the HSQL driver too:

 
 ...
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

         
            hsqldb
            hsqldb
            ${version.hsqldb}
        
...


The next thing you need to do is tell spring to enable Spring Data and its repository features this is done by simply adding the @EnableJpaRepositories to your Spring App class

@ComponentScan 
@EnableAutoConfiguration
@EnableJpaRepositories
public class HelloWorldApp {

    public static void main(String[] args) throws Exception {

        SpringApplication.run(HelloWorldApp.class, args);

    }
}

And that's it if you now build and run your application you will have a Spring web application with Spring Data and JPA support even though the app won't do much for the moment ;).

So what's happening here?

  • Annotating the Spring Application class with the @EnableJpaRepositories will cause a lot of "magic" to happen and a lot of things will be configured/initialized for you such as an Entity Manager, DataSource (see next item), JPA Vendor adapter ..
  • Since we haven't defined a DataSource if Spring finds an in memory JDBC driver in the Classpath it will automatically create one for us using a set of predefined conventions

Now let's add some logic to our app :

7.- Adding some Spring data and JPA logic

The first thing we're going to be doing is adding a simple JPA entity to perform some CRUD operations later on



import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Book {


    @Id
    protected String isbn;
    protected String title;
    protected String author;
    protected String description;
    // omitting setters/getters/constructors
}

So now that we have our entity lets use one of the great features of Spring Data : The Repositories Abstraction :

The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.

By annotating an interface with @Repository and making this interface extend CrudRepositoryYou will get among other things 2 pretty nifty goodies of the box:

  • Some utility CRUD methods such as findAll() or count()
  • Auto-implementation of methods based on naming convention such as findBooksByAuthor()

And the best part is you get all of this without writing any code logic for these methods (of course you can override these methods, and write some custom methods) as shown in the doc, you can even avoid yet to write some code by using for example the @Query annotation

So now lets create our CRUD repository for our entity with a custom method to find the books by their author


import com.ufasoli.tutorials.spring.boot.model.Book;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;


@Repository
public interface BookRepository extends CrudRepository {

    public Iterable findBooksByAuthor(@Param("author") String author);
}

This interface will be picked up by Spring an instantiated accordingly.

We're almost done with our JPA/database logic, one last thing I would like to do is to have some data inserted automatically into the database when the application starts (especially since we're dealing with an in-memory database

Once again we can take advantage of another Spring convention, if you place a data.sql file in your maven resources directory the script will be automatically executed when the database will be bootstrapped and after reverse engineering your entities into the database

INSERT INTO book(isbn, title, author,description) VALUES ('1111111', 'The Spirit Thief (The Legend of Eli Monpress #1)', 'Rachel Aaron',
                         'Eli Monpress is talented. He''s charming. And he''s a thief.But not just any thief. He''s the greatest thief of the age - and he''s also a wizard. And with the help of his partners - a swordsman with the most powerful magic sword in the world but no magical ability of his own, and a demonseed who can step through shadows and punch through walls - he''s going to put his plan into effect.The first step is to increase the size of the bounty on his head, so he''ll need to steal some big things. But he''ll start small for now. He''ll just steal something that no one will miss - at least for a while. Like a king');

INSERT INTO book(isbn, title, author,description) VALUES ('2222222', 'The Spirit Rebellion (The Legend of Eli Monpress, #2)', 'Rachel Aaron',
                         'Eli Monpress is brilliant. He''s incorrigible. And he''s a thief.He''s also still at large, which drives Miranda Lyonette crazy. While she''s been kicked out of the Spirit Court, Eli''s had plenty of time to plan his next adventure. But now the tables have turned, because Miranda has a new job -- and an opportunity to capture a certain thief. Things are about to get exciting for Eli. He''s picked a winner for his newest heist. His target: the Duke of Gaol''s famous ''thief-proof'' citadel. Eli knows Gaol is a trap, but what''s life without challenges? Except the Duke is one of the wealthiest men in the world, a wizard who rules his duchy with an iron fist, and an obsessive perfectionist with only one hobby: Eli. It seems that everyone is hunting for Eli Monpress');

INSERT INTO book(isbn, title, author,description) VALUES ('3333333', 'The Spirit Eater (The Legend of Eli Monpress, #3)', 'Rachel Aaron',
                         'With the pressure on after his success in Gaol, Eli Monpress, professional thief and degenerate, decides it''s time to lie low for a bit. Taking up residence in a tiny seaside village, Eli and his companions seize the chance for some fun and relaxation. Nico, however, is finding it a bit hard. Plagued by a demon''s voice in her head and feeling powerless, she only sees herself as a burden. Everyone''s holiday comes to an untimely close, though, when Pele arrives to beg Eli''s help for finding her missing father. But there are larger plans afoot than even Eli can see, and the real danger, and the solution, may lie with one of his own and her forgotten past. If only Nico could remember whose side she''s on.');

INSERT INTO book(isbn, title, author,description) VALUES ('4444444', 'The Spirit War (The Legend of Eli Monpress, #4)', 'Rachel Aaron',
                         'Eli Monpress is vain. He''s cocky. And he''s a thief. But he''s a thief who has just seen his bounty topped and he''s not happy about it. The bounty topper, as it turns out, is his best friend, bodyguard, and master swordsman, Josef. Who has been keeping secrets from Eli. Apparently, he''s the only prince of a rather feisty country and his mother (a formidable queen who''s every bit as driven and stubborn as he is) wants him to come home and do his duty, which means throwing over personal ambitions like proving he''s the greatest swordsman who ever lived. Family drama aside, Eli and Josef have their hands full. The Spirit Court has been usurped by the Council of Thrones and someone calling herself the Immortal Empress is staging a massive invasion. But it''s not just politics --- the Immortal Empress has a specific target in mind: Eli Monpress, the greatest thief in the world.');

INSERT INTO book(isbn, title, author,description) VALUES ('5555555', 'Spirit''s End (The Legend of Eli Monpress #5)', 'Rachel Aaron',
                         'First rule of thievery: don''t be a hero. When Eli broke the rules and saved the Council Kingdoms, he thought he knew the price, but resuming his place as the Shepherdess''s favorite isn''t as simple as bowing his head. Now that she has her darling back, Benehime is setting in motion a plan that could destroy everything she was created to protect, and even Eli''s charm might not be enough to stop her. But Eli Monpress always has a plan, and with disaster rapidly approaching, he''s pulling in every favor he can think of to make it work, including the grudging help of the Spirit Court''s new Rector, Miranda Lyonette. But with the world in panic, the demon stirring, and the Lord of Storms back on the hunt, it''s going to take more than luck and charm to pull Eli through this time. He''s going to have to break a few more rules and work with some old enemies if he''s going to survive');

8.- Wrapping things up with a REST controller

To wrap things up we'll add a simple RestController that will interact with our freshly created Repository


import com.ufasoli.tutorials.spring.boot.model.Book;
import com.ufasoli.tutorials.spring.boot.repositories.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController // assumes @ResponseBody annotation in methods annotated with  @RequestMapping
@RequestMapping(value = "/books", produces = MediaType.APPLICATION_JSON_VALUE)
public class BookController {

    @Autowired
    protected BookRepository bookRepository;

    @RequestMapping
    public Iterable books() {
        return bookRepository.findAll(); // uses the findAll() method inherited from CrudRepository
    }


    @RequestMapping(value = "/{isbn}")
    public Book book(@PathVariable("isbn") String isbn) {
        return bookRepository.findOne(isbn);// uses the findOne() method inherited from CrudRepository
    }


    @RequestMapping(value = "/{isbn}", method = RequestMethod.DELETE)
    public String deleteBook(@PathVariable("isbn") String isbn) {

        try {
            bookRepository.delete(isbn);
            return String.format("Book [%s] successfully deleted", isbn);// uses the delete() method inherited from CrudRepository
        } catch (Exception e) {
            return String.format("A problem occurred when deleting Book [%s]", e.getMessage());
        }
    }

    @RequestMapping("/author/{author}")
    public Iterable booksByAuthor(@PathVariable("author") String author) {

        return bookRepository.findBooksByAuthor(author);// uses the custom method defined in our BookRepository interface
    }


}

So that's it you can re-run your application now using the maven goal

     mvn clean package exec:java

You should see your application bootstrapping your database and inserting data, and once it's fully started you should be able to play with your Web Service

9.-Some final thoughts

I must say that I quite enjoyed playing with Spring boot, as long as you're using the full spring stack it helps you get things running quickly and has some very useful starter modules and conventions

I also added the actuator module which gives you some metrics and stats (as REST endpoints) on your application which is pretty cool to have when running the app in production

Check it out here

As usual you can find the code source for this application over at my github account here

Spring boot and spring data jpa tutorial - A sample application using spring 4.0 spring boot and JPA (part 1/2)

Spring boot is a strongly opinionated framework / generator based on the principle of convention over configuration, which according to the website:

Spring Boot makes it easy to create Spring-powered, production-grade applications and services with absolute minimum fuss. It takes an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need

Basically by using a few annotations and minimum boilerplate code the framework/generator will configure all the necessary beans and contexts based on a set of conventions.

Spring boot has a few modules that depending on your needs can speed-up development such as :

  • spring data jpa
  • spring data mongodb
  • spring web
  • spring actuator
  • ...

Personally I find that when using the spring stack this tool is pretty awesome!!

When using this tool you must know that there are actually 2 ways to use spring boot :

  1. Using the cli (and by extension groovy)
  2. Using good old maven and the spring-boot plugins

In this tutorial we will be building a simple Hello World tutorial as a RESTful web service

1.- Getting things started

Add the required maven dependencies to your pom.xml

        spring-boot-hello-world-ws
    spring-boot-hello-world-ws
    1.0-SNAPSHOT


    
    
        org.springframework.boot
        spring-boot-starter-parent
        1.0.0.RC1
    

    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

    

    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            

        
    

    
    
    
        
            spring-snapshots
            http://repo.spring.io/snapshot
            
                true
            
        
        
            spring-milestones
            http://repo.spring.io/milestone
            
                true
            
        
    
    
        
            spring-snapshots
            http://repo.spring.io/snapshot
        
        
            spring-milestones
            http://repo.spring.io/milestone
        
    

So what's happening here :

  • Since spring-boot is not G.A. yet you will need to include the Spring milestones repositories
  • When using maven your project will have to inherit from the spring boot starter parent in order for it to work
  • We are using the web module (see dependencies)
  • The spring-boot-maven-plugin will build a runnable jar file

2.- Creating our first controller

With the basic configuration out of the way we can start building our app.

Since this is going to be a RESTful API we will create a REST controller. Spring included a new annotation in the latest version @RestController. Types that carry this annotation are treated as controllers where @RequestMapping methods assume @ResponseBody semantics by default; which in our case it's what we want.

So with that being said let's write our first controller :


package com.ufasoli.tutorials.spring.boot.web.controllers;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 * User: Ulises Fasoli
 * Date: 04.02.14
 * Time: 15:33
 */
@RestController
@RequestMapping(value = "/hello", produces = MediaType.APPLICATION_JSON_VALUE)
public class HelloWorldController {

    @RequestMapping
    public String sayHello(){
        return "Hello World";
    }
}

Nothing special here just a simple Spring MVC controller but using the new @RestController annotation

We are now 2 steps away from running our Spring app.

3.- Creating our Spring Application main class

In order for the Spring context to be bootstrapped you will need to create a class that will run the Spring application inside a main method and a few annotations.So let's go ahead and do that :

package com.ufasoli.tutorials.spring.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

/**
 * Created with IntelliJ IDEA.
 * User: Ulises Fasoli
 * Date: 04.02.14
 * Time: 11:39
 *
 */
@ComponentScan // spring standard component scan
// spring boot autoconfiguration will bootstrap your Spring
//application while attempting to configure the beans you need
// it will also bootstrap an in-memory database if a driver is found
// in the classpath and no datasource is defined
@EnableAutoConfiguration
public class HelloWorldApp {

    public static void main(String[] args) throws Exception {

        SpringApplication.run(HelloWorldApp.class, args);

    }
}


What's happening here? :

  • The @Component is standard spring annotation to search for annotated beans in the classpath
  • The @EnableAutoConfiguration is spring boot specific and will be doing most of the "magic"

We are now one step away from running our spring application! Yep that's it no web.xml configuration, no XML files, nothing!!

4.- Taking it for a spin

With the application configured it's time to test our app, so fire-up your IDE or your console and execute the following maven goal :

  mvn clean package

Once your app is packaged you can run the generated runnable JAR file by simple going into the target folder and running :


  java -jar .\spring-boot-hello-world-ws-1.0-SNAPSHOT.jar
 

If everything worked as expected you should see the Spring boot / maven output in your console :


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::            (v1.0.0.RC1)

2014-02-04 15:46:47.628  INFO 12516 --- [           main] c.u.tutorials.spring.b
oot.HelloWorldApp  : Starting HelloWorldApp on LTULF01 with PID 12516 (C:\dev\wo
rkspaces\idea\java-blog-tutorials\spring-boot-hello-world-ws\target\spring-boot-
hello-world-ws-1.0-SNAPSHOT.jar started by ULF)
....

That's it you can now test your controller by calling the url :

 curl http://localhost:8080/hello.json

You should see the Hello world message printed out in the console

Personally it kind of bugs me to have to package the app and then run it manually so on part 2 of this tutorial we will change this so Maven will do the work for us.....

SyntaxHighlighter and blogger dynamic templates

Recently I decided to switch my blogger template to use one of Google's dynamic templates since I really like the possibility to switch the presentation of the blog posts

Even though I thought this would be pretty straight-forward as it turns out I run into a problem. I use Alex Gorbatche's SyntaxHighlighter JavaScript plugin to "prettify" my code, and as it turns out Dynamic Templates and the Syntax Highlighter do not play well together (apparently the content of the posts is loaded after the script has been bootstrapped so you end up with ugly unreadable bits of code.

After goggling here and there I found a few workarounds some worked, others not.. (I'm sorry I do not have the links now, but they are easy to found). Those who worked basically consisted in altering my previous posts to give an id to each of the pre that I had used before which was unacceptable for me. So here is the solution that I came up with by inspiring myself of the different workarounds out there .

Basically what my workaround does is to delay the moment where the Highlighting will be performed to after the posts content has been loaded and then iterate through all the appropriate html tags in your code and apply highlighting


1.- Add SyntaxHighlighter's CSS resources in the template's head


<head>
     
      <link href='http://alexgorbatchev.com/pub/sh/3.0.83/styles/shCore.css' rel='stylesheet' type='text/css'/> 
      <link href='http://alexgorbatchev.com/pub/sh/3.0.83/styles/shThemeMidnight.css' rel='stylesheet' type='text/css'/>

   

2.- Add Javascript resouces and snippet to delay the script's bootstrapping at the bottom of the page (before the body closing tag




     

      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shCore.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushJava.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushSql.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushXml.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushXml.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushBash.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushJScript.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushPerl.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushPlain.js' type='text/javascript'/>
      <script src='http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushScala.js' type='text/javascript'/>

     <script language='javascript' type='text/javascript'>
       
          // define usual options
           SyntaxHighlighter.config.bloggerMode = true;  
           SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.382/scripts/clipboard.swf';
        
            function doHighlights(){
           
   
              if(jQuery("pre").length > 0){

                     if(hasConsole()){
                        console.log("About to highlight fields");           
                     }

                     jQuery("pre").each(function( index ) {  SyntaxHighlighter.highlight(undefined, jQuery( this ).get(0));   });

              }
          }

      

          function hasConsole(){

         return typeof console != "undefined";
         } 
          

         setInterval(doHighlights, 500);
  
  </script>
</body>



Please note a few things :
  • I tried using jQuery's document ready which I find more elegant than the JavaScript timeout but it didn't work probably because it was still executed too early
  • Here running the highlight function every 500 milliseconts which I know it's not great...
  • Finally please note that the above code snippet will apply to all the pre tags in your code (which is OK for me since I only use them to display code) but it might affect your blog layout if you use them for other purposes; in that case just modify the script to check for CSS classes corresponding to those used by SyntaxHighlighter

Testing email sending functionality with a free mock smtp server

Intro

Often web applications include some email sending functionality that you have to develop/and test and there are certainly a lot of way to do this, use a fake-email recipient, use a dummy email recipient, spam your colleagues, etc. and there are some advantages and drawbacks to each of these approaches.

Recently I had to do some maintenance on an application that would send a massive amount of emails (mailing list) and I needed to test if everything was still working properly after the code modifications and since I had to change the application to allow sending multi-part messages with attachments there was a possibility that something was broken in the process.

Now for obvious reasons I could not test this in the production environment as it will have an impact on the company's SMTP server and the poor souls receiving an indecent amount of emails so I needed a mock or fake SMTP server to emulate this...

A solution

I present you Fake SMTP server. This great little Java program allows you to easily test your email sending functionality without side-effects (like spamming all your colleagues) by mimicking a real SMTP server.

Once the server is started and listening it will provide you with a list of received emails as well as SMTP logs and RAW email data and it works for both "simple" and MultiPart emails with attachments

How to use it ?

Just download it, unzip it and run it:

[/home/ufasoli/tools/smtp ~] java -jar fakeSMTP.jar

this will start the GUI but not the server for that you will need to click on the "Start server" button

There are also a few command line options that you can provide when starting the server like for example to start the server automatically :

  • -o : Change the output directory
  • -p : Change the listening port
  • -s : Start the server automatically when you run the GUI

As indicated by the author on the websites there are a few alternatives :

Requirements

The only thing you need to run this server is JVM 1.6+. Please also note that if you run this on a Unix/Linux environment you will need root privileges to listen on the port 25

Keeping alive a SSH connection or in my case a multi-hop ssh tunnel to prevent timeout

A few months ago I wrote an article on how to create a multi-hop SSH tunnel between 3 machines

Since then I have been using this a lot for one of the projects I'm working on but I was annoyed that whenever the connection went idle for more than 2 minutes (like if I was reading an article or answering an email) the connection will be dropped abruptly and I will have to start it all over again...

After playing a bit with SSH options and reading ssh man I finally found my salvation, that is the -o flag with 2 options :

TCPKeepAlive
Specifies whether the system should send TCP keepalive messages to the other side. If they are sent, death of the connection or crash of one of the machines will be properly noticed. However, this means that connections will die if the route is down temporarily, and some people find it annoying. On the other hand,if TCP keepalives are not sent, sessions may hang indefinitely on he server, leaving host users and consuming server resources. The default is "yes" (to send TCP keepalive messages), and the server will notice if the network goes down or the client host crashes. This avoids infinitely hanging sessions. To disable TCP keepalive messages, the value should be set to "no".
ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received from the server, ssh will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. This option applies to protocol version 2 only.

Below is the line of code that I use to create my multi-hop SSH tunnel and to prevent it from getting disconnected when idle :

ssh -o TCPKeepAlive=no -o ServerAliveInterval=15 -v -L38080:localhost:38080 ufasoli@host1 -t ssh -o TCPKeepAlive=no -o ServerAliveInterval=15 -v -L38080:localhost:38080 ufasoli@host2 -t ssh -o TCPKeepAlive=no -o ServerAliveInterval=15 -v -L38080:localhost:8080 ufasoli@host3

Here I'm disabling the TCPKeepAlive option on all the SSH chained connections and sending a message through the tunnel every 15 seconds to keep the data flowing

Please note that disabling the TCPKeepAlive option might be frowned upon by your IT Linux Guru / System administrator since as stated in the manual can keep alive dead connections (like if you forget to close your connection) so be careful when using these options and do not forget to properly close your SSH connection / tunnel. Also as I always say, I'm no Linux Guru so I'm not aware of the possible side-effects of this options so use them at your own risk !

OSX show used ports or listening applications with their PID

On OSX you can display applications listening on a given port using the lsof the commands described below will show listening application...