OPNsense Forum

Archive => 22.1 Legacy Series => Topic started by: PerpetualNewbie on February 17, 2022, 05:15:18 pm

Title: Persistent NIC ordering/naming basedon MAC address(es)
Post by: PerpetualNewbie on February 17, 2022, 05:15:18 pm
Hello,

We have an OPNSense system up and running with over 16 network interfaces, many with 4 interfaces per card. Several cards have died over the years, and when they are replaced, the NIC ordering and naming on boot is often confused leading to broken rules.

Add to this, the PCI Address assignments for NIC in various slots can change with BIOS updates, but not always.

There is a package recently added to HBSD/FreeBSD "ethname" which is designed to handle this by having a static configuration file with MAC addresses and NIC assigned named for those MAC. This did not work for us in 21.*, even when enabled.

Testing in 22.*, this "works" in that it what what it claims, but only after all the other software has started, including interface configuration. This results in a system which has interface names configured based on MAC, but with layer3 addresses based on the name each interface had before being renamed. (Interfaces renamed, but service broken.)
It would be nice if this could happen and be completed before any services are started, and allow us to edit these files to change MAC when a NIC is to be replaced, so we can add the MAC of a replacement NIC to this file, and then shutdown, replace NIC, and boot up.

Up until now, I've managed to be physically present at the OPNSense device when we perform upgrades, and then use a script that checks NIC interfaces against a "known good table for NIC naming based on MAC addresses also in table" then query the PCI address for the various interfaces, and then populate "/boot/devices.hints" with the necessary information to have the booting kernel assign interface names as we need.

When we have a BIOS upgrade, we boot OPNSense, run the script, and then reboot again.

When there is an OPNSense upgrade that requires a reboot, that usually clears any edits to "/boot/devices.hints" and then requires me to login, run the script and reboot again.

How does everyone else handle occasions of random NIC re-ordering?

Is there an internal method we should be using?

If there is no built-in method for ensuring NIC are always assigned the same names on each boot, are there plans to add one?

Are there plans to have support for "ethname" get called before any services of interface address assignments?
(As of Dec. 2021, the answer was no: https://forum.opnsense.org/index.php?topic=25805.msg124381#msg124381 )

If none of these are presently possible (with present software set/base), is there a way to have the system "run my script to updated devices.hints" for me after each upgrade replaces my custom naming for interfaces in /boot/devices.hints, if so, how? Just drop it in the shutdown scripted process? Create a service/package to run it on shutdown? What is the preferred/suggested method?

If none of these, is there a ways to have a persistent local "/boot/devices.hints" like "/boot/devices.hints.local" which is used similar to "/boot/loader.conf.local" which is used, but not destroyed/replaced on upgrade?

TIA
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: franco on February 18, 2022, 08:28:54 am
Hi PerpetualNewbie,

# pkg install ethname

Add your script to rc.syshook early facility.

https://docs.opnsense.org/development/backend/autorun.html#syshook


Cheers,
Franco
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: zbig on February 18, 2022, 08:36:10 am
Yeah, it is kind of an issue. My instance runs on VMware and it took me some time to realize what was going on that the mere act of adding a new network interface to the VM was shuffling all my interface assignments around. The fact that I had (needlessly) assigned a spoofed MAC on one of the interfaces at OPNsense level and after the mixup the OS was suddenly trying to configure the same MAC on two different IFs, just added to the confusion.
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: PerpetualNewbie on February 26, 2022, 05:45:29 am
Hi PerpetualNewbie,

# pkg install ethname

Add your script to rc.syshook early facility.

https://docs.opnsense.org/development/backend/autorun.html#syshook


Cheers,
Franco

This worked for us, so far. (The only unknowns at this point are: will these survive minor upgrades? and will these survive major upgrades? : Hard to know, as we cannot know the future so well as to rule out the possibility that some future upgrade will abandon support for this or change how it is implemented.)

Thanks for the link! :-)

The required changes were applied to a sample OPNSense system running 22.1 , confirmed to work, then upgraded to 22.1.1 and these changes to ensure NIC names by MAC address survived this minor upgrade. (Nice!)

...

Added package ethname (something we had previously done)
pkg install ethname

Create a new bourne shell script and save to /usr/local/etc/rc.syshook.d/early/02-ethname
(bare bones example without careful security and sanity checks)

Bare-bones example without security or sanity check: "/usr/local/etc/rc.syshook.d/early/02-ethname"
---------------------------------------------
#!/bin/sh

# Manual call to ethname "service" not enabled in /etc/rc.conf*:
/usr/local/etc/rc.d/ethname onestart
---------------------------------------------

(You can add a lot more in the way of sanity checking and security checks to such a script to catch and report errors, but that is up to you.)
(It made sense to me to have it happen before the upgrade early script, in case any upgrade relies on the NIC being named as they would in production.)

Then set owner and mode to match present default for other early scripts:
chown root:wheel /usr/local/etc/rc.syshook.d/early/02-ethname
chmod 0755 /usr/local/etc/rc.syshook.d/early/02-ethname

If you enable it in /etc/rc.conf* then it may get called more than once.
Left not enabled, a call from the /usr/local/etc/rc.syshook.d/early/02-ethname as "onestart" runs it only once before other services and network assignment based on name are completed.

Next, there is need to populate the configuration file.
As of 22.1 and Feb. 25, 2022, the package-provided "/usr/local/etc/rc.d/ethname" has a dot-include of "/etc/rc.subr" and it has a call to "load_rc_config" defined to search for a config for ethame as "/etc/rc.conf.d/ethname" (among other paths/names if defined and present) to load a configuration for how to name NIC based on MAC address and other ethname configurations.

