OpenVPN Connect/Disconnect Notification Setup

Want to share your OpenWrt / Gargoyle knowledge? Implemented a new feature? Let us know here.

Moderator: Moderators

Post Reply
User avatar
mckman
Posts: 21
Joined: Sun Jun 15, 2014 7:38 am

OpenVPN Connect/Disconnect Notification Setup

Post by mckman »

Hello,

I wanted to share a setup I use to email me from my gmail account when someone connects and disconnects to/from my OpenVPN server that is running on my WNDRMACv2 using Gargoyle 1.6.X (built 06042014). The core scripts I copied from this link (http://linksysinfo.org/index.php?thread ... ons.36633/) and made some minor modifications so that they would work on Openwrt based firmware and the email notifications a little cleaner.

Prerequisites
  • Router with at least 16MB of Flash storage (ex. WNDRMAC v2 or WNDR3700 v2)
  • Gargoyle 1.6.X
  • OpenVPN Server configured and working
  • SSH Client such as Putty to configure
  • [Optional] SCP Client for easier copying and backup
Configuration

First, you must ssh into your router using your SSH client. Since I primarily use Windows 7, I prefer to use good ole Putty to accomplish this.

Once you've logged into your router using SSH, you must update the available packages for Gargyole using the following command:

Code: Select all

opkg update
Then install Python packages using the following command:

Code: Select all

opkg install python
Then install the Python openssl package using the following command:

Code: Select all

opkg install python-openssl
Then create a scripts folder within root:

Code: Select all

mkdir /root/scripts
Then copy (or create using vi editor within ssh) a few scripts to the router as follows:

/root/scripts/mail.py

Code: Select all

#!/bin/sh
import os
import smtplib
import mimetypes
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEAudio import MIMEAudio
from email.MIMEImage import MIMEImage
from email.Encoders import encode_base64

def sendMail(subject, text, *attachmentFilePaths):
  gmailUser = 'yourgmailaccount@gmail.com'
  gmailPassword = 'yourgmailpassword'
  recipient = 'recipientaddress@whatever.com'

  msg = MIMEMultipart()
  msg['From'] = gmailUser
  msg['To'] = recipient
  msg['Subject'] = subject
  msg.attach(MIMEText(text))

  for attachmentFilePath in attachmentFilePaths:
    msg.attach(getAttachment(attachmentFilePath))

  mailServer = smtplib.SMTP('smtp.gmail.com', 587)
  mailServer.ehlo()
  mailServer.starttls()
  mailServer.ehlo()
  mailServer.login(gmailUser, gmailPassword)
  mailServer.sendmail(gmailUser, recipient, msg.as_string())
  mailServer.close()

  print('Sent email to %s' % recipient)

def getAttachment(attachmentFilePath):
  contentType, encoding = mimetypes.guess_type(attachmentFilePath)

  if contentType is None or encoding is not None:
    contentType = 'application/octet-stream'

  mainType, subType = contentType.split('/', 1)
  file = open(attachmentFilePath, 'rb')

  if mainType == 'text':
    attachment = MIMEText(file.read())
  elif mainType == 'message':
    attachment = email.message_from_file(file)
  elif mainType == 'image':
    attachment = MIMEImage(file.read(),_subType=subType)
  elif mainType == 'audio':
    attachment = MIMEAudio(file.read(),_subType=subType)
  else:
    attachment = MIMEBase(mainType, subType)
  attachment.set_payload(file.read())
  encode_base64(attachment)

  file.close()

  attachment.add_header('Content-Disposition', 'attachment',  filename=os.path.basename(attachmentFilePath))
  return attachment
In the above script, make sure to change the following:
yourgmailaccount@gmail.com to your own gmail account email address.
yourgmailpassword to your own gmail account password.
recipientaddress@whatever.com to the email address you'd like to send the notification to.

You can change the smtp.gmail.com information with another email provider if you want to use something other than gmail.

/root/scripts/client-connect.py

Code: Select all

#!/bin/sh
import datetime
import os
import socket
import mail
 
time = datetime.datetime.now()
formatted_time = time.strftime("%A, %B %d, %Y at %I:%M:%S %p")
name = os.environ['common_name']
localip = os.environ['ifconfig_pool_remote_ip']
remoteip = os.environ['untrusted_ip']
hostname = socket.getfqdn(remoteip)

subject = name + " has successfully connected via OPENVPN!"
message = formatted_time + "\r\n\r\nAn OpenVPN Client has connected.\r\n\r\nCommon Name: " + name + "\r\nRemote IP (DNS Name): " + remoteip + " (" + hostname + ") \r\nLocal IP: " + localip + "\r\n\r\n"
 
mail.sendMail(subject, message)
/root/scripts/client-disconnect.py

Code: Select all

#!/bin/sh
import datetime
import os
import socket
import mail
 
time = datetime.datetime.now()
formatted_time = time.strftime("%A, %B %d, %Y at %I:%M:%S %p")
name = os.environ['common_name']
localip = os.environ['ifconfig_pool_remote_ip']
remoteip = os.environ['untrusted_ip']
hostname = socket.getfqdn(remoteip)
bytesrec = os.environ['bytes_received']
bytessent = os.environ['bytes_sent']
duration = os.environ['time_duration']

subject = name + " has disconnected from OPENVPN!"
message = formatted_time + "\r\n\r\nAn OpenVPN Client has disconnected.\r\n\r\nCommon Name: " + name + "\r\nRemote IP (DNS Name): " + remoteip + " (" + hostname + ") \r\nLocal IP: " + localip + "\r\n\r\n" + "\r\nBytes sent: " + bytessent + "\r\nBytes received: " + bytesrec + "\r\nDuration: " + duration + " sec.\r\n\r\n"
 
mail.sendMail(subject, message)
/root/vpnconnect

Code: Select all

#!/bin/sh
python /root/scripts/client-connect.py
/root/vpndisconnect

Code: Select all

#!/bin/sh
python /root/scripts/client-disconnect.py
Then you must make these scripts executable by doing the following:

Code: Select all

chmod 755 /root/scripts/mail.py

Code: Select all

chmod 755 /root/scripts/client-connect.py

Code: Select all

chmod 755 /root/scripts/client-disconnect.py

Code: Select all

chmod 755 /root/vpnconnect

Code: Select all

chmod 755 /root/vpndisconnect
Then you must modify the Openvpn server configuration file to include the following lines at the end of the file in order to execute the scripts:

/etc/config/openvpn/server.conf

Code: Select all

script-security 2
client-connect /root/vpnconnect
client-disconnect /root/vpndisconnect
Then issue the following command:

Code: Select all

/etc/init.d/openvpn restart
Now each time a client connects and disconnects to the openvpn server, it will send an email notification to the recipient specified in the mail.py script. You can play around with the message formatting in client-connect.py and client-disconnect.py scripts if you want to customize the emails.

The connect email will look like this:

Code: Select all

Friday, June 13, 2014 at 03:28:20 PM

An OpenVPN Client has connected.

Common Name: xxxxxxxxx
Remote IP (DNS Name): xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
Local IP: xxx.xxx.xxx.xxx
The disconnect email will look like this:

Code: Select all

Friday, June 06, 2014 at 10:00:31 PM

An OpenVPN Client has disconnected.

Common Name: xxxxxxx
Remote IP (DNS Name): xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)
Local IP: xxx.xxx.xxx.xxx


