Email Notification - OpenVPN Client Connect (Common Name)
-
I'm gonna test it as soon as I'm back in office
-
@Stewart
Very appreciated here. Thanks! -
I'm finishing up some updates. It includes selecting a date range instead of a particular day and defaults to the current month instead of showing the whole log file when it opens. I have some out of office appointments today but hope to be able to post the update later today.
-
Here is the updated /usr/local/www/vpn_openvpn_userlogging.php
<?php /* * vpn_openvpn_userlogging.php * * Sept 2021 */ ##|+PRIV ##|*IDENT=page-openvpn-userlogging ##|*NAME=OpenVPN: User Logging ##|*DESCR=View OpenVPN User Connections. ##|*MATCH=vpn_openvpn_userlogging.php* ##|-PRIV require_once("guiconfig.inc"); require_once("openvpn.inc"); require_once("pfsense-utils.inc"); require_once("pkg-utils.inc"); global $openvpn_topologies, $openvpn_tls_modes; $shortcut_section = "openvpn"; include("head.inc"); $tab_array = array(); $tab_array[] = array(gettext("Servers"), false, "vpn_openvpn_server.php"); $tab_array[] = array(gettext("Clients"), true, "vpn_openvpn_client.php"); $tab_array[] = array(gettext("Client Specific Overrides"), false, "vpn_openvpn_csc.php"); $tab_array[] = array(gettext("Wizards"), false, "wizard.php?xml=openvpn_wizard.xml"); add_package_tabs("OpenVPN", $tab_array); display_top_tabs($tab_array); ?> <head><style> /* ************************* This style is used for the popup date picker ************************* */ /* (A) POPUP */ .picker-wrap { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.5); opacity: 0; visibility: hidden; transition: opacity 0.2s; } .picker-wrap.show { opacity: 1; visibility: visible; } .picker-wrap .picker { margin: 50vh auto 0 auto; transform: translateY(-50%); } /* (B) CONTAINER */ .picker { max-width: 300px; background: #444444; padding: 10px; } /* (C) MONTH + YEAR */ .picker-m, .picker-y { width: 50%; padding: 5px; box-sizing: border-box; font-size: 16px; } /* (D) DAY */ .picker-d table { color: #fff; border-collapse: separate; width: 100%; margin-top: 10px; } .picker-d table td { width: 14.28%; /* 7 EQUAL COLUMNS */ padding: 5px; text-align: center; } /* HEADER CELLS */ .picker-d-h td { font-weight: bold; } /* BLANK DATES */ .picker-d-b { background: #4e4e4e; } /* TODAY */ .picker-d-td { background: #d84f4f; } /* PICKABLE DATES */ .picker-d-d:hover { cursor: pointer; background: #a33c3c; } /* UNPICKABLE DATES */ .picker-d-dd { color: #888; background: #4e4e4e; } /* ************************* End style used for the popup date picker ************************* */ </style></head> <?php // ************************* PHP Functions ************************* // Function to calculate time from seconds to human readable format function seconds2human($ss) { $s = $ss%60; $m = floor(($ss%3600)/60); $h = floor(($ss%86400)/3600); $d = floor(($ss%2592000)/86400); $M = floor($ss/2592000); return "$d days $h hours $m minutes $s seconds"; } // ************************* Global Variables ************************* $logFilename = '/var/log/OpenVPN_Users.log'; //Log to be read in to generate information from $userFilename = '/tmp/OpenVPN_UniqueUsers.log'; //Scratchpad that stores usernames that then get read back into an array $secondsCounter = 0; //Running Tally of Time $dataUploadedTotal = 0; //Running Tally of Data Uploaded $dataDownloadedTotal = 0; //Running Tally of Data Downloaded $passesDateFilter = ""; // $dataArray = []; //Used to store all // ************************* Pre-Fill User Option Boxes ************************* // Pre-Fill Start Date Selection Options // if (isset($_POST["input-startpop"])) { // If Submit is pressed if ($_POST["input-startpop"]=="") { // $startDateSelected = date('Y-m-01'); // If the Start Date info is blank, set it to the first of the current calendar month }else{ // $startDateSelected = $_POST["input-startpop"]; // Or If Start Date is filled, pre-fill the Start Date with the info carried from POST } // }else{ // $startDateSelected = date('Y-m-01'); // Or on page load fill the Start Date with the first of the current calendar month. } // // Pre-Fill End Date Selection Options // if (isset($_POST["input-endpop"])) { // If Submit is pressed if ($_POST["input-endpop"]=="") { // $endDateSelected = date('Y-m-31'); // If the End Date info is blank, set it to the last of the current calendar month }else{ // $endDateSelected = $_POST["input-endpop"]; // Or If the End Date is filled, pre-fill the Start Date with the info carried from POST } // }else{ // $endDateSelected = date('Y-m-31'); // On Page load fill the End Date with the last of the current calendar month. } // // Pre-Fill Shown Option for Users Dropdown // if (isset($_POST["user_selected"])) { // If Submit is pressed $nameSelected = $_POST["user_selected"]; //Receive the user selected and filter based on it }else{ // $nameSelected = "All Users"; //Receive the user selected and filter based on it } // // Delete the $userFilename log so it can be filled fresh with each run // This could be moved to the end but it's been left at the top for diagnostic purposes unlink($userFilename); // ************************* End of Functions, Variables, and Pre-Work ************************* ?> <body><div class='panel panel-default'><div class='panel-heading'><h2 class='panel-title'> <?=gettext('Client Connections')?> <? // ************************* HTML Store and Load Point ************************* ob_start(); ?> </h2></div> <div class="table-responsive"> <table id="tblResults" class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable> <thead><tr><th width=8%>USER</th><th width=12%>EVENT</th><th width=13%>EVENT DATE</th><th width=7%>EVENT TIME</th><th width=60%>INFORMATION</th></tr></thead><tbody> <?php $fh = fopen("{$userFilename}", "a"); // Opens a scratchpad that stores usernames that then get read back into an array if (($h = fopen("{$logFilename}", "r")) !== FALSE) // Opens the logfile created by the connect.sh and disconnect.sh scripts to parse { // ************************* Open the file for reading and loop through each line ************************* while (($data = fgetcsv($h, 500, ";")) !== FALSE) // Go through line of log file and break out on each semicolon { // ************************* Assign the Array Information ************************* // Assign the $data record to variables for more readable code $recUser = $data[0]; // Store User in arr[0] $recEvent = $data[1]; // Store Event $recDate = $data[2]; // Store Event Date $recTime = $data[3]; // Store Event Time $recInfo = $data[4]; // Store Event Information fwrite($fh,substr(htmlspecialchars($recUser)."\n",6)); // Write the connected user to scratch file to be pulled into the user list later // ************************* Perform Checks to see if row should be displayed ************************* $startDateConv=strtotime($startDateSelected); // Set start date value for comparison $endDateConv=strtotime($endDateSelected); // Set end date value for comparison $recDateConv=strtotime($recDate); // Set the date value of the received entry for comparison // ************************* Perform Evaluation Checks ************************* $passesNameFilter = ($nameSelected == "" || $nameSelected == "All Users" || $nameSelected == substr(htmlspecialchars($recUser),6)); $passesDateFilter = ($recDateConv >= $startDateConv) && ($recDateConv <= $endDateConv); // If either of the filters fails to pass... if($passesNameFilter == false || $passesDateFilter == false) { // Continue on and exit the while loop if name/date criterea aren't met continue; } // If both filters pass, capture the raw row in $dataArray $dataArray[] = $data; // ************************* For a row to be displayed, prepare the informatin ************************* // Prepare the data from recdata (received data) to htmldata (data to be used in formatting and parsing) $htmlUser = substr(htmlspecialchars($recUser),6); $htmlEvent = htmlspecialchars($recEvent); $htmlTime = substr(htmlspecialchars($recTime),3); $htmlInfo = htmlspecialchars($recInfo); $htmlDate = trim(htmlspecialchars($recDate)); // Event Info - Parse the Information Column Depending on Event Type if (strpos($recEvent,"DISCONNECTED") !== false){ //Manipulate Time $seconds=strstr(substr(htmlspecialchars($recInfo),10), "s", true); $secondsCounter += $seconds; //Display Data $htmlInfo = str_replace("DATA","<BR/> DATA",$recInfo); //Manipulate Data Uploaded $dataUploaded = strstr(substr(strstr($recInfo, "): ", false),3)," ", true); $dataUploadedTotal += $dataUploaded; //Manipulate Data Downloaded $dataDownloaded = strstr(substr(strstr(substr(strstr($recInfo, "): ", false),3), "): ", false),3)," ", true); $dataDownloadedTotal += $dataDownloaded; }elseif (strpos($recEvent,"CONNECTED") != false) { $needle = "IP"; $insertCode = "<br/>"; $pos = strpos($recInfo, $needle); $htmlInfo = substr_replace($recInfo, $insertCode , $pos , 0); $htmlInfo = str_replace("INTERNAL","<BR/> INTERNAL",$recInfo); } // ************************* Display the Information ************************* echo "<tr>"; echo "<td>{$htmlUser}<br/></td>"; echo "<td>{$htmlEvent}<br/></td>"; echo "<td>{$htmlDate}<br/></td>"; echo "<td>{$htmlTime}<br/></td>"; echo "<td>{$htmlInfo}<br/></td>"; echo "</tr>".PHP_EOL; } // ************************* After all lines have looped, show totals at the bottom of the screen ************************* echo '<tr><td></td><td></td><td></td><td></td><td>Total Time Connected: <strong>'.seconds2human($secondsCounter) . '</strong>'; echo '<br />Total Data Uploaded (Received): <strong>' . $dataUploadedTotal . ' MB</strong>'; echo '<br />Total Data Downloaded (Sent): <strong>' . $dataDownloadedTotal . ' MB</strong></td></tr>'; } // Close the file with the usernames fclose($fh); echo "</tbody></table></div>"; $the_html_code = ob_get_clean(); echo "</div>"; // ************************* Build User List and Date Popup Picker ************************* $arrUserlist = file("$userFilename", FILE_IGNORE_NEW_LINES); echo "<form method='post' action='vpn_openvpn_userlogging.php'>"; // ************************* Generate Name Selection Drop Down ************************* echo "<select name='user_selected'><option selected='selected'>$nameSelected</option>"; ?><option value="All Users">All Users</option><?php foreach(array_unique($arrUserlist) as $item){ ?><option value="<?php echo $item; ?>"><?php echo $item; ?></option><?php } echo "</select>"; // ************************* User Interaction Secion ************************* echo "<input type='text' name='input-startpop' id='input-startpop' placeholder='".$startDateSelected."'/>"; // Start Date Pop-up Picker echo "<input type='text' name='input-endpop' id='input-endpop' placeholder='".$endDateSelected."'/>"; // Stop Date Pop-up Picker echo "<input type='submit' value='Submit'></form>"; // Submit Button // ************************* HTML Code is compiled. Send it back to the top. ************************* echo $the_html_code; ?> <!--- ************************* Javascript for Date Picker ************************* ---> <script> window.addEventListener("load", function(){ picker.attach({ target: "input-startpop" }); }); </script> <script> window.addEventListener("load", function(){ picker.attach({ target: "input-endpop" }); }); </script> <script> var picker = { // (A) ATTACH DATEPICKER TO TARGET // target : datepicker will populate this field // container : datepicker will be generated in this container // startmon : start on Monday (default false) // disableday : array of days to disable, e.g. [2,7] to disable Tue and Sun attach : function (opt) { // (A1) CREATE NEW DATEPICKER var dp = document.createElement("div"); dp.dataset.target = opt.target; dp.dataset.startmon = opt.startmon ? "1" : "0"; dp.classList.add("picker"); if (opt.disableday) { dp.dataset.disableday = JSON.stringify(opt.disableday); } // (A2) DEFAULT TO CURRENT MONTH + YEAR - NOTE: UTC+0! var today = new Date(), thisMonth = today.getUTCMonth(), // Note: Jan is 0 thisYear = today.getUTCFullYear(), months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; // (A3) MONTH SELECT var select = document.createElement("select"), option = null; select.classList.add("picker-m"); for (var mth in months) { option = document.createElement("option"); option.value = parseInt(mth) + 1; option.text = months[mth]; select.appendChild(option); } select.selectedIndex = thisMonth; select.addEventListener("change", function(){ picker.draw(this); }); dp.appendChild(select); // (A4) YEAR SELECT var yRange = 10; // Year range to show, I.E. from thisYear-yRange to thisYear+yRange select = document.createElement("select"); select.classList.add("picker-y"); for (var y = thisYear-yRange; y < thisYear+yRange; y++) { option = document.createElement("option"); option.value = y; option.text = y; select.appendChild(option); } select.selectedIndex = yRange; select.addEventListener("change", function(){ picker.draw(this); }); dp.appendChild(select); // (A5) DAY SELECT var days = document.createElement("div"); days.classList.add("picker-d"); dp.appendChild(days); // (A6) ATTACH DATE PICKER TO TARGET CONTAINER + DRAW THE DATES picker.draw(select); // (A6-I) INLINE DATE PICKER if (opt.container) { document.getElementById(opt.container).appendChild(dp); } // (A6-P) POPUP DATE PICKER else { // (A6-P-1) MARK THIS AS A "POPUP" var uniqueID = 0; while (document.getElementById("picker-" + uniqueID) != null) { uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; } dp.dataset.popup = "1"; dp.dataset.dpid = uniqueID; // (A6-P-2) CREATE WRAPPER var wrapper = document.createElement("div"); wrapper.id = "picker-" + uniqueID; wrapper.classList.add("picker-wrap"); wrapper.appendChild(dp); // (A6-P-3) ATTACH ONCLICK TO SHOW/HIDE DATEPICKER var target = document.getElementById(opt.target); target.dataset.dp = uniqueID; target.readOnly = true; // Prevent onscreen keyboar on mobile devices target.onfocus = function () { document.getElementById("picker-" + this.dataset.dp).classList.add("show"); }; wrapper.addEventListener("click", function (evt) { if (evt.target.classList.contains("picker-wrap")) { this.classList.remove("show"); } }); // (A6-P-4) ATTACH POPUP DATEPICKER TO DOCUMENT document.body.appendChild(wrapper); } }, // (B) DRAW THE DAYS IN MONTH // el : HTML reference to either year or month selector draw : function (el) { // (B1) GET DATE PICKER COMPONENTS var parent = el.parentElement, year = parent.getElementsByClassName("picker-y")[0].value, month = parent.getElementsByClassName("picker-m")[0].value, days = parent.getElementsByClassName("picker-d")[0]; // (B2) DATE RANGE CALCULATION - NOTE: UTC+0! var daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate(), startDay = new Date(Date.UTC(year, month-1, 1)).getUTCDay(), // Note: Sun = 0 endDay = new Date(Date.UTC(year, month-1, daysInMonth)).getUTCDay(), startDay = startDay==0 ? 7 : startDay, endDay = endDay==0 ? 7 : endDay; // (B3) GENERATE DATE SQUARES (IN ARRAY FIRST) var squares = [], disableday = null; if (parent.dataset.disableday) { disableday = JSON.parse(parent.dataset.disableday); } // (B4) EMPTY SQUARES BEFORE FIRST DAY OF MONTH if (parent.dataset.startmon=="1" && startDay!=1) { for (var i=1; i<startDay; i++) { squares.push("B"); } } if (parent.dataset.startmon=="0" && startDay!=7) { for (var i=0; i<startDay; i++) { squares.push("B"); } } // (B5) DAYS OF MONTH // (B5-1) ALL DAYS ENABLED, JUST ADD if (disableday==null) { for (var i=1; i<=daysInMonth; i++) { squares.push([i, false]); } } // (B5-2) SOME DAYS DISABLED else { var thisday = startDay; for (var i=1; i<=daysInMonth; i++) { // CHECK IF DAY IS DISABLED var disabled = disableday.includes(thisday); // DAY OF MONTH, DISABLED squares.push([i, disabled]); // NEXT DAY thisday++; if (thisday==8) { thisday = 1; } } } // (B6) EMPTY SQUARES AFTER LAST DAY OF MONTH if (parent.dataset.startmon=="1" && endDay!=7) { for (var i=endDay; i<7; i++) { squares.push("B"); } } if (parent.dataset.startmon=="0" && endDay!=6) { for (var i=endDay; i<(endDay==7?13:6); i++) { squares.push("B"); } } // (B7) DRAW HTML var daynames = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat"]; if (parent.dataset.startmon=="1") { daynames.push("Sun"); } else { daynames.unshift("Sun"); } // (B7-1) HTML DATE HEADER var table = document.createElement("table"), row = table.insertRow(), cell = null; row.classList.add("picker-d-h"); for (let d of daynames) { cell = row.insertCell(); cell.innerHTML = d; } // (B7-2) HTML DATE CELLS var total = squares.length, row = table.insertRow(), today = new Date(), todayDate = null; if (today.getUTCMonth()+1 == month && today.getUTCFullYear() == year) { todayDate = today.getUTCDate(); } for (var i=0; i<total; i++) { if (i!=total && i%7==0) { row = table.insertRow(); } cell = row.insertCell(); if (squares[i] == "B") { cell.classList.add("picker-d-b"); } else { cell.innerHTML = squares[i][0]; // NOT ALLOWED TO CHOOSE THIS DAY if (squares[i][1]) { cell.classList.add("picker-d-dd"); } // ALLOWED TO CHOOSE THIS DAY else { if (i == todayDate) { cell.classList.add("picker-d-td"); } cell.classList.add("picker-d-d"); cell.addEventListener("click", function(){ picker.pick(this); }); } } } // (B7-3) ATTACH NEW CALENDAR TO DATEPICKER days.innerHTML = ""; days.appendChild(table); }, // (C) CHOOSE A DATE // el : HTML reference to selected date cell pick : function (el) { // (C1) GET ALL COMPONENTS var parent = el.parentElement; while (!parent.classList.contains("picker")) { parent = parent.parentElement; } // (C2) GET FULL SELECTED YEAR MONTH DAY var year = parent.getElementsByClassName("picker-y")[0].value, month = parent.getElementsByClassName("picker-m")[0].value, day = el.innerHTML; // YYYY-MM-DD FORMAT - CHANGE FORMAT HERE IF YOU WANT ! if (parseInt(month)<10) { month = "0" + month; } if (parseInt(day)<10) { day = "0" + day; } var fullDate = year + "-" + month + "-" + day; // (C3) UPDATE SELECTED DATE document.getElementById(parent.dataset.target).value = fullDate; // (C4) POPUP ONLY - CLOSE THE POPUP if (parent.dataset.popup == "1") { document.getElementById("picker-" + parent.dataset.dpid).classList.remove("show"); } } }; </script> <!--- ************************* End Javascript for Date Picker ************************* ---> </body> </html> <?php include("foot.inc");?>
The update includes a few enhancements such as date range, better selection defaults, and log file limiting as well as improved notation. Give a spin and let me know how it works out for you.
-
-
@stewart said in Email Notification - OpenVPN Client Connect (Common Name):
Have you had a chance to test out the scripts? Any feedback?
Sure! I only changed the timestamp to use H24 notation. No issues so far:
-
@stewart Thank you for this script, works like a charm !
Regarding the log file limiting you mention, I can't seem to find this in your code ?
I think it would be good to set a maximum filesize (and/or even truncate files) ? What would be best practice in implementing this ?And what if one has multiple OpenVPN servers, would grouping by server be possible ? Maybe in the same manner as usernames are being propped in an array and end user can choose from by dropdown list ?
-
Sorry, I didn't see a message that someone had posted in here.
Regarding the log file limiting you mention, I can't seem to find this in your code ?
I think it would be good to set a maximum filesize (and/or even truncate files) ? What would be best practice in implementing this ?Very good question and one I don't have an answer to. I haven't really looked at it other than to know it needs to be done, otherwise the file will just continue to grow. At that point, it may be a cron job but I'd assume it would be need to be handled like the rest of the system logs and I have no idea how to do that.
I can tell you that the site I developed this on has several VPN users that connect and disconnect frequently throughout the day. Their /var/log/OpenVPN_Users.log file appears to be growing at about 10K / week or roughly 1 MB every other year. Over the expected 7 year lifecycle I suppose it will only be about 3.5MB - 4MB in size. Hardly a concern for this system but for systems with many users constantly going in and out it could get larger, faster.
And what if one has multiple OpenVPN servers, would grouping by server be possible ? Maybe in the same manner as usernames are being propped in an array and end user can choose from by dropdown list ?
Another good question. I'm not sure if that is a variable that can be extracted. Since the script files are unique to the server you could theoretically just rename the connect.sh, disconnect.sh, OpenVPN_Users.log, and vpn_openvpn_userlogging.php files and then update the pointers in the files to the new locations. That would cause you to have a second page that tracks the second server. Off the top of my head it seems fairly simple for you to do manually, but not automatically by the script if you can't pull the name of the server from the $local_connect_value.
-
I had an issue with a user where the case changed between login and logout. No idea why but it created some oddities in the logs so I've updated the connect.sh and disconnect.sh files with a minor strtolower change.
connect.sh
#!/usr/local/bin/php -q <?php // Gather Info $date = date('Y-m-d'); $time = date('g:i a'); require_once("/etc/inc/notices.inc"); // Compile Info String to Send $local_connect_value = "USER: " . strtolower(getenv('common_name')) . "; CONNECTED; " . $date . "; at " .$time . "; IP CONNECTED FROM: " . getenv('trusted_ip') . " INTERNAL IP ASSIGNED: " . getenv('ifconfig_pool_remote_ip') . "\n"; // Send Email Notification of Event // notify_all_remote($local_connect_value); $filename="/var/log/OpenVPN_Users.log"; $fp = fopen($filename, 'a'); fwrite($fp,$local_connect_value); fclose($fp); ?>
disconnect.sh
#!/usr/local/bin/php -q <?php // Gather Info require_once("/etc/inc/notices.inc"); $date = date('Y-m-d'); $time = date('g:i a'); $durationSeconds = getenv('time_duration'); // Function to calculate time from seconds to human readable format function seconds2human($ss) { $s = $ss%60; $m = floor(($ss%3600)/60); $h = floor(($ss%86400)/3600); $d = floor(($ss%2592000)/86400); $M = floor($ss/2592000); return "$d days $h hours $m minutes $s seconds"; } // Compile Info String to Send $local_connect_value .= "USER: " . strtolower(getenv('common_name')) . "; DISCONNECTED; " . $date . "; at " . $time . "; DURATION: " . $durationSeconds . " seconds or " . seconds2human($durationSeconds) . " DATA UPLOADED (RECEIVED): ". round(((getenv('bytes_received'))/1048576),2) . " MB DATA DOWNLOADED (SENT): " . round(((getenv('bytes_sent'))/1048576),2) ." MB\n"; // Send Email Notification of Event // notify_all_remote($local_connect_value); // Output to Log File $filename="/var/log/OpenVPN_Users.log"; $fp = fopen($filename, 'a'); fwrite($fp,$local_connect_value); fclose($fp); ?>
-
-
-
-
-
It's been working in our environment but there's no real integration into the GUI and I need to manually type in the page each time. Is there a way to integrate it or get it integrated? I know if I go mucking around in the interface it's just going to get overwritten with the next update.
Also, 4 months later and the log file is roughly 169K in size so it will grow to about .5MB after a year, depending on usage. That keeps it in line with my estimate of 3.5MB-4MB after the 7 year lifecycle.
-
Our OpenVPN is using Radius Server synced with Windows Active Directory Domain server for logon. Is there any way this email notification will work in such a scenario?
because currently we only get the following information, username field is blank
-
"user_name" ?
"vpn_client_ip" ?Show the script you are using.
See the example "connect.sh" file above.
The scripts file is called with a bunch of pre defined environment variable set.
Ask Google how to print all the environment variables when it starts. Normally, if known, a variable like "common_name" should contain the name. -
my connect.sh is exactly what you mentioned in the post above 1646309481558
i just changed the name from notify.sh to connect.sh and left disconnect.sh as is.
/root/connect.sh file:
#!/usr/local/bin/php -q <?php require_once("/etc/inc/notices.inc"); $local_connect_value = " user_name: " . getenv('common_name') . " vpn_client_ip: " . getenv('ifconfig_pool_remote_ip') . " on " . date('F j, Y, g:i a'); log_error("About to send a mail : Connecting"); notify_all_remote($local_connect_value); ?>
/root/disconnect.sh file:
#!/usr/local/bin/php -q <?php require_once("/etc/inc/notices.inc"); $local_connect_value .= ", during : " . getenv('time_duration') . " seconds, received : " . getenv('bytes_received') . " bytes, send : " . getenv('bytes_sent') ." bytes. DISCONNRECTED."; log_error("About to send a mail : Disconnecting"); notify_all_remote($local_connect_value); ?>
-
-
Looks ok.
What happens - I think - is that when LDAP is used, the common_name environment isn't set as it isn't known. So getenv('common_name') return 'nothing' or an empty string.I've never used LDAP, so I can't be sure.
edit : again : have all the env variables printed, and see what's in there.
-
@gertjan said in Email Notification - OpenVPN Client Connect (Common Name):
have all the env variables printed, and see what's in there.
How do you do that?
-
I created a small test file /root/test.php :
#!/usr/local/bin/php -q <?php print_r(getenv(), $output); echo $output; ?>
Now (made it executable) :
./test.phpworks for me.
Array ( [SSH_CLIENT] => 192.168.1.2 59841 22 [LOGNAME] => root [MAIL] => /var/mail/root [PATH] => /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin [PWD] => /root [TERM] => xterm [SSH_TTY] => /dev/pts/0 [USER] => root [HOME] => /root [SSH_CONNECTION] => 192.168.1.2 59841 192.168.1.1 22 [SHELL] => /bin/sh [BLOCKSIZE] => K [HOSTTYPE] => FreeBSD [VENDOR] => amd [OSTYPE] => FreeBSD [MACHTYPE] => x86_64 [SHLVL] => 1 [GROUP] => wheel [HOST] => pfsense.munetwork.net [REMOTEHOST] => 192.168.1.2 [CLICOLOR] => true [LSCOLORS] => exfxcxdxbxegedabagacad )
This was just a test - my script file
Add $output to the $local_connect_value string, and have it mailed to you.
Or log it :#!/usr/local/bin/php -q <?php require_once("/etc/inc/notices.inc"); $local_connect_value = " user_name: " . getenv('common_name') . " vpn_client_ip: " . getenv('ifconfig_pool_remote_ip') . " on " . date('F j, Y, g:i a'); print_r(getenv(), $output); log_error($output); log_error("About to send a mail : Connecting"); notify_all_remote($local_connect_value); ?>
-
@gertjan
after changing the connect.sh file to your updated example i am not getting any new information in the email.
And this is what i see in the status of the VPN connection
-
@aasimenator said in Email Notification - OpenVPN Client Connect (Common Name):
i am not getting any new information in the email.
Because the variable $output was send to the local log, the most important screens in pfSense are the logs.
At the same place you will also have this line : Status > System Logs > System > GeneralAbout to send a mail : Connecting
That's what
log_error("About to send a mail : Connecting");
is all about.
It logs an 'error' which is actually just an incontinent text message.to the logs.Same thing for the variables your looking for : check the logs.
The output string $output can be added to $local_connect_value string, why not.
-
@gertjan
No information in the logs near the Connecting message -
There it is :
Never the less : nothing.
Unbelievable but I had to Google it up.Change
print_r(getenv(), $output);
to
$output = print_r(getenv(), true);
I've tested it.
It shows a lot of info.
One of them is the :