SSH Tunneling on Linux and Mac

Do you need to tunnel to another machine frequently?

Would you like an App to save time and make it more user friendly?

Well, good news!

There’s a solution for Linux and Apple machines.

For Linux you can try Gnome SSH Manager.

From their website:

gSTM is a front-end for managing SSH-tunneled port redirects. It stores tunnel configurations in a simple XML format. The tunnels (local, remote and dynamic) can be managed and individually started/stopped through one simple interface.


Another option for Linux is IOSSHy.

From their website:

IOSSHy provides an easy to use desktop tool to quickly create and destroy SSH tunnels and launch commands based on a preconfigured setup.

Password are stored in the keyring provided by the operating system (ES: gnome’s keyring, kde’s kwallet, osx keychain, etc…)


For MacOS (OSX) it’s called Tunnel Manager.

From their website:

SSH Tunnel Manager is a macOS application to manage your SSH tunnels. If you don’t know what that is, quite honestly, maybe you don’t need SSH Tunnel Manager, but if you appreciate the power of connecting together two networks using the SSH protocol, then STM is for you.


Did you know: SSH Tunneling is also commonly referred to as LocalForwarding, RemoteForwarding, Local Port Forwarding, Remote Port Forwarding.


Force Password Authentication with SSH

If you want to connect to a host by using a password instead of a public key you can use the following command to initiate a request.

Note: This will only work if your host allows the user you are trying to connect with to authenticate by using password. Typically, this is disabled for root users and not advised to enable password authencation unless you really know what you are doing.

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no

Resolve Password Prompt with Encrypted Home Directory

If you are experiencing this issue read on for the official solution from Ubuntu.

Encrypted Home Directory

If you have an encrypted home directory, SSH cannot access your authorized_keys file because it is inside your encrypted home directory and won’t be available until after you are authenticated. Therefore, SSH will default to password authentication.

To solve this, create a folder outside your home named /etc/ssh/<username> (replace “<username>” with your actual username). This directory should have 755 permissions and be owned by the user. Move the authorized_keys file into it. The authorized_keys file should have 644 permissions and be owned by the user. 

Then edit your /etc/ssh/sshd_config and add:

AuthorizedKeysFile    /etc/ssh/%u/authorized_keys

Finally, restart ssh with:

sudo service ssh restart

The next time you connect with SSH you should not have to enter your password.


For a more in-depth discussion we recommend having a look at the following Unix StackExchange entry.


ssh key_read: uudecode failed

A couple things to check if you this type of error.

The error is given by the client. So check your client know_hosts file.

For additional debugging try connecting to the host using verbose mode.


ssh -v



Fix X2GO keyboard mapping MacOSX, Ubuntu, Mint, VirtualBox keyboard layout

Many posts written about this topic.

The solution that will work is to add a keyboard mapping on the host machine that you will connect to.

This new keyboard layout must be the only keyboard layout on the system. If another keyboard layout is in the list you will want to remove it as it may be the cause of the issues.

Once your client and host both have the same keyboard layouts installed you will need to end your x2go session and restart it for the keyboard mapping to take effect.


Ubuntu/Mint cannot login via ssh even after ssh-copy-id


This may be caused by a directive in the /etc/ssh/ssh_config file.

To allow login with RSA key you need to uncomment the line:

#   IdentityFile ~/.ssh/id_rsa

   IdentityFile ~/.ssh/id_rsa

Save the changed to ssh_config and try login again.

To diagnose the issue you can try.

ssh -vv user@hostname

If you are having a key-exchange issue then your verbose error log will show



This is solution is not mentioned on this site:


SSH Public key failed authentication


Set permissions with

chmod 700 .ssh chmod 600 .ssh/authorized_keys

 If find the following in your logs.

sshd[28426]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key

sshd[28426]: Authentication refused: bad ownership or modes for file /home/beta/.ssh/authorized_keys



 Check in logs for clues

 For Debian:

less /var/log/auth.log

For Redhat:

less /var/log/secure 




Web hook pull Git Repo down to a web server for production without history or .git folder

Deploying with web hook

Place a file with the line below in your web root. Have the web hook on github or gitlab call the url i.e.

This will update your web root (public_html , www) with the latest version of your code without the history and without .git folder.


`git archive –format=tar – master | tar -xf -`



Alternate method 

Deploying a Git repository to a remote server

Git’s archive command is basically the equivalent of SVN’s export – it dumps a copy of the entire repository without any of the version control files, making it perfect for deploying to a testing or production server.

Using a combination of git archive, SSH, and Gzip; deploying a Git repository to a remote server can be done quickly and easily:

git archive --format=tar origin/master | gzip -9c | ssh "tar --directory=/var/www -xvzf -"

Let’s take a look at the different parts of that command.

This tells Git to combine all of the repository’s files into a single tarball file. The benefit of doing this is that a large single file can be transferred much quicker than thousands of smaller files.

If you are familiar with Git, you should recognise that these are the default names for a Git remote and branch. You should change these to match your remote/branch setup.

gzip -9c
The tarball created by git archive is piped into Gzip, which applies compression to reduce the size of the file. The 9 flag tells Gzip to use the best compression method, and the c flag makes Gzip write the compressed file to stdout. The reason we want Gzip to write to standard output is so that we can send the compressed repository straight to the remote server via SSH.

