(2) How to find namespaces in a Linux system
2017-02-22 09:54
489 查看
http://www.opencloudblog.com/?p=251
Namespaces in Linux are heavily used by many applications, e.g. LXC, Docker and Openstack.
Question: How to find all existing namespaces in a Linux system?
The answer is quite difficult, because it’s easy to hide a namespace or more exactly make it difficult to find them.
ipc for IPC objects and POSIX message queues
mnt for filesystem mountpoints
net for network abstraction (VRF)
pid to provide a separated, isolated process ID number space
uts to isolate two system identifiers — nodename and domainname – to be used by uname
These namespaces are shown for every process in the system. if you execute as root
ls -lai /proc/1/ns
Shell
ls -lai /proc/1/ns
60073292 dr-x--x--x 2 root root 0 Dec 15 18:23 .
10395 dr-xr-xr-x 9 root root 0 Dec 4 11:07 ..
60073293 lrwxrwxrwx 1 root root 0 Dec 15 18:23 ipc -> ipc:[4026531839]
60073294 lrwxrwxrwx 1 root root 0 Dec 15 18:23 mnt -> mnt:[4026531840]
60073295 lrwxrwxrwx 1 root root 0 Dec 15 18:23 net -> net:[4026531968]
60073296 lrwxrwxrwx 1 root root 0 Dec 15 18:23 pid -> pid:[4026531836]
60073297 lrwxrwxrwx 1 root root 0 Dec 15 18:23 uts -> uts:[4026531838]
you get the list of attached namespaces of the init process using PID=1. Even this process has attached namespaces. These are the default namespaces for ipc, mnt, net, pid and uts. For example, the default net namespace is using the ID net:[4026531968].
The number in the brackets is a inode number.
In order to find other namespaces with attached processes in the system, we use these entries of the PID=1 as a reference. Any process or thread in the system, which has not the same namespace ID as PID=1 is not belonging to the DEFAULT
namespace.
Additionally, you find the namespaces created by „ip netns add <NAME>“ by default in
/var/run/netns/ .
Get the reference namespaces from the init process (PID=1). Assumption: PID=1 is assigned to the default namespaces supported by the system
Loop through /var/run/netns/ and add the entries to the list
Loop through /proc/ over all PIDs and look for entries in /proc/<PID>/ns/ which are not the same as for PID=1 and add then to the list
Print the result
List all non default namespaces in a system
Python
#!/usr/bin/python
#
# List all Namespaces (works for Ubuntu 12.04 and higher)
#
# (C) Ralf Trezeciak 2013-2014
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import fnmatch
if os.geteuid() != 0:
print "This script must be run as root\nBye"
exit(1)
def getinode( pid , type):
link = '/proc/' + pid + '/ns/' + type
ret = ''
try:
ret = os.readlink( link )
except OSError as e:
ret = ''
pass
return ret
#
# get the running command
def getcmd( p ):
try:
cmd = open(os.path.join('/proc', p, 'cmdline'), 'rb').read()
if cmd == '':
cmd = open(os.path.join('/proc', p, 'comm'), 'rb').read()
cmd = cmd.replace('\x00' , ' ')
cmd = cmd.replace('\n' , ' ')
return cmd
except:
return ''
#
# look for docker parents
def getpcmd( p ):
try:
f = '/proc/' + p + '/stat'
arr = open( f, 'rb').read().split()
cmd = getcmd( arr[3] )
if cmd.startswith( '/usr/bin/docker' ):
return 'docker'
except:
pass
return ''
#
# get the namespaces of PID=1
# assumption: these are the namespaces supported by the system
#
nslist = os.listdir('/proc/1/ns/')
if len(nslist) == 0:
print 'No Namespaces found for PID=1'
exit(1)
#print nslist
#
# get the inodes used for PID=1
#
baseinode = []
for x in nslist:
baseinode.append( getinode( '1' , x ) )
#print "Default namespaces: " , baseinode
err = 0
ns = []
ipnlist = []
#
# loop over the network namespaces created using "ip"
#
try:
netns = os.listdir('/var/run/netns/')
for p in netns:
fd = os.open( '/var/run/netns/' + p, os.O_RDONLY )
info = os.fstat(fd)
os.close( fd)
ns.append( '-- net:[' + str(info.st_ino) + '] created by ip netns add ' + p )
ipnlist.append( 'net:[' + str(info.st_ino) + ']' )
except:
# might fail if no network namespaces are existing
pass
#
# walk through all pids and list diffs
#
pidlist = fnmatch.filter(os.listdir('/proc/'), '[0123456789]*')
#print pidlist
for p in pidlist:
try:
pnslist = os.listdir('/proc/' + p + '/ns/')
for x in pnslist:
i = getinode ( p , x )
if i != '' and i not in baseinode:
cmd = getcmd( p )
pcmd = getpcmd( p )
if pcmd != '':
cmd = '[' + pcmd + '] ' + cmd
tag = ''
if i in ipnlist:
tag='**'
ns.append( p + ' ' + i + tag + ' ' + cmd)
except:
# might happen if a pid is destroyed during list processing
pass
#
# print the stuff
#
print '{0:>10} {1:20} {2}'.format('PID','Namespace','Thread/Command')
for e in ns:
x = e.split( ' ' , 2 )
print '{0:>10} {1:20} {2}'.format(x[0],x[1],x[2][:60])
#
Copy the script to your system as listns.py , and run it as root using python
listns.py
Shell
PID Namespace Thread/Command
-- net:[4026533172] created by ip netns add qrouter-c33ffc14-dbc2-4730-b787-4747
-- net:[4026533112] created by ip netns add qrouter-5a691ed3-f6d3-4346-891a-3b59
-- net:[4026533050] created by ip netns add qdhcp-02e848cb-72d0-49df-8592-2f7a03
-- net:[4026532992] created by ip netns add qdhcp-47cfcdef-2b34-43b8-a504-6720e5
297 mnt:[4026531856] kdevtmpfs
3429 net:[4026533050]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3429 mnt:[4026533108] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3446 net:[4026532992]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3446 mnt:[4026533109] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3486 net:[4026533050]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3486 mnt:[4026533107] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3499 net:[4026532992]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3499 mnt:[4026533110] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
4117 net:[4026533112]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
4117 mnt:[4026533169] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
41998 net:[4026533172]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
41998 mnt:[4026533229] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
The example above is from an Openstack network node. The first four entries are entries created using the command ip. The entry PID=297 is a kernel thread and no user process. All other processes listed, are started by Openstack agents. These process are
using network and mount namespaces. PID entries marked with ‚**‘ have a corresponding entry created with the ip command.
When a docker command is started, the output is:
Shell
PID Namespace Thread/Command
-- net:[4026532676] created by ip netns add test
35 mnt:[4026531856] kdevtmpfs
6189 net:[4026532585] [docker] /bin/bash
6189 uts:[4026532581] [docker] /bin/bash
6189 ipc:[4026532582] [docker] /bin/bash
6189 pid:[4026532583] [docker] /bin/bash
6189 mnt:[4026532580] [docker] /bin/bash
The docker child running in the namespaces is marked using [docker].
On a node running mininet and a simple network setup the output looks like:
mininet example
Shell
PID Namespace Thread/Command
14 mnt:[4026531856] kdevtmpfs
1198 net:[4026532150] bash -ms mininet:h1
1199 net:[4026532201] bash -ms mininet:h2
1202 net:[4026532252] bash -ms mininet:h3
1203 net:[4026532303] bash -ms mininet:h4
Chrome's namespaces
Shell
PID Namespace Thread/Command
63 mnt:[4026531856] kdevtmpfs
30747 net:[4026532344] /opt/google/chrome/chrome --type=zygote
30747 pid:[4026532337] /opt/google/chrome/chrome --type=zygote
30753 net:[4026532344] /opt/google/chrome/nacl_helper
30753 pid:[4026532337] /opt/google/chrome/nacl_helper
30754 net:[4026532344] /opt/google/chrome/chrome --type=zygote
30754 pid:[4026532337] /opt/google/chrome/chrome --type=zygote
30801 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30801 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30807 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30807 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30813 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30813 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30820 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30820 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30829 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30829 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30835 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30835 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30841 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30841 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30887 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30887 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30893 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30893 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30901 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30901 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30910 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30910 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30915 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30915 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30923 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30923 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30933 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30933 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30938 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30938 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30944 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30944 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31271 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31271 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31538 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31538 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
Chrome makes use of pid and network namespaces to restrict the access of subcomponents. The network namespace does not have a link in /var/run/netns/.
The script cannot find a network namespace, which do not have any process attached to AND which has no reference in /var/run/netns/. If root creates the reference inode somewhere else in the filesystem, you may only detect network ports (ovs port, veth port
on one side), which are not attached to a known network namespace –> an unknown guest might be on your system using a „hidden“ (not so easy to find) network namespace.
And — Linux namespaces can be stacked.
Namespaces in Linux are heavily used by many applications, e.g. LXC, Docker and Openstack.
Question: How to find all existing namespaces in a Linux system?
The answer is quite difficult, because it’s easy to hide a namespace or more exactly make it difficult to find them.
Exploring the system
In the basic/default setup Ubuntu 12.04 and higher provide namespaces foripc for IPC objects and POSIX message queues
mnt for filesystem mountpoints
net for network abstraction (VRF)
pid to provide a separated, isolated process ID number space
uts to isolate two system identifiers — nodename and domainname – to be used by uname
These namespaces are shown for every process in the system. if you execute as root
ls -lai /proc/1/ns
Shell
ls -lai /proc/1/ns
60073292 dr-x--x--x 2 root root 0 Dec 15 18:23 .
10395 dr-xr-xr-x 9 root root 0 Dec 4 11:07 ..
60073293 lrwxrwxrwx 1 root root 0 Dec 15 18:23 ipc -> ipc:[4026531839]
60073294 lrwxrwxrwx 1 root root 0 Dec 15 18:23 mnt -> mnt:[4026531840]
60073295 lrwxrwxrwx 1 root root 0 Dec 15 18:23 net -> net:[4026531968]
60073296 lrwxrwxrwx 1 root root 0 Dec 15 18:23 pid -> pid:[4026531836]
60073297 lrwxrwxrwx 1 root root 0 Dec 15 18:23 uts -> uts:[4026531838]
1 2 3 4 5 6 7 8 9 | ls -lai /proc/1/ns 60073292 dr-x--x--x 2 root root 0 Dec 15 18:23 . 10395 dr-xr-xr-x 9 root root 0 Dec 4 11:07 .. 60073293 lrwxrwxrwx 1 root root 0 Dec 15 18:23 ipc -> ipc:[4026531839] 60073294 lrwxrwxrwx 1 root root 0 Dec 15 18:23 mnt -> mnt:[4026531840] 60073295 lrwxrwxrwx 1 root root 0 Dec 15 18:23 net -> net:[4026531968] 60073296 lrwxrwxrwx 1 root root 0 Dec 15 18:23 pid -> pid:[4026531836] 60073297 lrwxrwxrwx 1 root root 0 Dec 15 18:23 uts -> uts:[4026531838] |
The number in the brackets is a inode number.
In order to find other namespaces with attached processes in the system, we use these entries of the PID=1 as a reference. Any process or thread in the system, which has not the same namespace ID as PID=1 is not belonging to the DEFAULT
namespace.
Additionally, you find the namespaces created by „ip netns add <NAME>“ by default in
/var/run/netns/ .
The python code
The python code below is listing all non default namespaces in a system. The program flow isGet the reference namespaces from the init process (PID=1). Assumption: PID=1 is assigned to the default namespaces supported by the system
Loop through /var/run/netns/ and add the entries to the list
Loop through /proc/ over all PIDs and look for entries in /proc/<PID>/ns/ which are not the same as for PID=1 and add then to the list
Print the result
List all non default namespaces in a system
Python
#!/usr/bin/python
#
# List all Namespaces (works for Ubuntu 12.04 and higher)
#
# (C) Ralf Trezeciak 2013-2014
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import fnmatch
if os.geteuid() != 0:
print "This script must be run as root\nBye"
exit(1)
def getinode( pid , type):
link = '/proc/' + pid + '/ns/' + type
ret = ''
try:
ret = os.readlink( link )
except OSError as e:
ret = ''
pass
return ret
#
# get the running command
def getcmd( p ):
try:
cmd = open(os.path.join('/proc', p, 'cmdline'), 'rb').read()
if cmd == '':
cmd = open(os.path.join('/proc', p, 'comm'), 'rb').read()
cmd = cmd.replace('\x00' , ' ')
cmd = cmd.replace('\n' , ' ')
return cmd
except:
return ''
#
# look for docker parents
def getpcmd( p ):
try:
f = '/proc/' + p + '/stat'
arr = open( f, 'rb').read().split()
cmd = getcmd( arr[3] )
if cmd.startswith( '/usr/bin/docker' ):
return 'docker'
except:
pass
return ''
#
# get the namespaces of PID=1
# assumption: these are the namespaces supported by the system
#
nslist = os.listdir('/proc/1/ns/')
if len(nslist) == 0:
print 'No Namespaces found for PID=1'
exit(1)
#print nslist
#
# get the inodes used for PID=1
#
baseinode = []
for x in nslist:
baseinode.append( getinode( '1' , x ) )
#print "Default namespaces: " , baseinode
err = 0
ns = []
ipnlist = []
#
# loop over the network namespaces created using "ip"
#
try:
netns = os.listdir('/var/run/netns/')
for p in netns:
fd = os.open( '/var/run/netns/' + p, os.O_RDONLY )
info = os.fstat(fd)
os.close( fd)
ns.append( '-- net:[' + str(info.st_ino) + '] created by ip netns add ' + p )
ipnlist.append( 'net:[' + str(info.st_ino) + ']' )
except:
# might fail if no network namespaces are existing
pass
#
# walk through all pids and list diffs
#
pidlist = fnmatch.filter(os.listdir('/proc/'), '[0123456789]*')
#print pidlist
for p in pidlist:
try:
pnslist = os.listdir('/proc/' + p + '/ns/')
for x in pnslist:
i = getinode ( p , x )
if i != '' and i not in baseinode:
cmd = getcmd( p )
pcmd = getpcmd( p )
if pcmd != '':
cmd = '[' + pcmd + '] ' + cmd
tag = ''
if i in ipnlist:
tag='**'
ns.append( p + ' ' + i + tag + ' ' + cmd)
except:
# might happen if a pid is destroyed during list processing
pass
#
# print the stuff
#
print '{0:>10} {1:20} {2}'.format('PID','Namespace','Thread/Command')
for e in ns:
x = e.split( ' ' , 2 )
print '{0:>10} {1:20} {2}'.format(x[0],x[1],x[2][:60])
#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #!/usr/bin/python # # List all Namespaces (works for Ubuntu 12.04 and higher) # # (C) Ralf Trezeciak 2013-2014 # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # import os import fnmatch if os.geteuid() != 0: "This script must be run as root\nBye" exit(1) def getinode( pid , type): link = '/proc/' + pid + '/ns/' + type ret = '' try: ret = os.readlink( link ) except OSError as e: ret = '' pass return ret # # get the running command def getcmd( p ): try: cmd = open(os.path.join('/proc', p, 'cmdline'), 'rb').read() if cmd == '': cmd = open(os.path.join('/proc', p, 'comm'), 'rb').read() cmd = cmd.replace('\x00' , ' ') cmd = cmd.replace('\n' , ' ') return cmd except: return '' # # look for docker parents def getpcmd( p ): try: f = '/proc/' + p + '/stat' arr = open( f, 'rb').read().split() cmd = getcmd( arr[3] ) if cmd.startswith( '/usr/bin/docker' ): return 'docker' except: pass return '' # # get the namespaces of PID=1 # assumption: these are the namespaces supported by the system # nslist = os.listdir('/proc/1/ns/') if len(nslist) == 0: 'No Namespaces found for PID=1' exit(1) #print nslist # # get the inodes used for PID=1 # baseinode = [] for x in nslist: baseinode.append( getinode( '1' , x ) ) #print "Default namespaces: " , baseinode err = 0 ns = [] ipnlist = [] # # loop over the network namespaces created using "ip" # try: netns = os.listdir('/var/run/netns/') for p in netns: fd = os.open( '/var/run/netns/' + p, os.O_RDONLY ) info = os.fstat(fd) os.close( fd) ns.append( '-- net:[' + str(info.st_ino) + '] created by ip netns add ' + p ) ipnlist.append( 'net:[' + str(info.st_ino) + ']' ) except: # might fail if no network namespaces are existing pass # # walk through all pids and list diffs # pidlist = fnmatch.filter(os.listdir('/proc/'), '[0123456789]*') #print pidlist for p in pidlist: try: pnslist = os.listdir('/proc/' + p + '/ns/') for x in pnslist: i = getinode ( p , x ) if i != '' and i not in baseinode: cmd = getcmd( p ) pcmd = getpcmd( p ) if pcmd != '': cmd = '[' + pcmd + '] ' + cmd tag = '' if i in ipnlist: tag='**' ns.append( p + ' ' + i + tag + ' ' + cmd) except: # might happen if a pid is destroyed during list processing pass # # print the stuff # print '{0:>10} {1:20} {2}'.format('PID','Namespace','Thread/Command') for e in ns: x = e.split( ' ' , 2 ) '{0:>10} {1:20} {2}'.format(x[0],x[1],x[2][:60]) # |
listns.py
Shell
PID Namespace Thread/Command
-- net:[4026533172] created by ip netns add qrouter-c33ffc14-dbc2-4730-b787-4747
-- net:[4026533112] created by ip netns add qrouter-5a691ed3-f6d3-4346-891a-3b59
-- net:[4026533050] created by ip netns add qdhcp-02e848cb-72d0-49df-8592-2f7a03
-- net:[4026532992] created by ip netns add qdhcp-47cfcdef-2b34-43b8-a504-6720e5
297 mnt:[4026531856] kdevtmpfs
3429 net:[4026533050]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3429 mnt:[4026533108] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3446 net:[4026532992]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3446 mnt:[4026533109] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa
3486 net:[4026533050]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3486 mnt:[4026533107] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3499 net:[4026532992]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
3499 mnt:[4026533110] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
4117 net:[4026533112]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
4117 mnt:[4026533169] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
41998 net:[4026533172]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
41998 mnt:[4026533229] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | PID Namespace Thread/Command -- net:[4026533172] created by ip netns add qrouter-c33ffc14-dbc2-4730-b787-4747 -- net:[4026533112] created by ip netns add qrouter-5a691ed3-f6d3-4346-891a-3b59 -- net:[4026533050] created by ip netns add qdhcp-02e848cb-72d0-49df-8592-2f7a03 -- net:[4026532992] created by ip netns add qdhcp-47cfcdef-2b34-43b8-a504-6720e5 297 mnt:[4026531856] kdevtmpfs 3429 net:[4026533050]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa 3429 mnt:[4026533108] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa 3446 net:[4026532992]** dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa 3446 mnt:[4026533109] dnsmasq --no-hosts --no-resolv --strict-order --bind-interfa 3486 net:[4026533050]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 3486 mnt:[4026533107] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 3499 net:[4026532992]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 3499 mnt:[4026533110] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 4117 net:[4026533112]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 4117 mnt:[4026533169] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 41998 net:[4026533172]** /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil 41998 mnt:[4026533229] /usr/bin/python /usr/bin/neutron-ns-metadata-proxy --pid_fil |
using network and mount namespaces. PID entries marked with ‚**‘ have a corresponding entry created with the ip command.
When a docker command is started, the output is:
Shell
PID Namespace Thread/Command
-- net:[4026532676] created by ip netns add test
35 mnt:[4026531856] kdevtmpfs
6189 net:[4026532585] [docker] /bin/bash
6189 uts:[4026532581] [docker] /bin/bash
6189 ipc:[4026532582] [docker] /bin/bash
6189 pid:[4026532583] [docker] /bin/bash
6189 mnt:[4026532580] [docker] /bin/bash
1 2 3 4 5 6 7 8 | PID Namespace Thread/Command -- net:[4026532676] created by ip netns add test 35 mnt:[4026531856] kdevtmpfs 6189 net:[4026532585] [docker] /bin/bash 6189 uts:[4026532581] [docker] /bin/bash 6189 ipc:[4026532582] [docker] /bin/bash 6189 pid:[4026532583] [docker] /bin/bash 6189 mnt:[4026532580] [docker] /bin/bash |
On a node running mininet and a simple network setup the output looks like:
mininet example
Shell
PID Namespace Thread/Command
14 mnt:[4026531856] kdevtmpfs
1198 net:[4026532150] bash -ms mininet:h1
1199 net:[4026532201] bash -ms mininet:h2
1202 net:[4026532252] bash -ms mininet:h3
1203 net:[4026532303] bash -ms mininet:h4
1 2 3 4 5 6 | PID Namespace Thread/Command 14 mnt:[4026531856] kdevtmpfs 1198 net:[4026532150] bash -ms mininet:h1 1199 net:[4026532201] bash -ms mininet:h2 1202 net:[4026532252] bash -ms mininet:h3 1203 net:[4026532303] bash -ms mininet:h4 |
Googles Chrome Browser
Googles Chrome Browser makes extensive use of the linux namespaces. Start Chrome and run the python script. The output looks like:Chrome's namespaces
Shell
PID Namespace Thread/Command
63 mnt:[4026531856] kdevtmpfs
30747 net:[4026532344] /opt/google/chrome/chrome --type=zygote
30747 pid:[4026532337] /opt/google/chrome/chrome --type=zygote
30753 net:[4026532344] /opt/google/chrome/nacl_helper
30753 pid:[4026532337] /opt/google/chrome/nacl_helper
30754 net:[4026532344] /opt/google/chrome/chrome --type=zygote
30754 pid:[4026532337] /opt/google/chrome/chrome --type=zygote
30801 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30801 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30807 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30807 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30813 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30813 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30820 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30820 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30829 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30829 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30835 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30835 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30841 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30841 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30887 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30887 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30893 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30893 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30901 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30901 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30910 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30910 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30915 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30915 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30923 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30923 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30933 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30933 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30938 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30938 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30944 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
30944 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31271 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31271 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31538 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
31538 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | PID Namespace Thread/Command 63 mnt:[4026531856] kdevtmpfs 30747 net:[4026532344] /opt/google/chrome/chrome --type=zygote 30747 pid:[4026532337] /opt/google/chrome/chrome --type=zygote 30753 net:[4026532344] /opt/google/chrome/nacl_helper 30753 pid:[4026532337] /opt/google/chrome/nacl_helper 30754 net:[4026532344] /opt/google/chrome/chrome --type=zygote 30754 pid:[4026532337] /opt/google/chrome/chrome --type=zygote 30801 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30801 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30807 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30807 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30813 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30813 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30820 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30820 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30829 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30829 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30835 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30835 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30841 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30841 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30887 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30887 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30893 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30893 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30901 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30901 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30910 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30910 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30915 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30915 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30923 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30923 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30933 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30933 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30938 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30938 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30944 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 30944 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 31271 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 31271 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 31538 net:[4026532344] /opt/google/chrome/chrome --type=renderer --lang=en-US --for 31538 pid:[4026532337] /opt/google/chrome/chrome --type=renderer --lang=en-US --for |
Conclusion
It’s quite hard to explore the Linux namespace. There is a lot of documentation flowing around. I did not find any simple program to look for namespaces in the system. So I wrote one.The script cannot find a network namespace, which do not have any process attached to AND which has no reference in /var/run/netns/. If root creates the reference inode somewhere else in the filesystem, you may only detect network ports (ovs port, veth port
on one side), which are not attached to a known network namespace –> an unknown guest might be on your system using a „hidden“ (not so easy to find) network namespace.
And — Linux namespaces can be stacked.
相关文章推荐
- How to programmatically clear the filesystem memory cache in C++ on a Linux system?
- How to access system messages in Linux? Does Linux have something like Windows Event Log?
- How to find and fix faults in Linux applications.
- how to find shell type in linux
- 【转载】How To Find IP Conflicts In Linux
- How to Find Your IP Address in Ubuntu Linux
- How to Change Timezone in your Linux System
- How to Backup Your System in linux
- How to find PID of process listening on a port in Linux? netstat and lsof command examples
- How to deal with "Could not find component on update server. Contact VMware Support or your system administrator." in Vmware.
- How To Get System Info In Linux
- Troubleshooting High I/O Wait in Linux --- A walkthrough on how to find processes that are causing h
- How to Set and Unset Local, User and System Wide Environment Variables in Linux
- How to Mount and Unmount Filesystem / Partition in Linux (Mount/Umount Command Examples)
- How to build qemu-system-arm in Linux
- How to find and fix Bash Shell-shock vulnerability CVE-2014-6271 in unix like system
- How to Use `strace` to Trace the System Call in Linux
- Howto Reboot or halt Linux system in emergency (ZT)
- How do I find out Linux Resource utilization to detect system bottlenecks?
- How to compile GCC-4.3.3 in the Linux?