Skip to content

Rachid-Koucha/linux_ns

Repository files navigation

Articles and accompanying example programs about linux namespaces

1 Introduction
2 Maintainers
3 Download
4 Build
5 Covers
6 Description of the utilities
    6.1 lxc-pid
    6.2 lxc-start2
    6.3 cmpns
    6.4 clonens
    6.5 execns
    6.6 shns
    6.7 shns2
    6.8 shns3
    6.9 idns
    6.10 ownerns
    6.11 parentns
    6.12 userns
    6.13 linfo
    6.14 setnshost
    6.15 fsinfo

1 Introduction

The examples programs available here illustrate the articles serie published in french in GNU Linux Magazine France presenting the Linux namespaces in details from user to kernel space. They are written with a minimum number of lines to make them easier to understand. Hence, the source code may appear not robust (no checks on the return codes, basic algorithmic...).

The articles are first published in the magazine. The list is located here. They become available for free after 4 to 6 months and a pdf copy is stored in the articles sub-directory:

2 Maintainers

For any question or remark, please contact me

3 Download

The source code is available on github. Use the following command to clone it:

$ git clone https://github.com/Rachid-Koucha/linux_ns.git

The example programs are at the top level. The articles available for free are in the articles sub-directory in pdf format.

4 Build

The build is done with cmake:

$ cmake .
-- The C compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
[...]
$ make
Scanning dependencies of target reaper
[  1%] Building C object CMakeFiles/reaper.dir/reaper.c.o
[  2%] Linking C executable reaper
[  2%] Built target reaper
[...]

To clean the built files:

$ make clean

5 Covers

The covers of the published articles are:

  • Issue#239 of July/August 2020:

  • Issue#240 of September 2020:

  • Issue#243 of December 2020:

  • Issue#245 of February 2021:

  • Issue#246 of March 2021:

  • Issue#247 of April 2021:

  • Issue#250 of July-August 2021:

  • Issue#256 of March-April 2022:

  • Issue#258 of July-August 2022:

6 Description of the utilities

The following simple utilities are used to illustrate the articles serie concerning the Linux namespaces. They are not designed to be used in a larger scope although they may provide some hints to write some more elaborated tools around the Linux namespaces.

6.1 lxc-pid

lxc-pid is a shell script which retrieves and displays the pid of the init process of a LXC container.

For example:

$ sudo lxc-start -n bbox
$ sudo lxc-ls -f
$ sudo lxc-ls -f
NAME    STATE   AUTOSTART GROUPS IPV4       IPV6 UNPRIVILEGED 
bbox    RUNNING 0         -      10.0.3.230 -    false     
$ sudo ./lxc-pid bbox
14642
$ sudo lxc-stop -n bbox
$ $ sudo ./lxc-pid bbox
Unknown container bbox

6.2 lxc-start2

lxc-start2 is a shell script to start a LXC container which displays its name in its shell prompt.

For example, we start a container named bbox (of course it is supposed to have been created):

$ sudo ./lxc-start2 bbox
$ sudo lxc-attach -n bbox
$ sudo lxc-console -n bbox -t 0

Connected to tty 0
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu4) built-in shell (ash)
Enter 'help' for a list of built-in commands.

bbox# <CTRL>+<a>+<q>
$

6.3 cmpns

cmpns compares the namespaces of two processes which identifiers are passed as parameters.

In this example, we compare the namespaces of the current shell with the namespaces of the init process of the host:

$ sudo ./cmpns $$ 1
cgroup is equal
ipc is equal
mnt is equal
net is equal
pid is equal
user is equal
uts is equal

In this example, we compare the namespaces of the current shell with the namespaces of the init process of a LXC container:

$ sudo lxc-start -n bbox
$ sudo ./lxc-pid bbox
14857
$ sudo ./cmpns $$ 14857
cgroup is different
ipc is different
mnt is different
net is different
pid is different
user is equal
uts is different

Privileged containers run in the same user namespaces as the host. Hence, the equality in the above display.

6.4 clonens

clonens creates a new process in new namespaces. The latters are passed as parameters with their symbolic names (cgroup, ipc, mnt, net, pid, user and uts).

For example, in one terminal, we launch a process in new pid and uts namespaces. The launched process is suspended on pause():