ssh “tar –directory=/var/www -xvzf -“
The Gzipped tarball is then piped through SSH to your remote server. The remote server runs tar --directory=/var/www -xvzf - which extracts the Gzipped tarball into the /var/www directory. Note that the hyphen (-) at the end of the tar command tells tar to receive data from a piped command instead of a file.

How to SSH with PHP with Debian and Ubuntu

Make SSH connections with PHP

Not everyone knows about PHP‘s capabilities of making SSH connections and executing remote commands, but it can be very useful. I’ve been using it a lot in PHP CLI applications that I run from cronjobs, but initially it was a pain to get it to work. The PHP manual on Secure Shell2 Functions is not very practice or thorough for that matter, so I would like to share my knowledge in this how to, to make it a little less time consuming setting this up.

In this article I’m going to assume that:

  • You’re running Debian / Ubuntu
    If not, you will have to substitute the package manager aptitude with whatever your distribution provides
  • You’re running PHP 5
    If not, just replace php5 with php4 everywhere
  • You have basic knowledge of PHP & server administration
  • You already have PHP installed



First let’s install the following packages:

sudo aptitude update
sudo aptitude install php5-dev php5-cli php-pear buid-essential \
openssl-dev zlib1g-dev

That should set us up alright.


Now we need libssh2 from sourcefourge. We have to compile this, but no worries, this is all you need to do:

cd /usr/src
tar -zxvf libssh2-0.14.tar.gz
cd libssh2-0.14/
make all install

That’s it! Easy right? If you want you can check if there’s a newer version at but 0.14 will do just fine.


Next we need to link libssh & PHP together. There’s a PECL module for this so let’s install using:

pecl install -f ssh2

The -f makes sure ssh2 is installed even though there’s not a stable candidate. You could also use the package name: ssh2-beta to overrule this.

Now you need to make sure our new module is loaded by PHP. Edit your php.ini file (for CLI utitilies: /etc/php5/cli/php.ini, for Apache utilities /etc/php5/apache2/php.ini)

It should be placed beneath the: “Dynamic Extensions” section somewhere around line 515.


Great! PHP supports SSH – time to code

You’ve just enabled ssh2 support in PHP. Now how can we make use of this? There are 2 options. SSH supports the: 

  • execute method
    This tells the server’s operating system to execute something and pipe the output back to your script. (recommended)
  • shell method
    This opens an actual shell to the operating system, just as you would normally when logging in with your terminal application. Some routers that don’t have a full POSIX compliant implementation, but run their own application as soon as you login, require this. (advanced)

Method 1: Execute

Best would be to create functions or even a class for the following code, but this is the basic idea and will definitely get you started:

if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist")
// log in at on port 22
if(!($con = ssh2_connect("", 22))){
  echo "fail: unable to establish connection\n";
} else {
  // try to authenticate with username root, password secretpassword
  if(!ssh2_auth_password($con, "root", "secretpassword")) {
    echo "fail: unable to authenticate\n";
  } else {
    // allright, we're in!
    echo "okay: logged in...\n";
    // execute a command
    if(!($stream = ssh2_exec($con, "ls -al" )) ){
      echo "fail: unable to execute command\n";
    } else{
      // collect returning data from command
      stream_set_blocking( $stream, true );
      $data = "";
      while( $buf = fread($stream,4096) ){
        $data .= $buf;

Method 2: Shell

Best would be to create functions or even a class for the following code, but this is the basic idea and will definitely get you started:

if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist")
// log in at on port 22
if(!($con = ssh2_connect("", 22))){
  echo "fail: unable to establish connection\n";
} else {
  // try to authenticate with username root, password secretpassword
  if(!ssh2_auth_password($con, "root", "secretpassword")) {
    echo "fail: unable to authenticate\n";
  } else {
    // allright, we're in!
    echo "okay: logged in...\n";
    // create a shell
    if(!($shell = ssh2_shell($con, 'vt102', null, 80, 40, SSH2_TERM_UNIT_CHARS))){
      echo "fail: unable to establish shell\n";
    } else{
      stream_set_blocking( $shell, true );
      // send a command 
      fwrite($shell,"ls -al\n");
      // & collect returning data
      $data = "";
      while( $buf = fread($shell,,4096) ){
        $data .= $buf;


Sometimes when a server is busy, or a connection is buggy, the buffer may run dry, and the PHP script stops collecting data from a command output (even though the command hasn’t completed yet!). There are a couple of things you could do about that:

ssh2_exec($con, 'ls -al; echo "__COMMAND_FINISHED__"' );

Now, in the loop where you keep checking for the buffer, just see if the COMMAND_FINISHED line is coming by. Because then you know you have all the data. To avoid infinite loops, just limit the loop with a timeout of 10 seconds or so:

$time_start = time();
$data = "";
while( true ){
  $data .= fread($stream, 4096);
  if(strpos($data,"__COMMAND_FINISHED__") !== false){
    echo "okay: command finished\n";
  if( (time()-$time_start) > 10 ){
    echo "fail: timeout of 10 seconds has been reached\n";

In the example above, you’d better set stream_set_blocking to false.

Can’t get enough?

PHP can send files over ssh!

ssh2_scp_send($con, "/tmp/source.dat", "/tmp/dest.dat", 0644);