How to route back to original interface - networking

Sorry, my networking skills are subpar,
I have a scenario where I have 2 different networks and have 2 servers in those networks, server A is in network A, server B in network B
When someone tries to connect to an external server (over internet), we have a virtual interface configured between A & B (IPIP tunnel)
1)
If I try to netcat/telnet external server (x.x.100.3), I have a route on serverA that routes to my virtual inteface (tunnel1)
2) tunnel1 sends packets over IPIP tunnel to its peer "tunnel2"
3) I need to route any requests to x.x.100.3 over to another internet-facing p1p1 interface
4) serverB sends packets to external serverC over p1p1 interface (I tested running tcpdump -i p1p1 and can see the packets going out
5) reply from C comes back to p1p1
If I do the same netcat cmd from B, I get connected. Yet from A, I get a timeout.
SO my question is, how do I configure this setup so the user who initiates Netcat on server A, gets the reply from server C? Right now the connection stops at server B (p1p1) because the packet header is changing after the Route on B.
I tried playing with iproute2 table rules but cannot get it to work. I basically need to use Server B as a "proxy" network server for any requests going to external server C.
Thanks!

figured out the problem, I didnt have a gateway route in place. This was preventing the back-forth flow of packets.
heres the write up how to setup IPIP tunnel between 2 networks,
https://sites.google.com/site/mrxpalmeiras/linux/create-ipip-tunnel-between-networks

Related

Can you respond to a UDP packet from a different server?

If server A receives a UDP packet, can it forward it to server B and have server B directly respond to the end client without going back through server A since UDP is connectionless?
My gut feeling is no, unless both server A and server B have the same IP address (anycast maybe?)
But if the client is built to also be a UDP server, it could work in theory since the (logical) response from server B would just look like a new request. But then this really doesn't work in practice because of firewalls and NAT, for the same reason it's hard to host a game server from behind your firewall, router, and ISP.
If server A receives a UDP packet, can it forward it to server B and have server B directly respond to the end client without going back through server A since UDP is connectionless?
Yes, it can. However, there are a few caveats:
NAT devices, which most client are behind of. There are several types of NAT devices. A full-cone NAT will accept the redirected packet just fine, but an address-restricted NAT would require the packet to return from the same address it was sent to (hence, your anycast idea would work, as well as simply having server B spoof the IP of server A). A port restricted or symmetric NAT would also require the same source port (i.e. server B has to send the response from the same port server A received it from).
Other types of network middleboxes, such as firewalls might block the returning packet
Application - will the client application accept a response from a different IP address and port?

Forward packets using iptables

I have two servers : server A and server B.
Another company has server C and ASA FW.
I have established an IPsec Tunnel between Server B and the ASA firewall on the remote peer.
Now I need to make server A to connect to server C through the tunnel I established using Server B .
Can this be done using iptables, what are the required rules?
Note we are dealing here with only public ip addresses ( no NAT ).
Thanks for help
If you are not doing any NAT anywhere in the chain, you will need to set up server A to route to the network that server C is on via server B, so that packets from server A to server C will pass through server B. Likewise, you will need to make sure that any packets from server C to server A are directed through the VPN tunnel to server B.
Since you are using IPsec, you will need to make sure that you have the proper phase 2 definitions set up.

UDP hole punching for Server/Client communication under NAT with STUN

