pyavitz / debian-image-builder

Debian image builder for single board computers
Other
141 stars 33 forks source link

Mac addresses change at each start #44

Closed Averell7 closed 1 year ago

Averell7 commented 1 year ago

It is more a suggestion than an issue. Mac addresses change at each start, and it can be annoying. The reason is /etc/systemd/99-default.link which disables the normal rule which contains the command for persistent mac addesses. Is this really a good choice ? I just deleted this line and run like that without problems.

pyavitz commented 1 year ago

Is this referring to the NanoPi R5S? Is the MAC address changing? I thought I addressed this issue with a service, but it could be that the timing of the service needs to be changed/reverted or your suggestion used.

Currently the service is set to run this script really early (early depending on the img release used), originally it was much later in the boot process. Which could be why the MAC address is changing on you. I use this same MAC address bit on the R4SE and am told it works fine, although on that board I have it set to run later (I believe they are both set to run at the same time now).

Ideally there should really be another way to go about this, such as resolving this issue with u-boot if at all possible. But regardless of how it should or should not be, I don't own the HW and at the end of the day, how things are working come down to what people tell me and suggest. If you or anyone else has a better solution, open a PR or issue and show me.

Thanx

EDIT: Weren't you playing with a udev rule that changes the eth port names? This could be why the script is no longer working?

Averell7 commented 1 year ago

Yes, this is the NanoPi R5S. You are right that I added a udev rule, it this may explain that your script does not work, I will test. But nevertheless ths most simple (and hence maintanable way) is the normal one which is to not disable the existing rule which works fine : image The link in /etc/systemd/network has the same name, which means it overrides the above rule, and it is a link to /dev/null which disables totally this rule

pyavitz commented 1 year ago

Did you build your own Ubuntu Jammy or Kinetic img and are using ifupdown? If so, I disable a few things under those circumstances because other wise resolv and static ip would be broken on that release. That's the only reason I can think as to why that would be there and linked to /dev/null.

https://github.com/pyavitz/debian-image-builder/blob/feature/scripts/stage2#L19 https://github.com/pyavitz/debian-image-builder/blob/feature/scripts/stage2#L78

Anyway, as far as I know I'm not adding that file and can't find it linked in such a way on any of my current running systems. Regardless I can have the builder remove it, if found during builds.

Averell7 commented 1 year ago

I use the Debian-bullseyes 5.19 you shared here : https://github.com/pyavitz/binary/releases/tag/images But I see you have a more recent one. Mine was dowloaded on september 26. I will have a look at your last version.

Averell7 commented 1 year ago

You are rignt, in your last build, the files I had in /etc/systemd/network have disappeared, and the mac address does not change. But there is a problem : the three interfaces have the same mac address. Can you tell me which service you have added for this question ?

pyavitz commented 1 year ago

The actual service in question should be tweaks; /etc/systemd/system/tweaks.service The path to the script is in the service file.

Averell7 commented 1 year ago

OK, thanks. The problem is that the script gives the same address to the three adapters. It could be easily corrected, but this is not necessary. Once the 99-default.link (symlinked to /dev/null) in /etc/systemd/network is deleted, the MacAddressPolicy = persistent of the original rule works fine. The adresses will change a last time on next reboot, and then stay stable. So I preferred to remove your script.

But there is a mystery : as soon as I installed your image, I verified, there was nothing in /etc/systemd/network/ But I verified again a moment ago and the two files (@99-default... and @73-usb...) have been created. By whom ? Since I installed a lot of packages, it will be difficult to find, but I will try and if I have an answer I will post it here.

pyavitz commented 1 year ago

Its my understanding that like the R4SE, this R5S does not have a unique MAC address and that without some form of scripting or a u-boot intervention, you'll just be left with some random junk upon each reboot. A version of that script is also used on the R4SE img and I was told that it produced a diff addr per each port.

The MACADDR bit has two parts to it.

