How to check that an OpenVPN server is listening on a remote port without using OpenVPN client?
Solution 1:
Here is a shell one-liner:
echo -e "\x38\x01\x00\x00\x00\x00\x00\x00\x00" |
timeout 10 nc -u openvpnserver.com 1194 | cat -v
if there is an openvpn on the other end the output will be
@$M-^HM--LdM-t|M-^X^@^@^@^@^@@$M-^HM--LdM-t|M-^X^@^@^@^@^@@$M-^HM--LdM-t|M-^X...
otherwise it will just be mute and timeout after 10 seconds or display something different.
NOTE: this works only if tls-auth
config option is not active, otherwise the server rejects messages with incorrect HMAC.
Solution 2:
Sorry if I'm a bit late with my answer ;)
Send an udp packet with the following content:
$38$01$00$00$00$00$00$00$00
The server must respond something.
You can forge udp packets with python like this:
import socket
senddata= "\x38\x01\x00\x00\x00\x00\x00\x00\x00"
def checkserver(ip,port):
print('Checking %s:%s' %(ip,port))
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(5) # in seconds
sock.connect((ip, port))
print("Sending request...")
sock.send(senddata)
try:
dta=sock.recv(100)
print("Server reply: %s" %(dta))
except:
print("Server not responding")
sock.close()
print("###########################################################")
def main():
checkserver("addr.of.server1",1194)
checkserver("addr.of.server2",1195)
if __name__ == "__main__":
main()
Solution 3:
For anyone running across this who's trying to monitor a server that has tls-auth
enabled, you can use the python script here: https://github.com/liquidat/nagios-icinga-openvpn
The output is formatted for use in Nagios or Icinga, but it can be run by anything/anyone, provided you have python and the tls keyfile available.
For example, if you are using SHA256
as your digest, you'd use something like:
python check-openvpn.py -p 1194 --tls-auth ta.key --digest SHA256 vpn-server.example.com
Note: you might need to add --tls-auth-inverse
depending on the server's key-direction
value.