[asyncssh]: Reverse ssh tunnels with python asyncssh - paramiko

I am looking to use asyncssh with python3.7 (asyncio)
Here is what I want to build:
A remote device would be running a client that does a call-home to a centralized server. I want the server to be able to execute commands on client using reverse ssh tunnels on the incoming connection. I cannot use forward ssh (regular ssh) because the client could be behind NAT and server might not know the address of the client. I prefer client doing a call-home and then server managing the client.
The program for a POC should use python3 + an async implementation of ssh. I see asyncssh as the only viable choice (please suggest if you have an alternate):
Client: Connect to server and accepts reverse ssh tunnels to be opened on same outbound connection
Server: Accepts connection from client and keeps the session open. The server then opens reverse ssh tunnel to the client. For e.g. the server program should open 3 reverse ssh tunnnels on the incoming connection. Each of these tunnels would run one command ['ls', 'sleep 30 && date', 'sleep 5 && cat /proc/cpuinfo']
Server program should print the received response for each of these commands (one should come back amost immediately, other after 5 and other after 30).
I looked at the documentation, and I could not see examples of using multiple reverse ssh tunnels.
Anyone has experience using this? Can you point me to examples?

Developer of asyncssh has provided an example:
As of now, this is in develop branch. I have tested it and it does the job perfectly!
https://asyncssh.readthedocs.io/en/develop/#reverse-direction-example
[If you are checking this after a while, you might find it in master documentation.]

Related

Why does Nginx Proxy Manager Stream won't work?

I'm currently trying to setup a tunneling tool, specific for game servers.
So you can start the server locally and everyone can join without open your ports or getting unsecure.
Basicly I do a reverse ssh tunnel to one of my dedicated linux servers where the game port get mapped to a different port (for example 8888). So the server is now exposed to the internet and available for anyone and the user don't have to get unsecure and open his own ports. Everyone can connect to the following ip: SERVERADRESS:8888.
The command which gets executed looks like this:
ssh -N -R "*:8888:localhost:25565" root#SERVERADRESS
This works fine just as i want. But I also want to secure my "forwarding" server, so I'm relativ new to networking but I found reverse proxy's. I watched some tutorials and I installed the "Nginx Proxy Manager" tool which comes with a web interface and looks very good and easy. So there is an option to create an Stream (Picture below), there you can enter the incoming port and the forward Host + port, for example: REVERSEPROXY:7777 -> FORWARDINGSERVER:8888. So with this I want to hide the ip adress from the server where all the ssh tunnels. Sadly this Stream tool won't work, I already saw some other topics with that. They all said to enter the port into the docker-compose.yml which I already did + restart. But for now it won't work. Any other soloutions for this problem? Or completly different ideas to protect my server?
https://i.stack.imgur.com/FolLe.png https://i.stack.imgur.com/KuJbt.png https://i.stack.imgur.com/2SN4a.png https://i.stack.imgur.com/9kzbj.jpg
I try to do my own tunneling tool, but with a protection so that my server getting damaged.

Connect to a remote Jupyter runtime over HTTPS with Google Colab

I'm trying to use Google's Colab feature to connect to a remote run-time that is configured with HTTPS. However, I only see an option to inform the port on the UI, not the protocol.
I've checked the Network panel and the website starts a WebSocket connection with http://localhost:8888/http_over_websocket?min_version=0.0.1a3, HTTP-style.
Full details of my setup:
I have a public Jupyter server at https://123.123.123.123:8888 with self-signed certificate and password authentication
I've followed jupyter_http_over_ws' setup on the remote
I started the remote process with jupyter notebook --no-browser --keyfile key.pem --certfile crt.pem --ip 0.0.0.0 --notebook-dir notebook --NotebookApp.allow_origin='https://colab.research.google.com'
I've created a local port forwarding with ssh -L 8888:localhost:8888 dev#123.123.123.123
I've turned on network.websocket.allowInsecureFromHTTPS on Firefox
I've went to https://localhost:8888 and logged in
Naturally, when the UI calls http://localhost:8888/http_over_websocket?min_version=0.0.1a3 it fails. If I manually access https://localhost:8888/http_over_websocket?min_version=0.0.1a3 (note the extra s) it gets through.
I see three options to solve it:
Tell the UI to use secure WS connection
Run a proxy on my local machine to transform the HTTPS into plain HTTP
Turn off HTTPS on my remote
The last two I think will work, but I wouldn't like that way.
How to do #1?
Thanks a lot!
Your option 1 isn't possible in colab today.
Why do you want to use HTTPS over an SSH tunnel that already encrypts forwarded traffic?

Can "Monit" monitor the processes running on remote servers?