MACDEV=`findmnt -v -n -o SOURCE / | sed 's/dev//g' | sed -e 's#/$##' -e 's/\.git$//' -e 's#^.*/##' | sed 's/p1//g' | sed 's/p2//'`
if [[ -f /sys/class/block/$MACDEV/device/cid ]]; then
        # This one is said to produce a different address for each
    HASHDEV=`sha256sum /sys/class/block/$MACDEV/device/cid`
    MACADDR=`echo "${HASHDEV}" | dd bs=1 count=12 2>/dev/null | sed 's/../&:/g; s/:$//'`
else
        # This one is said to produce the same for all
    MACADDR=$(echo $FQDN|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
fi

I'm just going by what people who tested the imgs and scripts told me. So if its not working for you on that board, then maybe the scripting is off? This is just me guessing, but the distro probs knows there is no unique MAC address so its putting those files in place.

Averell7 commented 1 year ago

You are right that the device has n o fixed Mac address, I deduce it from the fact that they have a model where they indicate "Fixed Macaddress". I just give you my experience :

When your script is working, I get the second result, same address for all devices. When our script is removed and systemd rule 99-default.link is disabled, I have random mac adresses at each reboot. When this systemd rule is active, random addresses are created once, and after that they remain fix, due to the parameter MacAddressPolicy=persistent which works fine. Below two sreenshots with a reboot between them : image image Now you do what you want, I just explain you what is my preferred solution.

pyavitz commented 1 year ago

Thank you for the info, I do appreciate it.

Once I receive more information on the subject, I'll see about a better solution. Hopefully one that checks more boxes.

pyavitz commented 1 year ago

This was posted over at Armbian a few days ago.

/dts-v1/;
/plugin/;

/ {
    compatible = "allwinner,sun8i-h3";

    /* 
     * uboot tries to write a MAC address from ${mac_node}
     * to the device tree at 'local-mac-address' within 'ethernet0'
     *   fdt set ethernet0 local-mac-address ${mac_node}
     * This obviously doesn't work if the device tree does not match the  
     * expected structure, resulting in the kernel creating a random MAC.
     * 
     * This overlay adjusts the device tree to accept uboot's MAC address 
     * by adding 
     * - 'ethernet0' alias for symbol '/soc/ethernet@1c30000'
     *   (or change to whatever path your existing symbol 'emac' points to)
     * - 'local-mac-address' to structure at 'emac'
     * 
     * Tested to work on a NanoPi NEO 1.4 - adjust for other devices as required
     */

    fragment@0 {
        target-path = "/aliases";
        __overlay__ {
            ethernet0 = "/soc/ethernet@1c30000";
        };
    };

    fragment@1 {
        target = <&emac>;
        __overlay__ {
            local-mac-address = [00 00 00 00 00 00];
        };
    };
};

Something like this may be able to be used to set a proper MAC ADDR on the R4S and R5.

Averell7 commented 1 year ago

Thanks, it is a very interesting and elegant

phlax commented 1 year ago

i use an initrd script and a kernel flag for this

$ cat etc/initramfs-tools/scripts/init-top/setmac.sh
#!/bin/sh -e

PREREQ=""
prereqs()
{
    echo "$PREREQ"
}

case $1 in
prereqs)
    prereqs
    exit 0
    ;;
esac

# Parse the MAC address from the kernel command line
mac_address=$(cat /proc/cmdline | sed -n 's/.*mac=\([^ ]*\).*/\1/p')

if [ -n "$mac_address" ]; then
    # Set the MAC address for the interface
    echo "Setting mac adddress ${mac_address}"
    ip link set dev eth0 down
    ip link set dev eth0 address $mac_address
    ip link set dev eth0 up    
else
    echo "No mac address supplied not setting"    
fi

and then add mac=00:00:00:00:00 with correct/generated mac

phlax commented 1 year ago

it assumes eth0, but could easily be adapted for other/more interfaces

phlax commented 1 year ago

does above dtb set it to a correct/hardware mac?