Putting a secondary adapter into monitor mode using the network manager

I am trying to use a secondary wifi adapter that should be permanently in monitoring mode my current solution to get it working for testing is explained here. (just realized that is over a year old)

In short, the limitations of that are it doesn’t persist between restarts and requires physical access to the device.

I am trying to use the network manager to persist settings and hopefully make things stable even between os updates.

My source for this is mostly this page: Networking on Balena

I put a file called monitor into /etc/NetworkManager/system-connections
The file contents:
[connection]
id=balena-hotspot
type=wifi
autoconnect=false
interface-name=wlan1
permissions=
secondaries=

[wifi]
band=bg
mode=monitor

Unfortunately, that has no effect.

Can anyone point me in the right direction?

Hi @tacLog
there are a couple of things that could go wrong with your setup. For starters I wonder if you are aware that these changes will only be active after a reboot.
For further investigation I would like to take a look at your device. If you could enable support access in the dashboard and send me your device UUID via private message I can look into it.
Regards
Thomas

Hey @samothx thanks for the quick response

Support access is enabled

I was aware of that, I tried that several times and had no luck.

My current solution is described here

I hope there isn’t a good reason I should pm this but the uuid is:
a49451f78439e9a53876fb5a6172f6ee

Hi @tacLog,
I am looking into it now, actually I just logged on to that device before on a different thread…
Posting the device UUID is semi-safe. If you have a public device URL enabled, making your UUID public will allow people to access your services. So what you are losing is what is called security by obscurity - your device URL being unknown otherwise…

Ok, I did not read your post properly. Putting the file in /etc/NetworkManager/system-connections is not how it is meant to be done in Balena. The file is meant to be placed in /mnt/boot/system-connections and will be copied and processed at startup.
I have copied the file to that location for you.
Next step would be to find out if your file actually succeeds in enabling monitor mode.
If you reboot your device your file should be active, if you like I can do that for you.

Thanks @samothx I will reboot now and we will see.

And thanks for explaining the security implications of that, we will never be using a public url so this will never be a problem.

-Thomas

It did not work unfortunately.

The interfaces have appeared to switch, where now we are connected via wlan1 and wlan0 is unused. It is not clear to me which is the usb interface.

-Thomas

I kind of thought that might happen but did not really expect it…
You will probably have to add UDEV rules to create persistent device names.
I will look that up for you…

Generally adding udev rules to be executed on the HOST os is decribed here: https://github.com/balena-os/meta-balena#udevrules

Thank you, I will look into this.

I don’t know what UDEV rules are or how they could create persistent device names, but I will share what I find out here to double check I am getting things right and anyone who wants to do this later.

I am still looking into this and hopefully be able to supply the rules for you.

@samothx

Your awesome thanks!

Hi @tacLog
took a while to figure out:

"os":{
  "udevRules": { "10" : "SUBSYSTEM==\"net\", ACTION==\"add\", ATTR{address}==\"b8:27:eb:24:86:2b\", NAME=\"wlan-bi\"" } 
},

I got lucky adding something like the above to /mnt/boot/config.json

Be extremely careful to not destroy the json the file, or the device will not go online / show up in balena if you make a mistake there. I pasted the contents of the modified file into a json aware editor to check on syntax. Try this on a device you have manual access to first.

The above addition to config.json works as follows:

Change ATTR{address}==“b8:27:eb:24:86:2b” to match the MAC address of the network interface you want to rename.
Change NAME=“wlan-bi”" to the name you want the device to be available as.
I choose wlan-bi - for built in because that was the adapter I modified.

This will give you persistent interface names. Next we will have to sort out how to enable monitoring…

Excellent work! I will try that on the device above.

We don’t have to be too careful yet as I still have full access during development so no stress if we brick and have to re-flash it.

But noting the danger is important. Because of the scale that we will deploy in I will have to develop a management script that does this during our setup phase. This will be challenging given the requirement of the mac address.

Thank you for your help this far. I will get this step working on my device and see if I can still get into monitor mode with the old.

ip link set wlan1 down
iw wlan1 set monitor control
ip link set wlan1 up

Unfortunaltely I cannot see how to enable monitoring in NetworkManager. I have looked through here: https://developer.gnome.org/NetworkManager/stable/nm-settings.html .
I will forward your request to the team and see if anyone has an idea…