I want to setup monit on a server which is going to be a centralized server to monitor processes running on remote servers. I checked many docs related to setup monit but could not find how to setup for remote server processes. For example a centralized monit server should monitor nginx running on A server, mongod running on B server and so on. Any suggestion how to do this?
In the documentation, Monit can be able to test the connection remotely, using tcp or udp, what you can do is to provide a small status file that gets refreshed for each technology you are intending to monitor, and let Monit hit that status file through http, etc. and can be used as follows:
check host nginxserver with address www.nginxserver.com
if failed port 80 protocol http
and request "/some_file"
then alert
Since you are testing a web server that can be easily accomplished with the above. as a note , below is the part about Monit connection testing:
CONNECTION TESTING Monit is able to perform connection testing via
networked ports or via Unix sockets. A connection test may only be
used within a check process or within a check host service entry in
the Monit control file.
If a service listens on one or more sockets, Monit can connect to the
port (using either tcp or udp) and verify that the service will accept
a connection and that it is possible to write and read from the
socket. If a connection is not accepted or if there is a problem with
socket i/o, Monit will assume that something is wrong and execute a
specified action. If Monit is compiled with openssl, then ssl based
network services can also be tested.
The full syntax for the statement used for connection testing is as
follows (keywords are in capital and optional statements in
[brackets]),
IF FAILED [host] port [type] [protocol|{send/expect}+] [timeout]
[retry] [[] CYCLES] THEN action [ELSE IF SUCCEEDED [[]
CYCLES] THEN action]
or for Unix sockets,
IF FAILED [unixsocket] [type] [protocol|{send/expect}+] [timeout]
[retry] [[] CYCLES] THEN action [ELSE IF SUCCEEDED [[]
CYCLES] THEN action]
host:HOST hostname. Optionally specify the host to connect to. If the
host is not given then localhost is assumed if this test is used
inside a process entry. If this test was used inside a remote host
entry then the entry's remote host is assumed. Although host is
intended for testing name based virtual host in a HTTP server running
on local or remote host, it does allow the connection statement to be
used to test a server running on another machine. This may be useful;
For instance if you use Apache httpd as a front-end and an
application-server as the back-end running on another machine, this
statement may be used to test that the back-end server is running and
if not raise an alert.
port:PORT number. The port number to connect to
unixsocket:UNIXSOCKET PATH. Specifies the path to a Unix socket.
Servers based on Unix sockets always run on the local machine and do
not use a port.

The server rejected SFTP connection, but it listens for FTP connections

When I use WinSCP in Windows to connect to VMware with Ubuntu, it prompted this:
The server rejected SFTP connection, but it listens for FTP connections.
Did you want to use FTP protocol instead of SFTP? Prefer using encryption.
What's the matter?
I can succeed to ping Ubuntu in Windows.
The fact that you can ping the server has nothing to do with what protocols it supports.
The message says that the server does not listen on port 22 (SSH, SFTP), but listens on port 21 (FTP). The point of the message is that WinSCP defaults to SFTP protocol, what is not common. So it tries to help users who expect FTP to be a default. But that's not relevant to you apparently.
As #ps2goat suggested, make sure you setup SSH/SFTP server.
For more details, see the documentation for the error message The server rejected SFTP connection, but it listens for FTP connections.
If you see this error all of a sudden (when SFTP has always worked for you for this particular server), and if you are using CSF (ConfigServer Security & Firewall), then it might be that your IP was blocked for SSH access. Try flushing all blocks. Also, try restarting the SSH server.
Old question but still responding so others might get benefited.
I stumbled upon this error and the first thing I checked was if my ubuntu machine had ssh installed. It was there and the latest version and I still would get this error.
As long as you have ssh access to the target, check the ssh service status and most certainly it'd be found inactive. Turn it on using
sudo service ssh restart
and you should be back in the game.
Do check the status of the SFTP by using
sudo service ssh status
and take any corrective action.

Why is "fork" needed by socat when connecting to a web server?

I am trying to understand tcp connections between a browser and a web server. I have a web server running on my local machine, and can browse to it just fine, as expected, using localhost:3000 or 127.0.0.1:3000. (I am running "rails s"and WEBrick.)
I wanted to put a software intermediary between the browser and the web server, and so began experimenting with socat. The following works just fine:
socat TCP-LISTEN:8080,fork TCP:localhost:3000
I can browse to localhost:8080 and things work as expected. However, if I omit the ",fork" argument like so,
socat TCP-LISTEN:8080 TCP:localhost:3000
the local rails web site is quite broken looking in the browser.
Why is that fork argument necessary? Why wouldn't a browser <--> web server connection work without it?
Without the fork, socat will accept a single TCP connection, forward data bidirectionally between the two endpoints for as long as that connection remains open, then exit. You can see this yourself easily:
Run socat in one terminal window
Telnet to localhost 8080 in another terminal window. It connects to the socat instance.
Telnet to localhost 8080 in a third terminal window. You get a connection refused error, because socat is not listening for new connections anymore: it has moved on to servicing the one it already got.
Type an HTTP request into the second terminal window. You'll get an HTTP response, and then socat will exit as the connection is closed.
The fork option just makes it fork a new child to process the newly accepted connection while the parent goes back to waiting for new connections.
socat's use of fork() rather than something more sophisticated like preforking or connection pooling is the reason you wouldn't want to implement high-performance middleware with socat!

Resources