$ sudo ./clonens pid uts
Created process 14950 in requested namespaces

In another terminal, we compare the namespaces of the new process with the namespaces of the current shell to verify that the uts and pid namespaces are different:

$ sudo ./cmpns 14950 $$
cgroup is equal
ipc is equal
mnt is equal
net is equal
pid is different
user is equal
uts is different

6.5 execns

execns executes a program in one or more namespaces of a running process.

In this example, we run a shell in the namespaces of the init process of a running LXC container:

$ sudo ./lxc-pid bbox
14857
$ PS1="\h#\x20" sudo -E ./execns 14857 /bin/sh
Moved into namespace ipc
Moved into namespace pid
Moved into namespace net
Moved into namespace uts
Moved into namespace cgroup
Moved into namespace mnt


BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu4) built-in shell (ash)
Enter 'help' for a list of built-in commands.

bbox# exit
program's status: 0 (0x0)

6.6 shns

shns creates a shell in the namespaces specified as parameters.

For example:

$ PS1="SHNS# " sudo -E ./shns
New namespace 'ipc'
New namespace 'pid'
New namespace 'net'
New namespace 'user'
New namespace 'uts'
New namespace 'cgroup'
New namespace 'mnt'
SHNS# date
dim. 28 mars 2021 18:57:37 CEST
SHNS# exit
/bin/sh: 5: Cannot set tty process group (No such process)
program's status: 0 (0x0)

6.7 shns2

Like shns, shns2 creates a shell in the namespaces specified as parameters. But it prompts the user just before the execution of the shell.

For example:

$ PS1='SHNS$ ' ./shns2 ipc uts mnt user
New namespace 'ipc'
New namespace 'user'
New namespace 'uts'
New namespace 'mnt'
Process#15706 go forward ([Y]/N)? 

6.8 shns3

shns3 is the synthesis of shns and shns2. The usage is:

$ ./shns3 -h
Usage: shns3 [-h] [-d level] [-n nsname] [-u uidmap] [-g gidmap] [-s path]
  -h|--help            : This help
  -h|--debug level     : Debug level
  -n|--nspc nsname     : Create namespace
                         'nsname' is: cgroup|ipc|net|mnt|pid|user|uts
  -u|--umap uidmap     : User id mapping
                         'uidmap' is 'uid loweruid count'
  -g|--gmap gidmap     : Group id mapping
                         'gidmap' is 'gid lowergid count'
  -s|--shell path      : Execute shell
                         'path' is '/bin/sh' by default

The namespaces to create are passed with the --nspc option. The user ids and group ids mappings are respectively passed through the --umap and --gmap options. For example:

