On Wed, Apr 14, 2021 at 08:24:51PM +0200, Jorge Redondo Flames wrote:
On Wed, 14 Apr 2021 at 20:19, Jochen Bern Jochen.Bern@binect.de wrote:
On 14.04.21 19:58, Jorge Redondo Flames wrote:
Stunnel could listen on its local port *only* when the peer server is listening on its corresponding server socket. So if there is no serve on the other side, there should not be local listening socket. Does not that make sense?
No.
In the general situation (server *not* being on the same machine as stunnel), stunnel CANNOT know whether the server's listening short of trying to connect to it - which it will only do on behalf of an incoming client request, which would never happen if stunnel weren't listening.
Even if server and stunnel run on the same machine/OS, finding out about the server's state would require a bunch of special-purpose code.
Assuming that they *are* on a common Linux (or at least unixoid) system, however, it would be rather trivial to write a root cron job that checks the output of "ss"/"netstat" for the server's LISTEN and simply terminates stunnel if it isn't found.
Or even better, have the server *restarted* automatically whenever it croaks ...
Understood. Although it still seems to me that the code doing more or less what the cron job would do might worth.
So, three points here.
1. There are some services (some servers) that do not react very nicely to somebody connecting to them and disconnecting immediately. Some of them do some work at the moment of the connection (e.g. resolve the client's IP address, check it against firewall rules, or even do some actual, service-specific, work, e.g. allocate buffers, prepare some kind of data...). Some of them are configured in such ways as to avoid portscanners or denial of service attacks or spam or flood or... many other things. In general, unless you *know* that it is safe to connect and immediately disconnect from the remote service, it is very unwise to try to do that. In your particular case, you know that, but in general, it is not a good idea.
2. Even if stunnel would try to connect to the remote service, what happens if the connection fails? OK, you say stunnel should close its local listening socket, but what then - will it never open it again? And if here's the part when you say "it can try to connect to the remote server again and start listening again" - okay, how much time passes between these connection attempts? Even something like a second may be bad if a real client chooses exactly this second to try to connect to stunnel and... stunnel is not listening... even though the remote server has started listening immediately after stunnel's last unsuccessful attempt. So... whatever interval you pick, closing the local listening socket *will* result in real, live clients failing to connect.
3. A more general point: if you really want to check whether a service is operational, only checking whether it will accept a connection is not enough. I've seen *many* failure modes over the years: from an overloaded machine where the OS kernel will accept the connection, but none of the actual server processes will react, through an overloaded service process that accepts the connection but spends too much time processing other requests to pay any attention to it, to a firewall host gone crazy that will pass connection packets, but will then refuse to pass the actual payload (yes, I've seen that happen for at least three different reasons). So an actual service check would be to connect and then send some kind of simple request to the server that you know will not take it too much time and resources to process, but will give you some measure of confidence that the server is actually serving requests and data.
But in short, it is impossible for stunnel to know whether a remote server is listening for a connection without trying to connect, it may not be "polite" for it to try to connect too often, and trying to connect not-too-often *will* result in real clients being unable to connect in the intermediate intervals.
G'luck, Peter