Associate VPN user with a VLAN in pfSense

1st post…

I am new to PI and am VERY impressed, what a great solution, well done.

We run a multi-tenant network with each client having a dedicated VLAN.

We run OVPN on pfSense and to date have used the pfSense Radius package. This allowed us to assign IP addresses with VPN users and then use firewall rules to restrict users to their VLAN.

I have configured PI with FreeRadius and now have users authenticating using their LDAP UID and htop. This works well.

I need to be able to identify users in pfSense so I can restrict, using FW rules, which VLAN they can access.

Is there a way in PI to associate a realm with a VLAN and have this passed back to pfSense for use in FW rules?

Thanks in advance.

I have now created an extended atrribute in my LDAP schema called vpnStaticIP and created an attribute mapping in my LDAP resolver. This works.

I believe The only missing piece is to now return this IP address to pfSense as “Framed-IP-Address” however I have no idea how to achieve this.

A similar questions was asked and answered here but I do not know what to do:

I have now rename the mapped attribute to be called: Framed-IP-Address

However this is not flowing through to pfSense

I have updated /etc/privacyidea/rlm_perl.ini to map a static IP to Framed-IP-Address and this now shows in the log however pfSense is not using this IP

Wed Jul  9 10:08:59 2025 : Info: rlm_perl: privacyIDEA access granted for test1@c1005.cloud realm=''
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++ Parsing group: Mapping 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++ Found member 'Mapping user'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ Map: user : 172.48.0.2 -> Framed-IP-Address
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++ Parsing group: Attribute 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++ Found member 'Attribute Filter-Id'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ Attribute: IF ''->'' == '' THEN 'Filter-Id'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ no directory
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ User attribute is a string: 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ trying to match 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++++ Result: No match, no RADIUS attribute Filter-Id added.
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++ Found member 'Attribute otherAttribute'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ Attribute: IF ''->'' == '' THEN 'otherAttribute'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ no directory
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ User attribute is a string: 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ trying to match 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++++ Result: No match, no RADIUS attribute otherAttribute added.
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++ Found member 'Attribute Class'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ Attribute: IF ''->'' == '' THEN 'Class'
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++ no directory
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ User attribute is a string: 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: +++++++ trying to match 
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: ++++++++ Result: No match, no RADIUS attribute Class added.
Wed Jul  9 10:08:59 2025 : Info: rlm_perl: return RLM_MODULE_OK

You can map user attributes from privacyIDEA users to RADIUS attributes in the response.

You need to

  1. enable the user attributes in the privacyIDEA /validate/check response via a policy: 8.4. Authorization policies — privacyIDEA 3.11.4 documentation

  2. You need to edit your rlm_perl.ini of your freeradius server, to map these attributes to RADIUS attributes. See RADIUS plugin — privacyIDEA 3.11.4 documentation
    This can get pretty complicated and you need to make heavy use of the freeradius debugging freeradius -X.