# Consistent enumeration of network interfaces



## symlink (Jul 18, 2020)

Hi.

I'm new to the FreeBSD world.  As I'd like to gain some knowledge on this operating system, I decided to install FreeBSD on a little Raspberry board.  I plan to use it as a general purpose (headless) home server.

Among other things, I'd like to expose it to the open Internet, so I can use it as a sharing device.

The Raspberry platform has got a single Ethernet port, I purchased an external NIC (USB).  The idea is to attach one of the two NICs on the local network, and give the other one direct access to the broad-band.

I'd like to configure the firewall so that it is more liberal on the internal network, and more strict with connections coming from the outside.

Of course I base my firewall rules on the source network address, but I was wondering if it would be practical to base them on the network device name, instead.

I know it is feasible from the pf(4) standpoint, but I don't know (and I could not find any mention in the Handbook) if I can rely on the system assigning consistently the network device name.

What I would like to avoid, as you may understand, is to have the interface names swapped during a reboot, and ending up exposing to countless script kiddies some services that are not intended to be exposed.

Thanks in advance.


----------



## SirDice (Jul 20, 2020)

Interfaces are detected in the same order, every time. Unless you _add_ or _remove_ an interface the order will remain the same.


----------



## Ordoban (Jul 20, 2020)

SirDice said:


> Interfaces are detected in the same order, every time. Unless you _add_ or _remove_ an interface the order will remain the same.


This is the case for PCI devices, but USB? 
Are you sure they always become ready, detected and initialized in the same order?


----------



## SirDice (Jul 20, 2020)

Ordoban said:


> Are you sure they always become ready, detected and initialized in the same order?


If they are attached  in the same order, yes. If you change the order by swapping them around (or adding/removing) then their detection would also change accordingly.


----------



## olli@ (Jul 20, 2020)

SirDice said:


> If they are attached  in the same order, yes. If you change the order by swapping them around (or adding/removing) then their detection would also change accordingly.


If the USB devices are both present during boot, I’m not sure if they are always probed in the same order. There might be subtle timing issues when probing for USB devices, maybe sometimes one of them takes a little longer to respond, depending on circumstances (whether it has a link, for example). I wouldn’t rely on it for security-critical decisions.

Therefore my advice is to base the firewall rules on the IP addresses. If you want to restrict a rule to a particular device instead of (or in addition to) an IP address, you can use the device’s MAC address.

However, with a little more effort, there would be a clever way to use device names nonetheless:
The ifconfig(8) command can be used to rename network interfaces. For example, the command
`/sbin/ifconfig re1 name ext0`
renames the interface `re1` to `ext0`. You can use /etc/devd.conf (see the devd.conf(5) manual page) to run such an ifconfig(8) command whenever a certain USB device is attached. This can be matched by bus ID, device ID, serial number or other parameters. This way you can give your interfaces the names int0 and ext0 (meaning internal and external), for example. Then you can base your firewall rules on these new names.

(Disclaimer: I haven’t actually done that myself, and I’m not familiar with pf(4) because I prefer ipfw(4), but I don’t see a reason why it shouldn’t work that way.)


----------



## Ordoban (Jul 20, 2020)

olli@ said:


> If the USB devices are both present during boot, I’m not sure if they are always probed in the same order.


That is exactly what I thought. Thank you for your solution with the devd.conf. I didn't know that before. Learned something new again.


----------



## symlink (Jul 20, 2020)

Thank you everyone.

A quick check on dmesg() highlights that both interfaces are on USB (even the integrated one):


```
ue0: <USB Ethernet> on muge0
...
ue1: <USB Ethernet> on axge0
```

I think I'll go for the mac-address based rule at first, and later on learn my way around devd.conf(5): probably equally effective, but more interesting for the learning factor.

Cheers


----------



## olli@ (Jul 21, 2020)

symlink said:


> A quick check on dmesg() highlights that both interfaces are on USB (even the integrated one):
> 
> ```
> ue0: <USB Ethernet> on muge0
> ...


Ok, so one USB device uses the muge(4) driver, the other one uses the axge(4) driver. The command usbconfig(8) (requires root privileges) lists them along with vendor ID and product ID. However, I think there is no easy way in devd.conf(5) to get the relation between the network device (ue0, ue1) and the USB device (muge0, axge0). You’ll probably have to use a small script that uses devinfo(8) to get that relation.

The entry in devd.conf(5) would look like this:

```
notify 200 {
    match "system"    "IFNET";
    match "subsystem" "ue[0-9]+";
    match "type"      "ATTACH";
    action "/root/bin/rename-ue $subsystem";
};
```
And this is the script /root/bin/rename-ue:

```
#!/bin/sh
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
UE_DEV=$1
PARENT=$(devinfo -p $UE_DEV | cut -d" " -f2)
logger "Found network device $UE_DEV on USB parent $PARENT"
case "$PARENT" in
        muge[0-9]*)     ifconfig $UE_DEV name int0 ;;
        axge[0-9]*)     ifconfig $UE_DEV name ext0 ;;
esac
```
Make sure the script is executable (`chmod +x`), then type `service devd restart` so devd(8) reads the new configuration.

If it doesn’t work, add an `action` line to the devd.conf(5) entry that just appends a line to /var/log/messages:

```
action "logger Network interface $subsystem notification triggered"
```
That way you can find out if the notification entry in devd.conf(5) is triggered at all.
It is also helpful to enable devd debugging messages in /etc/syslog.conf. You need to create the /var/log/devd.log file if it doesn’t exist yet, and type `pkill -hup syslogd` for the changes to take effect. Then every devd event will be logged to that file.

*Note:* I have _not_ done the above myself because I don’t own any USB network devices. There may be typos in the code.


----------