$ ./shns3 -u '0 1000 1' -u '1 100000 100' -g '0 1000 1' -g '1 100000 100' -d 1
DEBUG_1 (main#358): New namespace 'ipc'
DEBUG_1 (main#358): New namespace 'pid'
DEBUG_1 (main#358): New namespace 'net'
DEBUG_1 (main#358): New namespace 'user'
DEBUG_1 (main#358): New namespace 'uts'
DEBUG_1 (main#358): New namespace 'cgroup'
DEBUG_1 (main#358): New namespace 'mnt'
DEBUG_1 (main#409): Running 'newuidmap 7565 0 1000 1 1 100000 100'...
DEBUG_1 (main#424): Running 'newgidmap 7565 0 1000 1 1 100000 100'...
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
#

6.9 idns

idns displays the identifiers of one or more namespaces of a given process. By default, all the namespaces are considered.

For example, to display the identifiers of the namespaces of the current shell:

$ sudo ./idns $$
/proc/7622/ns/cgroup [Device,Inode]: [4,4026531835]
/proc/7622/ns/ipc [Device,Inode]: [4,4026531839]
/proc/7622/ns/mnt [Device,Inode]: [4,4026531840]
/proc/7622/ns/net [Device,Inode]: [4,4026531992]
/proc/7622/ns/pid [Device,Inode]: [4,4026531836]
/proc/7622/ns/uts [Device,Inode]: [4,4026531838]
/proc/7622/ns/user [Device,Inode]: [4,4026531837]
$ sudo ./idns $$ uts ipc
/proc/7622/ns/uts [Device,Inode]: [4,4026531838]
/proc/7622/ns/ipc [Device,Inode]: [4,4026531839]

6.10 ownerns

ownerns displays the user_ns owning a the namespaces of a given process.

For example, we display the user_ns owning the namespaces of the current shell:

$ sudo ./ownerns $$
/proc/7622/ns/cgroup belongs to [Device,Inode]: [4,4026531837]
/proc/7622/ns/ipc belongs to [Device,Inode]: [4,4026531837]
/proc/7622/ns/mnt belongs to [Device,Inode]: [4,4026531837]
/proc/7622/ns/net belongs to [Device,Inode]: [4,4026531837]
/proc/7622/ns/pid belongs to [Device,Inode]: [4,4026531837]
/proc/7622/ns/uts belongs to [Device,Inode]: [4,4026531837]
ERROR@main#87: ioctl(/proc/7622/ns/user, NS_GET_USERNS): 'Operation not permitted' (1)

6.11 parentns

parentns displays the parent namespace of a the namespaces of a given process. This works only for hierarchical namespaces (i.e. pid_ns and user_ns).

For example, we display the parent user_ns of the init process of a running LXC container:

$ sudo ./lxc-pid bbox
14857
$ sudo ./parentns 14857 pid user
/proc/14857/ns/pid is child of [Device,Inode]: [4,4026531836]
ERROR@main#89: ioctl(/proc/14857/ns/user, NS_GET_PARENT): 'Operation not permitted' (1)

In the above display, there is an error for the user_ns as a privileged container runs in the user_ns as the host. And it is not possible to get the parent user namespace of the initial user_ns.

6.12 userns

userns displays the name and the user identifier of the user which created the user namespaces of a given process.

For example, we display the user identifier of the creator of the user namespace of the current shell:

$ echo $$
7622
$ sudo ./userns $$
/proc/7622/ns/user belongs to user: 'root' (0)

6.13 linfo

linfo displays information about a symbolink link.

For example:

$ ./linfo /proc/$$/ns/mnt
Symbolic link:
	Name: /proc/3098/ns/mnt
	Rights: 0777
	Device (major/minor): 0x0/0x5
	Inode: 0x1a284 (107140)
Target:
	Name: mnt:[4026531840]
	Rights: 0444
	Device (major/minor): 0x0/0x4
	Inode: 0xf0000000 (4026531840)

6.14 setnshost

setnshost sets the hostname in the uts namespace of a given process.

For example, we set the hostname in a LXC container using the pid of its init process:

$ sudo lxc-start -n bbox
$ sudo lxc-console -n bbox -t 0
Connected to tty 0
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu4) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/ # hostname
bbox
/ # <CTRL>+<a>+<q>
$ sudo ./lxc-pid bbox
5865
$ sudo ./setnshost 5865 qwerty
$ sudo lxc-console -n bbox -t 0

Connected to tty 0
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

/ # hostname
qwerty
/ # <CTRL>+<a>+<q>
$

6.15 fsinfo

fsinfo displays the information about a file system into which a file/directory resides.

To display the information about the root file system on my machine:

$ ./fsinfo /
Type             : 0xef53 (EXT2/3/4FS)
Block size       : 4096
Total blocks     : 119916557
Total free blocks: 117922759
Total files      : 30531584
Max name length  : 255
Mount flags      : 0x1020 (REMOUNT BIND)

The following displays the information about the PROCFS file system into which the ns directory resides:

$ ./fsinfo /proc/$$/ns    
Type             : 0x9fa0 (PROCFS)
Block size       : 4096
Total blocks     : 0
Total free blocks: 0
Total files      : 0
Max name length  : 255
Mount flags      : 0x102e (NODEV NOEXEC NOSUID REMOUNT BIND)

The following displays the information about the NSFS file system into which reside the targets of the symbolic links in the latter directory:

$ ./fsinfo /proc/$$/ns/mnt
Type             : 0x6e736673 (NSFS)
Block size       : 4096
Total blocks     : 0
Total free blocks: 0
Total files      : 0
Max name length  : 255
Mount flags      : 0x20 (REMOUNT)

About

Example programs and articles to study Linux namespaces

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published