Problem
I'm trying to develop a communication system where:
A, B are machines under NAT, A is the server B is the client
S is the STUN server
S is running on a machine reachable on the Internet
The flow is as follows:
A hits S with an opcode saying he's the server
S registers A as server
B hits S with an opcode saying he's the client
S sends to A B's external infos (IP, PORT)
S sends to B A's external infos (IP, PORT)
A starts sending B an opcode saying he's the server every 500ms
and meanwhile listens for packets saying he's got a client
B starts sending A an opcode saying he's the client every 500ms
and meanwhile listen for packets saying he's got the server
Trouble
Here's where the troubles start, the STUN server does its job, since both ends receive correct infos about the other.
But then I do never receive the other end's message, so both ends keep listening without receiving the handshake opcode nor anything else.
NAT's Behaviour
I did examine this NAT's behaviour and seems it does like this
A is at 192.168.X.X, on port 4444
connects to the outside exposing N.N.N.N:4444
so the port number is kept as long as it's free, gets a new (random ?) one if not available.
Tests
The tests I run have seen both ends (A, B) hosted on the same machine, both bound to the machine's internal IP, tried to bind to 127.0.0.1, 0.0.0.0, nothing changed.
If while they're listening for handshakes I echo something with nc to localhost, it is received and displayed (as an unrecognised message) without any problem. The connection routed via the NAT doesn't wotk tough, every packet is discarded.
Also tried with A hosted on the machine, B on an Android phone under mobile data, with a simple app written ad-hoc. Still locks waiting for something, like the nodejs tests.
Update:
Another thing I tried to do is to open an hole with nc
On two different machines under the same NAT I ran:
echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4567 -p 4568
echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4568 -p 4567
Different times for each machine. From my understanding this should punch an hole in the NAT with the first packets discarded and the subsequent forwarded. But nothing happened, no end got the message.
I've also tried:
from local machine
echo "GREET UNKOWN PEER" | nc -u <PUBLIC IP> 4567 -p 4568
from public machine
echo "GREET UNKOWN PEER" | nc -u <NAT IP> 4568 -p 4567
this one works, the local machine under NAT contacts the public one and after the first discarded packet is able to receive and send on the assigned port. I wonder why this doesn't work on two machines under the same NAT (???)
Code
I didn't show any code because I think there is some kind logic flaw in this, however here's the github project for that.
index.js contains the STUN server, the tests folder contains the test cases: test.js starts the stun server, PeerClientTest.js and PeerServerTest.js are mockups of the client and server.
Run node tests/test.js to start the server on a public machine (change IPs in config.js and tests/config.js)
then node tests/PeerServerTest.js to start the server ("A") and node tests/PeerClientTest.js to start the client ("B"). Both will recognize each other via STUN, then listen for the other end's handshake opcode while sending their own handshake opcode. This never happens so they just keep sending/listening forever.
Node is not required, so if there are better solutions in other languages just tell, will be appreciated.
B's NAT is filtering A's packets and is not letting them through. NAT filters unknown packets sent to it. Your server A is sending packet to client B. But client B previously never sent a packet through NAT to A. So to B's NAT A's packets are unknown and being discarded.
You need to punch a hole in B's NAT for the NAT to allow the incoming packets. Send a packet from B to A NAT's IP:Port. After that when you send a packet from A to B, B's NAT won't discard A's packet.
This won't work if A and B's NAT has a combination like Symmetric and Symmetric/PRC NAT. In this case you will have to use a TURN relay server.

Is it possible to redirect TCP connections

Given the following scenario:
Computer A connects to a public server from behind a firewall.
Computer B connects to the same public server from behind a firewall.
Now, is there any way for Computer A to talk directly to Computer B using those outbound connections without sending all data through the server?
Can the server link those connections somehow?
Two peers, talking to each other, using outbound connections instead of dealing with inbound firewall issues.
Possible, yes. Easy, no.
At least one of the firewalls needs to be updated to forward a port on the external IP to a port on the machine behind it. The other machine can then connect to that port to open a bidirectional TCP/IP connection.
To accomplish this, you can make use of UPnP on the firewall to accomplish "hole punching" or "NAT traversal".
Once the firewall port is open, you forward that port number over the public server and pass it along with the public IP address already known to the server along to the other machine. It can now create the connection.
I don't think that it can be achieved mate. Unless you have access to the public server network and create a route to direct incoming A directly to the B and vice versa.

Winsock2 non-local refused

(I have not put code in this question since the actual code probably doesn't matter here. If you say it does though then I can edit the question later to put it in.)
I'm new to using winsock2 or any other networking API for that matter. I have a very simple server application and client application in which the server sends a string to the client and then disconnects.
The applications work fine when I use localhost or 127.0.0.1 as the inet_addr() argument, but when I use my "real" IP, the client application just gets WSAECONNREFUSED and the server doesn't see it. I made sure that the port was the same for both applications and that also the protocol was the same.
[Edit] I have come back to this issue after abandoning networking for a while. I think this may actually have something to with the fact I am using a router, and not something in my code.
WSAECONNREFUSED is an active refusal of the connection by the peer or by an intermediate firewall. If it was the peer who issued it, it means you got the IP address or the port wrong, or else you got it right but the server isn't actually running; anyway, nothing is listening at that IP:port. If it was the firewall, adjust it.
Did you use htons() on the port number?
inet_addr() only works with IP address strings, you have to use gethostbyname() or getaddrinfo() to resolve localhost or any other hostname string to an IP address.
WSACONNREFUSED means the connection was actively refused on the remote end that you are trying to connect to.
If the server machine is refusing, that means either there is no socket listening on the requested IP:Port, or that there is one but its queue of pending client connections is full so it cannot accept a new connection at that moment.
If a router is refusing, that usually means the router is not configured to forward inbound connections for the requested IP:Port to a machine on the router's network. If you have a server running behind a router and are trying to connect to it using the router's public IP address, then the router has to be setup for port forwarding.
If a firewall is refusing, that usually means the requested port is not open.
Either way, there is no way for the client to know in code why the connection was refused. All it can do is wait for a period of time and then try again.

Resources