Score:2

How to enable Promiscuous Mode permanently on a NIC managed by NetworkManager?

th flag

I'm trying to bridge two of several NICs to act like a switching hub.
To do so, need to enable the promiscuous mode on the NICs.
Even if I set it to “promisc on” with the “ip link” command, the setting will be reset when I reboot the PC.

How can I enable Promiscuous Mode permanently, even if I reboot my PC?

The environment is Ubuntu Desktop 20.04 LTS.
For this reason, the network configuration is based on NetworkManager.

A sample of the minimum configuration is shown below:

Vagrant.configure("2") do |config|
  config.vm.define :bridge do |machine|
    machine.vm.box = "bento/ubuntu-20.04"
    machine.vm.network :private_network, auto_config: false, virtualbox__intnet: "intnet_a"
    machine.vm.network :private_network, auto_config: false, virtualbox__intnet: "intnet_b"

    machine.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get install -y network-manager
      cat > /etc/netplan/50-bridge.yaml <<'EOS'
network:
  version: 2
  ethernets:
    eth1:
      addresses:
        - 0.0.0.0/32
    eth2:
      addresses:
        - 0.0.0.0/32
  bridges:
    br0:
      interfaces:
        - eth1
        - eth2
EOS
      echo 'network: { version: 2, renderer: NetworkManager }' > /etc/netplan/99-NetworkManager.yaml
      netplan apply
    SHELL
  end
end

The "ip link" command activates the PROMISC status of the NIC, as shown below.

$ sudo ip link set dev eth1 promisc on
$ sudo ip link set dev eth2 promisc on
$ ip addr
[...]
3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:48:57 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
[...]

However, after rebooting the OS, the PROMISC status will be reset.

$ sudo reboot
[...]
$ ip addr
[...]
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:48:57 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
[...]

In this example, I used Vagrant for the purpose of showing a reproducible environment.
Vagrant is not a requirement, what I really want to use is Ubuntu on a physical PC.
Simply enabling Promiscuous Mode through a Vagrant provisioning run does not solve this problem.

Score:0
th flag

I found several methods and solved myself.

Method 1: Use NetworkManager-dispatcher

$ sudo bash -c 'cat > /etc/NetworkManager/dispatcher.d/50-promisc' <<'EOS'
#!/usr/bin/bash -e
case "$2" in
    up)
        if [[ "$1" = "eth1" ]] || [[ "$1" = "eth2" ]]; then
            ip link set dev $1 promisc on
        fi
        ;;
esac
EOS
$ sudo chmod u=rwx,g=rx,o=rx /etc/NetworkManager/dispatcher.d/50-promisc
$ sudo reboot
[...]
$ ip addr
[...]
3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:48:57 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
[...]

Register a script for NetworkManager-dispatcher that will enable promisc when the target NIC (eth1 or eth2) is in the up state.

Method 2: Register a one-shot service in systemd that is delayed until the network-online.target unit starts

$ sudo bash -c 'cat > /etc/systemd/system/bridge-promisc.service' <<'EOS'
[Unit]
Description=Makes interfaces run in promiscuous mode at boot
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ip link set dev eth1 promisc on
ExecStart=/usr/sbin/ip link set dev eth2 promisc on
TimeoutStartSec=0
RemainAfterExit=yes

[Install]
WantedBy=default.target
EOS
$ sudo systemctl enable bridge-promisc
$ sudo reboot
[...]
$ ip addr
[...]
3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
4: eth2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether xx:xx:xx:xx:48:57 brd ff:ff:ff:ff:ff:ff
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:xx:c4:f5 brd ff:ff:ff:ff:ff:ff
[...]

I think this method can be applied to patterns that do not use NetworkManager.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.