I have an application that listens for connections on a port, but I occasionally take it down for updates and the like. I'd like a way to configure the system such that if that program is running, requests for that port are sent to the application, but if it's not running the requests are directed to some other application (that can return a temporarily unavailable message). What's the easiest way to accomplish that?I don't have root access on the target machine, so I'd prefer to avoid things like iptables. I've considered a helper application that does nothing but route connections to the other two applications, but I'm hoping there's an easier way
Route incoming network requests for a given port to different applications
linux;networking;ip;not root user;tcp
Your question implies that both programs would be running in alternation on the same machine, bound to the same port. This is a bad idea. You will run into the TIME_WAIT (a.k.a. 2MSL) problem if you try this. This article describes the problem. (It's Windows-centric, but most of what it's talking about applies to any TCP/IP stack.)The BSD sockets API does provide a way to defeat this protection (setsockopt(SO_REUSEADDR)), but this is not one of the cases where doing so is justified.Instead, solve the problem the same way the High Availability folk do: put a reverse proxy between the world and your real back-end server.In the HTTP world, one popular solution to this problem is nginx. You can configure it so that while the back end server is down, it serves static content to clients. If your protocol looks like HTTP, IMAP or POP, maybe you can use nginx as-is. If not, you could build a custom proxy server.You probably need two TCP ports for this to work. The proxy binds to the public-facing port number, on the public IP. Your back-end server binds to a secondary port, on the localhost interface only. Thus, traffic can get from the public network to the back-end server only through the proxy.You can get away with binding both to the same port if both programs are written to allow it. For instance, if your public IP is 1.2.3.4 and your public service port is 2345, both programs can bind to port 2345 if the reverse proxy binds only to IP 1.2.3.4 and the real server binds only to 127.0.0.1. If either binds to INADDR_ANY (0.0.0.0) you need different ports.This solves the 2MSL problem because your clients are always talking to the same program, the proxy server. The network stack won't ever be confused about what to do with any stray packets swept up in the 2MSL time.A variation on the reverse proxy is the load balancer, and it could also work here. A load balancer is designed to intelligently route traffic to different machines. This sort of proxy would make sense if you thought your app might someday need to scale horizontally. You'd select a load balancer that knows how to send traffic to a special service down host when all the normal application servers are down. The main problem the load balancer solution variant is that a generic load balancer might blindly assume that all back-end services it proxies for are using the same port number, differing only in IP. You might be able to get a more flexible load balancer, or get multiple IPs for your shared server, though.