Listening to EVERY port on a machine - linux

For testing purposes I want to build a server that listens for TCP connections to every port (or at least on most of the ports) on a certain interface (e.g., eth0). The server is accessed via SSH to eth1, so no problem there. (I do not care about UDP or other protocols)
I want to do a special kind of middlebox detection/analysis, therefore I need to be able to fully establish a connection. Having an HTTP connection would be the best, because the "client" could be implemented as JS in the Browser.
I started with a simple jetty server, but had to realize that jetty needs to spawn at least on thread per port it is listening to. This leads to problems when I want to listen to several thousand ports. Or is there a way around that?
My next try was to use iptables:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 127.0.0.1:8080`
It seemed to work. It allows to connect on every port and the traffic gets routed to the local port 8080 where jetty listens. But now I no longer know which port was used by the client. Because jetty thinks the connection was established via port 8080. Is there a way to determine the real incomming port from jetty? I could send the port as part of the HTTP request, but if the client tries to contact port 1234 .. and a middlebox redirects this to port 5678 .. I am unable to know what port was used.
I also tried userland solutions like socat. The problem was even worse than before. Because now jetty also saw the remote IP as being 127.0.0.1.
Or, is there another way to achieve this?
Oh and btw: I have full control of the machine. So I could change the kernel or whatever is needed. Right now I use Ubuntu 14.04 LTS, but if a solution needs something else I could go with that.

NB: This is a Python solution, because I know Python, but you can accomplish the same thing in any language the exposes the underlying C library getsockopt call.
If you replace your DNAT rule with a REDIRECT rule, you can then
use getsockopt with the SO_ORIGINAL_DST option to retrieve the
original address of a REDIRECT-ed connection.
Consider the following code:
#!/usr/bin/python
import socket
import struct
SO_ORIGINAL_DST = 80
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 2000))
s.listen(10)
while True:
csock, caddr = s.accept()
orig_dst = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
orig_port = struct.unpack('>H', orig_dst[2:4])
orig_addr = socket.inet_ntoa(orig_dst[4:8])
print 'connection from', caddr
print 'connection to', (orig_addr, orig_port)
print
If I have an iptables rule that looks like:
# iptables -t nat -A PREROUTING -p tcp --dport 1500:1600 \
-j REDIRECT --to-port 2000
And while the above Python code is running I connect from another
host to my_ip_address:1500, I see:
connection from ('192.168.1.20', 35790)
connection to ('192.168.1.75', (1500,))
And if I connect to port 1550 I see:
connection from ('192.168.1.20', 42054)
connection to ('192.168.1.75', (1550,))
Which I think is exactly what you were asking for. Note that to my knowledge this will only work for TCP connections; there are other solutions (possibly involving the TPROXY iptables target) that may work with UDP connections as well.

Related

Linux/MacOs - Know which process filter UDP 443 packets

Is there a way, on Linux / MacOs to find which process is filtering my UDP packets on a specific port ?
Here some details and why I'm asking:
On my MacOs ( Mojave 10.14) , if I try to send a UDP packet to any address ( DNS resolves correctly) to port 443, I cannot see anything leaving my laptop ( using tcpdump)
If I do the exact same test but for a different port , for instance 444, I can see the packet leaving ( on tcpdump).
There is a process which is filtering UDP packet to port 443 and I want to know which process it is ( Firewall disabled on my mac).
The exact commands I'm using for my tests :
sudo tcpdump udp port 443
nc -u IPADDRESS 443
I type something stuff here..
==> I cannot see anything going through
sudo tcpdump udp port 444
nc -u IPADDRESS 444
I type something stuff here..
==> I can see a datagram leaving my interface
I know this can be tricky to find which process might be filtering this port.. If anyone has an idea, would be great.
I would not want to rely on the method ' Kill everything until it works'

Linux, CentOS 6.2: Unable to fetch data from SSL sites (cURL, wget, etc)

Machine: CentOS 6.2
I've had a Perl script which I've been using for ages, which has previously had no problem (and still doesn't) fetching data using LWP from port 80 locations. However, attempting to fetch from https locations, on port 443, always fails.
To simplify the diagnostics, I figured I'd try the same idea from the command line using cURL and wget, but these also fail with https, while they also both work fetching regular http data.
Figuring that the same problem affects all three methods, I'm trying to ascertain exactly what it is that might be wrong, and how to fix it. It's a dedicated server, and I have root access so I can pretty much do what I want to.
I've tried forcing cURL to use ipv4, and a bunch of other flags that looked interesting, but I always end up with the requests failing with "curl: (7) couldn't connect to host".
$ cat debugdump.txt
== Info: About to connect() to www.xyz.com port 443 (#0)
== Info: Trying 194.xxx.xxx.xx... == Info: Connection timed out
== Info: couldn't connect to host
== Info: Closing connection #0
... and similar connection time-outs with wget as well.
If I try fetching the same data with http, and with the -L flag (to follow redirects) then it will similarly fail on the secure portion of it.
So, basically I want to be able to retrieve remote data served via https, but am currently unable to do so. I know I definitely should be able to. I've spent ages trying to resolve this, but so far to no avail. Any useful information to help solve the problem would be much appreciated. Thanks!
Edit
Additional info: I'm not really too familiar with firewalls, but FYI, the entries in /etc/sysconfig/iptables relating to port 443 are:
-A INPUT -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -j Cid2676X....
-A OUTPUT -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -j Cid2676X...
However, I'm not sure why/if I'd need to open port 443 (if it's not already open) anyway; I mean, I'm fetching from port 443 on another server, not listening for traffic on my 443; surely I'm using some other random port on my own machine to fetch with?
Edit 2
Figured out that if I temporarily disable the iptables then the problem goes away. Of course, I need to have the iptables active, so I need to know what it is about the iptables that is preventing me fetching from secure sites. Suggestions welcome.

Enable HTTP TCP connection requests in Arch Linux for neo4j

My laptop is running a local neo4j server. I can use it with localhost:7474 but when i try connecting it with 192.168.1.12:7474 it is unreacheable.
Turns out linux is blocking connections other than web server port 80. Because i can access my Apache server on 192.168.1.12/
I am trying to allow TCP connections on port 7474 by using
iptables -A TCP -p tcp --dport 7474 -j ACCEPT
but it gives a response as -
iptables: No chain/target/match by that name.
How can i make other clients access neo4j server running at my laptop on port 7474. My laptop IP addr is 192.168.1.12.
I doubt that it is blocking it. Probably your neo4j server is only running at 127.0.0.1. You can check this out with netstat -nplt: you will probably see something (the apache) listening on 0.0.0.0:80 or :::80 (e.g. catchall address) but on port 7474 you will probably only see 127.0.0.1:7474 or ::1:7474. If this is the case you need to reconfigure your neo4j server to listen not only on localhost (don't know how, checkout the documentation).
Okay. I had uncommented the webserver address line but it still wasn't working.
So i reinstalled neo4j. That solved it. Weird but worked.

netstat commands to run on unix server, what commands should I use for my use-case and why?

Sorry in advance for such a noob question, but I'm certainly a noob.
My question is what does it mean to LISTEN or ACCEPT on a port as it relates to my example?
EXAMPLE:
I have a tomcat server, and It will use port 8080. I want to make sure that port is available for me to use.
What commands should I perform on my unix server and why?
what information would a command like this give me: netstat -an | grep LISTEN
If a port shows up as LISTEN in netstat, it means the port is in use by a server process, so you can't use it. Here is an example:
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
which shows that port 631 is in use.
Ignore the UNIX type sockets at the end - they are irrelevant.
For checking port 8080 is in use or not, you can simply use the command netstat -an|grep 8080. If you get an output in below format, that means 8080 is already in use and you need to assign a new port for the tomcat.
# netstat -an
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN
Netstat command displays various network related information such as network connections, routing tables, interface statistics, masquerade connections, multicast memberships etc,
a option with netstat will give you both listening and non listening ports
n option when you don’t want the name of the host, port or user to be displayed, use netstat -n option. This will display in numbers, instead of resolving the host name, port name, user name. This also speeds up the output, as netstat is not performing any look-up.
For more understand the use of netstat command here are its options:
-a : All ports
-t : Ports TCP
-u : Ports UDP
-l : Listening ports
-n : IP address without domain name resolution
-p : Name of the program and it associated PID
So:
-To display all port (TCP & UDP), PId with the associated name of the program :
$ netstat -paunt
-To display all Listening ports (TCP), PId with the associated name of the program : (and we can also filter with the grep command)
$ sudo netstat -plnt | grep ':80'
I hope it will be helpful :)
You can also use telnet to check if the port is open and listening e.g,
Zeeshan$ telnet google.com 80
Trying 173.194.35.5...
Connected to google.com.
Escape character is '^]'.
I am telnetting google.com on port 80. If you see the third line in the output, you will notice it says it is connected with the Google's web server. The same way you have a JAVA application server called Tomcat and it is listening on port 8080. In fact it is asking clients to connect to it on port 8080 so it can give away the JAVA services to client. When I will use from a client side telnet localhost 8080 I will be connected the same way I have connected with Google's web server on port 80. Provided that Tomcat is running and listening on port 8080. If port 8080 is not free and occupied by some other application you can simply change the port 8080 to another free port. Telnet should give you the following status:
accepted (connected), refused, and timeout
connection refused - nothing is running on that port
accepted - some application is running on the port
timeout - a firewall is blocking access
So now there are two possible ways to check. From the same machine you are running Tomcat server:
telnet localhost 8080
Of if you want to check it from some other machine or outside of the network:
telnet 192.168.1.1 8080
I hope that helps.
use can also run the below command, it will list the Port and corresponding PID, if any process is using those ports
netstat -tulpn

Can Socket.io listen on multiple ports?

Is it possible for socket.io to listen on multiple ports in one server?
Background - I need to satisfy two problems:
1.Some cooperate & other closed networks block all traffic which does not use port 80.
2.Some anti viruses block websocket traffic on port 80. Port 4000 is the safest port to use.
I therefore need to my node server to be able to use port 80 and 4000 simultaneously. Has anyone experienced similar problems? How did you solve it?
Thank you.
Suppose your process is listening on port 4000, it's my understanding you can use iptables to internally forward requests for port 80.
# iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 4000
/edit got the ports the wrong way around.

Resources