Bytes sent: 7683
Bytes received: 6143
Duration: 379 sec.

Important Notes
Anytime you make a change to the OpenVPN setup via the Gargoyle gui, the server.conf modifications above will be removed. You will need to re-add the modifications above to re-enable these notices.

The configuration above is not automatically backed up or preserved via the Gargoyle backup process or when attempting to preserve the configuration during a firmware upgrade. I overcome this by using winscp to copy the setup from the root folder, perform a restore or upgrade, then copying the root folder back and performing the chmod steps above.

Enjoy!
Netgear WNDR3700 v1
Netgear WNDRMAC v2
TP-Link MR3020 v1.8
TP-Link WR743ND v1

ispyisail
Moderator
Posts: 5185
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: OpenVPN Connect/Disconnect Notification Setup

Post by ispyisail »

Thanks

A good variation of this would be when a user reaches data limits. e.g 80% then 100%

User avatar
mckman
Posts: 21
Joined: Sun Jun 15, 2014 7:38 am

Re: OpenVPN Connect/Disconnect Notification Setup

Post by mckman »

ispyisail,

That's a good point. I may try to provide a solution for this in a few days.
Netgear WNDR3700 v1
Netgear WNDRMAC v2
TP-Link MR3020 v1.8
TP-Link WR743ND v1

Post Reply