Hmm, I looked through there myself and came to a similar conclusion.

I know this is hacky and risky but is there any way a container could excute those commands above as root to set monitor mode?

Can a container ssh into it’s own host?

Anyways thanks so much for your help so far!

I have come across disussions about exactly that topic - just have to find them again ;). Not quite sure if that was the best solution but you can add a private host key - also to /mnt/boot/config.json and it will be added to your authorized_keys file.

"os":{
  "sshKeys":["your public key"]
}

With that you should be able to ssh from a container into the host (using port 22222).

I have since solved this issue.

@samothx
Thanks for you help you really pushed me in the right direction with a udev rule, I just needed to make it less specific for fleet wide deployment.

Sets to get a secondary (or primary if it supports it and you have a wired connection) wireless adapter into monitor mode from within a container.

First check if your adapter supports it.
iw list will output the supported modes if you can’t grep for monitor it won’t work.

Second, configure the network manager to not touch it.
find / -name "NetworkManager.conf"
-To find all version of the NetworkManger config
-You want the one that is on the long path like this:
/mnt/sysroot/active/balena/aufs/diff/somerandomhashtthatisdevicespecificbestIcantell/etc/NetworkManager/NetworkManager.conf
then:
echo -e "[device]\nwifi.scan-rand-mac-address=no\n[keyfile]\nunmanaged-devices=interface-name:wlan9" >> $thepathyourfound/NetworkManager.conf
Those additions one stop it from changing Mac address which can affect the next step and two stop it from interfering with our new monitoring interface wlan9 which we will set up in the next step.
Sources:here and here

Now for udev rules:
Source for more info: Best source ever
You can edit your config.json a variety of ways, just make sure you change the one that will be loaded on reboot. The easiest way is to plug it into a machine and access the belena_boot partition directly.
However, note if you mess up the json formatting your device will not boot, so try this on devices you have physical access to.
Mostly follow the guild to get something you can use to id the device with. @samothx used the address in their example but that is too specific for me so I used the driver:
"os":{"udevRules":{"11":"SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"rt2800usb\", NAME=\"wlan9\""}},
See the documentation on this for more help or push me to add more detail.

Lastly, now that you can see your device has been named wlan9 after a reboot with iwconfig (probably in a container)
From within a container with the right network tools installed, look up for your distribution what you need.
ip link set wlan9 down
iw wlan9 set monitor control
ip link set wlan9 up

And that should do it!

-Thomas

I would really be interested in enabling monitor mode as well. Will this work without setting up the secondary wifi connection in resin-boot/system-connections/resin-wifi/ . I’m also trying to enable two wifi adapters that I got from pi hut. So far I haven’t been able to see the second connection work. I have been using the “Raspberry Pi 3 and additional network dongle” forum post to try and get this working. I’m wondering how the addition of this in the config.json will help. I’m on a Odroid xu4.,

Hey,

I can answer some of your questions @Leathal1

Firstly, to use monitor mode on an adapter. The adapter can’t be in infrastructure mode and therefor can’t have a connection at all. I am not sure what you mean when you say:

So far I haven’t been able to see the second connection work.

I use nmcli dev status to check the connection status of my adapters. For putting an adapter in monitor mode, you should un-manage it in the network manager. The instructions I posted above work, but are a pure hack and not scalable aside from being against the principle that you should avoid modifying things outside the container.

To accomplish this now, I install network manager in my container safely using the instructions here.
More or less include these lines in your dockerfile:
apt-get update && apt-get install -y \
network-manager=1.14.* \
&& systemctl mask NetworkManager.service
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

And run this command in an automated fashion on container start:
nmcli device set adapter_name managed no where adapter_name is wlan1 or whatever your adapter is called.

This was is better because it allows you to do to it at runtime in your container. Now the uart rules are all about making that adapter name stable between restarts. On my device wlan0 wasn’t always the same adapter and I wanted to always have it be the same one. So I used the fact that the onboard adapter for the fin which doesn’t support monitoring mode anyways has a different driver to make a uart rule that renamed my other adapters based on their drivers. You can see that rule in my post above. I have since modified that rule to support multiple adapters at once. I can post help with that if you like.

However, I don’t fully understand your use case. If you want to provide more details and I can probably answer further questions.
Good luck!

-Thomas