Intro This is a question that seeks an extension of the answers at how-to-restrict-an-ssh-user-to-only-allow-ssh-tunneling

Problem Statement I have tried to implement the suggestion at the reference to create a user with no shell access but I could not connect to a tunnel in the name of that user.

Requirement I want to be able to have an unprotected remote computer (machine A) initiate a reverse tunnel back to my firewall. Machine A is a headless box with no user input. It is out in the wild and may be behind a firewall. My firewall (MyFW) is a linux machine and I have CLI root access.

I need Machine A to initiate a reverse ssh tunnel back to MyFW. Usually a local tunnel will be created on a user Machine C on the protected side of MyFW. The local ssh tunnel would connect to the reverse tunnel at MyFW as required.

If someone breaks into Machine A, and finds the reverse tunnel, I don't want them to be able use the reverse tunnel to gain access beyond the tunnel entrance (port) at MyFW.

What have I tried

I have used ssh and tunnels for some years, so I understand their general config and operation. For testing I setup 2 machines on my desk, machines A & B. Both are linux machines, neither is a firewall. The aim being to get the simplest setup working.

I started by creating ssh keys on machine A with:


In the usual way.

adding a user "tunnel" to the machine B acting as MyFW. The following commands were executed by another user with sudo.

useradd tunnel -m -d /home/tunnel -s /bin/true

The tunnel user does not have a password. I created a home dir because the above command does not.

mkdir /home/tunnel/.ssh

I created ssh keys for the user tunnel and put them in the /home/tunnel dir


I manually copied the public key from the remote machine A to the /home/tunnel/.ssh/authorized_keys file in the MyFW machine B.

I set the values in the ssh config files:

AllowTcpForwarding Yes
GatewayPorts yes

The purpose of this was to create a user at the firewall, to create and link tunnels while blocking any access attempt by a hacker. There is nothing of value on the real remote Machine A so it wouldn't matter much if a hacker trashed it.


To test, I setup a local tunnel on the remote Machine A, then attempted to ssh from Machine A to MyFW.

This works for a normal 'user':

$ ssh -L 9022:localhost:222 [email protected]
$ ssh localhost -p 9022

As expected, the first command creates the tunnel. The 2nd command tunnels ssh to the CLI of the machine on the other end.

but this doesn't work for the restricted 'tunnel':

$ ssh -L 9222:localhost:222 [email protected]
$ ssh localhost -p 9222

The CLI reports that the connection closes. There is nothing I can see in the syslog to show what the problem is.

Given that the tunnel user doesn't have a shell, should I expect a tunneled ssh to work?? As I write this I think maybe not. How should I test the tunnel?


What am I doing wrong??

Can someone please try this out and post a set of working instructions or errors in mine.

How can a tunnel with a restricted user be tested?


The user tunnel account was created without a password. This caused problems using ssh because the tunnel account was reported locked.

The fix for a locked account is at this link.

It seems that creating an account without a password, in an attempt to stop password hacking (can't hack a password if it doesn't exist), is a bad idea and weakens security.

2 Answers 2


use -N to make a tunnel only connection

ssh -N -L 9222:localhost:222 [email protected] &
  • You are probably right but I also think I need to amend my test setup. I tried to setup the simplest tunnel across my desk. I probably went too simple so that the tunnel doesn't work for a highly restricted user. The simple setup works for a simple user, but not for the restricted user. I am going to set up a reverse tunnel from a machine inside my network to my firewall. That will closely mimic the final setup aimed for. The setup will include the -N option. If that works, then I should be able to make an ssh connection through the reverse tunnel to the account of a normal user.
    – user643684
    Commented Jul 14, 2021 at 20:44
  • I went back through my command logs and found that I had already added the -N option prior to seeing your answer. I failed to accurately post the command I used. So yes, you were correct in identifying that the -N option is needed, but that was not the root cause of the problem. I tried to up tick the score but it wouldn't let me. Please note I am suffering the after effects of concussion so the brain is not working properly.
    – user643684
    Commented Jul 15, 2021 at 2:43
  • The -N option is essential when building a tunnel with a restricted user account. It was one of two problems identifiable in my question. My answer identified specific problems with my attempts. Your answer is of more general use. I accepted your answer.
    – user643684
    Commented Jul 15, 2021 at 3:38

Without changing any configuration files etc, I tried the following command sequence. These commands built a tunnel from the simulated remote machine to the simulated local firewall machine. The tunnel entrance was port 9222 on the remote machine.

On a terminal on the remote machine:

$ ssh -L 9222:localhost:22 -N [email protected]

to build a tunnel to the firewall at IP Note that if the -N option is not included, the connection automatically closes. The tunnel user only exists on the firewall and does not have a password. The tunnel user does not exist on the remote machine. ssh keys were exchanged in advance so the firewall accepted the connection to the tunnel user. The ssh command to build the tunnel remains in the foreground (just for testing). After entering the above command, the prompt does not appear. The prompt will only appear once the tunnel is closed with cntl-C This is expected behaviour.

In order to connect the remote machine to the firewall CLI, I ran the following command on the remote machine in another terminal.

$ sudo ssh -p 9222 fwuser@localhost

This command on the remote machine makes an ssh connection to the port 9222 at localhost (remote machine) to the fwuser account on the firewall machine. That was the root cause problem with my commands shown in the question. I had not specified the correct user (fwuser) in the failed command.

ssh thinks it is making a connection on the same machine that the command is being type in. It is actually making a connection to port 9222 and reaching through the tunnel to log-on as fwuser at the other end of the tunnel. I was running a terminal on the remote machine, but I had the prompt of the firewall machine.

Once the tunnel is built, the tunnel user is effectively invisible to the traffic flowing through the tunnel.

In summary, using a restricted user, without shell access, works just like any other user when building a tunnel. It does take a little more effort to exchange ssh keys. The -N option is essential in the command to build the tunnel.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .