TCP port switcheroo
September 24, 2009 4:28 PM   Subscribe

I would like to forward a local port to another local port...in effect, disguising one port for another. Is this possible?

First, I'm on Windows XP SP3.

I would like any apps on my PC that try to make a connection through (for example) port 1234, to be routed out through port 4321 instead.
kinda like a hosts file, but for local ports, not IPs/DNS names.

I've been playing with NetCat and FPipe, thinking they might work, but I am obviously not getting the correct command line.

Does anyone have any suggestions?
posted by AltReality to Computers & Internet (16 answers total)
 
Best answer: It sounds like you want to do port forwarding - an app connects to a.b.c.d:1111 and you want it to actually be connecting to e.f.g.h:2222?

There are some netcat variants out there that have different command line switches and capabilities - this page lists the options for the GNU version, which includes

" -L, --tunnel=ADDRESS:PORT forward local port to remote address"
posted by jquinby at 4:46 PM on September 24, 2009


Best answer: From a very quick review of the link you provided, FPipe will kind of do what you want, but maybe not exactly the way (I think) you're envisioning it.

I'm intepreting your question to mean that you want to control the port that your traffic originates from, and not change the destination port that your traffic is going to.

Right now you have something like this:

[Application on localhost:1234] ----- TCP Connection -----> [Remote host:6789]

You want the outbound connection to come from port 4321 instead of 1234.

To do this with FPipe, you configure FPipe to listen on local port 6789, and connect to remote host on 6789, originating from port 4321. Then you configure your application to connect to localhost instead of the normal remote host.

Or visually:
[Application sending from localhost:1234]
   |
   |
  TCP Connection
   |
   V
[FPipe listening on localhost:6789]
   |
   |
  (FPipe internal forwarding)
   |
   |
[FPipe sending from localhost:4321] ---- TCP Connection ----> [Remote host listening on:6789]
So to summarize:
  • Configure FPipe to listen to whatever remote port number your application connects to (6789 in this drawing).
  • Configure FPipe to connect to the normal remote host name on the normal port (6789 in this drawing)
  • Configure FPipe to originate its connection from port 4321.
  • Configure your application to connect to localhost instead of the usual remote host.
Your application must connect to FPipe locally, and FPipe then handles the communication with the remote host according to the way you've configure it. I hope I am making sense.
posted by FishBike at 4:48 PM on September 24, 2009


Response by poster: jquinby: Thank you for your response...I'll check into that shortly...

FishBike: That does make sense, and thank you for your response...unfortunately it won't help with my situation. I'll explain in a bit more detail...

I have an app installed on a USB key that I use at work and at home. The application is configured to connect through port 1234, which works fine at home. The firewall at work blocks port 1234. I would like to redirect port 1234 to port 4321, for whichever host I happen to be connecting to at the time.

Using telnet as an example:

[Telnet www.whatever.com 1234]
|
|
[redirection app]
|
|
[connection established to www.whatever.com on port 4321]

Does that make any sense?
a local tunnel may be exactly what I'm looking for. - I'll check on that. :)
posted by AltReality at 5:08 PM on September 24, 2009


Response by poster: nope..local tunneling looks like it still requires a hostname up front, in the redirection configuration. I want it to route to whatever host I specify in the command...only redirecting the port, not the host as well. :(
posted by AltReality at 5:11 PM on September 24, 2009


If you have openssh running, you can do it like this:

ssh -NL 1234:google.com:80 localhost

Telnet to port 1234 of localhost will be piped to google.com:80. You can install openssh on windows with cygwin.

Be aware that if you're doing this to redirect HTTP, you might not get good results due to the hostname header (which is used for virtual hosting) having localhost:1234 instead of google.com:80.
posted by cj_ at 5:18 PM on September 24, 2009


Best answer: Ok, I think I understand better what you're trying to do. You don't care what port number your connection originates from (it's usually assigned randomly anyway, in most applications), but you want to set it up so when your application tries to connect to any host's port 1234 it actually ends up connecting to that host's port 4321 instead?

I'm going to assume your application doesn't allow you to specify, on the command line or in a configuration file, the destination port number to use. In which case, I've seen hardware firewall devices with flexible translation rules that allow port numbers to be modified on-the-fly like this, but have not seen anything you could install on a Windows box to do it. Such a thing might exist, though.

The various tunneling apps only do it for a pre-defined remote host. You can, with some of them, set up numerous tunnels, one per remote host that you want to connect to, but I'm guessing the number of remote hosts is too large for that to be workable either.

The problem is that even though there is a 'hosts file'-like mechanism for port numbers (the 'services' file), just about zero applications actually consult that file any more. Just as you can't use the hosts file to override hard-coded IP addresses, you can't use the services file to override hard-coded (or just numerically configured) port numbers.

Even if you succeed, do you have control over the remote hosts to get them to listen on the new port number? If the remote application you're trying to connect to only listens for connections on port 1234, trying to talk to it on 4321 won't work anyway. You need to be able to get it to listen on 4321 as well.
posted by FishBike at 5:34 PM on September 24, 2009


Response by poster: That is also a good point FishBike, I am having the remote server configured to listen on both ports, but here's the catch...they are limiting it to IP address...so I can't connect to the secondary IP address from home. lol....what a conundrum :) Thank you for explaining though...I appreciate it.
posted by AltReality at 5:42 PM on September 24, 2009


I still get the feeling I am not quite understanding the scenario. When you say you're having "the remote server configured to listen on both ports", does that mean there's actually only one remote server? Sorry for my clue-resistance here!
posted by FishBike at 6:26 PM on September 24, 2009


You are looking for a local tunnel - you point your app at localhost port XXXX and have it set to connect to remote host on YYYY
posted by TravellingDen at 7:34 PM on September 24, 2009


Best answer: Just to confirm, what you're talking about is a situation where you request an outgoing connection to port 1234 on an arbitrary host, and that it gets transparently turned into a connection to port 4321 on the same host?

I'm afraid that's an extremely tall order. Tunneling and redirection software won't help you, since they wait for a connection on a fixed host and reconnect to another fixed host. In your case you can't connect to a tunnel - how would it know the real host you wanted to connect to?

A piece of software would have to be running within the Windows networking driver stack, like a firewall package does, but this is such an unusual thing to want that I would be surprised to find any existing package that does this.

Nooow, it is technically possible to do this, but the only way I can think of would involve setting up your own little network that connected through a gateway you control and doing some extremely underhanded TCP tricks on that gateway. Either that or writing your own code that hooked into the Windows networking stack.

Sorry to be discouraging, but I don't think getting this working will be worth the trouble. I would correct the configuration of the remote server to allow both IPs on port 4321.
posted by pocams at 8:03 PM on September 24, 2009


Best answer: There is no trivial solution to your problem, meaning one that a typical user could implement without introducing something significant like a dedicated proxy server sitting in between you & the Internet that was modified to do the dirty trick of switching the destination port on all outgoing packets & source port on incoming ones. It's doable, it's just a lot more of a bother to make it work than you're likely to find practical. Unless you want to buy a PC with 2 NICs, install a proxy/firewall on it then configure & it in a fairly tricky way & troubleshoot the whole deal to get it to work, my advice is to accept that it's not gonna happen.
posted by scalefree at 9:54 PM on September 24, 2009


Response by poster: Wow...Thanks for all the input. I didn't realize it would be such a tall order :)

FishBike: I think you are understanding it correctly. It is apparantly a very strange request, and I don't blame you for thinking you are wrong. You are correct that there is generally one main server, however I will want to connect to others. Your post has made me realize that for those other servers though, they will not be listening on the secondary port, so that part is useless. Thank you for making me see that.

TravellingDen: I want to specify the remote host in the application software, not the redirection software. But thank you for your input.

pocams: Thank you for your insight. You are correct that your proposed solution would be more work than it was worth. :) Thank you.

scalefree: Thanks. I think I'm in agreement with you unfortunately. Thank you for your response.
posted by AltReality at 2:29 AM on September 25, 2009


Ok, so, since it turns out there's only one server you'll be able to connect to on this alternate port, do you still need to be able to specify the server name to connect to from your application? Or can you now use one of these connection forwarding utilities and just tell the application to connect to "localhost" instead?

I can imagine several reasons why you might not be able to specify "localhost" from within your application. Like maybe the host names to connect to are in a dropdown list that you can't change. Or you need to record screen shots showing the remote host name. Or something in the application itself needs to know the name of the server it is trying to connect to.

If any of those type of reasons apply, you can probably still make this work with the forwarding utilities. Just add a line to your "hosts" file that defines the remote host's IP address as 127.0.0.1, which is really "localhost".

If you do that, you can still tell your application to connect to "www.example.com", but you'll be tricking it into connecting to the localhost interface instead. A forwarding application will be listening there on the standard port the application wants to use, and configured to forward that connection to the real IP address of "www.example.com" on the alternate port you want to use. You'd manually specify the IP address of www.example.com instead of using the host name when setting up the forwarding utility.
posted by FishBike at 5:44 AM on September 25, 2009


Response by poster: Well I'll be damned. That will do exactly what I want it to do FishBike.
The reason I didn't want to tell the app to connect to localhost is because I would still have to change it every time I took the app home, and back to work. That was the reason for wanting to redirect the port in the first place :)

Setting the host in the hosts file to point to localhost, then telling the redirect app to listen on localhost and route out to the server will work perfectly :) It doesn't quite work when talking about multiple servers, but other servers aren't listening on the secondary port anyway, so that part is moot.

Thanks for the help....I think that solved my problem Mr. FishBike. :)


hmm...you don't think the redirect app will try to route out through that hostname, and get trapped by the hosts file again do you? endless loop-style? cause that would suck. :)
posted by AltReality at 10:58 AM on September 25, 2009


hmm...you don't think the redirect app will try to route out through that hostname, and get trapped by the hosts file again do you? endless loop-style? cause that would suck. :)

As long as when you're configuring the redirection application, you use the IP address of the remote server instead of its host name, it'll be fine. In other words, don't configure it to forward to 'www.example.com' because that will indeed forward to localhost once you have hacked the hosts file in this way. Configure it to forward to '5.6.7.8' or whatever the real IP address of www.example.com is.
posted by FishBike at 11:02 AM on September 25, 2009


Response by poster: gotcha. I can do that. Thanks :)

damn quick response too :)
posted by AltReality at 11:13 AM on September 25, 2009


« Older What cover crops should I plant on my organic farm...   |   How do I deal with the fact that I hate teaching... Newer »
This thread is closed to new comments.