What is the best way to forward all requests on a certain port to another machine on the network? - networking

I have two dedicated servers and no hardware firewall. I'd like to forward all requests that come into the primary server on port 1008 to be fulfilled by another dedicated server on the same network. I know I need to set up some kind of TCP proxy, but I first heard of IPTables yesterday. Any quick tips?

The easiest way is to use something which is just a TCP proxy. It is possible to achieve this using iptables, but not easy.
It is easy to forward requests from A intended for B to C (using DNAT) but harder to get C's responses to go back to A via B (because DNAT does not change the sender address). A would then ignore the responses as they'd be coming from C rather than B.
Essentially the way of doing it would be to set up B as C's default gateway, and using forwarding, however, this places an additional point of failure in B; if B fails, C's outbound traffic (including responses to requests sent to C directly) would end up going down a black hole.
Using IPtables it is possible without this routing trick I think, but you'd need to have the same connection SNAT'd and DNAT'd, which is tricky at best.
Normally in such situations, most people put another host (firewall) in front of the two machines and have it make DNAT decisions - of course this introduces a point of failure as well, which is why in critical setups, the firewall typically has a rendundant backup (its configuration is synchronised and sometimes its connection tracking table is)

Carson is right: put a bridging firewall between servers and clients. Shorewall (IP tables) can then redirect traffic to different ports and different machines.
With the firewall being a bridge, you don't have to change your network settings, yet the bridge interface has to be assigned one IP address of each network clients and servers are in. Else the redirection won't work.
Caveat: the machine where the connection originally was pointed to has to be online (means: its IP address has to be in use), else the redirect won't work.
If the redirection is meant as a means of failover for high-availability, I would consider a load balancer (cluster) instead of the firewall, which leads to linux virtual server (for a general approach) or to a load balancer software like Apache (with mod proxy_balancer), balance or pount (if only http request are to be balanced). There's also hardware appliances like from f5 for load balancing.

First off I would recommend you get a firewall in place. I've used Shorewall for a long time to manage iptables and it is pretty easy to configure. Second if you use something like Shorewall there are easy guides on how to do DNAT (port fowarding).

Related

find out/predict the port the router is/will be using for a given connection

I know that ipchicken.com will tell you your router's ip address and the port it is using for your connection. But can this information be obtained "locally"? (Without relying on a website).
What I want it for is establishing a connection between two random hosts...without a "dedicated server" in the middle. My problem is to reach through the NAT. I think the best bet is a kind of TCP hole punching, where both hosts connect somewhere and then just tell each other (it can be by phone or chat or similar) the current ip address and the port number their routers are using. It should trick the routers into forwarding the packets to the hosts, albeit coming from a different source than they originally connected to.
Is it possible to find the port number your router is using to patch you through in a more local manner than ipchicken.com?
Are there any ideas on other possible approaches to this problem?
EDIT: Setting port forwarding on the router is not an option in this case, as many people (including me) do not have admin powers over their routers and I do not want to impose such a task on the "users" of my application
The router would use a different source port for every outgoing connection, so checking based on an outgoing connection will not work for your use case.
For an incoming connection, i.e., if you want to reach a specific machine behind a NAT device (like a home router), you'll have to explicitly open up some ports on the router and set up forwarding rules. The router would then listen for incoming connections on that port and forward it to a machine:port based on the configured rule.
How you do this would depend on the specific router make/model. Search the web or logon to the admin interface and look around, it should be easy to find. However make sure you understand the security implications of opening up a port on your router!
UPDATE based on edited question:
Without port-forwarding and if both devices are behind NAT, your only solution is to have an intermediary server! If only one of them is behind NAT, you can have that machine initiate the connection.
You could use a Stun server as the external globally reachable server.

how to redirect connections to IPs behind the NAT to NATted (public ) IPs at the source?

