A proxy that bridges simultaneous clients to a single connection - linux

I am looking for a tool (under linux) that will allow me to set up an end to end proxy that accepts multiple simultaneous clients on one port at one end, forwards the data to the other end with a single connection then "expands" the connection at the other end to connect back to a service that accepts multiple connections. To clarify, here is a diagram of what I want to achieve:
http://i.stack.imgur.com/rgTMd.png
(apparantly I need more then 10 rep to have the image embedded in this page)
If you're interested, the reason why I am attempting to do this is because I want to build a system that would make it easier to tunnel over arbitrary protocols, as long as the protocol supports some way to send some message from one end to another. I would put the system in between proxy end A and proxy end B in the diagram above.
Here is an example of how I want it to work:
First I will run the following commands
mkfifo backpipe
nc -l 7778 0<backpipe | tee f1 | nc localhost 7777 | tee f2 >backpipe
The "server proxy" will be running on port 7777.
The "client proxy" that the application will connect to will be running on port 8080
The client proxy will connect to port 7778
Solve for "server proxy" and "client proxy"

OpenSSH already supports this with the -D option:
ssh -D <port> -l username remotehost
A SOCKS server will listen for connections on and forward them to the other end of the SSH connection.

I've decided to code my own solution for the mean time. It's a bit of python code that accepts multiple clients and basically proxies the communication through the standard input/output. If anyone is interested, here's the code http://pastebin.com/1E45Exsy
Don't trust this code to work perfectly. I have not tested it properly and it doesn't handle disconnecting clients.
I will continue to search for a more elegant and robust solution, but this should do in the meantime. I'll post updates to the code here if I make them.

Related

Unable to establish TCP connections with server

I have 2 centOS-7 machines say machine A,B.
Machine A have a server listening on port 80. When i run curl-loader(for load testing purpose) with 2000 request per second in the same machine, all the request is hitting the server, i checked 'ss -s' command and open TCP sockets is more than 2000.
But my problem is when i run curl-loader in machine B and try to hit server A only few requests are reaching server, remaining all are dropping out.
in machine B 'ss -s' command returns 2K+ value. but in machine A 'ss -s' command will return only value 25-30. Remaining all request are returned are TCP-CONNECT error
#arkascha is probably right. Some throttling is happening. I would only add that the throttling could be in the network, in the server OR in the client. Any of them could be throttling the number of connections.
It's better to test it without any squid or high level software. You can just do:
(On server) $ echo hello | nc -l -k 10000
(On client) $ for ((i=0; i<2000; i++)); do nc :10000 & done
This will create a "mini" TCP server on the server machine on port 10000. Anyone that connects to that server will receive the message "hello".
Then from the client, you can create 2000 (almost simultaneous) TCP connections to the server on port 10000.
If the connections are successfully established, then the throttling is probably at the "proxy" level. If the connections appear throttled, then the throttling is likely at the firewall or network level.

linux command to connect to another server using hostname and port number

