Disable IPv6 Functionality on Multi-Container Device

We have multi-container devices, each of which connect to a different local router (through ethernet).
We also have a specific domain that when you go to it, it checks your external IP against our devices’ external IPs and sends you to the appropriate local server for the wifi network you are at. However, for some routers, the device gets an ipv6 external address, whilst the user’s phone gets an ipv4 address. I’m hoping to put together:

  1. Disable the ipv6 functionality, a quick solution
  2. An elegant solution later on if possible.

Any assistance with this is appreciated.

If I could get any assistance with this, I would appreciate it.

Hi, here is a way to disable ipv6 on your balena device using nmcli (replace 087fd7c with your device uuid).

balena ssh 087fd7c

root@087fd7c:~# nmcli con show
NAME                UUID                                  TYPE      DEVICE
Wired connection    087fd7cd-9a6b-423c-8b64-c30cbf6a7126  ethernet  eno1
...

root@087fd7c:~# nmcli con edit 087fd7cd-9a6b-423c-8b64-c30cbf6a7126

nmcli> set ipv6.method disable

nmcli> save persistent
Connection 'Wired connection' (087fd7cd-9a6b-423c-8b64-c30cbf6a7126) successfully updated.

nmcli> quit

root@087fd7c:~# nmcli con down 087fd7cd-9a6b-423c-8b64-c30cbf6a7126; nmcli con up 087fd7cd-9a6b-423c-8b64-c30cbf6a7126

Please make sure to try in a single device (hopefully a development device) and let us know if that works for you.

Thank you!

1 Like

Hello @pipex,

That works when I ssh into the device’s host OS and run that code. However, it doesn’t appear that I can run it from one of my services on the device, as in that scenario it does not recognize nmcli. Is there any way to run a script from the host OS (on a multi-container device) during a device bootup?

I was considering changing the sysctl.conf file, something like the below? Are there any issues to this for a Balena OS device?

Cheers,
Spen

Hi @spencerwf,

You are right you cannot run that command from a container out of the box, but you if you configure the io.balena.features.dbus label for your service, you can use the dbus socket to communicate with the host using nmcli installed within the container. Below is an example on how to do that. If you set restart: always on your container, that ensures the container is restarted on each reboot.

Alternatively you could run a command to disable ipv6 in all your fleet devices at once (please try on a subset of devices first if possible)

balena devices --fleet {{fleet}} --json | jq '.[] | select(.is_online) | "\(.device_name) \(.uuid)"' -r | while IFS=" " read -r name uuid; do echo ==== $name; echo 'nmcli connection modify "Wired connection 1" ipv6.method "disabled"; nmcli connection up "Wired connection 1"; exit;' | balena ssh "$uuid"; done

Let us know how that works for you. Thank you!

1 Like

Hello @pipex,

Thank you for the reply. I’ve done the following:
Added in docker-compose.yml:

labels:
  io.balena.features.dbus: '1'

Added a script called ‘disable_ipv6.sh’ containing:

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

apt-get update && apt-get install network-manager

nmcli con mod eth0 ipv6.method disable 

echo "IPv6 disabled"

Which is called from within my start.sh script:

#!/usr/bin/env bash

# Moved below line to disable_ipv6.sh file
# export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

apt-get update && apt-get install network-manager

# Optional step - it takes a couple of seconds (or longer) to establish a WiFi connection
# sometimes. In this case, the following checks will fail and wifi-connect
# will be launched even if the device will be able to connect to a WiFi network.
# If this is your case, you can wait for a while and then check for the connection.
sleep 15
# which nmcli
# if [ $? -ne 0 ]
# then
# 	printf 'Installing wget\n'
# 	sudo apt install network-manager
# fi

# (crontab -l; echo "${LOBBY_START_GAME:*/4 8 * * *} /usr/src/scripts/lobby.sh") | crontab -
# (crontab -l; echo "${BACKLIGHT_OFF:-0 23 * * *} /usr/src/backlight_off.sh") | crontab -

# Choose a condition for running WiFi Connect according to your use case:

# 1. Is there a default gateway?
# ip route | grep default

# 2. Is there Internet connectivity?
# nmcli -t g | grep full

# 3. Is there Internet connectivity via a google ping?
wget --spider http://google.com 2>&1

# 4. Is there an active WiFi connection?
# iwgetid -r
chmod 755 ./scripts/disable_ipv6.sh
sudo ./scripts/disable_ipv6.sh

if [ $? -eq 0 ]; then
    printf 'Skipping WiFi Connect\n'
else
    printf 'Starting WiFi Connect\n'
    ./wifi-connect
fi

printf 'Starting Lobby MVP Application\n'

# Start your application here.
# cd colyseus

printf 'NPM Install Command Starting\n'
npm install
# npm install -g pm2

printf 'Running NPM Start Command\n'
npm start

Unfortunately, I’m getting an Error: unknown connection 'eth0' is not recognized, however when I ssh into that device and run nmcli it does show ‘eth0’ as a connection.

Is there a reason this would not be recognized?

I now have the disable_ipv6.sh script running correctly, however, I’m getting the following error:

Exported DBUS_SYSTEM_BUS_ADDRESSError: failed to modify ipv6.method: 'disable' not among [ignore, auto, dhcp, link-local, manual, shared].

To me this indicates I still need to setup some permissions for the service, and I am currently trying to understand where that could be.

@pipex, would you be able to assist with this issue? It seems like disable isn’t an option when using nmcli from the service? Is there a setting to broaden the range of settings accessible through dbus in the service?

@spencerwf, Could you check to see if running the command nmcli con mod $YOUR_CONNECTION ipv6.method "disabled" from the host OS works?

Hello Cywang, it does work, however, I’m hoping to disable it automatically for all of our devices.