I have an application that relies on IP addresses for communication (Domain names simply does not work. :(... )
Its function is to connect to its peer on the other machine and send data over after establishing trust. During the "trust establishing" phase they both exchange their IPs for future communication. They both are behind the two different firewalls and are NATted. One is in our NATted office network and other is in the cloud NATted behind their firewall. The applications knows their respective private IPs and exchange that (the 10.x.xxx.xxx range), when they try to connect back to each other (using the private IPs with range 10.x.xxx.xxx) for transferring data they fail. The connection is TCP and the port range is pretty varied.
I am curious if there is anyway I can hard code (for this one time) a rule (at may be firewall level or some place outside my application) that says if there is a connection being initiated for IP address 10.x.xxx.xxx then redirect it to 205.x.xxx.xxx?
Private IP address ranges like 10.x.y.z are, by their very nature, private.
You can't do any meaningful resolution unless each node in between the endpoints has rules in place to translate these.
Translation is tricky, all the main tools you would use cater for static translation (port forwarding, e.g. where a particular port is forwarded to a particular IP). This is one avenue, but it is a hacky one (it requires you to open lots of ports, procedurally update your router and probably have some sort of broker server to maintain mappings).
Alternatively, you could run the isolated networks over a VPN, which would give your endpoints mutual private IPs which you can use to connect to eachother. It would simply be a case of binding to this new address and communicating across the VPN. This would also potentially encrypt your communication over the internet.
Other possibilities are to use NAT/TCP punchthrough techniques which can allow traversal, but these are really a patch to a broken network topology (Read up on IPv6 to see how this can be alleviated).
Alternatively, you could route all the connections over a proxy, but this will complicate matters compared to a VPN.
To answer the question about hardcoding a rule, port forwarding is the solution here. It will obviously depend on your router configuration for the peer accepting the connection, but this client should have the port target port forwarded to the machine. This will obviously not scale very well and is really shifting to a server/client architecture for one connection!
Depending on your hardware, you may be able to forward a range of ports (if a single port cannot be established) and limit the port forwarding to certain incoming connections (the external IPs).
Information on port forwarding can be found at http://portforward.com/
This sounds a lot like what you'd want out of a VPN. Is there anyway that you could set one up? Basically the Site-To-Site VPN between you and the cloud would say 'oh hey, here is an ip located on the remote network, go ahead and connect through the link'. Would this kind of solution work in your case?
Something along these lines: http://i.msdn.microsoft.com/dynimg/IC589512.jpg

NAT translation not working from inside the network (hairpin condition)

I'm writing a P2P application. Peers regularly ping a main server to update their current IP/port, so when a peer wants to reach another one it can ask the server for that information. For now peers use UPnP to configure the NAT (for classic home setups) to be accessible from outside.
So everything works, except when a peer's client tries to reach another (or the same) peer's server and both are behind the same NAT. Since in that case the client is trying to reach its own "external" (public) IP address from behind the NAT, the NAT doesn't do the port forwarding and is unable to route the IP packet.
For now I'm thinking of two solutions:
query the NAT with UPnP to see to which local IP the port is forwarded
store on the main server the internal IPs of the peers
Can you think of other solutions? What strategies do mainstream P2P applications implement to solve this problem?
Since in that case the client is trying to reach its own "external"
(public) IP address from behind the NAT, the NAT doesn't do the port
forwarding and is unable to route the IP packet.
This is known as the hairpin condition. Not all router/NAT solve this properly. The solutions are:
a) Check whether your router/NAT can be configured to enable 'hairpining'. This solution works iff you control all router/NATs in your deployment.
b) Buy another router/node allowing this. Just like a), it works iff your control all router/NATs in your deployment.
c) If you can get obtain the port information for from UPnP, this is a solution too, but not all Router/NAT know or support UPnP. It does not cover for all cases in large deployment.
d) Using multicasting to 'discover' other nodes on the LAN and even communicate with them is a common solution to this problem. You need to agree on an IP address and have peers listen to it.
e) Storing the private IP address on the server is a solution too, but it requires more storage capacity on the server than solution d. There is a timeout (i.e., expiration of data validity) to handle too.
f) Use a TURN like communication between peers (i.e., communication between nodes pass through central server). This solution is rock solid, but not the most efficient in terms of bandwidth consumption.
Hope this helps.
Interactive Connectivity Establishment (ICE) was specifically developed for solving that type of NAT problems. It uses STUN and TURN to achieve the result and is used in modern p2p applications. (e.g. Voicechat)
The PJNATH library has a document explaining
unlike standalone STUN solution, it (ICE) solves the hairpinning issue, since it also offers host candidates.

How to tamper with source IP address on Windows

