Stability | provisional |
---|---|
Portability | non-portable (requires Linux) |
Safe Haskell | None |
Language | Haskell2010 |
This module provides bindings to the unshare(2)
and setns(2)
linux
system calls. These functions can be used to create new namespaces by
detaching the current process from its current namespaces, or to move
the current process to an already existing namespace. Note that linux
also provides the clone(2)
function which can be used to create new
namespaces, but we do not support this function in this module; the way
this function works makes it hard to use it from haskell as it interacts
badly with GHC'c RTS.
Note: Using this module in a program that uses the threaded RTS does
not make much sense. Namespaces are per process/thread and manipulating
them in one thread will not affect the namespaces of the other threads
of the same process. The threaded RTS makes it is hard to predict what
OS thread will be used to run the haskell threads. Therefore, using this
module in such applications will result in unpredictable behavior.
Similarly, using this module in ghci
is also problematic.
- data Namespace
- unshare :: [Namespace] -> IO ()
- setNamespace :: Fd -> Maybe Namespace -> IO ()
- enterNamespace :: ProcessID -> Namespace -> IO ()
- data NamespaceID
- getNamespaceID :: Maybe ProcessID -> Namespace -> IO NamespaceID
- data UserMapping = UserMapping UserID UserID Int
- data GroupMapping = GroupMapping GroupID GroupID Int
- writeUserMappings :: Maybe ProcessID -> [UserMapping] -> IO ()
- writeGroupMappings :: Maybe ProcessID -> [GroupMapping] -> IO ()
Main types and functions
Types of namespaces.
unshare :: [Namespace] -> IO () Source
Detach the process from one or more namespaces and move it to new
ones. See the man page of unshare(2)
for more details.
:: Fd | A file descriptor referring to a namespace file in a
|
-> Maybe Namespace | Specify the namespace type that the file
descriptor must refer to. If the two types do not
much, the function will fail. Use |
-> IO () |
Move process to an already existing namespace. See the man page of
setns(2)
for more details. See also enterNamespace
for a slightly
higher level version of this function.
Utility functions
:: ProcessID | The |
-> Namespace | The type of the namespace. |
-> IO () |
Move process to an already existing namespace. This is a wrapper
around setNamespace
. This function requires /proc
to be
mounted.
data NamespaceID Source
A unique namespace id.
getNamespaceID :: Maybe ProcessID -> Namespace -> IO NamespaceID Source
Retrieve the id of a Namespace. Useful for debugging. This
function requires /proc
to be mounted.
User/Group mappings
data UserMapping Source
A single user mapping, used with user namespaces. See
user_namespaces(7)
for more details.
data GroupMapping Source
A single group mapping, used with user namespaces. See
user_namespaces(7)
for more details.
:: Maybe ProcessID | The pid of any process in the target user
namespace. |
-> [UserMapping] | |
-> IO () |
Define the user mappings for the specified user namespace. This
function requires /proc
to be mounted. See user_namespaces(7)
for more details.
:: Maybe ProcessID | The pid of any process in the target user
namespace. |
-> [GroupMapping] | |
-> IO () |
Define the group mappings for the specified user namespace. This
function requires /proc
to be mounted. See user_namespaces(7)
for more details.
Example
Here's an example of creating a new network namespace. We also create a user namespace. This allows us to execute the program as an unprivileged user.
import System.Process import System.Posix.User import System.Linux.Namespaces main :: IO () main = do putStrLn "*** Network interfaces in the parent namespace ***" callCommand "ip addr" putStrLn "" -- find the uid, we must do that before unshare uid <- getEffectiveUserID unshare [User, Network] -- map current user to user 0 (i.e. root) inside the namespace writeUserMappings Nothing [UserMapping 0 uid 1] -- enable the loopback interface -- we can do that because we are root inside the namespace callCommand "ip link set dev lo up" putStrLn "*** Network interfaces in the new namespace ***" callCommand "ip addr"