Skip to content

Instantly share code, notes, and snippets.

@najamelan
Last active May 25, 2023 08:03
Show Gist options
  • Save najamelan/8442fe2148a21abdc8f1176f786681d9 to your computer and use it in GitHub Desktop.
Save najamelan/8442fe2148a21abdc8f1176f786681d9 to your computer and use it in GitHub Desktop.
Configure physical network cards to be in their own network namespace

Keeping physical network cards in a dedicated namespace could be a way to control which processes can access the network. For non privileged processes in the main namespace, it would seem that the only network card in the machine is the loopback device. WARNING: Personally I haven't managed to connect to wifi this way. The idea comes from this post, but hacked upon until it works.

Create an udev rule to move any new non-virtual interface to a new namespace as soon as it's plugged in:

# /etc/udev/rules.d/99-physical-netns.rules

SUBSYSTEM=="net", ACTION=="add", DEVPATH!="/devices/virtual/*",TAG+="systemd", ENV{SYSTEMD_WANTS}="physical-namespace@$id.service"

This will call the systemd service with the ID of the network device:

/etc/systemd/system/physical-namespace@.service

[Unit]

	Description = Move interface to physical namespace
	Requires    = netns@physical.service
	After       = netns@physical.service

[Service]

	Type            = oneshot
	RemainAfterExit = true
	ExecStart       = /usr/local/bin/move-netif %I physical

netns@physical will create the namespace if it doesn't exist:

/etc/systemd/system/netns@.service
[Unit]

	Description     = Creates a network namespace


[Service]

	Type            = oneshot
	RemainAfterExit = true
	ExecStart       = /usr/local/bin/create_netns %i

create_netns does the actual work:

/usr/local/bin/create_netns

#! /usr/bin/fish

set name $argv[ 1 ]

if not test -e /var/run/netns/$name

	ip netns add $name
	exit $status
end

move-netif finally moves the interface:

/usr/local/bin/move-netif

#! /usr/bin/fish

set devpath   /$argv[ 1 ]
set target_ns  $argv[ 2 ]

if test -e $devpath/phy80211

	set phy ( basename (readlink $devpath/phy80211) )
	iw phy $phy set netns name $target_ns
	exit $status

else

	set ifname (basename $devpath)
	ip link set $ifname netns $target_ns
	exit $status

end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment