Username IPoE Radius

Hello, we are currently testing the following scenario to see if we can use the VyOS system in production.
For hardware reasons we decided to run VyOS on AWS, from the lab using a MikroTik I configured it as OpenVPN Client and VyOS as OpenVPN in client mode, both in TAP mode with the purpose of connecting to the MikroTik and the broadcast or DHCP request get to VyOS.

In VyOS, the requests are received and an IPoE service is configured pointing to an external Radius server, but the detail is that the username arrives with the name of the interface instead of the mac address or something different that can be configured Which is where I’m stuck.

Capture on Radius server

interfaces {
    bridge br0 {
        member {
            interface vtun10 {
            }
        }
        mtu 1557
    }
    ethernet eth0 {
        address dhcp
        address dhcpv6
        hw-id 12:38:f3:b2:85:51
    }
    loopback lo {
    }
    openvpn vtun10 {
        device-type tap
        local-port 1194
        mode server
        persistent-tunnel
        protocol udp
        server {
            client mikrotik1 {
                ip 100.67.67.129
            }
            subnet 100.67.67.128/25
        }
        tls {
            ca-certificate openvpn_vtun10_1
            certificate openvpn_vtun10
            dh-params openvpn_vtun10
        }
    }
}
pki {
    ca openvpn_vtun10_1 {
        certificate xxxxxxxxxxx
    }
    certificate openvpn_vtun10 {
        certificate xxxxxxxxxxx
        private {
            key ****************
        }
    }
    dh openvpn_vtun10 {
        parameters xxxxxxxxx
    }
}
protocols {
    static {
        route 100.67.67.128/25 {
            interface vtun10 {
            }
        }
    }
}
service {
    ipoe-server {
        authentication {
            mode radius
            radius {
                accounting-interim-interval 120
                preallocate-vif
                server x.x.x.x {
                    key ****************
                }
            }
        }
        interface br0 {
            client-subnet 100.67.67.128/25
        }
        name-server 8.8.8.8
        name-server 8.8.4.4
    }
}

Can you configure the username and the rest of the radius protocols via the command line? or is a custom script required?
And if it is a script, do you have any documentation on how to do it?

Checking the /var/log/messages file shows the following when addressing:

Feb 13 07:20:57 vyos01 accel-ipoe: ipoe0:: radius:packet: unknown attribute received (0.92)
Feb 13 07:20:57 vyos01 accel-ipoe: ipoe0:: radius:packet: vendor 26 not found
Feb 13 07:20:57 vyos01 accel-ipoe: ipoe0:br0: ipoe: no free IPv6 address
zqz@vyos01.dev:~$  show ipoe-server sessions 
ifname | username |    calling-sid    |      ip       | rate-limit | type | comp | state  |  uptime  
--------+----------+-------------------+---------------+------------+------+------+--------+----------
 ipoe0  | br0      | aa:15:d4:6e:57:5b | 100.67.67.130 |            | ipoe |      | active | 00:17:44
zqz@vyos01.dev:~$

Client MAC address is in Calling-Station-Id attribute.
You must configure MAC-Auth on your RADIUS server: https://wiki.freeradius.org/guide/mac-auth

Thank you very much for the prompt response, but what we are looking for is to be able to take the mac address that comes from DHCP Discover and place it in the username field to be sent to the Radius server.

This is because the final idea is to receive the Discover requests in IPv4 Circuit-ID & Remote-ID that come in Option 82 to be able to concatenate them in the username field.

And for IPv6, in the Request field, take option 18 (Interface-ID) and option 37 (Remote-ID) to similarly concatenate the data in the radius attribute of username and be sent to the Radius server.

DHCPv4 example:

Circuit-ID = Customer number
Remote-ID = Interface where the device is connected
username= Customer number | Interface
It would look like this:
Circuit-ID=22556677
Remote-ID = 1/2/16
username=22556677|1/2/16

Example for DHCPv6

Interface-ID=22556677
Remote-ID = 1/2/16
username=22556677|1/2/16

That is why my intention to seek flexibility from Bras or VyOS

In VyOS IPoE is implemented by accel-ppp. According to the accel-ppp documentation, you can use a LUA script to modify the username. Look here: https://docs.accel-ppp.org/configuration/ipoe.html

Unfortunately, this cannot be configured directly in the VyOS CLI. You can create a feature request on https://vyos.dev/

/usr/share/vyos/templates/accel-ppp/ipoe.config.j2

It survive reboot but not upgrade

/run/accel-pppd/ipoe.conf

It not survive reboot, it is generated at boot / commit. But you modified template, so it should be generated properly.

/run/accel-pppd/ipoe.lua

It not survive reboot. Proper place for user scripts is in /config/user-data/

2 Likes

Thank you very much I finished modifying the files:

/usr/share/vyos/templates/accel-ppp/ipoe.config.j2
/run/accel-pppd/ipoe.conf
And I had to create the file:
/run/accel-pppd/ipoe.lua

Leaving the end as follows:

ipoe.config.j2 file


{# j2lint: disable=operator-enclosed-by-spaces #}
### generated by ipoe.py ###
[modules]
log_syslog
ipoe
shaper
{# Common authentication backend definitions #}
{% include 'accel-ppp/config_modules_auth_mode.j2' %}
ipv6pool
ipv6_nd
ipv6_dhcp
ippool

[core]
thread-count={{ thread_count }}

[common]
{% if max_concurrent_sessions is vyos_defined %}
max-starting={{ max_concurrent_sessions }}
{% endif %}

[log]
syslog=accel-ipoe,daemon
copy=1
level=5

[ipoe]
verbose=1
{% if interface is vyos_defined %}
{%     for iface, iface_config in interface.items() %}
{%         set tmp = 'interface=' %}
{%         if iface_config.vlan is vyos_defined %}
{%             set tmp = tmp ~ 're:^' ~ iface ~ '\.' ~ iface_config.vlan | range_to_regex ~ '$' %}
{%         else %}
{%             set tmp = tmp ~ iface %}
{%         endif %}
{%         set shared = '' %}
{%         if iface_config.network is vyos_defined('shared') %}
{%             set shared = 'shared=1,' %}
{%         elif iface_config.network is vyos_defined('vlan') %}
{%             set shared = 'shared=0,' %}
{%         endif %}
{%         set range = 'range=' ~ iface_config.client_subnet ~ ',' if iface_config.client_subnet is vyos_defined else '' %}
{%         set relay = ',' ~ 'relay=' ~ iface_config.external_dhcp.dhcp_relay  if iface_config.external_dhcp.dhcp_relay is vyos_defined else '' %}
{%         set giaddr = ',' ~ 'giaddr=' ~ iface_config.external_dhcp.giaddr if iface_config.external_dhcp.giaddr is vyos_defined else '' %}
{{ tmp }},{{ shared }}mode={{ iface_config.mode | upper }},ifcfg=1,{{ range }}start=dhcpv4,ipv6=1{{ relay }}{{ giaddr }}
{%         if iface_config.vlan is vyos_defined %}
vlan-mon={{ iface }},{{ iface_config.vlan | join(',') }}
{%         endif %}
{%     endfor %}
{% endif %}
{% if authentication.mode is vyos_defined('noauth') %}
noauth=1
{% elif authentication.mode is vyos_defined('radius') %}
lua-file=/run/accel-pppd/ipoe.lua
username=lua:userame_func
password=csid
{% elif authentication.mode is vyos_defined('local') %}
username=ifname
password=csid
{% endif %}
{% if default_pool is vyos_defined %}
ip-pool={{ default_pool }}
{% endif %}
{% if default_ipv6_pool is vyos_defined %}
ipv6-pool={{ default_ipv6_pool }}
ipv6-pool-delegate={{ default_ipv6_pool }}
{% endif %}
{% if gateway_address is vyos_defined %}
{%     for gw_addr in gateway_address %}
gw-ip-address={{ gw_addr }}
{%     endfor %}
{% endif %}
proxy-arp=1

{# Common IP pool definitions #}
{% include 'accel-ppp/config_ip_pool.j2' %}

{# Common IPv6 pool definitions #}
{% include 'accel-ppp/config_ipv6_pool.j2' %}

{# Common DNS name-server definition #}
{% include 'accel-ppp/config_name_server.j2' %}

{# Common chap-secrets and RADIUS server/option definitions #}
{% include 'accel-ppp/config_chap_secrets_radius.j2' %}

{# Common RADIUS shaper configuration #}
{% include 'accel-ppp/config_shaper_radius.j2' %}

[cli]
tcp=127.0.0.1:2002

ipoe.conf file

### generated by ipoe.py ###
[modules]
log_syslog
ipoe
shaper
radius
ipv6pool
ipv6_nd
ipv6_dhcp
ippool

[core]
thread-count=1

[common]

[log]
syslog=accel-ipoe,daemon
copy=1
level=5

[ipoe]
verbose=1
interface=br0,shared=1,mode=L2,ifcfg=1,range=100.67.67.128/25,start=dhcpv4,ipv6=1
lua-file=/run/accel-pppd/ipoe.lua
username=lua:username_func
password:csid
proxy-arp=1



[dns]
dns1=8.8.8.8
dns2=8.8.4.4

[ipv6-dns]

[radius]
verbose=1
server=x.x.x.x,secret,auth-port=1812,acct-port=1813,req-limit=0,fail-time=0
acct-interim-interval=120
acct-timeout=3
timeout=3
max-try=3
nas-identifier=VyOS-Zqz

[shaper]
verbose=1
down-limiter=tbf

[cli]

ipoe.lua file

function username_func(pkt)
  return pkt:hwaddr()
end

Now my question is, if I upgrade the version of VyOS or restart the computer, will these changes remain or do I have to make them again?

Hi,

put all your files in to /config/user-data and modify /config/scripts/vyos-postconfig-bootup.script to create symlinks before the config will be loaded, that should be persistent

1 Like

Hello… thank you very much for the information, it worked well for me even though after a restart or reset the configuration was maintained.

Thank you so much.

1 Like