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. The former can be used to create new namespaces and move
the calling process to them, whereas the latter can be used to move the
calling process to an already existing namespace created by some other
process.
Note that linux provides another function related to namespaces which is
not supported by this module: clone(2)
. This function works like
fork(2)
and is used to create new namespaces (like unshare(2)
).
Unfortunately, like fork(2)
, it does not interact well with GHC'c RTS
which is why it has been omitted from this module.
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 problematic too.
- 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] -> Bool -> 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
match, the function will fail. Use |
-> IO () |
Move the 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 the 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.
:: Maybe ProcessID | The |
-> Namespace | The type of the namespace. |
-> IO NamespaceID |
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 |
-> [UserMapping] | The mappings. |
-> 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 |
-> [GroupMapping] | The mappings. |
-> Bool | Prevent processes in the child user namespace
from calling |
-> 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"