I have a server (M: Main) that I trust very much (I have it home, locked, with an alarm, etc), to which I can SSH from the internet.

I also have a number of "remote servers" and "IoT devices" (O: Others) that I trust a bit less (because they are outside in the world, physically accessible to other people than me). "In theory", they are safe (for example, at the home of a family member), but still I trust these a bit less.

I want to be able to SSH to the "O" devices from the internet. I do not want to set router port forwarding at the location of the "O" devices, this would be too much hazzle. So, the solution I consider is to set up a reverse ssh tunnel for each "O" device that forwards connections from some port of "M" to port 22 on the corresponding "O" device.

For this, I have to set up SSH keys on the "O" devices, to connect to some account on "M" to perform the ssh -R command. To enable automatic reboot in case of a problem, this SSH key needs to be usable by "O" out of the box, without me to enter any passphrase, ie the SSH must be available fully decrypted on "O". So, I cannot really fully trust the "O" keys (they may get stolen or else), when used to log onto "M", and I do not want people having access of these keys to be able to do anything on the "M" machine else than ssh port forwarding.

My question is, how to make this as well and secure as possible?

The solution I have found so far is to set up a very limited account on "M", that only allows to perform the port forwarding. For this, I:

  • create the user (user_r) on "M", with user_r not being able to sudo
  • set up a SSH key to log to user_r, and disable password ssh login for "M"
  • change the default shell for "M" by editing /etc/passwd for user_r to /usr/sbin/nologin

From there on, it is possible to establish a SSH reverse tunnel that forward from "M" to "O", by running on "O":

ssh -NR M_PORT:localhost:22 user_r@M_IP_OR_DOMAIN

Dropping the N, or trying to "ssh in a normal way", using user_r account on "M", just returns immediately and says that the account is disabled, but using -NR still lets me set up the reverse tunnel.

My questions:

  • is this secure?
  • is there a way to make this even more secure?
  • any flaws / possible improvements / better solution?
  • 2
    You might want to consider running SSH as a TOR hidden service on the "O" devices. This way, you'll be able to access these devices remotely via SSH, without setting up port-forwarding on the NAT routers in front of these devices, and without having to allow these devices access to your trusted server to create a reverse-ssh tunnel. For more info, see thomas.inf3.ch/2019-03-11-tor-ssh/index.html.
    – mti2935
    Commented Mar 7, 2022 at 10:50
  • 1
    If I understand well, 1) this sets up a TOR "server" on "O" (though "O" will not serve anything to "normal" people, right? I.e., the TOR network cannot use "O" as an entry / end / bouncing point right?), 2) this "server" gets an address in TOR that can be used to reach it (though there is not much "normal" people can do), 3) for me, who has the SSH key, I can use this TOR address to log safely on "O" with SSH? This sounds really nice. The only thing that is "scary" for me is that it relies on TOR, which I know little about - I will have to learn about it to be sure I understand what I do :) .
    – Zorglub29
    Commented Mar 7, 2022 at 11:44
  • 1
    Btw, this means that using this method instead of the "classical" DNS registration, I will never need again to set up some DNS registration for the servers I want to be able to SSH to, right? I.e. I this just uses the TOR hidden service and use it "as I would have with a DNS"?
    – Zorglub29
    Commented Mar 7, 2022 at 12:05
  • 1
    Yes to all of the above. With regard to your question about connecting to the SSH server running as a TOR hidden service on one of the 'O' devices - the hidden service would have an address on the TOR network (like wei66g5djlymzxhr.onion), and you would need to have TOR running on the client that you are connecting from. See nurdletech.com/linux-notes/ssh/hidden-service.html (last section) on how to make the connection.
    – mti2935
    Commented Mar 7, 2022 at 12:23
  • 1
    Ok, so this is the "only" extra hurdle: the client connecting to "O" will always have to go through the TOR network, so will have to have it set up :) . Understood, makes sense, thanks for pointing that out :) . Is there any more drawback to using a TOR hidden service? Higher latency / lower speed I guess, but any more issues?
    – Zorglub29
    Commented Mar 7, 2022 at 12:43

1 Answer 1


Your SSH settings are solid and well protected, with only one fatal flow: port forwarding.

One attacker can start connections to your main server, but nothing stops him to forward to other ports inside your secure network. If he can run ssh -R, he can run ssh -L too, and access your router, cameras, and other IoT devices connected on your network, or even ssh -D and use your main server as a proxy, allowing him to run nmap on your network, or access the internet using your main server IP while doing so.

You could do is to setup your own tunneling solution. Something like ngrok, but self-hosted. There are several solutions, so it will be easy to pick one. Host your tunneling solution on your main server, run the client on the IoT devices, and you are done: you can access anything from your main server.

  • Aaah, thanks for pointing that out. So what you mean is, doing a SSH -L, the attacker can forward his local port to a port on "M", and from there he can try to ping my whole network to find vulnerable devices and do nasty things with these, right? That would be bad... Is there a simpler option than installing "yet another piece of software", like disabling local, but not reverse, port forwarding on "M"? For example superuser.com/questions/229743/… answer by Markus Rathgeb, i.e. in sshd config "AllowTcpForwarding=remote". Would that do it? :)
    – Zorglub29
    Commented Mar 7, 2022 at 9:53
  • The interesting thing is that I was not able to find the superuser discussion I link to before, but knowing what I should google thanks to your answer it came up immediately ^^ :) . Thanks again.
    – Zorglub29
    Commented Mar 7, 2022 at 9:56
  • 1
    And using ssh -D, he uses your main server as a proxy.
    – ThoriumBR
    Commented Mar 7, 2022 at 10:02
  • But that will not be possible with the "AllowTcpForwarding remote" setting I think, right? :) Will check / test tonight :) .
    – Zorglub29
    Commented Mar 7, 2022 at 10:46
  • This discussion was very helpful to me so I'm posting this link here, which clarifies the use of AllowTcpForwarding. From what I can determine, it looks like setting AllowTcpForwarding=remote would actually prevent local and proxy forwarding (-L, -D, and -W), allowing only remote port forwarding to be enabled (-R). Link to discussion: superuser.com/a/1767149/283641 Please comment if I'm incorrect about this and if there's still an attack vector present. Commented May 21 at 19:58

You must log in to answer this question.

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