We meet a testing scenario which needs to tamper with source IP address of a Http request to simulate clients coming from different countries. Do you know any tool help on this?
Last but not least, our web site is built with ASP.NET.
Thanks.
In a test environment it usually isn't difficult. First read this SO question about virtual network interfaces.
If the server and client are on the same machine, all you have to do is figure out how to get your client software to bind to your virtual interface.
wget for instance has the --bind-address option to specify which local address to bind to. Web browsers are a bit more difficult to do this with; you may need to just run it in a VM.
If your server and client are on the same LAN, you just need to configure your router with some static routes to your client machine. In this case you probably don't need a virtual network interface, just set a static IP for your client machine; as long as the gateway is set up correctly it should be able to send packets to the server, and as long as the route is set up correctly the replies should find their way back to the client.
If the client and server are separated by an internet, it's rather more difficult. One option is to set up a network tunnel endpoint on the server and tunnel it to the client machine, which "knows" that it has the virtual network interface.
As noted in answers to the ServerFault question "Are IP addresses trivial to forge", you cannot easily forge source addresses in a protocol that required two way communication (e.g. TCP). Note that this "two way communication" is required at the packet level. You cannot just say "no problem, I want to send requests and ignore HTTP responses." To establish a TCP session, you need to receive data. Your best bet is to use a proxy server.
I am unsure if the IP standard allows for this, but if you are working in a Lab environment, where you don't need internet connectivity during the test, I can see it working under following circumstances:
Basically, I would set the server's network interface to use netmask 0.0.0.0 and flush the rest of the routing table.
Then you could configure a client machine to take on any IP address as long as you use netmask 0.0.0.0. And two-way communication should be possible.
Server[1.2.3.4/0] <---> Client[x.x.x.x/0]
But please bear with me. I haven't tested this, so I could be wrong :-)
If you have access to your infrastructure, you can add an interface off the router and then place a static route on the router to that network.
Server-----Router----Internet
/
Test_PC----/
Alternatively you can look into PBR (Policy Based Routing) and on the routers you can flag source packets and change the source on the fly, so your server will think they are coming from where you'd like them to come from.
Server-------------Router_with_PBR-------------Internet----- PC
SCR:4.2.2.2 Change SCR:6.6.6.6 to 4.2.2.2 6.6.6.6
But you have to ask yourself why do you want to see when packets come from different countries. Some countries have massive proxy servers that filter access ( "Great Firewall of China"), so the above tests will not prove much.
Your best bet then is using proxy servers or if your looking for a long term solution then setup a server (virtual is great for this) and use RDP for testing. I'm sure you can rent a virtual server somewhere for a month or two.
That's not possible. Because when you forge the ip address, the response is never going to come back, which is required for http.
The best way is to use proxies. See also this question on serverfault.
If you change your source IP address, that means no traffic from your web server will be able to reach back to the client.
You might be able to use some kind of proxy and/or address translation filter to do the remapping while still allowing two-way communication.

Create a Windows (win32) service discoverable across the network

In short: How to reliably discover a server running somewhere on a (presumably multi-segmented) local area network with zero client configuration
My client application has to locate the server application without knowing the server IP address. It has to work on a local LAN that may be split into segments with hubs or other switching devices.
I already have a working solution, but it is a bit cumbersome to get it working on multi-segment networks. It works as follows:
When the client starts up, it sends UDP broadcasts on its own network segment. If the server is running on the same segment, it works without any issues - the server responds with the appropriate messages.
If the server and client are running on networks separated by a hub / switch that won't forward UDP (the most likely case), then I have a server instance running on each segment, and they forward client requests to each other via TCP - but I need to configure this for the server instances (simple, but still a pain for tech support.) This is the main problem that I need to address. There are sites where we have hundreds of clients running on 5 or 6 separate segments.
The problems I'm facing:
1. Although my application installer enables the appropriate ports on the firewall, sometimes I come across situations where this doesn't seem to happen correctly.
2. Having to run multiple server instances (and therefore configure and maintain them) on hub/switched networks that won't forward UDP
Finally I need a solution that will work without maintenance on a minimal Windows network (XP / 2000 / Vista) that probably doesn't have Active Directory or other lookup services configured.
I don't want to tag on any runtime stuff for this - should be able to do it with plain VC++ or Delphi.
What approaches do commercial apps usually take? I know that SQL Server uses a combination of broadcast and NetBEUI calls (I may be wrong about this).
Thanks in advance.
You have a few terminology issues:
Where you say "network segment" you appear to mean "IP subnet". Devices on the same network segment can see the same IP broadcasts.
Where you say "hub/switch" you appear mean "IP router".
Where you say "won't forward UDP", the problem is actually "won't forward IP broadcasts".
Once we get past that, you have a few options:
Your servers could register themselves under a well-known name in DNS, if you have a DNS server that allows dynamic DNS updates. You should probably use a SRV record as specified in RFC2782. The clients then do a DNS lookup to find the server(s).
You could statically assign your server(s) well-known names in the organisation's DNS, perhaps with a SRV record as with the previous option.
Your servers could join an IP multicast group, if your routers support IP multicast. The clients then send their initial discovery request as a UDP packet to the (pre-ordained) multicast address.
If you have domain server, I would go with small service on it. You can connect with other services to it and use it as distribution point.
Why domain server? It is relatively easy to find it's name (DsGetDcName).
Other choices would include DHCP server, DNS server or something of that kind that needs to be filled by maintenance staff anyhow.

Resources