How to provide "reverse ssh" to a shell? - linux

Scenario:
Many embedded devices (running Linux) out in the fields, behind routers so NAT'd and we can't make connections to them.
We need for a support person to be able to initiate a terminal/shell session on any of the devices.
Their local terminal will also be NAT'd behind a corporate firewall, so we need some central "meeting point" that both they and the device can connect to.
If necessary, we could require the support person to log into some sort of terminal server, but I'd prefer a solution that just popped up a terminal window on their desktop.
We can (through other means) tell the device to execute some arbitary script or application to start up the session.
Without the NAT, it's just SSH to the device and away we go. But what are my options in this NAT'd environment?
We're OK to develop code at either end or at the meeting point server if required, but obviously if there are apps out there so we don't have to write stuff, even better.
Pointers to other questions I may have missed (although I have looked) or to applications that I should consider for the central "meeting point" server welcomed

How about simply setting up an ssh server that is reachable by both the device and the support user, and have the device set up a reverse tunnel (using remote port forwarding)?
ssh -R 10022:localhost:22 device#server
Then the support personnel can simply connect to the server and log on using
ssh -p 10022 localhost
Of course there are several security aspects that need to be accounted for here, depending on what kind of information the devices hold/have access to and how the support organization is set up.

SSH is an adequate tool for this. You will, as you say, need a middle-man server. But it would be very easy to set up, assuming that your 'other means of executing a script' are remote and can be executed from your office.
So, fire up a new server on a global IP (an Amazon AWS micro node is free for a year and would do the job just fine), and install an ssh deamon. Say it has the hostname middleman.example.org.
The script to put onto your embedded devices would look like;
#!/bin/bash
ssh -i ./middle_id.pem -R 22:localhost:2222 middleuser#middle.example.org
(The private key authentication would be a way of making the login non-interactive)
The script to put onto your desktop machines would look like; (assuming the argument $1 is the IP of the embedded device, and that prod_remote_device.sh executes the above script on the chosen embedded device.)
#!/bin/bash
./prod_remote_device.sh $1
ssh -i ./device_id.pem deviceuser#middle.example.org:2222
And that should forward your connection to the embedded device.

In order to make it bind to all interfaces, use:
ssh -N -R 0.0.0.0:2222:localhost:22 root#example.com
Don't forget to edit /etc/ssh/sshd_config and go to GatewayPorts and enable it and set it to yes.
And Then connect to it from any Loopback or Ethernet interface.

Related

How to connect to an integrated VM without using SSH tunelling

I want to connect to a locked (cannot be modified and I do not have permissions to log into) windows vm which is hosted in a linux machine. Until now these two machines were communicating via port 2277. However for security reasons, the port 2277 is only accessible via localhost (127.0.0.1).
The original proposed solution was to use ssh-tunneling. However since the hosted windows vm will always stay with the linux machine, so I was thinking something simpler.
This Windows virtual machine has ip 192.168.0.1 and the default gateway is 192.168.0.2. The later is the ip address that my linux machine can see.
After searching the internet I tried
socat TCP4:192.168.0.1:2277,reuseaddr,fork TCP4:127.0.0.1:2277
as well as some other random combinations without success.
My understanding is that this failed because for socat to work both sockets must be open.
However the first one is not open by default (checked with ss -ltn) as I need to run the windows service first (which it cannot run as it cannot communicate with iphost:2277)
Any ideas on how to proceed?
Socat provides the retry=N and forever options to handle situations like this. Thus, try something like this:
socat -d -d TCP4:192.168.0.1:2277,reuseaddr,fork,forever TCP4:127.0.0.1:2277
With the interval=<seconds> option you can specify how long Socat waits after each failed attempt.
It turns out that the command that I wanted was the following
socat tcp-listen:2277,bind=192.168.0.1,fork,reuseaddr tcp:127.0.0.1:2277
The retry=N and forever options could be also useful.

Remote SSH/SFTP with Netbeans

