익명 14:16

Issue with PHP and network namespaces

Issue with PHP and network namespaces

I develop a PHP application that manipulates network namespaces (it is its essential purpose). Almost everything seems to work except one important thing:

When I create a network namespace - or a network interface in an existing namespace - from PHP code (PHP running as FPM), the created objects are not properly visible from the rest of the system.

For example, after creating the namespace from PHP code, the command ip netns list run from regular command line outputs the following:

Error: Peer netns reference is invalid.
Error: Peer netns reference is invalid.
nat_1

The name of the namespace nat_1 is shown, but you cannot "enter" that namespace using command ip netns exec nat_1 <command>. The error message is shown:

setting the network namespace "nat_1" failed: Invalid argument

The namespace is, however, properly visible and accessible within the PHP code.

When creating the namespace, PHP code in fact executes a shell script, and the same shell script run from command line produces a namespace that is correctly accessible.

This is probably because of the fact that for some reason, network devices seem to be "private" to the PHP process. When I run the command cat /proc/<pid>/mountinfo, where <pid> is the PID of main php-fpm process, I can see the following line in the output:

130 605 0:4 net:[4026534470] /run/netns/nat_1 rw shared:277 - nsfs nsfs rw

but there is no similar line in output of cat /proc/self/mountinfo run from the command line.

systemctl show php-fpm shows that PrivateDevices, PrivateMounts, PrivateNetwork and RestrictNamespaces are all set to no (only PrivateTmp is yes). I also have overridden settings in HTTPD systemd unit to also set these values to no - but this didn't help.

I don't know what else can I check to obtain my goal, which is that the namespaces and network interfaces created within them should be common for whole system and accessible from all processes.

Please help.



Top Answer/Comment:

I was able to get what I think you are doing by setting this value in the php-fpm unit.

BindPaths=/run/netns

The path MUST exist on startup so you'll need to have it created on startup using tmpfiles.d or something, but when it exists this starts php-fpm in a manner you can create network namespaces with ip and see them from outside of the unit.

Enter the namespace of PHP-FPM for the sake of viewing namespaces

$ nsenter -t $(systemctl show php-fpm -p MainPID --value) -m
$ ip netns list
wibble
wobble

Add one new entry, remove an old

$ ip netns add testing
$ ip netns del wibble
$ ip netns list
testing
wobble

Come of out of the namespace into the main root namespace.

$ exit
logout
$ ip netns list
testing
wobble
상단 광고의 [X] 버튼을 누르면 내용이 보입니다