Project

General

Profile

Actions

Bug #8087

open

Provide Calling-Station-ID to RADIUS backed VPN connections

Added by Sunrunner20 20 almost 8 years ago. Updated 17 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Authentication
Target version:
-
Start date:
11/13/2017
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
Release Notes:
Affected Version:
All
Affected Architecture:

Description

I'm using Duo 2fa radius proxy to connect to the on board RADIUS server in PFsense and am not getting an IP or a username in the Duo Notifications. This is a much valued feature to validate that the request is coming from one of my machines (I'm not always there when secneg occurs). I do not know the RADIUS attribute for username.

Actions #1

Updated by Jim Pingle about 6 years ago

  • Category set to Authentication

Might not be possible to put the client address in there since I am not sure the auth system will see that from OpenVPN/IPsec, but it might be worth looking into.

There have been changes since this request was made, however. It does fill in the NAS-IP-Address (configurable in the auth server settings) and NAS-Identifier, which will show at least which firewall the request came through.

Actions #2

Updated by Viktor Gurov over 5 years ago

Calling-Station-Id is already supported by EAP-RADIUS strongswan plugin, see https://wiki.strongswan.org/projects/strongswan/wiki/EAPRadius#Attributes-sent-to-RADIUS-servers

testing packet capture:

Attribute Value Pairs
    AVP: t=User-Name(1) l=6 val=test
    AVP: t=NAS-Port-Type(61) l=6 val=Virtual(5)
    AVP: t=Service-Type(6) l=6 val=Framed(2)
    AVP: t=NAS-Port(5) l=6 val=18
    AVP: t=NAS-Port-Id(87) l=12 val=con-mobile
    AVP: t=NAS-IP-Address(4) l=6 val=192.168.3.4
    AVP: t=Called-Station-Id(30) l=19 val=192.168.3.4[4500]
    AVP: t=Calling-Station-Id(31) l=20 val=192.168.3.3[54552]
    AVP: t=EAP-Message(79) l=11 Last Segment[1]
    AVP: t=NAS-Identifier(32) l=12 val=strongSwan
    AVP: t=Message-Authenticator(80) l=18 val=e782d4fcf522e54f87db557dfb529a0f

in case of OpenVPN, the current implementation of openvpn-plugin-auth-script.so do not support $clientid environment variable

Actions #3

Updated by Brandon Verkada about 3 years ago

Has there been any update on this? Ran into the same issue, pfSense OpenVPN not forwarding the Radius parameters to DUO.

Actions #4

Updated by Christian Ullrich almost 3 years ago

OpenVPN makes the client's apparent address available in environment variables:

--- openvpn.auth-user.php.orig  2022-12-03 14:08:05.556382000 +0100
+++ openvpn.auth-user.php       2022-12-03 14:08:34.276103000 +0100
@@ -102,7 +102,7 @@
 $attributes = array("nas_identifier" => "openVPN",
     "nas_port_type" => RADIUS_VIRTUAL,
     "nas_port" => $_GET['nas_port'],
-    "calling_station_id" => get_interface_ip() . ":" . $_GET['nas_port']);
+    "calling_station_id" => getenv("untrusted_ip") . ":" . getenv("untrusted_port"));

 foreach ($authmodes as $authmode) {
     $authcfg = auth_get_authserver($authmode);
Actions #5

Updated by Brandon Verkada almost 3 years ago

Christian Ullrich wrote in #note-4:

OpenVPN makes the client's apparent address available in environment variables:

[...]

Thanks Christian. I patched the openvpn.auth-user.php but had to change it a bit, skipping the untrusted_port part, otherwise DUO won't parse the IP parameter correctly. It may be a DUO-related issue only, not sure.
So what ended up working for me is replacing the whole line with:

"calling_station_id" => getenv("untrusted_ip"));
Actions #6

Updated by Marcos M almost 3 years ago

The format itself is application-specific.

Actions #7

Updated by Brandon Verkada over 1 year ago

Welp, even "my" last hack stopped working somewhere along the pfSense stable upgrade path, currently on "23.09.1-RELEASE (amd64)" and the `calling_station_id` doesn't get populated with `untrusted_ip` (although present when tcpduming the openvpn client stream), the `untrusted_port` does propagate correctly though. Weird.

"calling_station_id" => getenv("untrusted_ip") . ":" . getenv("untrusted_port"));

If anyone has a solution it would be much appreciated.

Actions #8

Updated by Erich Weiler 7 months ago

Just a followup on this item... I also would love for this to work. I can verify that @Brandon Verkada is right, it seems like "untrusted_port" seems to be available in the pfSense php scripts, but "untrusted_ip" doesn't seem to work. I verified in the OpenVPN 2.6 docs that "untrusted_ip" is indeed a valid environment variable, as documented here:

https://openvpn.net/community-resources/reference-manual-for-openvpn-2-6/

It seems these scripts are pulling in several other environment variables such as "username", "password", "common_name" and "untrusted_port", but I can't seem to get it to pull in "untrusted_ip". I think it's probably a simple fix somewhere to import this environment variable into the openvpn.auth-user.php script... Does anyone know how we can do that? It would make dozens of people in my organization extremely happy... :)

Actions #9

Updated by Brandon Verkada 7 months ago

We have three patches now that do the trick:

  • duofix.sh
#!/bin/sh
patch -b /etc/inc/openvpn.attributes.php openvpn.attributes.php.patch
patch -b /etc/inc/openvpn.auth-user.php openvpn.auth-user.php.patch
patch -b /usr/local/sbin/ovpn_auth_verify_async ovpn_auth_verify_async.patch
  • openvpn.attributes.php.patch
--- /etc/inc/openvpn.attributes.php    2024-02-14 01:26:06.236903000 -0800
+++ /etc/inc/openvpn.attributes.php.duofix    2024-02-14 01:26:28.982237000 -0800
@@ -21,7 +21,7 @@
  * limitations under the License.
  */

-global $attributes, $username, $dev, $untrusted_port;
+global $attributes, $username, $dev, $untrusted_port, $untrusted_ip;

 if (empty($dev)) {
     $dev = "openvpn";
  • openvpn.auth-user.php.patch
--- /etc/inc/openvpn.auth-user.php    2024-02-14 01:11:18.732283000 -0800
+++ /etc/inc/openvpn.auth-user.php.duofix    2024-02-14 01:22:49.415374000 -0800
@@ -36,7 +36,7 @@
 /* setup syslog logging */
 openlog("openvpn", LOG_ODELAY, LOG_AUTH);

-global $common_name, $username, $dev, $untrusted_port;
+global $common_name, $username, $dev, $untrusted_port, $untrusted_ip;

 if (isset($_GET['username'])) {
     $authmodes = explode(",", base64_decode($_GET['authcfg']));
@@ -48,6 +48,7 @@
     $strictusercn = $_GET['strictcn'] == "false" ? false : true;
     $dev = $_GET['dev'];
     $untrusted_port = $_GET['untrusted_port'];
+    $untrusted_ip = $_GET['untrusted_ip'];
 } else {
     /* read data from environment */
     $username = getenv("username");
@@ -55,6 +56,7 @@
     $common_name = getenv("common_name");
     $dev = getenv("dev");
     $untrusted_port = getenv("untrusted_port");
+    $untrusted_ip = getenv("untrusted_ip");
 }

 if (!$username) {
@@ -102,7 +104,7 @@
 $attributes = array("nas_identifier" => "openVPN",
     "nas_port_type" => RADIUS_VIRTUAL,
     "nas_port" => $_GET['nas_port'],
-    "calling_station_id" => get_interface_ip() . ":" . $_GET['nas_port']);
+    "calling_station_id" => $untrusted_ip);

 foreach ($authmodes as $authmode) {
     $authcfg = auth_get_authserver($authmode);
  • ovpn_auth_verify_async.patch
--- /usr/local/sbin/ovpn_auth_verify_async    2024-02-14 01:11:07.610506000 -0800
+++ /usr/local/sbin/ovpn_auth_verify_async.duofix    2024-02-14 02:58:54.461206000 -0800
@@ -62,7 +62,7 @@
 # ---------- Perform Check
 auth_credentials="username=${username}&password=${password}" 
 # Note that common_name is also assumed to be set by the environment
-auth_server_1="cn=${common_name}&strictcn=${strictcn}&authcfg=${authcfg}&dev=${dev}&untrusted_port=${untrusted_port}" 
+auth_server_1="cn=${common_name}&strictcn=${strictcn}&authcfg=${authcfg}&dev=${dev}&untrusted_port=${untrusted_port}&untrusted_ip=${untrusted_ip}" 
 auth_server_2="modeid=${modeid}&nas_port=${nas_port}" 
 auth_args="${auth_credentials}&${auth_server_1}&${auth_server_2}" 

Actions #10

Updated by Erich Weiler 7 months ago

Beautiful, thank you so much! It works like a charm. This is so great. Thanks a million!

Actions #11

Updated by Brandon Verkada 7 months ago

Erich Weiler wrote in #note-10:

Beautiful, thank you so much! It works like a charm. This is so great. Thanks a million!

Happy to help, solved a lot of issues in our company as well. People are much happier :)

In any case, don't forget to reapply the patch after Netgate pushes a pfSense update (which is rare nowadays) as the files can get overwritten by default versions.

Actions #12

Updated by Alex Kolesnik 17 days ago

Folks, I believe "calling_station_id" must have the port number along with the IP address. Skipping the port is really bad, 'cos it breaks the ability to distinguish clients connections from each other. I don't know what DUO is but it's the one that should be tweaked to handle the correct attribute, not vice versa.

Any chances to have this change in the base?

Actions

Also available in: Atom PDF