what is the Linux command to connect to another server using host name and port number?
how to connect to another server using only host name and port number then check if an existing process is running? the only way i see it working is to log in to the server and run the PS command. but is there a way to do it without logging in directly to the other server and connect only with host name and port number and check the running process?
If you just want to try an arbitrary connection to a given host/port combination, you could try one nmap, telnet or nc (netcat).
Note that you can't necessarily determine whether or not a process is running remotely - it might be running on that port, but simply ignore anything it sees over the port. To really be sure, you will need to run ps or netstat or etc. via ssh or etc.
If you want to use SSH from e.g. a script or, more generally, without typing in login information, then you will want to use public key authentication. Ubuntu has some good documentation on how to set this up, and it's very much applicable to other distrobutions as well: https://help.ubuntu.com/community/SSH/OpenSSH/Keys.
If you have no access to the server you're trying to list processes on at all, then I'm afraid there isn't a way to list running processes remotely (besides remote tools like nmap and so on, as mentioned earlier - you can always probe public ports without authentication [although you might make people angry if you do this to servers you don't own]). This is a feature, not a problem.
telnet connects to most of services. With it you can ensure that port is open and see hello message (if any). Also nc is more low level.
eri#eri-macro ~ $ telnet smtp.yandex.ru 25
Trying 87.250.250.38...
Connected to smtp.yandex.ru.
Escape character is '^]'.
220 smtp16.mail.yandex.net ESMTP (Want to use Yandex.Mail for your domain? Visit http://pdd.yandex.ru)
helo
501 5.5.4 HELO requires domain address.
HELO ya.ru
250 smtp16.mail.yandex.net
MAIL FROM: <someusername#somecompany.ru>
502 5.5.2 Syntax error, command unrecognized.
If there is plain text protocol you cat talk with service by keyboard. If connection is secured try openssl.
openssl s_client -quiet -connect www.google.com:443
depth=1 /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
verify error:num=20:unable to get local issuer certificate
verify return:0
GET /
<HTML><HEAD>
If protocol is not known you may see much of hieroglyphs or just Connected to ... message.
Try this :
ssh <YOUR_HOST_NAME> 'ps auxwww'
Like Dark Falcon said in the comments, you need a protocol to communicate with the server, a port alone is useless in this case.
By default on unix (and unix like) servers, ssh is the way to go.
Remote Shell with this command. Example is cat a file on the remote machine.
rsh host port 'cat remotefile' >> localfile
host and port self explainitory
remotefile: name of some file on the machine remote logging to in home directory
localfile: name of file cat information to.
Use monitoring software (like Nagios). It looks at your processes, sensors, load and thatever you configured to watch. It continuously stores log. It alerts you by email\sms\jabber if something fails. You can access it with browser or by HTTP API.

How can I tunnel Telnet connections between two interfaces?

I have the following network:
PC1 --|¯¯¯¯¯¯¯¯¯| |¯¯¯¯¯¯¯¯¯|-- board2
PC2 --| gateway |-- (eth0) [server] (eth1) --| gateway |
PC3 --|_________| |_________|-- board1
As you can see, the server (running Linux) has 2 interfaces so that the PCs and embedded boards are not on the same subnetwork.
I would like to develop a simple application (or use an existing one) that tunnels incomming Telnet connections from eth0 (using a specific port) to boards through eth1.
I don't have root privileges on the server, but I have a regular Unix account. I don't want the PCs to actually "log in" to the server; I just want them to pass through it to connect to the boards. The server has Python, PHP and Perl installed.
I want to support multiple connections. The port number could be used to forward the connection to the right board (say I have 10 boards, then the tunnel listens on ports 3000 to 3009).
I can imagine a simple Web application to do that, but I want a native Telnet connection that will support CTRL+C and all that stuff and allow you to use any terminal emulator on the PCs (i.e. PuTTY or another one), which run Windows.
Any help would be much appreciated.
It sounds like you're looking for a TCP proxy. A proxy accepts connections on one port, connects to another ip/port, and then passes traffic back and forth.
If you have xinetd on your system you already have what you need. The redirect directive for a service causes xinetd to open a connection to another host/port and act as a proxy. See this document for an example.
balance is another very simple proxy tool that will do what you need. This is probably easier to run as a non-root user, especially since it's configured entirely on the command line.
Since you're not root on your server you'll need to run these on ports > 1024, but otherwise you should be all set.

Debug smtp connection

I am using the perl module Net::Smtp_auth to send a mail to myself using the web.de SMTP server on port 25 (no encryption). It works well my computer. But I would like to use the same script to send notification messages about finished jobs on a different machine where I don't have root privileges. On this machine I get a timeout for the connection. I wonder in which way the connection is blocked, what might be the reason to block it (prevent spamers?) and if there might be a way to circumvent the problem. I have some linux tools available but no nmap.
Might the connection be influenced by proxy settings and, if yes, how do I tell it to SMTP_auth?
The perl script is basically the SMTP_auth example from cpan. But I do not expect that it is relevant here:
#!/usr/bin/perl -w
use Net::SMTP_auth;
$message=$ARGV[0];
$smtp = Net::SMTP_auth->new('smtp.web.de') or die "Failed to open SMTP connection: $!";
$smtp->auth('CRAM-MD5', 'adress', 'password');
$smtp->mail('adress#web.de');
$smtp->to('adress#web.de');
$smtp->data();
$smtp->datasend("To: adress\#web.de\n");
$smtp->datasend("From: adress\#web.de\n");
$smtp->datasend("\n");
$smtp->datasend("$message\n");
$smtp->dataend();
$smtp->quit;
If the other machines are in a different network than your home machine, it may well be that the ISP there is blocking outgoing port 25 to anything but their own SMTP servers, as that is a common spam-mitigation technique. The established convention is that for outgoing mail across networks, one should use port 587 (the SMTP submission-only port) instead.
An easy way to verify if the problem is your program or not is to try to telnet to that host and port. If telnet doesn't connect but other services do, your ISP is filtering port 25.

What's the easiest way to test a gateway?

I want to test a toy gateway I wrote. The testing will occur on Linux machines. I would like to do this in the easiest way possible, ideally writing no code and using existing utilities. This boils down to two questions:
Is there an existing utility that can send packets with simple stuff in them(like a string that I supply) to a host through a user-specified gateway, without reconfiguring Linux's network settings? If so, what syntax would I use for the utility?
Is there a simple utility I can run on the receiving end to verify that the correct packet was received? If so, what syntax would I use for the utility?
I don't know about the first, but I don't think it's that hard to modify your routing table:
route add -host 1.2.3.4 gw 5.6.7.8
(replace 1.2.3.4 by your target IP and 5.6.7.8 by the IP of your gateway).
For 2.:
On the target server type netcat -l 1234 and on the client then type netcat 1.2.3.4 1234. (1234 is a "random" port number)(depending on your distribution netcat might be called simple "nc".) If a connection gets established you can just type data on the client or the server machine, press enter and see the data arriving on the other machine.
The easiest would probably be the nc(1). Assuming your gateway IP is 192.168.1.1 and you are using TCP, then on the server, listening on port 8888:
~$ nc -k -l 8888
On the client:
~$ nc 192.168.1.1 8888
your input
...
^C

Resources