So, the end user would need to populate a new file "/etc/rc.conf.d/ethname"

Example "/etc/rc.conf.d/ethname": (Example MAC addresses obviously don't match your MAC addresses.)
---------------------------------------------
ethname_enable="NO"
ethname_timeout=30
ethname_igb0_mac="ac:f0:0f:00:00:01"
ethname_igb1_mac="ac:f0:0f:00:00:03"
ethname_igb2_mac="ac:f0:0f:00:00:05"
ethname_igb3_mac="ac:f0:0f:00:00:07"
ethname_ixl0_mac="ac:f1:0f:00:00:01"
ethname_ixl1_mac="ac:f1:0f:00:00:03"
ethname_ixl2_mac="ac:f1:0f:00:00:05"
ethname_ixl3_mac="ac:f1:0f:00:00:07"
ethname_ix0_mac="ac:f2:0f:00:00:01"
ethname_ix1_mac="ac:f2:0f:00:00:03"
ethname_ix2_mac="ac:f2:0f:00:00:05"
ethname_ix3_mac="ac:f2:0f:00:00:07"
---------------------------------------------

Then set the owner and mode for this to match other files as of Feb 25, 2022:
chown root:wheel /etc/rc.conf.d/ethname
chmod 0644 /etc/rc.conf.d/ethname

As you can see, as of Feb 25, 2022, the format is fairly straight-forward, name the interface as part of the variable name and specify the MAC address of the NIC that should use that name.

Read the man page for ethname or read the source code of their script to confirm this example is still the present method when you read this.


Now, if we know a NIC has failed, we can read the MAC addresses of the new NIC for all its interfaces, edit the file "/etc/rc.conf.d/ethname" to replace the broken NIC's MAC addresses with the new NIC, save, shut down, replace the NIC, and boot.

Simple and clean. Only one shutdown and reboot required.

This also avoids the *high-risk* method of relying on PCI addresses and /boot/devices.hints method of naming interfaces : PCI address assignments which can change when a card is added or removed, when a card dies, or when BIOS is upgraded, and for some motherboards/VM, on each reboot.

Thanks again!

(Hopefully this feedback and details provided will help someone else interested in doing the same thing.)
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: franco on February 28, 2022, 12:22:10 pm
This worked for us, so far. (The only unknowns at this point are: will these survive minor upgrades? and will these survive major upgrades? : Hard to know, as we cannot know the future so well as to rule out the possibility that some future upgrade will abandon support for this or change how it is implemented.)

Yes these facilities are designed to be permanent solutions to missing integrations into OPNsense (due to scope, lack of upstreaming, etc.).

Thank you for the write-up on how to achieve this, highly appreciated. :)


Cheers,
Franco
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: PerpetualNewbie on March 19, 2022, 08:04:46 am
This has worked flawlessly for all upgrades since, including the latest 22.1.3
Thanks again!
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: stanthewizzard on May 25, 2022, 04:17:31 pm
YOU just saved me

I used you "tuto" for 8 firewalls on esxi

IT WORKS (vmx in my case)

Thanks
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: PerpetualNewbie on May 25, 2022, 05:01:51 pm
Thanks :-)
It has reliably worked with every upgrade since it was installed.
We even had a NIC fail. I edited the config while the server was up, commented out the MAC addresses from the failed card, put in the new MAC addresses for the replacement, shut down, replaced NIC, rebooted, worked.
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: stanthewizzard on May 25, 2022, 11:30:34 pm
Awesome
8 firewall hardened on my side
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: EBorisch on September 08, 2022, 04:52:58 am
Hi; ethname author here.

A few quick comments:

1) I’m glad to hear you’re finding it useful!
2) There’s no need to worry about running it multiple times (mentioned in one of the posts); it is designed to detect names already correctly assigned and gracefully skip over those.
3) If there is something that would improve the experience for OPNsense users (while not breaking it for others) feel free to submit a PR on guthub, even if it’s just a documentation update to describe the best way to use it for OPNsense.

Thanks!
 - Eric
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: xouyz on March 25, 2023, 11:47:40 pm
Hi everyone. I'm interested to implement this solution using ethname.
However, when I tested it, I've got an issue: on startup, when early ethname hook is called, my USB ethernet adapters are not already loaded. If during this hook, I run "netif start", I only see my PCI interface. I'm running OPNSense 22.7
Do you have an idea to help me to fix that?

Thanks for your help!
Xouyz
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: EBorisch on March 26, 2023, 12:55:13 am
On FreeBSD when I originally wrote this and had USB Ethernet adapters, adding the appropriate if_load_X="yes" into /boot/loader.conf did the trick. I’m not an opnsense user, so YMMV.
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: xouyz on March 29, 2023, 01:04:38 am
Thanks for your answer, that's really helpful. I'll try it and I'll share a full feedback here.
Title: Re: Persistent NIC ordering/naming basedon MAC address(es)
Post by: xouyz on April 15, 2023, 07:26:52 pm
So, I successfully tested it today. Many thanks again to everyone in this topic.
Here are the what you should do to mount USB ethernet interfaces before early scripts.

To correctly start the USB interface, you have to go to the web interface: dashboard -> System -> Settings -> Tunables.

Add a new tunable with name "if_X_load" where X is the shortcut name of your driver. In my case, it is "axge" for ASIX AX88179, so I put "if_axge_load" in name field.
Set "YES" in value field.

Then, you can simply follow the wonderful tutorial made by PerpetualNewbie. It's just perfect.

Little tip: To check startup log when you're logged in SSH (so after startup), you can use the command "dmesg -a". Maybe it's obvious for many users here but I didn't know this command and it was super useful to help me to debug ^^