I know you can set up remote connection in Netbeans or as others have suggested, mount the remote file system locally and let Netbeans read that.
This current set-up I have to SSH into a remote server and then SSH again into another one.
Is it possible in Netbeans to access the filesystem on the 2nd server hop?
I think you can setup a SSH local port forwarding on your first remote server to archive what you want here. Once ssh connection established with the first server, it will be tunnel to second server. Also, will be much more convenient if using SSH public key as authentication method.
Run below command on your local (Need to keep this running)
ssh -NL 2222:server2.example.com:22 server1.example.com
Test connection with ssh locally
ssh localhost 2222
So in your case, Netbeans just need to connect to localhost port 2222.
Ref: https://www.ssh.com/ssh/tunneling/example
That isn't answer you expect, but to big to put it in comment.
I think best solution is configure autostart some service which will create tunnel to first server on your login and bind local port (let's say 2222) to second remote server ssh port. This is basical feature of ssh client. When you can configure Netbeans to connect to localhost:2222 and login right into second server. You might need to use keys authentication for first server.
Where are examples to make such thing. Like is underneath link on article
http://www.pc-freak.net/blog/start-ssh-tunnel-pc-boots-windows-alwaysup/
Since you can get ssh access via a daisy-chain, you can very likely use SSHFS:
https://github.com/libfuse/sshfs
Available in Debian (and therefore, likely many other distributions):
https://packages.debian.org/jessie/sshfs
As long as you have ssh keys set up properly on each server, you can daisy-chain mounting via SSHFS to the machine where your NetBeans app is running.
https://en.wikipedia.org/wiki/SSHFS
NOTE: There are some caveats, including that SSHFS expects that it is the only mechanism used to update the filesystem, and that there is only one writer at a time. Undesirable behavior can occur if you allow other mechanisms to change the files or directories on the target server, including data loss and/or corruption.

Script for merging two SSH connections together?

I'm trying to write a bash script to merge 2 already-existing SSH connections.
For example, if I have an embedded device automatically creating an SSH connection to my server (from behind a firewall), how can I connect to that server in the middle, and jump into the already-existing connection from that embedded device?
I have looked into the possibility of using the server as a 'jump host', but it seems like I will need to reliably determine (and send SSH requests) to that embedded device?
I have also looked at having the embedded device create a 'screen' on the remote server and connect to that, but that just seems like it would be operating on the remote server.
I'm sorry if this is the wrong place to ask this, but I don't know where else to ask.
It sounds like your requirements are going to need either a uPNP solution or tunnelling solution to get through your firewall. The following link discusses reverse SSH tunneling as one part of this solution.
https://unix.stackexchange.com/questions/46235/how-does-reverse-ssh-tunneling-work

How to attach ttyS to screen and capture it simultaneously

For capturing ssh sessions I use "script" command: "script -c 'ssh user#host' outfile". But I have no idea how to capture sessions to remote hosts, that connected over com(serial) port.
screen script -c 'screen /dev/ttyS0 57600' file
ends immediately with empty log. Both 2 functions that implemented in screen is necessary: ability to switch between opened sessions and ability to perform i/o to /dev/ttyS. I started develop some tiny utility to redirect stdin/stdout to /dev/ttyS but now it's so buggy and doesn't work yet.
First off, a terminal program, like minicom (or good-ol cu), as suggested by Laszlo, is needed to communicate with the remote system. Once you can get such a program to work, then screen can be brought into the picture. Note that this also requires a getty running on the remote computer's serial port. If it's an old-fashioned serial port, you may also need a special null-modem cable.
Screen can be used with such a connection to be able to move access of the session across terminals. However, it cannot be used to spawn more than one session with the remote server. That's because the program running on the serial port (getty) only supports a single session. In this case, the screen runs on the local machine, and the terminal-program session running within screen connects to the remote server. So, it is possible to have multiple screens, but just not more than one connected to the remote server over a single serial port.
With all of that said, serial ports can be used to network two machines, assuming both support the same serial-line networking protocol. Networking eliminates these restrictions.
To open an interactive terminal session to a COM port (/dev/ttyS*), you probably want to use a terminal emulator software, like 'minicom'.

SSHFS through multiple connections

I have to occasionally work remotely. In order to do so, I have to connect to a gateway server, through which I can then connect to the development server. At work I can connect directly to the dev server. I use SSHFS to map the remote folder to a local one (in Ubuntu). My colleagues don't seem to mind using vim for all of their work, but I really prefer and IDE. I know that using just ssh I can tunnel through multiple connections (ssh -t server1 ssh -t server2), but I'd like to do the same with SSHFS. Does anyone know how this could be accomplished?
Yes, it can be done. For this, the remote server has to support local port forwarding (which might be disabled for security reasons). What you bascially do, you instruct the remote server to open a tunnel to a server in the other network for you:
ssh -fL 127.0.0.1:someport:host.in.the.remote.net:22 proxy.host
someport should be an unused port on your machine (for example 2222), host.in.the.remote.net should be the hostname or IP of the development machine you eventually want to connect to, from within the network of the proxy.host, which is the intermediate server you have to go through. -f instructs ssh to detach from the terminal after the connection is established.
You run this command, and after it is in the background, the remote machine's ssh port can be referred to as 127.0.0.1:someport and can be used as such by sshfs. I don't know of a way to automate this though, but you should easily be able to script it.
Make sure you clear this action with the remote administrator beforehands if you're unsure about the policies. You may need to change the 22 in the first command if the development machine serves ssh on a different port.

Resources