Fake network card on GNU/Linux systems

Notes published the
3 - 4 minutes to read, 786 words

On GNU/Linux systems, it is possible to create virtual network cards.

It happened that a program I needed to use, uses the mac address of the network card for loading an internal configuration file.

This technique made it possible to use the same unmodified program on multiple devices, without telling the user to configure it appropriately.

Unfortunately, being unable to override this behavior means that the program broke when the machines were upgraded.

Manually add virtual devices on GNU/Linux systems

Fortunately, at least on GNU/Linux systems, it is trivial to add a dummy network device; remember, the program just needs to read the MAC address, it does not try to communicate with someone else over the network card.

ip link add veth0 type dummy
ip link set veth0 address fe:de:fe:de:fe:de

Where veth0 is the card’s name (virtual eth0), and fe:de:fe:de:fe:de is the mac address we are interested in.

You can verify that there is a new device with ip address show veth0 (or just use ip -all/ip a to show all devices), it should contain the following lines

veth0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 link/ether fe:de:fe:de:fe:de brd ff:ff:ff:ff:ff:ff

Add virtual device through /etc/network/interfaces

You can execute both ip commands on startup through cron, systemd, .login, or other means, but it makes the most sense to me if those virtual devices are configured together with other devices, and the most sensible places where to add them is /etc/network/interfaces (or any file in /etc/network/interfaces.d/)

Add the following file:

/etc/network/interfaces.d/veth0
auto veth0
iface veth0 inet manual
  pre-up    ip link add    veth0 type dummy
  pre-up    ip link set    veth0 address fe:de:fe:de:fe:de
  post-down ip link delete veth0

Then use sudo ifup veth0 (or sudo ifup --all) for activating the device (and sudo ifdown veth0 for deactivating). You can check if the interface is present with ip address show veth0, or just use ip -all/ip a to show all devices.

The output will look slightly different, but for my use case, it is good enough.

veth0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
 link/ether fe:de:fe:de:fe:de brd ff:ff:ff:ff:ff:ff
 inet6 fe80::fcde:feff:fede:fede/64 scope link proto kernel_ll
    valid_lft forever preferred_lft forever

The device is in the state UNKNOWN and not DOWN. For my use-cases it is not relevant, but if it is for yours, you can change the state to down automatically:

/etc/network/interfaces.d/veth0
auto veth0
iface veth0 inet manual
  pre-up    ip link add    veth0 type dummy
  pre-up    ip link set    veth0 address fe:de:fe:de:fe:de
  up        ip link set    veth0 down
  post-down ip link delete veth0

Add virtual device through /etc/network/interfaces, an alternate method

On Debian systems, if you have the package ifupdown-ng-compat installed, the configuration can look like the following one:

/etc/network/interfaces.d/veth1
auto veth1
iface veth1 inet static
  link-type dummy
  hwaddress fe:de:fe:de:fe:de

It does the exact same thing as the first revision of /etc/network/interfaces.d/veth0; the state of the created device is the same, except for having a different name.

Since ifupdown-ng-compat conflicts with ifupdown-ng, I prefer to use the method presented in the previous section.

I also did not see a way to set the device to the state DOWN automatically.

Add a virtual device in a virtual machine

If the system is running in a virtual environment, like in VirtualBox, then it is possible to create a virtual unattached network card, without changing any configuration on the OS and thus works on Windows machines too.

ip a on virtualbox with detached device
enp0s9: <NO-CARRIER,BROADCAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
 link/ether fe:de:fe:de:fe:de brd ff:ff:ff:ff:ff:ff

Add virtual devices on WSL2

On WSL2, virtual network interfaces from /etc/network/interfaces.d are not configured automatically, cron is not executed, and systemd neither.

You can add the following lines to /etc/wsl.conf to start one or multiple services; for example:

[boot]
command="ifup --all;service cron start"

Do you want to share your opinion? Or is there an error, some parts that are not clear enough?

You can contact me anytime.