maikcat wroteyou can query status log also which can be updated frequently if you use
status /etc/openvpn/status.log 3
3 is seconds...
Michael.
Yes that is what my script does. it greps for the line with the CN at the beginning.
However, this does not handle the condition that the client has left less than 60 seconds ago without telling the server,
e.g. a powercycle, and then makes a new connection. The status will still indicate it is connected.
Unfortunately it appears that there is no "unique ID" (e.g. hash of the MAC address(es) and/or hostname) of the
client sent to the server, so the server cannot know if it is the same or another client that is connecting.
What I want should not be that special, but it appears openvpn is not able to do it out-of-the-box. And my attempts
to solve it using a script have not been successfull either.
Let's describe my requirement:
1. I want fixed address per CN. So of course each CN should connect only once during normal operation.
2. When a client is powercycled or has erratic internet connectivity, the reconnects it does should be accepted
without problem.
3. When a client is mistakenly fitted with the wrong certificate, so two clients connect with the same CN, the
error should be handled in a clearly detectible way that favours the first connected client. I.e. the user should
get an error message like "connection refused", not a half-working connection.
Initially I set this up without the "duplicate-cn" option. This means that the 2nd requirement is satisfied
(when a client reconnects, the first session is dropped and the second is established), but there is a
problem with the 3rd requirement. When this situation occurs, the second connection takes over
from the first, but the first client will notice that, it will reconnect, and again take over the connection.
This means there is a pendulum effect and both clients have erratic network connectivity without clear
error message.
Ok, enter the "duplicate-cn" option. This makes it work a little better, because the first client is not interrupted,
but it still causes havoc because the two clients will attempt to get the same IP address and routing is not OK.
So, I did the client-connect script that checks for an existing connection, and does "exit 1" when it detects
an existing session from the same CN. That works fine if the script can make the determination immediately,
but unfortunately that is not possible. When there is a session in the status file, it does not mean that
session is still valid. I tried to check that by doing a ping to the fixed IP, but that unfortunately made the
client-connect exit status detection fail (the topic of this thread).
Now that I have changed it to check only the session table, I can reliably reject duplicate connects from different
systems, but now I have introduced a race condition where the connection will be rejected when the client
is quickly powercycled or has erratic network connectivity. When the client reconnects before the server
has detected a dead connection, it is rejected.
So, how is this to be solved?
IMHO there should be handling in openvpn that gets active when the server detects a connecting client, and
that is able to detect if this is the same client that does a reconnect, or another client that does a new connect.
This could be implemented by doing an openvpn ping (the same ping that detects the dead connections, not
an ICMP ping) at the time a new session comes in, to detect if the old session is still alive.
When it isn't, the old session can be destroyed immediately and the new session accepted.
When it is, the new session can be rejected because it is from an incorrect client.
(this does not handle the error of setting up 2 sessions from the same client, but that can be lived with)
I don't think there is a configuration option that makes openvpn behave like that by itself.
But would it be possible to write a script that does that?
Is it possible to quickly check if another connection is still alive?
What is the maximum time a client-connect script can spend before openvpn continues and ignores the exit
status?