1

I have a local (local network, behind NAT router and firewall) Ubuntu machine and a publicly reachable (Ubuntu) server. I want to initiate a connection from the local machine to the server, then, on the server execute one specific Python script (no other commands or scripts) on the local machine. But here is the problem: I want to execute that Python script anytime in the future, sometimes multiple times after each execution. My first thought was a SSH tunnel like (executed on the local machine):

ssh user@remoteserver -R 21000:127.0.0.1:8081

But this doesn't get me anything. The next try I had was this answer here. But that executes the script at connection time, and then drops the connection after execution.

So finally, my question is: How can I establish a secure connection, initiated by the local machine to the server, on which I can execute Python scripts on the local machine on demand, not just on connection time of the SSH command?
(Please let me know if anything was just too confusing, and I will re-phrase parts of the question).

JJ Abrams
  • 185
  • If you have SSH access, and don't know in advance when or how often you will want to run the script, why is ssh user@remote.example.com /path/to/swanky_script.py on demand not a valid answer to this? – DopeGhoti Apr 02 '21 at 18:57
  • Thanks to both of you! I updated the question, because it seems to be missing the point made by @KamilMaciorowski I want to limit the execution to one specific Python script. – JJ Abrams Apr 02 '21 at 19:20

1 Answers1

2

There are few options, starting with this:

ssh -N -R 21000:127.0.0.1:22 user@remoteserver

This will create a tunnel to your local SSH server (assuming it's running and listening on the standard port 22). Anyone able to connect to localhost:21000 from the remoteserver will reach your SSH server (so they should use ssh for connecting). If they manage to authenticate, log in and get a shell, then in general they will be able to execute commands, including Python scripts.

See this answer of mine if you want to give access from the outside of remoteserver.

With local root access you can tweak this:

  • You can create a dedicated user and let the interested parties authenticate as this user.
  • You can use a restricted shell as the user's login shell to limit what they can do.
  • You can make the user's login shell automatically exec to a certain python script of your choice.
  • Or you can make the script be the user's login shell in the first place.

This approach may be most desired because your local SSH server will handle the authentication. Passers-by will not be able to execute the script.

Note the way a client connects to the tunnel with ssh, along with options used (-t, -T), determines if a tty is allocated for them on the server (i.e. on your local computer in this case).


Alternatively you can make your Python script available like in this another answer of mine. The initial command is:

# on your local machine
socat TCP-LISTEN:50011,fork EXEC:'/path/to/script',stderr,pty,echo=0

(See man 1 socat; you may want to bind to 127.0.0.1 only, using the bind= option.)

Then you create a tunnel to your local port 50011:

ssh -N -R 21000:127.0.0.1:50011 user@remoteserver

Anyone connecting to localhost:21000 on the remoteserver will reach your script without authentication. E.g. they can use nc for connecting.