Bi-directional communication using sockets via ssh tunnel - sockets

I have a server host (S) and a bunch of clients (C1, C2, C3, ...). I would like to open connection between S and C1, C2, C3 respectively for bi-directional communication. Ideally using sockets. SSH for authorisation purposes is preferred.
Ideally:
Client C1 creates SSH reverse tunnel to S, forwarding C1's port so it is accessible on S as it's own port.
Client program running on C1 creates a socket and binds to forwarded port.
Server program running on S creates a socket and binds to forwarded port.
Client and server can exchange data.
Is something like that possible? I tried coding up a draft using Python but to no avail:
Firstly, I run on C1: ssh -N -R 9999:localhost:15432 root#example.com - OK
Secondly, on server I run:
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 9999))
serversocket.listen(5)
while True:
connection, address = serversocket.accept()
buf = connection.recv(64)
if len(buf) > 0:
print buf
break
Thirdly, on client I run:
import socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 15432))
clientsocket.send('hello')
But I'm getting socket.error: [Errno 111] Connection refused on client. Also if I set up tunnel first and then launch server program, I'm getting [Errno 98] Address already in use. It only works when I first start the program, then set up a tunnel.
If aforementioned concept does not make sense, what would you suggest to create sort of synchronisation tool so any client listens for queries from the server and can respond with data? (preferrably in Python).
Thanks in advance.

-N doesn't do what you seem to think it does: it's intended for the ssh-destination to be able to connect back to the originator. But that would make the originating side the server.
It sounds like you should be using -L to simply create a connection from the client through the ssh tunnel to the server.
To demonstrate: I have a local server named 'bree'. On that machine, I execute (this could also be your python server listening on port 9999):
nc -l 9999
Now on my client machine, I execute this in one window (or could put it in the background):
ssh -N -L 9999:bree:9999 bree
This says: listen on the local (client) machine to port 9999, and when a connection to it is made, forward the request through the tunnel, and connect to port 9999 on bree.
Now, in a second window on the client machine, I execute:
nc localhost 9999
The two nc instances are connected.

Related

How can I check a socket from a webserver?

Im doing a challenge (CTF style) and everyting we got is an IP.
Scanning that IP only one port is open.
If I connect to that IP and port using netcat, I got a kind of "dance" doing in CMD, with a message at the end that says "Check socket 12345".
I need to understand again what truly a socket is because im not getting anywhere trying to connect to that socket.
Its possible to connect to a socket from a specific port? or I only can make a connection from a open port and there the web servers redirect my connection automatically to a socket?
You can use netcat nc and its -p option to set the source port.
Netcat man page say:
-p port
local port number (port numbers can be individual or ranges: lo-hi [inclusive])
Try "nc -p 12345 dest_IP dest_port"

How to ping to my local machine from AWS EC2 instance?

I have started an ubuntu instance on AWS EC2
e.g. [ec2-user#ip-XXX-XX-XX-XX ~]$
Inside this instance, I am running a socket program for sending the data to my local system.
The program is running properly, but not able to connect to my local IP.
I am trying to ping my local system also from AWS ec2 user, but it is also not working.But I am able to ping google(8.8.8.8).
e.g. [ec2-user#ip-xxx-xx-xx-xx ~]$ ping xxx.xxx.xx.xx(my local IP)
I have set all security groups(inbound), like All Trafic,All TCP and so on.
Sorry for bad English.
Thank You
Your computer (PC) cannot be pinged from an AWS hosted machine
This is probably because the VM on your computer is using NAT outbound to talk to the LAN, which goes to an Internet router, which sends the packets to AWS
The reverse route (inbound to your PC) does not exist so starting a ping echo request from a AWS machine will not work
It is possible to get around this by opening a pass through on your router but generally this is not a great idea
However if you want to make a socket connection securely there is a way
First, start a ssh session with remote port forwarding. In the Linux ssh client this is using the -R option.
For example, if your local system is running a listening service on port 80 and your remote system has the address of 54.10.10.10 then
ssh -R 8080:localhost:80 ec2-user#54.10.10.10
Will establish a circuit such that connections to the "localhost" on the remote ec2 server on port 8080 are connected to the "localhost" on port 80 of your local machine
If you are not using a ssh cli program, most ssh clients have a facility of this sort.
Note that it is necessary to keep the ssh session open to be able to use the connections

Python sockets will not connect

I'm trying to run a server and a client on two separate Windows 7 machines on the same network using sockets in Python 2.7. First I'm just trying to get them to connect before trying to do anything.
Currently my server is:
import socket
host = '0.0.0.0' #Also tried '', 'localhost', gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, 12345))
s.listen(5)
cs, addr = s.accept()
print "Connected."
My client is:
import socket
host = '127.0.0.1' #Also tried 'localhost', gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(host, 12345)
print "Connected."
The error I get is:
socket.error: [Errno 10061] No connection could be made because the target machine actively refused it.
I've looked through lots of other questions but none of the answers solved my problem. Any help is appreciated.
When I use the IP address of the server (10.0.63.40) as the host for the client, I get
[Errno 10060] A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host has
failed to respond
You are saying these are two separate machines. You cannot reach the one machine from the other by connecting to 127.0.0.1 or localhost.
Listening on 0.0.0.0 is fine, this means that the listening socket is reachable from all interfaces, including the local network.
However, for connecting to your server, you obviously need to use the IP address (or hostname, if you have properly set up a local name server) of your server machine in the local network.
Per your comment, the local IP address of your server machine is 10.0.63.40. That means you should end up calling s.connect("10.0.63.40", 12345).
I had the same problem when I tried to connect my client code with server one. It got resolved my by using this command:
socket.gethostbyname(socket.gethostname())
: note[ I run it locally not uploaded it into a live server]

TCP/IP default port for sending console messages?

Is there a dedicated port (lower than 1024) specifically for clients to send text based console output to a server? I've googled extensively but to no avail. What's the best port (lower than 1024) for sending text based console output if any?
A port is just a number. You can see well known port assignments in /etc/services.
You need a server application to be listening on the given port to accept your input. There are number of remote terminal protocols and their implementations, among which are Telnet (port 23) and Secure Shell, or SSH (port 22).
The simplest way to test your socket client is to setup netcat on the server to listen on whatever port you want (port is 777 in the example bellow), and then try to connect to it from somewhere else:
server:~# nc -l -p 777
then
client:~$ nc server 777
Note that on Unix you normally need super-user (root) rights to bind "privileged", i.e. bellow 1024, ports.
I'm going to use telnet (port 23) since that's closest to what I want. Sending console messages to a server from a client. okey dokey thanks!

Establish a TCP Socket connection using an intermediate host

I need to establish a Socket connection (TCP) between two hosts (say host1 and host2) in Java. But looks like I can't do that because of a firewall. Though there's a third host (say host3) which is accessible from both host1 and host2 and I think can be used as an intermediate for this connection.
So basically, I want to send a request from host1 (client) to host3, which redirects my request to host2 (server).
Could you please let me know how can this be achieved?
Thanks in advance!
You could establish a SSH tunnel with
ssh host3 -L4321:host2:6523
and then connect from host1 to host3 on port 4321. This effectively gets redirected to port 6523 on host2.
A similiar option could be to have ssh provide a SOCKS server.
ssh host3 -D 6543
and then use curl instead of wget.
Then you can do
curl http://host2/foo/bar --socks4 localhost:6543
(untested, --socks4a and --socks5 could be an option as well...)
This ssh command creates a SOCKS server locally which tunnels the connection attempts to the ssh server, which in turn executes them.