The objective of makejail is to help an administrator creating and updating a chroot jail with short configuration files.
Makejails attempts to guess and install into the jail all files required by the daemon.
You have to understand how it works to configure it efficiently.
Detailed mechanism
The list of these files is built from several sources:
- the main method is to trace what files the daemon attempts to access, add them into the jail and restart again until no further file is found.
- a list of files manually given in the configuration file.
- the files which belongs to a package and eventually the packages it requires.
When a file is added into the jail:
- the shared librairies it needs (given by ldd) are added too.
- upper directories are created if needed.
- if the file is a symbolic link, the target is added too.
- all the checks to determine what files a file needs are recursive.
- all files are copied maintaining the originals' ownerships and permissions.
Some files are handled with a special method:
- when the file is below /proc, the procfs filesystem is mounted inside the jail.
- when the file is a socket, it's not copied.
- when the file is the shared library cache, it's not copied, ldconfig is run at the end.
The steps of makejail are:
- eventually remove the files in the jail first.
- if you specified some packages, add all the files which belongs to them.
- if you specified some paths to include, add the files matching these patterns.
- start the daemon inside the jail, and trace it with strace, add the files it attempts to open which exist outside the jail, kill it and start again until no more file is found.
- start the daemon inside the jail, and trace it while running some test processes outside the jail, see with strace what files the daemon attempts to open.
Configuration files
The file must be written in a correct python syntax. The good news is that the syntax is simple, and you can eventually write some python code to define the syntax.
Some default directives may be defined in /etc/makejail, the configuration file given on the command line has predecence.
All paths you use in the configuration file must be absolute.
Configuration directives
Basics
Defaults won't work, you must define specific values for these directives.
chroot
The path to the chroot. The directory must exist and have correct permissions and ownerships.
Format: "/path/to/jail"
Default: None
testCommandsInsideJail
The commands used to start the daemon, a good starting point may be the command used in the startup script in /etc/init.d
Format: ["command1","command2"]
Default: []
processNames
The name of the runnning processes after the daemon has been started.
Format: ["process1","process2"]
Default: []
Tests
After the daemon itself has been chrooted successfully, some commands can be executed from outside the jail to test the daemon.
testCommandsOutsideJail
The test commands which should be executed.
Format: ["command1","command2"]
Default: []
promptForInteractiveTests
Whether makejail should pause so you can stress the daemon yourself.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
promptForSomeMoreTests=0
Whether makejail should loop while running tests until you tell it it's over.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
maxExecutions
Maximum number of times a command is executed before aborting.
Format: integer
Default: 100
Copying files
doNotCopy
Do not copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
When initializing the jail, copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
Format: ["path1","path2"]
Default: []
cleanJailFirst
Whether makejail should remove files in jail first.
Format: 0 to do nothing or 1 to remove files from the jail.
Default: 1
preserve
Useful only if cleanJailFirst=1, makejail won't remove files or directories if their path begins with one of the strings in this list.
When updating a jail, you should for example put the locations of log files here.
Format: ["path1","path2"]
Default: []
maxRemove
Useful only if cleanJailFirst=1, makejail aborts if it's about to remove more than this number of files from the jail.
This may prevent makejail from erasing unwanted files if you wrote chroot="/usr" or if you have mounted a partition in the jail.
Format: integer
Default: 500
users
Makejail will filter the files listed in the directive userFiles and copy only lines matching these users, which means lines starting with "user:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["user1","user2"]
Default: []
groups
Makejail will filter the files listed in the directive groupFiles and copy only lines matching these groups, which means lines starting with "group:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["group1","group2"]
Default: []
Timing
These times are in seconds, the values are the duration of sleeps at various stages of makejail.
sleepAfterStartCommand
Duration of sleep after starting the daemon, after this delay makejail considers it's in a correctly running state.
Format: floating number
Default: 2
sleepAfterTest
Duration of sleep after a test command has been run, after this delay makejail considers the daemon has finished its tasks related to this command.
Format: floating number
Default: 2
sleepAfterKillall
Duration of sleep after killing the daemon processes.
Format: floating number
Default: 1
sleepAfterStraceAttachPid
Duration of sleep after attaching strace to a running process id.
Format: floating number
Default: 0.2
Debian specific
I initially thought with starting with the package description, but this method usually installs a bunch of files you won't need.
packages
The name of the packages. It will copy the files which belongs to the package according to the file /var/lib/dpkg/info/$package.list.
Format: ["package1","package2"]
Default: []
useDepends
If you want to also install other packages required by the the initial list you specified.
It looks at the line "Depends:" in the output of `dpkg -p $package`.
Format: 1 (use depends) or 0 (don't use depends)
Default: 0
blockDepends
Useful only if useDepends=1, it prevents the installation of these packages even if dpkg says they are required.
Format: ["package1","package2"]
Default: []
debianDpkgInfoDir
Path to the dpkg $package.list files, "%s" will be replaced by the name of the package.
Format: "/path/to/info/files/%s.list"
Default: "/var/lib/dpkg/info/%s.list"
Paths so specific files and commands
pathToLdConfig
Path to the executable ldconfig, used to generate the shared librairies cache. ldconfig is executed in the jail to regenerate this cache.
Format: "/path/to/ldconfig"
Default: "/sbin/ldconfig"
pathToLdSoConf
The path to the configuration files used by ldconfig, which says which directories should be scanned searching for shared librairies.
Set this to None if your system doesn't use such a file.
Format: "/path/to/ld.so.conf"
Default: "/etc/ld.so.conf"
pathToLdSoCache
The path to the shared librairies cache generated by ldconfig.
Format: "/path/to/ld.so.cache"
Default: "/etc/ld.so.cache"
procPath
The path to the procfs filesystem.
Format: "/path/to/proc"
Default: "/proc"
userFiles
List of the files whose contents should be filtered, to keep only the users listed in the directive "users".
Format: ["file1","file2]
Default: ["/etc/passwd","/etc/shadow"]
groupFiles
List of the files whose contents should be filtered, to keep only the groups listed in the directive "groups".
Format: ["file1","file2]
Default:["/etc/group","/etc/gshadow"]
tempDir
The temporary directory where makejail can write temporary files.
There may be a lot of files generated here if keepStraceOutputs=1.
Format: "/temp/directory"
Default: "/tmp/makejail_logs"
psCommand
The command line used to list running processes.
The output must include the pid and the name of the process.
Format: "ps [options]"
Default: "ps -e"
psColumns
In which columns of the output of psCommand are the ids and the name of the processes.
Spaces separate the columns, the first column is numbered 1.
Format: (columnPid,columnProcessName)
Default: [1,4]
Commands to run to trace processes
Here you can configure the commands which must be run to trace processes. These are called strace though you can use another program, like ktrace on OpenBSD.
The defaults should be suitable for systems using strace. "-f" means strace should trace process children too. Though it's interested only in file accesses, it doesn't use "-e trace=file" because with this option it doesn't catch calls for "bind" and "connect" to sockets.
straceCommand
String describing the strace command when executing a command line. "%command" will be replaced by the command to execute, and "%file" by the path to the temporary trace file.
String describing the strace command when attaching itself to a running process. "%pid" will be replaced by the id of the process to trace, and "%file" by the path to the temporary trace file.
Format: "strace_command [options] %pid > %file"
Default: "strace -f -p %pid >/dev/null 2>>%file"
straceCommandStop
Command to execute to stop the tracing.
Format: "strace_stop_command"
Default: "killall -9 strace"
straceCommandView
Set this to None if the trace output files can be read directly, or the command line to execute which prints the trace on stdout. "%file" will be replaced by the name of this file.
Format: "strace_command_viewer [options] %file"
Default: None
keepStraceOutputs
Whether makejail should remove the outputs of strace from the directory tempDir.
Format: 0 (to remove the files) or 1 (to keep them)
Default: 0
Patterns in the trace outputs
These are three patterns which should match failed attempts to access a file in the traces.
You must define a group (between parenthesis) which will be matched by the path of the file.
The syntax of the regular expressions in python is detailed here: http://py-howto.sourceforge.net/regex/regex.html
If the match on a line means it is a failed attempt only if the next line matches another expression (typically a return code, no group needed), you can use an array of two strings instead of one string, the first string is the main expression, and the second one is the expression which must match the next line. See global.OpenBSD in the examples directory.
stracePatterns
Regular expressions to detect a failed attempt at accessing a file.
If the file exists outside the jail makejail will copy it into the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['.*\("([^"]*)",.*\) .* ENOENT .*']
straceCreatePatterns
Regular expressions to detect a failed attempt at creating a file.
If the directory where the file should be created exists outside the jail, it will create it inside the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
makejail-0.0.5/doc/README 0100644 0000000 0000000 00000031342 07561105120 013415 0 ustar root root *********
* Usage *
*********
./makejail configuration_file
************
* Overview *
************
The objective of makejail is to help an administrator creating and updating a chroot jail with short configuration files.
Makejails attempts to guess and install into the jail all files required by the daemon.
You have to understand how it works to configure it efficiently.
**********************
* Detailed mechanism *
**********************
The list of these files is built from several sources:
- the main method is to trace what files the daemon attempts to access, add them into the jail and restart again until no further file is found.
- a list of files manually given in the configuration file.
- the files which belongs to a package and eventually the packages it requires.
When a file is added into the jail:
- the shared librairies it needs (given by ldd) are added too.
- upper directories are created if needed.
- if the file is a symbolic link, the target is added too.
- all the checks to determine what files a file needs are recursive.
- all files are copied maintaining the originals' ownerships and permissions.
Some files are handled with a special method:
- when the file is below /proc, the procfs filesystem is mounted inside the jail.
- when the file is a socket, it's not copied.
- when the file is the shared library cache, it's not copied, ldconfig is run at the end.
The steps of makejail are:
- eventually remove the files in the jail first.
- if you specified some packages, add all the files which belongs to them.
- if you specified some paths to include, add the files matching these patterns.
- start the daemon inside the jail, and trace it with strace, add the files it attempts to open which exist outside the jail, kill it and start again until no more file is found.
- start the daemon inside the jail, and trace it while running some test processes outside the jail, see with strace what files the daemon attempts to open.
***********************
* Configuration files *
***********************
The file must be written in a correct python syntax. The good news is that the syntax is simple, and you can eventually write some python code to define the syntax.
Some default directives may be defined in /etc/makejail, the configuration file given on the command line has predecence.
All paths you use in the configuration file must be absolute.
****************************
* Configuration directives *
****************************
Basics
======
Defaults won't work, you must define specific values for these directives.
chroot
------
The path to the chroot. The directory must exist and have correct permissions and ownerships.
Format: "/path/to/jail"
Default: None
testCommandsInsideJail
----------------------
The commands used to start the daemon, a good starting point may be the command used in the startup script in /etc/init.d
Format: ["command1","command2"]
Default: []
processNames
------------
The name of the runnning processes after the daemon has been started.
Format: ["process1","process2"]
Default: []
Tests
=====
After the daemon itself has been chrooted successfully, some commands can be executed from outside the jail to test the daemon.
testCommandsOutsideJail
-----------------------
The test commands which should be executed.
Format: ["command1","command2"]
Default: []
promptForInteractiveTests
-------------------------
Whether makejail should pause so you can stress the daemon yourself.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
promptForSomeMoreTests=0
------------------------
Whether makejail should loop while running tests until you tell it it's over.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
maxExecutions
-------------
Maximum number of times a command is executed before aborting.
Format: integer
Default: 100
Copying files
=============
doNotCopy
---------
Do not copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
Format: ["path1","path2"]
Default: ["/usr/share/doc","/usr/share/info","/usr/share/man","/etc/fstab","/etc/mtab"]
forceCopy
---------
When initializing the jail, copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
Format: ["path1","path2"]
Default: []
cleanJailFirst
--------------
Whether makejail should remove files in jail first.
Format: 0 to do nothing or 1 to remove files from the jail.
Default: 1
preserve
--------
Useful only if cleanJailFirst=1, makejail won't remove files or directories if their path begins with one of the strings in this list.
When updating a jail, you should for example put the locations of log files here.
Format: ["path1","path2"]
Default: []
maxRemove
---------
Useful only if cleanJailFirst=1, makejail aborts if it's about to remove more than this number of files from the jail.
This may prevent makejail from erasing unwanted files if you wrote chroot="/usr" or if you have mounted a partition in the jail.
Format: integer
Default: 500
users
-----
Makejail will filter the files listed in the directive userFiles and copy only lines matching these users, which means lines starting with "user:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["user1","user2"]
Default: []
groups
------
Makejail will filter the files listed in the directive groupFiles and copy only lines matching these groups, which means lines starting with "group:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["group1","group2"]
Default: []
Timing
======
These times are in seconds, the values are the duration of sleeps at various stages of makejail.
sleepAfterStartCommand
----------------------
Duration of sleep after starting the daemon, after this delay makejail considers it's in a correctly running state.
Format: floating number
Default: 2
sleepAfterTest
--------------
Duration of sleep after a test command has been run, after this delay makejail considers the daemon has finished its tasks related to this command.
Format: floating number
Default: 2
sleepAfterKillall
-----------------
Duration of sleep after killing the daemon processes.
Format: floating number
Default: 1
sleepAfterStraceAttachPid
-------------------------
Duration of sleep after attaching strace to a running process id.
Format: floating number
Default: 0.2
Debian specific
===============
I initially thought with starting with the package description, but this method usually installs a bunch of files you won't need.
packages
--------
The name of the packages. It will copy the files which belongs to the package according to the file /var/lib/dpkg/info/$package.list.
Format: ["package1","package2"]
Default: []
useDepends
----------
If you want to also install other packages required by the the initial list you specified.
It looks at the line "Depends:" in the output of `dpkg -p $package`.
Format: 1 (use depends) or 0 (don't use depends)
Default: 0
blockDepends
------------
Useful only if useDepends=1, it prevents the installation of these packages even if dpkg says they are required.
Format: ["package1","package2"]
Default: []
debianDpkgInfoDir
-----------------
Path to the dpkg $package.list files, "%s" will be replaced by the name of the package.
Format: "/path/to/info/files/%s.list"
Default: "/var/lib/dpkg/info/%s.list"
Paths so specific files and commands
====================================
pathToLdConfig
--------------
Path to the executable ldconfig, used to generate the shared librairies cache. ldconfig is executed in the jail to regenerate this cache.
Format: "/path/to/ldconfig"
Default: "/sbin/ldconfig"
pathToLdSoConf
--------------
The path to the configuration files used by ldconfig, which says which directories should be scanned searching for shared librairies.
Set this to None if your system doesn't use such a file.
Format: "/path/to/ld.so.conf"
Default: "/etc/ld.so.conf"
pathToLdSoCache
---------------
The path to the shared librairies cache generated by ldconfig.
Format: "/path/to/ld.so.cache"
Default: "/etc/ld.so.cache"
procPath
--------
The path to the procfs filesystem.
Format: "/path/to/proc"
Default: "/proc"
userFiles
---------
List of the files whose contents should be filtered, to keep only the users listed in the directive "users".
Format: ["file1","file2]
Default: ["/etc/passwd","/etc/shadow"]
groupFiles
----------
List of the files whose contents should be filtered, to keep only the groups listed in the directive "groups".
Format: ["file1","file2]
Default:["/etc/group","/etc/gshadow"]
tempDir
-------
The temporary directory where makejail can write temporary files.
There may be a lot of files generated here if keepStraceOutputs=1.
Format: "/temp/directory"
Default: "/tmp/makejail_logs"
psCommand
---------
The command line used to list running processes.
The output must include the pid and the name of the process.
Format: "ps [options]"
Default: "ps -e"
psColumns
---------
In which columns of the output of psCommand are the ids and the name of the processes.
Spaces separate the columns, the first column is numbered 1.
Format: (columnPid,columnProcessName)
Default: [1,4]
Commands to run to trace processes
==================================
Here you can configure the commands which must be run to trace processes. These are called strace though you can use another program, like ktrace on OpenBSD.
The defaults should be suitable for systems using strace. "-f" means strace should trace process children too. Though it's interested only in file accesses, it doesn't use "-e trace=file" because with this option it doesn't catch calls for "bind" and "connect" to sockets.
straceCommand
-------------
String describing the strace command when executing a command line. "%command" will be replaced by the command to execute, and "%file" by the path to the temporary trace file.
Format: "strace_command [options] %command > %file"
Default: "strace -f %command >/dev/null 2>>%file"
straceCommandPid
----------------
String describing the strace command when attaching itself to a running process. "%pid" will be replaced by the id of the process to trace, and "%file" by the path to the temporary trace file.
Format: "strace_command [options] %pid > %file"
Default: "strace -f -p %pid >/dev/null 2>>%file"
straceCommandStop
------------------
Command to execute to stop the tracing.
Format: "strace_stop_command"
Default: "killall -9 strace"
straceCommandView
-----------------
Set this to None if the trace output files can be read directly, or the command line to execute which prints the trace on stdout. "%file" will be replaced by the name of this file.
Format: "strace_command_viewer [options] %file"
Default: None
keepStraceOutputs
-----------------
Whether makejail should remove the outputs of strace from the directory tempDir.
Format: 0 (to remove the files) or 1 (to keep them)
Default: 0
Patterns in the trace outputs
=============================
These are three patterns which should match failed attempts to access a file in the traces.
You must define a group (between parenthesis) which will be matched by the path of the file.
The syntax of the regular expressions in python is detailed here: http://py-howto.sourceforge.net/regex/regex.html
If the match on a line means it is a failed attempt only if the next line matches another expression (typically a return code, no group needed), you can use an array of two strings instead of one string, the first string is the main expression, and the second one is the expression which must match the next line. See global.OpenBSD in the examples directory.
stracePatterns
--------------
Regular expressions to detect a failed attempt at accessing a file.
If the file exists outside the jail makejail will copy it into the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['.*\("([^"]*)",.*\) .* ENOENT .*']
straceCreatePatterns
--------------------
Regular expressions to detect a failed attempt at creating a file.
If the directory where the file should be created exists outside the jail, it will create it inside the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['.*\("([^"]*)",.*O_CREAT.*\) .* ENOENT .*','bind\(.* path="([^"]*)".* ENOENT .*']
straceSocketPatterns
--------------------
Regular expressions to detect a failed attempt at accessing a socket.
makejail can't create the socket, it will just print a warning.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['connect\(.* path="([^"]*)".* ENOENT .*']
makejail-0.0.5/Makefile 0100644 0000000 0000000 00000002423 07437056461 013445 0 ustar root root # Makefile for makejail
prefix = /usr
BIN_DIR = $(prefix)/sbin
DOC_DIR = $(prefix)/share/doc/makejail
MAN_DIR = $(prefix)/share/man/man8
HTML_DIR = $(DOC_DIR)/html
MAN_PAGE = makejail.8
EXAMPLES_DIR = $(DOC_DIR)/examples
INSTALL = install
DISTDIR = makejail
.PHONY: install distclean
all:
@echo "Usage: make [install|uninstall|docs|clean_docs]"
docs:
./makedocs
docbook-to-man manpage.sgml > $(MAN_PAGE)
install:
if (test ! -d $(BIN_DIR)); then mkdir -p $(BIN_DIR) ; fi
$(INSTALL) makejail $(BIN_DIR)
chmod 700 $(BIN_DIR)/makejail
if (test ! -d $(DOC_DIR)); then mkdir -p $(DOC_DIR) ; chmod 755 $(DOC_DIR) ; fi
cp doc/README $(DOC_DIR)
chmod 644 $(DOC_DIR)/README
if (test ! -d $(HTML_DIR)); then mkdir -p $(HTML_DIR) ; chmod 755 $(HTML_DIR) ; fi
cp doc/index.html $(HTML_DIR)
chmod 644 $(HTML_DIR)/index.html
if (test ! -d $(EXAMPLES_DIR)); then mkdir -p $(EXAMPLES_DIR) ; chmod 755 $(EXAMPLES_DIR) ; fi
cp -Rp examples/* $(EXAMPLES_DIR)
chmod 644 $(EXAMPLES_DIR)/*
if (test ! -d $(MAN_DIR)); then mkdir -p $(MAN_DIR) ; chmod 755 $(MAN_DIR) ; fi
$(INSTALL) makejail.8 $(MAN_DIR)
chmod 644 $(MAN_DIR)/$(MAN_PAGE)
clean_docs:
rm -rf doc manpage.sgml makejail.8
uninstall:
rm -f $(BIN_DIR)/makejail
rm -rf $(EXAMPLES_DIR)
rm -rf $(DOC_DIR)
rm -f $(MAN_DIR)/$(MAN_PAGE)
makejail-0.0.5/doc.src 0100644 0000000 0000000 00000030005 07537273017 013257 0 ustar root root __MANMODE=0__
H1:Usage
PRE:./makejail configuration_file
__MANMODE=1__
H1:Overview
The objective of makejail is to help an administrator creating and updating a chroot jail with short configuration files.
Makejails attempts to guess and install into the jail all files required by the daemon.
You have to understand how it works to configure it efficiently.
H1:Detailed mechanism
The list of these files is built from several sources:
- the main method is to trace what files the daemon attempts to access, add them into the jail and restart again until no further file is found.
- a list of files manually given in the configuration file.
- the files which belongs to a package and eventually the packages it requires.
When a file is added into the jail:
- the shared librairies it needs (given by ldd) are added too.
- upper directories are created if needed.
- if the file is a symbolic link, the target is added too.
- all the checks to determine what files a file needs are recursive.
- all files are copied maintaining the originals' ownerships and permissions.
Some files are handled with a special method:
- when the file is below /proc, the procfs filesystem is mounted inside the jail.
- when the file is a socket, it's not copied.
- when the file is the shared library cache, it's not copied, ldconfig is run at the end.
The steps of makejail are:
- eventually remove the files in the jail first.
- if you specified some packages, add all the files which belongs to them.
- if you specified some paths to include, add the files matching these patterns.
- start the daemon inside the jail, and trace it with strace, add the files it attempts to open which exist outside the jail, kill it and start again until no more file is found.
- start the daemon inside the jail, and trace it while running some test processes outside the jail, see with strace what files the daemon attempts to open.
H1:Configuration files
The file must be written in a correct python syntax. The good news is that the syntax is simple, and you can eventually write some python code to define the syntax.
Some default directives may be defined in /etc/makejail, the configuration file given on the command line has predecence.
All paths you use in the configuration file must be absolute.
__MANMODE=2__
H1:Configuration directives
H2:Basics
Defaults won't work, you must define specific values for these directives.
H3:chroot
The path to the chroot. The directory must exist and have correct permissions and ownerships.
Format: "/path/to/jail"
Default: None
H3:testCommandsInsideJail
The commands used to start the daemon, a good starting point may be the command used in the startup script in /etc/init.d
Format: ["command1","command2"]
Default: []
H3:processNames
The name of the runnning processes after the daemon has been started.
Format: ["process1","process2"]
Default: []
H2:Tests
After the daemon itself has been chrooted successfully, some commands can be executed from outside the jail to test the daemon.
H3:testCommandsOutsideJail
The test commands which should be executed.
Format: ["command1","command2"]
Default: []
H3:promptForInteractiveTests
Whether makejail should pause so you can stress the daemon yourself.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
H3:promptForSomeMoreTests=0
Whether makejail should loop while running tests until you tell it it's over.
Use only if makejail is run interactively, and don't redirect its outputs.
Format: 1 (prompt) or 0 (don't prompt)
Default: 0
H3:maxExecutions
Maximum number of times a command is executed before aborting.
Format: integer
Default: 100
H2:Copying files
H3:doNotCopy
Do not copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
Format: ["path1","path2"]
Default: ["/usr/share/doc","/usr/share/info","/usr/share/man","/etc/fstab","/etc/mtab"]
H3:forceCopy
When initializing the jail, copy the files matching these patterns according to the rules used by the Unix shell.
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
Format: ["path1","path2"]
Default: []
H3:cleanJailFirst
Whether makejail should remove files in jail first.
Format: 0 to do nothing or 1 to remove files from the jail.
Default: 1
H3:preserve
Useful only if cleanJailFirst=1, makejail won't remove files or directories if their path begins with one of the strings in this list.
When updating a jail, you should for example put the locations of log files here.
Format: ["path1","path2"]
Default: []
H3:maxRemove
Useful only if cleanJailFirst=1, makejail aborts if it's about to remove more than this number of files from the jail.
This may prevent makejail from erasing unwanted files if you wrote chroot="/usr" or if you have mounted a partition in the jail.
Format: integer
Default: 500
H3:users
Makejail will filter the files listed in the directive userFiles and copy only lines matching these users, which means lines starting with "user:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["user1","user2"]
Default: []
H3:groups
Makejail will filter the files listed in the directive groupFiles and copy only lines matching these groups, which means lines starting with "group:"
You can use ["*"] to disable filtering and copy the whole file.
Format: ["group1","group2"]
Default: []
H2:Timing
These times are in seconds, the values are the duration of sleeps at various stages of makejail.
H3:sleepAfterStartCommand
Duration of sleep after starting the daemon, after this delay makejail considers it's in a correctly running state.
Format: floating number
Default: 2
H3:sleepAfterTest
Duration of sleep after a test command has been run, after this delay makejail considers the daemon has finished its tasks related to this command.
Format: floating number
Default: 2
H3:sleepAfterKillall
Duration of sleep after killing the daemon processes.
Format: floating number
Default: 1
H3:sleepAfterStraceAttachPid
Duration of sleep after attaching strace to a running process id.
Format: floating number
Default: 0.2
H2:Debian specific
I initially thought with starting with the package description, but this method usually installs a bunch of files you won't need.
H3:packages
The name of the packages. It will copy the files which belongs to the package according to the file /var/lib/dpkg/info/$package.list.
Format: ["package1","package2"]
Default: []
H3:useDepends
If you want to also install other packages required by the the initial list you specified.
It looks at the line "Depends:" in the output of `dpkg -p $package`.
Format: 1 (use depends) or 0 (don't use depends)
Default: 0
H3:blockDepends
Useful only if useDepends=1, it prevents the installation of these packages even if dpkg says they are required.
Format: ["package1","package2"]
Default: []
H3:debianDpkgInfoDir
Path to the dpkg $package.list files, "%s" will be replaced by the name of the package.
Format: "/path/to/info/files/%s.list"
Default: "/var/lib/dpkg/info/%s.list"
H2:Paths so specific files and commands
H3:pathToLdConfig
Path to the executable ldconfig, used to generate the shared librairies cache. ldconfig is executed in the jail to regenerate this cache.
Format: "/path/to/ldconfig"
Default: "/sbin/ldconfig"
H3:pathToLdSoConf
The path to the configuration files used by ldconfig, which says which directories should be scanned searching for shared librairies.
Set this to None if your system doesn't use such a file.
Format: "/path/to/ld.so.conf"
Default: "/etc/ld.so.conf"
H3:pathToLdSoCache
The path to the shared librairies cache generated by ldconfig.
Format: "/path/to/ld.so.cache"
Default: "/etc/ld.so.cache"
H3:procPath
The path to the procfs filesystem.
Format: "/path/to/proc"
Default: "/proc"
H3:userFiles
List of the files whose contents should be filtered, to keep only the users listed in the directive "users".
Format: ["file1","file2]
Default: ["/etc/passwd","/etc/shadow"]
H3:groupFiles
List of the files whose contents should be filtered, to keep only the groups listed in the directive "groups".
Format: ["file1","file2]
Default:["/etc/group","/etc/gshadow"]
H3:tempDir
The temporary directory where makejail can write temporary files.
There may be a lot of files generated here if keepStraceOutputs=1.
Format: "/temp/directory"
Default: "/tmp/makejail_logs"
H3:psCommand
The command line used to list running processes.
The output must include the pid and the name of the process.
Format: "ps [options]"
Default: "ps -e"
H3:psColumns
In which columns of the output of psCommand are the ids and the name of the processes.
Spaces separate the columns, the first column is numbered 1.
Format: (columnPid,columnProcessName)
Default: [1,4]
H2:Commands to run to trace processes
Here you can configure the commands which must be run to trace processes. These are called strace though you can use another program, like ktrace on OpenBSD.
The defaults should be suitable for systems using strace. "-f" means strace should trace process children too. Though it's interested only in file accesses, it doesn't use "-e trace=file" because with this option it doesn't catch calls for "bind" and "connect" to sockets.
H3:straceCommand
String describing the strace command when executing a command line. "%command" will be replaced by the command to execute, and "%file" by the path to the temporary trace file.
Format: "strace_command [options] %command > %file"
Default: "strace -f %command >/dev/null 2>>%file"
H3:straceCommandPid
String describing the strace command when attaching itself to a running process. "%pid" will be replaced by the id of the process to trace, and "%file" by the path to the temporary trace file.
Format: "strace_command [options] %pid > %file"
Default: "strace -f -p %pid >/dev/null 2>>%file"
H3: straceCommandStop
Command to execute to stop the tracing.
Format: "strace_stop_command"
Default: "killall -9 strace"
H3:straceCommandView
Set this to None if the trace output files can be read directly, or the command line to execute which prints the trace on stdout. "%file" will be replaced by the name of this file.
Format: "strace_command_viewer [options] %file"
Default: None
H3:keepStraceOutputs
Whether makejail should remove the outputs of strace from the directory tempDir.
Format: 0 (to remove the files) or 1 (to keep them)
Default: 0
H2:Patterns in the trace outputs
These are three patterns which should match failed attempts to access a file in the traces.
You must define a group (between parenthesis) which will be matched by the path of the file.
The syntax of the regular expressions in python is detailed here: http://py-howto.sourceforge.net/regex/regex.html
If the match on a line means it is a failed attempt only if the next line matches another expression (typically a return code, no group needed), you can use an array of two strings instead of one string, the first string is the main expression, and the second one is the expression which must match the next line. See global.OpenBSD in the examples directory.
H3:stracePatterns
Regular expressions to detect a failed attempt at accessing a file.
If the file exists outside the jail makejail will copy it into the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['.*\("([^"]*)",.*\) .* ENOENT .*']
H3:straceCreatePatterns
Regular expressions to detect a failed attempt at creating a file.
If the directory where the file should be created exists outside the jail, it will create it inside the jail.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['.*\("([^"]*)",.*O_CREAT.*\) .* ENOENT .*','bind\(.* path="([^"]*)".* ENOENT .*']
H3:straceSocketPatterns
Regular expressions to detect a failed attempt at accessing a socket.
makejail can't create the socket, it will just print a warning.
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
Default: ['connect\(.* path="([^"]*)".* ENOENT .*']
__MANMODE=0__
makejail-0.0.5/makedocs 0100755 0000000 0000000 00000012203 07437056461 013516 0 ustar root root #!/usr/bin/env python
import string,os,time,re
print "Making docs"
docDir="doc"
sourcePath="doc.src"
htmlPath="%s/index.html" % docDir
textPath="%s/README" % docDir
manPath="manpage.sgml"
manTemplatePath="manpage.sgml.template"
if not(os.path.isdir(docDir)):
print "Creating directory %s" % docDir
os.mkdir(docDir)
source=open(sourcePath)
lines=map(string.strip,source.readlines())
source.close()
html=open(htmlPath,"w")
text=open(textPath,"w")
man=open(manPath,"w")
html.write("""
Makejail documentation
""")
# It's amazing how much time I waste automatizing such things, but I enjoy
def createFromTemplate(items):
if items.has_key('templatestring'):
s=items['templatestring']
del items['templatestring']
elif items.has_key('templatefile'):
f=open(items['templatefile'],"r")
s=f.read()
f.close()
del items['templatefile']
else:
raise "No template string/file"
startpos=string.find(s,"__INSERT=")
while startpos>=0:
endpos=string.index(s,"__",startpos+2)
subtemplate=s[startpos+9:endpos]
fsubtemplate=open(subtemplate)
subs=fsubtemplate.read()
fsubtemplate.close()
s=string.replace(s,"__INSERT=%s__" % fsubtemplate,subs)
startpos=string.find(s,"__INSERT=")
for key in items.keys():
if key[:8]=="BOOLEAN(":
assert key[-1]==")"
boolid=key[8:-1]
starttag="__IF(%s)__" % boolid
endtag="__ENDIF(%s)__" % boolid
elsetag="__ELSE(%s)__" % boolid
startpos=string.find(s,starttag)
while (startpos>=0):
endpos=string.find(s,endtag)
elsepos=string.find(s,elsetag,startpos,endpos)
beforeif=s[:startpos]
if elsepos==-1:
iftemplate=s[startpos+len(starttag):endpos]
elsetemplate=""
afterif=s[endpos+len(endtag):]
else:
iftemplate=s[startpos+len(starttag):elsepos]
elsetemplate=s[elsepos+len(elsetag):endpos]
afterif=s[endpos+len(endtag):]
if items[key]:
s=beforeif+iftemplate+afterif
else:
s=beforeif+elsetemplate+afterif
startpos=string.find(s,starttag)
elif key[:5]=="LOOP(":
assert key[-1]==")"
loopid=key[5:-1]
starttag="__STARTLOOP(%s)__" % loopid
endtag="__ENDLOOP(%s)__" % loopid
startpos=string.find(s,starttag)
while (startpos>=0):
endpos=string.find(s,endtag)
beforeloop=s[:startpos]
looptemplate=s[startpos+len(starttag):endpos]
afterloop=s[endpos+len(endtag):]
bodyloops=""
for subitems in items[key]:
loopitems={'templatestring':looptemplate}
for subkey in subitems.keys():
loopitems[subkey]=subitems[subkey]
bodyloop=createFromTemplate(loopitems)
bodyloops=bodyloops+bodyloop
s=beforeloop+bodyloops+afterloop
startpos=string.find(s,starttag)
else:
if items[key]==None:
raise "Error : items['%s']=None" % key
if type(items[key])==type([]):
items[key]=string.join(items[key],"\n")
try:
s=string.replace(s,"__%s__" % key,items[key])
except:
raise "Type Error for the key '%s'" % key
return s
manModeRegExp=re.compile("^__MANMODE=([0-2])__$")
manMode=None
lastTag={"H1":None,"H2":None,"H3":None}
manItems=[]
for line in lines:
manMatch=manModeRegExp.match(line)
if manMatch:
manMode=int(manMatch.groups()[0])
continue
if ":" in line:
tag=string.split(line,":")[0]
if tag in ("H1","H2","H3","PRE"):
line=string.join(string.split(line,":")[1:],":")
lastTag[tag]=line
if tag=="H1":
lastTag["H2"]=None
lastTag["H3"]=None
elif tag=="H2":
lastTag["H3"]=None
else:
tag=None
else:
tag=None
if tag:
htmlString="<%s>%s%s>" % (tag,line,tag)
if tag=="PRE":
textString=line
elif tag=="H1":
sep="*" * (len(line)+4)
textString="%s\n* %s *\n%s" % (sep,line,sep)
elif tag=="H2":
textString="%s\n%s" % (line,"="*len(line))
elif tag=="H3":
textString="%s\n%s" % (line,"-"*len(line))
else:
raise ValueError
else:
htmlString="%s " % line
textString=line
if manMode and line:
if manMode==1:
if tag:
assert tag=="H1"
manItems.append({"H1":line,
"BOOLEAN(TWOLEVELS)":0,
"LOOP(H1PARAS)":[]})
else:
manItems[-1]["LOOP(H1PARAS)"].append({"H1PARA":line})
elif manMode==2:
if tag=="H1":
pass
elif tag=="H2":
manItems.append({"H1":"%s - %s" % (lastTag["H1"],line),
"BOOLEAN(TWOLEVELS)":1,
"LOOP(H1PARAS)":[],
"LOOP(SUBITEMS)":[]})
elif tag=="H3":
manItems[-1]["LOOP(SUBITEMS)"].append({"H2":line,
"LOOP(H2PARAS)":[]})
else:
if lastTag["H3"]:
manItems[-1]["LOOP(SUBITEMS)"][-1]["LOOP(H2PARAS)"].append({"H2PARA":line})
else:
manItems[-1]["LOOP(H1PARAS)"].append({"H1PARA":line})
else:
raise ValueError
html.write("%s\n" % htmlString)
text.write("%s\n" % textString)
for endTag in ("body","html"):
html.write("%s>\n" % endTag)
manTemplateItems={"templatefile":manTemplatePath,
"SYSTEMDATE":time.strftime("%B %d, %Y",time.localtime(time.time())),
"LOOP(ITEMS)":manItems}
man.write(createFromTemplate(manTemplateItems))
html.close()
print "HTML file %s generated" % htmlPath
text.close()
print "Text file %s generated" % textPath
man.close()
print "Man page %s generated" % manPath
makejail-0.0.5/makejail 0100755 0000000 0000000 00000067376 07561105120 013513 0 ustar root root #!/usr/bin/env python
# Author: alain@onesite.org
# License: GPL
# OS: GNU/Linux
# Version: 0.0.5
# Required unusual external programs:
# strace (package strace)
# killall (package psmisc)
# stat (package stat)
# Configuration defaults
# Don't change this file, to define new defaults values create a file /etc/makejail
class configClass:
def __init__(self):
self.chroot=None
self.packages=[]
self.useDepends=0
self.blockDepends=[]
self.doNotCopy=["/usr/share/doc",
"/usr/share/info",
"/usr/share/man",
"/etc/fstab",
"/etc/mtab"]
self.forceCopy=[]
self.cleanJailFirst=0
self.preserve=[]
self.testCommandsInsideJail=[]
self.processNames=[]
self.testCommandsOutsideJail=[]
self.maxExecutions=100
self.sleepAfterStartCommand=2
self.sleepAfterTest=2
self.sleepAfterKillall=1
self.sleepAfterStraceAttachPid=0.2
self.maxRemove=500
self.keepStraceOutputs=0
self.promptForInteractiveTests=0
self.promptForSomeMoreTests=0
self.users=[]
self.groups=[]
self.debianDpkgInfoFile="/var/lib/dpkg/info/%s.list"
self.etcFile="/etc/makejail"
self.pathToLdConfig="/sbin/ldconfig"
self.pathToLdSoConf="/etc/ld.so.conf"
self.pathToLdSoCache="/etc/ld.so.cache"
self.procPath="/proc"
self.userFiles=["/etc/passwd",
"/etc/shadow",
"/etc/master.passwd"]
self.groupFiles=["/etc/group",
"/etc/gshadow"]
self.tempDir="/tmp/makejail_logs"
self.psCommand="ps -e"
self.psColumns=[1,4]
# -e file=trace doesn't catch socket connections
self.straceCommand="strace -f %command >/dev/null 2>>%file"
self.straceCommandPid="strace -f -p %pid >/dev/null 2>>%file"
self.straceCommandStop="killall -9 strace"
self.straceCommandView=None
self.stracePatterns=['.*\("([^"]*)",.*\) .*= -[0-9]* ENO.*',
'.*\("([^"]*)",.*\) .*= -[0-9]* EACCES.*']
self.straceCreatePatterns=['.*\("([^"]*)",.*O_CREAT.*\) .* ENOENT .*',
'bind\(.* path="([^"]*)".* ENOENT .*']
self.straceSocketPatterns=['connect\(.* path="([^"]*)".* ENOENT .*']
# Global variables
needLdCache=0
warnings=[]
procMounted=0
compiledRegExps={}
installedPackages=[]
installedFiles={}
indentLevel=0
doNotKillPids=[]
tmpOut=None
import stat
import sys
import imp
import string
import os
import shutil
import types
import popen2
import tempfile
import re
import glob
import time
import select
import fcntl
# May be useful to parse correctly some program outputs
os.environ["LANG"]="C"
def moveIndent(direction):
global indentLevel
indentLevel=indentLevel+direction
def debug(s,endLine=1):
sys.stdout.write(" "*indentLevel+s+"\n"*endLine)
def abort(s):
sys.stderr.write("\nERROR: %s\n" % s)
sys.exit(1)
def compileRegExp(pattern):
global compiledRegExps
if compiledRegExps.has_key(pattern):
compiled=compiledRegExps[pattern]
else:
compiled=re.compile(pattern)
compiledRegExps[pattern]=compiled
return compiled
def matchPattern(pattern,line,nextLine=None):
# If pattern is an array of two strings, matches the first pattern
# only if the next line matches the second pattern
if pattern==None:
return None
elif type(pattern)==types.StringType:
matchobject=compileRegExp(pattern).match(line)
if matchobject:
return matchobject.groups()[0]
elif nextLine:
(currentPattern,nextPattern)=pattern
matchobject=compileRegExp(currentPattern).match(line)
if matchobject and compileRegExp(nextPattern).match(nextLine):
return matchobject.groups()[0]
def matchPatterns(patterns,line,nextLine=None):
if patterns==None:
return None
for pattern in patterns:
match=matchPattern(pattern,line,nextLine)
if match:
return match
def startslike(s,pattern):
if s==pattern:
return 1
if len(s)config.maxRemove:
abort("Found %i files to remove, the maximum it %i" % (len(queue),config.maxRemove))
debug("Removing %i files in queue" % len(queue))
for file in queue:
debug(" Removing %s" % file)
try:
if os.path.isdir(file) and not(os.path.islink(file)):
os.rmdir(file)
else:
os.unlink(file)
except OSError:
if file=="%s%s" % (config.chroot,config.procPath):
debug(" Cannot remove %s, it's probably mounted" % config.procPath)
else:
abort("Cannot remove the path %s" % file)
def readFileLines(fileName):
try:
f=open(fileName,"r")
except IOError:
abort("Cannot read file '%s'" % fileName)
lines=f.readlines()
f.close()
return map(string.strip,lines)
def dpkgInfoFiles(package):
return readFileLines(config.debianDpkgInfoFile % package)
def copyStat(source,target):
statInfos=os.stat(source)
os.chmod(target,statInfos[stat.ST_MODE])
os.chown(target,statInfos[stat.ST_UID],statInfos[stat.ST_GID])
def mountProc():
debug("Mounting %s" % config.procPath)
moveIndent(1)
returnCode=os.system("mount -t proc proc %s%s" % (config.chroot,config.procPath))
if returnCode==0:
debug("%s mounted successfully" % config.procPath)
warnings.append(("/proc",None))
else:
abort("Unable to mount %s" % config.procPath)
moveIndent(-1)
def addPasswdFile(file,what):
moveIndent(1)
if what=="users":
entries=config.users
elif what=="groups":
entries=config.groups
else:
raise ValueError
dest="%s%s" % (config.chroot,file)
debug("Copying with filtering on %s : %s -> %s" % (what,file,dest))
if "*" in entries:
debug('Entry "*" in %s, the file is simply copied' % what)
shutil.copy(file,dest)
else:
f=open(file,"r")
lines=f.readlines()
f.close()
d=open(dest,"w")
matches=[]
for line in lines:
if not(":" in line):
continue
entry=string.split(line,":")[0]
if entry in entries:
d.write(line)
matches.append(entry)
d.close()
if len(matches)>1:
entryString="entries"
else:
entryString="entry"
debug("%i %s copied : %s" % (len(matches),entryString,string.join(matches,",")))
moveIndent(-1)
def getMajorMinor(fileName):
# Pure python functions should be available in 2.3
try:
return map(lambda h: int(h,16),execute('stat -t -c "%%t %%T" %s' % fileName)[0].split())
except:
abort("Cannot get the major and minor codes for the file %s" % fileName)
def fileIsNewer(fileName1,fileName2):
return os.stat(fileName1)[stat.ST_MTIME]>os.stat(fileName2)[stat.ST_MTIME]
def addFileToJail(fileName):
global needLdCache,procMounted
if not(fileName):
return []
missingFiles=[]
if installedFiles.has_key(fileName):
return []
debug("Checking path '%s'" % fileName)
if fileName==config.pathToLdSoCache:
installedFiles[fileName]=-1
debug(" Shared libs cache file %s marked as needed, it will be generated at the end" % config.pathToLdSoCache)
needLdCache=1
return []
if config.doNotCopy:
ignored=0
for ignorePath in config.doNotCopy:
if startslike(fileName,ignorePath):
ignored=1
break
if ignored:
debug(" Ignoring because of doNotCopy directive: %s" % fileName)
installedFiles[fileName]=0
return []
try:
statMode=os.stat(fileName)[stat.ST_MODE]
except OSError:
debug(" The path '%s' doesn't exist" % fileName)
return []
installedFiles[fileName]=1
if fileName[0]!="/":
abort("The path '%s' is not absolute" % fileName)
elif fileName=="/.":
return []
if startslike(fileName,config.procPath):
if procMounted:
debug(" %s has just been mounted" % config.procPath)
else:
os.mkdir("%s%s" % (config.chroot,config.procPath))
os.chmod("%s%s" % (config.chroot,config.procPath),0555)
mountProc()
procMounted=1
return []
targetDirs=string.split(fileName[1:],"/")[:-1]
checkDir=""
for targetDir in targetDirs:
checkDir=checkDir+"/%s" % targetDir
fileInChroot="%s%s" % (config.chroot,checkDir)
if not(os.path.isdir(fileInChroot)):
debug(" Dir '%s' missing" % fileInChroot)
moveIndent(1)
addFileToJail(checkDir)
moveIndent(-1)
fileInChroot="%s%s" % (config.chroot,fileName)
if os.path.exists(fileInChroot):
if fileIsNewer(fileName,fileInChroot):
debug(" File %s is newer than the %s, overwriting" % (fileName,fileInChroot))
else:
debug(" File %s already exists" % fileInChroot)
return []
elif os.path.islink(fileName):
linkTarget=os.readlink(fileName)
debug(" '%s' is a symlink to '%s'" % (fileName,linkTarget))
moveIndent(1)
fileDir=os.path.split(fileName)[0]
if linkTarget[-1]=="/":
linkTarget=linkTarget[:-1]
if linkTarget[0]=="/":
absoluteLinkTarget=linkTarget
else:
absoluteLinkTarget="%s/%s" % (fileDir,linkTarget)
newFiles=addFileToJail(absoluteLinkTarget)
missingFiles=missingFiles+newFiles
newWorkingDir="%s/%s" % (config.chroot,fileDir[1:])
os.chdir(newWorkingDir)
debug(" Creating '%s' as a symlink to '%s' (pwd=%s)" % (fileName[1:],linkTarget,newWorkingDir))
os.symlink(linkTarget,os.path.split(fileName)[1])
os.chdir("/")
missingFiles.append(fileName)
moveIndent(-1)
elif stat.S_ISSOCK(statMode):
debug("Failed to connect to socket %s, file exists" % fileName)
installedFiles[fileName]=-1
warnings.append(("socket",(fileName,"exists")))
return [fileName]
elif os.path.isdir(fileName):
if os.path.isdir(fileInChroot):
debug(" Dir %s already exists" % fileInChroot)
return []
debug(" Making dir %s" % fileInChroot)
os.mkdir(fileInChroot)
missingFiles.append(fileName)
elif stat.S_ISCHR(statMode) or stat.S_ISBLK(statMode):
if stat.S_ISCHR(statMode):
label="character"
deviceType="c"
else:
label="block"
deviceType="b"
(major,minor)=getMajorMinor(fileName)
debug(" Creating %s device %s (major=%i,minor=%i)" % (label,
fileName,
major,
minor))
os.system("mknod %s %s %i %i" % (fileInChroot,
deviceType,
major,
minor))
missingFiles.append(fileName)
elif stat.S_ISBLK(statMode):
debug(" Creating block device : %s -> %s" % (fileName,fileInChroot))
os.system("cp -a %s %s" % (fileName,fileInChroot))
missingFiles.append(fileName)
elif fileName in config.userFiles:
missingFiles.append(fileName)
addPasswdFile(fileName,"users")
elif fileName in config.groupFiles:
missingFiles.append(fileName)
addPasswdFile(fileName,"groups")
else:
debug(" Copying %s -> %s" % (fileName,fileInChroot))
shutil.copyfile(fileName,fileInChroot)
missingFiles.append(fileName)
copyStat(fileName,fileInChroot)
if os.path.isfile(fileName):
checkRequirements(fileName)
return missingFiles
def fileReadlines(fileName):
f=open(fileName,"r")
lines=f.readlines()
f.close()
return lines
def makeNonBlocking(fd):
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
try:
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
except AttributeError:
import FCNTL
fcntl.fcntl(fd, fcntl.F_SETFL, fl | FCNTL.FNDELAY)
def execute(command):
debug(" Executing : %s" % command)
child=popen2.Popen3(command,1)
child.tochild.close()
files=(child.fromchild,child.childerr)
fds=[files[0].fileno(),files[1].fileno()]
for fd in fds:
makeNonBlocking(fd)
datas=[[],[]]
feedbackStreams=(sys.stdout,sys.stderr)
feedbackQueues=["",""]
finished=[0,0]
while 1:
ready=select.select(fds,[],[])
for i in (0,1):
if fds[i] in ready[0]:
chunk=files[i].read()
if chunk=="":
finished[i]=1
feedbackQueues[i]+=chunk
for i in (0,1):
while "\n" in feedbackQueues[i]:
pos=feedbackQueues[i].find("\n")
line=feedbackQueues[i][:pos+1]
datas[i].append(line[:-1])
feedbackQueues[i]=feedbackQueues[i][pos+1:]
if finished==[1,1]:
break
select.select([],[],[],.05)
errCode=child.wait()
if errCode:
debug(" WARNING: exit code %i" % errCode)
return datas[0]
def commandPids(processNames):
pids=[]
for psLine in execute(config.psCommand)[1:]:
processCommandLine=string.split(psLine)[config.psColumns[1]-1]
name=string.split(string.split(processCommandLine)[0],"/")[-1]
if name in processNames:
pid=int(string.split(psLine)[config.psColumns[0]-1])
if not(pid in doNotKillPids):
pids.append(int(pid))
return pids
def fileType(file):
return string.strip(string.split(execute("file %s" % file)[0],":")[1])
def checkRequirements(file):
moveIndent(1)
ft=fileType(file)
if string.find(ft,"script")!=-1:
f=open(file,"r")
head=f.readline()
f.close()
if head[:2]=="#!":
script=string.split(head[2:])[0]
debug("%s is a script run with the interpreter %s" % (file,script))
addFileToJail(script)
else:
sharedStrings=("shared object","dynamically linked")
shared=None
for sharedString in sharedStrings:
if string.find(ft,sharedString)!=-1:
shared=sharedString
break
if shared:
moveIndent(1)
debug("%s, checking the required libraries with ldd" % shared)
ldd_lines=map(string.strip,execute("ldd %s" % file))
ignoreStrings=["not a dynamic executable",
"statically linked"]
for ignoreString in ignoreStrings:
if ldd_lines[0]==ignoreString:
debug(ignoreString)
moveIndent(-2)
return
for line in ldd_lines:
if not(line):
continue
if string.find(line,"=>")==-1:
continue
lib=string.strip(string.split(string.split(line,"=>")[1],"(")[0])
addFileToJail(lib)
moveIndent(-1)
moveIndent(-1)
def addPackageToJail(package):
global installedPackages
if (package in installedPackages):
return
installedPackages.append(package)
if (package in config.blockDepends):
debug("The package %s is in Depends but won't be installed")
return
debug("Installing the package %s" % package)
moveIndent(1)
debug("Copying the files from the dpkg information")
moveIndent(1)
files=dpkgInfoFiles(package)
for file in files:
addFileToJail(file)
moveIndent(-1)
if config.useDepends:
debug("Checking Depends")
moveIndent(1)
depends=debianGetDepends(package)
for depend in depends:
addPackageToJail(depend)
moveIndent(-1)
moveIndent(-1)
def addMissingFilesFromStraceLines(lines):
missingFiles=[]
for n in range(len(lines)):
line=lines[n]
if n==len(lines)-1:
nextLine=None
else:
nextLine=lines[n+1]
line=string.strip(line)
missingFile=matchPatterns(config.stracePatterns,line,nextLine)
if missingFile and not (missingFile in missingFiles):
if missingFile==config.chroot:
continue
if string.split(missingFile,"/")[-1]=="chroot":
continue
try:
statInfos=os.stat(missingFile)
fileExists=1
except OSError:
fileExists=0
if fileExists:
moveIndent(1)
if addFileToJail(missingFile):
missingFiles.append(missingFile)
moveIndent(-1)
continue
missingFile=matchPatterns(config.straceCreatePatterns,line,nextLine)
if missingFile and not (missingFile in missingFiles):
debug("Failed attempt at creating the file %s" % missingFile)
missingFile=removeTrailingSlashes(missingFile)
dir=string.join(string.split(missingFile,"/")[:-1],"/")
if os.path.isdir(dir) and not(os.path.isdir(config.chroot+dir)):
moveIndent(1)
if addFileToJail(dir):
missingFiles.append(dir)
moveIndent(-1)
continue
missingFile=matchPatterns(config.straceSocketPatterns,line,nextLine)
if missingFile and not(installedFiles.has_key(missingFile)):
try:
statMode=os.stat(missingFile)[stat.ST_MODE]
except:
exists="doesn't exist"
else:
if stat.S_ISSOCK(statMode):
exists="exists"
else:
exists="exists but is not a socket ??"
debug("Failed to connect to socket %s, file %s" % (missingFile,exists))
installedFiles[missingFile]=-1
warnings.append(("socket",(missingFile,exists)))
return missingFiles
def removeTrailingSlashes(s):
while s[-1]=="/":
s=s[:-1]
return s
def sleep(delay):
if delay:
if delay>=2.0:
s="s"
else:
s=""
debug("Sleeping for %.2f second%s" % (delay,s))
time.sleep(delay)
def addMissingFilesFromProcess(items,testCommandsOutsideJail=[]):
straceTempFileName=tempfile.mktemp("trace")
straceTempFile=open(straceTempFileName,"w")
straceTempFile.close()
if not(type(items) in (types.ListType,types.TupleType)):
items=[items]
for item in items:
if type(item) in (types.IntType,types.LongType):
command=config.straceCommandPid
command=string.replace(command,"%pid",str(item))
s="Tracing process %i" % item
elif type(item)==types.StringType:
command=config.straceCommand
command=string.replace(command,"%command",item)
s="Tracing command %s" % item
else:
raise ValueError
command=string.replace(command,"%file",straceTempFileName)
debug(s)
os.system("%s &" % command)
if type(item)==types.StringType:
sleep(config.sleepAfterStartCommand)
else:
sleep(config.sleepAfterStraceAttachPid)
if testCommandsOutsideJail:
if not(type(testCommandsOutsideJail in (types.ListType,types.TupleType))):
testCommandsOutsideJail=[testCommandsOutsideJail]
for testCommand in testCommandsOutsideJail:
if testCommand=="interactive":
raw_input("Interactive tests: press Enter when complete")
else:
debug("Executing test command '%s' ... " % testCommand)
returnCode=os.system("%s >/dev/null 2>/dev/null" % testCommand)
debug(" return code is %i" % returnCode)
sleep(config.sleepAfterTest)
debug("Stopping tracing ... ",endLine=0)
lines=map(string.strip,execute(config.straceCommandStop))
out=[]
for line in lines:
if line:
out.append(line)
debug(string.join(out," "))
if config.straceCommandView:
command=string.replace(config.straceCommandView,"%file",straceTempFileName)
lines=execute(command)
else:
straceTempFile=open(straceTempFileName,"r")
lines=straceTempFile.readlines()
straceTempFile.close()
if config.keepStraceOutputs:
whatWillHappenToThisPoorTraceFile=" (available in %s)" % straceTempFileName
else:
whatWillHappenToThisPoorTraceFile=""
os.unlink(straceTempFileName)
debug("Looking for missing files in the trace file%s" % whatWillHappenToThisPoorTraceFile)
missingFiles=addMissingFilesFromStraceLines(lines)
return missingFiles
def killall(processNames):
if type(processNames)==types.StringType:
processNames=[processNames]
if len(processNames)==1:
s="processes named '%s'" % processNames[0]
else:
s="processes matching %s" % str(processNames)
if processNames:
debug("Killing %s ... : " % s,endLine=0)
pids=commandPids(processNames)
if len(pids):
debug(string.join(map(str,pids),","))
for pid in pids:
out=execute("kill -9 %i 2>&1" % pid)
sleep(config.sleepAfterKillall)
else:
debug("no process found")
def debianIsPackageInstalled(package):
dpkgOut=execute("dpkg -l %s" %package)
if not(dpkgOut):
return 0
lastLine=dpkgOut[-1]
return (lastLine[0]=="i")
def debianGetDepends(package):
depends=[]
for line in execute("dpkg -p %s" % package):
if startslike(line,"Depends: "):
packs=string.split(string.replace(line[8:],"|",","),",")
for pack in packs:
pack=string.split(string.strip(pack)," ")[0]
if debianIsPackageInstalled(pack):
depends.append(pack)
return depends
def tryExecute(commands):
if type(commands)==types.StringType:
commands=[commands]
for command in commands:
debug("Executing command '%s' (pwd=%s)" % (command,config.tempDir),endLine=0)
os.chdir(config.tempDir)
returnCode=os.system("%s >/dev/null 2>/dev/null &" % command)
debug(" return code is %i " % returnCode)
def checkConfig():
if os.geteuid()!=0:
abort("Effective user it is not 0, this command must be run as root")
if not(config.chroot):
abort("You didn't defined the variable chroot")
config.chroot(removeTrailingSlashes(config.chroot))
if config.chroot[0]!="/":
abort("The variable chroot must be an absolute path")
if not(config.testCommandsInsideJail) and ("interactive" in config.testCommandsOutsideJail):
abort("Cannot have 'interactive' in testCommandsOutsideJail if testCommandsInsideJail is not defined")
def runTests(tests,chrootCommands=None):
finished=0
i=1
moveIndent(1)
while not(finished):
debug("Execution #%i" % i)
moveIndent(1)
if chrootCommands:
sleep(config.sleepAfterStartCommand)
pids=commandPids(config.processNames)
if pids:
missingFiles=addMissingFilesFromProcess(pids,tests)
else:
moveIndent(-1)
return 0
else:
missingFiles=addMissingFilesFromProcess(tests)
if not(missingFiles):
debug("No missing file found")
finished=1
elif i>config.maxExecutions:
debug("Still missing files after %i tries" % config.maxExecutions)
finished=1
i=i+1
if chrootCommands:
killall(config.processNames)
tryExecute(chrootCommands)
moveIndent(-1)
killall(config.processNames)
moveIndent(-1)
return 1
def displayWarnings():
for warning in warnings:
(warningType,warningDetail)=warning
if warningType=="/proc":
s=["You'll need the filesystem procfs mounted as %s%s" % (config.chroot,config.procPath),
"It's mounted now, you can mount it again for example before starting the daemon with :",
"mount -t proc proc %s%s" % (config.chroot,config.procPath)]
elif warningType=="socket":
(socketFile,exists)=warningDetail
if socketFile=="/dev/log":
s=["Attempt to access /dev/log, a socket used by syslogd. Some suggestions:",
"- if your version of syslogd supports it you can tell it to listen to the",
" additional socket %s/dev/log, and put it in the configuration directive 'preserve'" % config.chroot,
" maybe start syslog with the option -a %s/dev/log" % config.chroot,
"- use a syslog proxy like holelogd",
"- configure the daemon to log into files instead through syslog"]
else:
s=["Attempt to access the socket file %s, which %s outside the jail" % (socketFile,exists),
"if needed it must be created inside the jail as %s%s""" % (config.chroot,socketFile)]
s=s+["If you create the socket, put it in the configuration option 'preserve'",
"so it won't be deleted when you launch this script again"]
if exists!="exists":
s=s+["As this socket doesn't exist outside the jail, you can probably ignore this warning safely."]
else:
abort("No method to display the warning '%s'" % warningType)
sys.stdout.write("\nWARNING:\n%s\n" % string.join(map(lambda l:" %s" % l,s),"\n"))
def initRunningPids():
debug("Initializing list of running processes")
for psLine in execute(config.psCommand)[1:]:
pid=int(string.split(psLine)[config.psColumns[0]-1])
doNotKillPids.append(pid)
def makeChroot():
global tmpOut
debug("Chroot directory is %s" % config.chroot)
# In the strace output, the command attempt to access
# the directory where this script was started outside
# the jail
os.chdir("/")
# See what processes are running so they don't get killed later
initRunningPids()
# Create temp strace dir
if not(os.path.isdir(config.tempDir)):
debug("Creating temp dir %s" % config.tempDir)
os.mkdir(config.tempDir)
tempfile.tempdir=config.tempDir
tmpOut=tempfile.mktemp("out")
killall(config.processNames)
if config.cleanJailFirst:
cleanJail()
# === Add packages
for package in config.packages:
addPackageToJail(package)
# === Copy specific paths
for globExpression in config.forceCopy:
debug("Adding files matching '%s'" % globExpression)
moveIndent(1)
for file in glob.glob(globExpression):
addFileToJail(file)
moveIndent(-1)
chrootCommands=[]
if config.testCommandsInsideJail:
for command in config.testCommandsInsideJail:
chrootCommands.append("chroot %s %s" % (config.chroot,command))
# === Execute main command until there is no missing file
if chrootCommands:
finished=0
i=1
debug("Running strace on commands from inside jail")
moveIndent(1)
killall(config.processNames)
while not(finished):
debug("Execution #%i" % i)
moveIndent(1)
missingFiles=addMissingFilesFromProcess(chrootCommands)
i=i+1
if not(missingFiles):
debug("No missing file found")
finished=1
if i>config.maxExecutions:
debug("Still missing files after %i tries" % config.maxExecutions)
finished=1
killall(config.processNames)
moveIndent(-1)
moveIndent(-1)
# === Try it
if chrootCommands:
tryExecute(chrootCommands)
# === Make tests
continueTests=1
while continueTests:
if config.testCommandsOutsideJail:
debug("Running tests from outside the jail")
if not(runTests(config.testCommandsOutsideJail,chrootCommands)):
debug("No running process found, cannot run tests")
if config.promptForInteractiveTests:
debug("Running interactive tests from outside the jail")
if chrootCommands:
tryExecute(chrootCommands)
if not(runTests(["interactive"],chrootCommands)):
debug("No running process found, cannot run tests")
continueTests=0
if config.promptForSomeMoreTests:
prompt="Paused to give you a chance to fix some problems, do you want to run tests again (y/n) ? "
while prompt:
yesNo=string.lower(raw_input(prompt))
if yesNo=="y":
continueTests=1
prompt=None
elif yesNo=="n":
continueTests=0
prompt=None
else:
prompt="Please reply with 'y' or 'n': "
if chrootCommands:
tryExecute(chrootCommands)
sleep(config.sleepAfterStartCommand)
killall(config.processNames)
# /etc/ld.so.cache
if needLdCache:
debug("Generating %s" % config.pathToLdSoCache)
moveIndent(1)
# /etc/ld.so.conf may contains path which are invalid in chroot, ldconfig ignores them
addFileToJail(config.pathToLdSoConf)
newLdConfig="%s%s" % (config.chroot,config.pathToLdConfig)
ldconfigAlreadyHere=os.path.isfile(newLdConfig)
newFiles=addFileToJail(config.pathToLdConfig)
tryExecute("chroot %s %s" % (config.chroot,config.pathToLdConfig))
debug("Removing ldconfig from jail")
moveIndent(1)
newFiles.reverse()
for file in newFiles:
file="%s%s" % (config.chroot,file)
if os.path.islink(file) or os.path.isfile(file):
debug("Removing file %s" % file)
os.unlink(file)
elif os.path.isdir(file):
debug("Removing dir %s" % file)
os.rmdir(file)
else:
raise ValueError
moveIndent(-2)
displayWarnings()
def loadConfig(file):
debug("Loading configuration file %s" % file)
moveIndent(1)
try:
assert os.path.isfile(file)
fp=open(file,"r")
except:
abort("Cannot open configuration file '%s'" % file)
if ("/" in configFile):
dir=string.join(string.split(file,"/")[:-1],"/")
if dir[0]!="/":
dir="%s/%s" % (os.getcwd,dir)
sys.path.insert(0,dir)
try:
newConfig=imp.load_module("newConfig%s" % file,fp,file,("","r",1))
except:
if fp:
fp.close()
sys.stderr.write("Cannot load configuration file '%s' as a python module\n" % file)
sys.stderr.write("Executing it with python which should display a syntax error:\n")
os.system("python %s" % file)
sys.exit(1)
# Remove byte-compile file
bcFile="%sc" % file
if os.path.isfile(bcFile):
os.unlink(bcFile)
if fp:
fp.close()
for key in newConfig.__dict__.keys():
if key[:2]=="__":
continue
if not(config.__dict__.has_key(key)):
abort("Invalid configuration key '%s'" % key)
s=newConfig.__dict__[key]
if type(s)==types.StringType:
s="'%s'" % s
else:
s="%s" % s
debug("Defining %s = %s" % (key,s))
config.__dict__[key]=newConfig.__dict__[key]
moveIndent(-1)
if __name__=="__main__":
config=configClass()
try:
configFile=sys.argv[1]
except IndexError:
abort("Usage: %s configFile" % sys.argv[0])
if os.path.isfile(config.etcFile):
loadConfig(config.etcFile)
loadConfig(configFile)
checkConfig()
makeChroot()
sys.exit(0)
makejail-0.0.5/manpage.sgml.template 0100644 0000000 0000000 00000006014 07437056461 016113 0 ustar root root manpage.1'. You may view
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
less'. A typical entry in a Makefile or Makefile.am is:
manpage.1: manpage.sgml
docbook-to-man $< > $@
-->
Tesio">
Alain">
__SYSTEMDATE__">
8">
alain@onesite.org">
MAKEJAIL">
Debian GNU/Linux">
GNU">
]>
&dhemail;
&dhfirstname;
&dhsurname;
2002&dhusername;
&dhdate;
&dhucpackage;
&dhsection;
&dhpackage;Helps creating and maintaining a chroot jail&dhpackage;configuration_file
__STARTLOOP(ITEMS)__
__IF(TWOLEVELS)__
__H1__
__STARTLOOP(H1PARAS)__
__H1PARA__
__ENDLOOP(H1PARAS)__
__STARTLOOP(SUBITEMS)__
__STARTLOOP(H2PARAS)__
__H2PARA__
__ENDLOOP(H2PARAS)__
__ENDLOOP(SUBITEMS)__
__ELSE(TWOLEVELS)__
__H1__
__STARTLOOP(H1PARAS)__
__H1PARA__
__ENDLOOP(H1PARAS)__
__ENDIF(TWOLEVELS)__
__ENDLOOP(ITEMS)__
AUTHORThis manual page was written by &dhusername;, alain@onesite.orgThis software comes with no warranty.REPORTING BUGSReport bugs to makejail@floc.net
makejail-0.0.5/examples/ 0040755 0000000 0000000 00000000000 07561105120 013606 5 ustar root root makejail-0.0.5/examples/apache.py 0100644 0000000 0000000 00000002573 07555605117 015423 0 ustar root root chroot="/var/chroot/apache"
testCommandsInsideJail=["/usr/sbin/apachectl start"]
processNames=["apache"]
# Eventually append here the commands which access some services
# such as cgi or php scripts, database access, ...
testCommandsOutsideJail=["wget -r --spider http://localhost/",
"lynx --source https://localhost/"]
preserve=["/var/www",
"/var/log/apache",
"/dev/log"]
users=["www-data"]
groups=["www-data"]
# launch makejail
#
# copy the documents and the logs to the jail
# cp -Rp /var/www /var/chroot/apache/var
# cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache
#
# configure syslog to also listen to the socket /var/chroot/apache/dev/log, restart sysklogd
#
# In the startup script /etc/init.d/apache, just change the paths
# of variables used from outside the jail:
# APACHECTL="chroot /var/chroot/apache /usr/sbin/apachectl" (remove the line which tests -f $APACHECTL)
# PIDFILE=/var/chroot/apache/var/run/$NAME.pid
# CONF=/var/chroot/apache/etc/apache/httpd.conf
#
# handle /proc in the script (mount when it starts, unmount when it stops):
# chroot /var/chroot/apache /bin/mount /proc
#
# apache can fail starting though apachectl doesn't fail, see error.log in the chroot
#
# tested successfully with apache 1.3.22 on Debian woody
# (also with php4, mysql and a search engine)
# OpenBSD
#processNames=["httpd"]
#users=["nobody"]
#groups=["nogroup","www"]
makejail-0.0.5/examples/bind.py 0100644 0000000 0000000 00000001624 07434253663 015113 0 ustar root root chroot="/var/chroot/bind"
forceCopy=["/etc/bind/*","/var/cache/bind"]
preserve=["/var/cache/bind"]
testCommandsInsideJail=["start-stop-daemon --start --quiet --pidfile /var/run/named.pid --exec /usr/sbin/named"]
processNames=["named"]
testCommandsOutsideJail=["dig @127.0.0.1 yahoo.com",
"dig @127.0.0.1 -x 127.0.0.1",
"dig @127.0.0.1 -x 198.186.203.20",
"ping -c 1 www.google.com"]
# start makejail with this configuration file, it won't be able to start the daemon,
# it should display a warning about /dev/log and /proc
#
# In the startup script:
# replace "start-stop-daemon ..." with "chroot /var/chroot/bind start-stop-daemon ..."
#
# handle /proc (mount when it starts, unmount when it stops):
# chroot /var/chroot/apache /bin/mount /proc
#
# configure syslog to also listen to the socket /var/chroot/bind/dev/log, restart sysklogd
# tested successfully with bind 9.2.0 on Debian woody
makejail-0.0.5/examples/global.OpenBSD 0100644 0000000 0000000 00000001234 07437056464 016241 0 ustar root root # Copy this file into /etc/makejail to set defaults
# configuration options specific to OpenBSD (tested on 3.0)
pathToLdSoConf=None
pathToLdSoCache="/var/run/ld.so.hints"
psCommand="ps -ax"
psColumns=[1,5]
straceCommand="ktrace -a -f %file -i %command"
straceCommandPid="ktrace -p %pid -a -f %file -i"
straceCommandStop="ktrace -C"
straceCommandView="kdump -f %file"
stracePatterns=[['.* NAMI +"([^"]*)".*',
'.* RET *(exec.*|open|access|utimes|chown|.*stat|readlink|chdir) -1 errno 2.*']]
straceCreatePatterns=[['.* NAMI +"([^"]*)".*',
'.* RET *bind -1 errno 2.*']]
straceSocketPatterns=[['.* NAMI +"([^"]*)".*',
'.* RET *connect -1 errno 2.*']]
makejail-0.0.5/examples/mldonkey.py 0100644 0000000 0000000 00000004350 07560656042 016016 0 ustar root root # Tested on GNU/Linux Debian sid
# mldonkey from cvs compiled and run in /home/alain/mldonkey
# Set personals string values in this file and the wrapper code.
# First you have to create a wrapper to execute mldonkey as non-root
# See for example mldonkey_wrapper. at the bottom of this file, you
# can compile it with "gcc -o mldonkey_wrapper mldonkey_wrapper.c"
# It's better than su and sudo which are suid programs
#
# Make sure you can run the wrapper as root outside the jail and that everything
# works fine
#
# Run makejail using this configuration file
#
# Then you can start mldonkey with this command as root :
# chroot /var/chroot/mldonkey /home/alain/mldonkey/mldonkey_wrapper
#
# If you system uses /proc and if there is a comment about it at the
# end of makejail output you must create it (for example at each system startup)
chroot="/var/chroot/mldonkey"
testCommandsInsideJail=["/home/alain/mldonkey/mldonkey_wrapper"]
processNames=["mldonkey"]
preserve=["/dev/log",
"/home/alain/mldonkey/*.ini"]
forceCopy=["/home/alain/mldonkey/*.ini"]
testCommandsOutsideJail=["su - alain -c /home/alain/mldonkey/mldonkey_gui"]
# The users which should be allowed to run mldonkey
# Make sure they can execute /usr/local/mldonkey before building the jail
users=["alain"]
groups=["alain"]
keepStraceOutputs=1
# Below is the code of mldonkey_wrapper.c
#
##include
##include
##include
#
#main (ac,av)
#{
# int status;
# struct passwd *pnew;
# char **newav;
#
# pnew=getpwnam("alain");
#
# status=setregid(pnew->pw_gid,pnew->pw_gid);
# if (status != 0)
# {
# printf("wrapper.c: error in setgeuid, errno = %d\n",errno);
# return;
# }
#
# status=setreuid(pnew->pw_uid,pnew->pw_uid);
# if (status != 0)
# {
# printf("wrapper.c: error in setreuid, errno = %d\n",errno);
# return;
# }
#
# printf("Root privileged dropped successfully\n");
#
# chdir("/home/alain/mldonkey");
# printf("Changed working directory to /home/alain\n");
#
# newav=(char**)malloc(6);
# newav[0]="mldonkey";
# newav[1]="-ask_for_gui";
# newav[2]="false";
# newav[3]="-start_gui";
# newav[4]="false";
# newav[5]=0;
#
# execv("/home/alain/mldonkey/mldonkey",newav);
#
# free(newav);
#
#}
makejail-0.0.5/examples/mysqld.py 0100644 0000000 0000000 00000001333 07437056464 015510 0 ustar root root chroot="/var/chroot/mysqld"
testCommandsInsideJail=["safe_mysqld"]
sleepAfterStartCommand=5
processNames=["mysqld"]
testCommandsOutsideJail=["mysql --user=root --socket='/var/chroot/mysqld/var/run/mysqld/mysqld.sock' --exec='show tables' mysql"]
preserve=["/var/lib/mysql",
"/var/log/mysql"]
users=["mysql"]
groups=["mysql"]
# Steps:
#
# Copy the directories in the "preserve" directive to the jail
# with exactly the same ownerships and permissions (cp -RpP)
# Run makejail
# To connect from local clients, keep in mind that the socket
# is now in the jail
# OpenBSD
# preserve=["/var/mysql"]
# testCommandsOutsideJail=["mysql --user=root --socket='/var/chroot/mysqld/var/run/mysql/mysql.sock' --exec='show tables' mysql"]
makejail-0.0.5/examples/ntpd.py 0100644 0000000 0000000 00000000264 07434253663 015143 0 ustar root root chroot="/var/chroot/ntpd"
testCommandsInsideJail=["start-stop-daemon --start --quiet --exec /usr/sbin/ntpd"]
processNames=["ntpd"]
testCommandsOutsideJail=["ntpdate -q 127.0.0.1"]
makejail-0.0.5/examples/postgresql.py 0100644 0000000 0000000 00000002431 07437056464 016402 0 ustar root root chroot="/var/chroot/postgresql"
testCommandsInsideJail=["/etc/init.d/postgresql start"]
processNames=["postmaster"]
testCommandsOutsideJail=["su - postgres -c \"psql -c '\z' test\""]
users=["postgres","root"]
groups=["postgres","root"]
preserve=["/dev/log",
"/var/lib/postgres"]
cleanJailFirst=0
# The script /etc/init.d/postgresql does some complex things so I've been lazy and
# chrooted it too
#
# start makejail with this configuration file, it won't be able to start the daemon,
# it should display a warning about /dev/log and /proc
#
# overwrite the data files into the jail: cp -a /var/lib/postgres /var/chroot/postgresql/var/lib
#
# configure syslog to also listen to the socket /var/chroot/postgresql/dev/log, restart sysklogd
#
# start makejail again
#
# The deamon now starts fine with chroot /var/chroot/postgresql /etc/init.d/postgresql start
#
# However you can't connect from a client as it doesn't find the socket /var/run/postgresql/.s.PGSQL.5432
# I don't know how to tell psql to use the socket in the jail or TCPIP but there must be a way
#
# create a new startup script /etc/init.d/postgresql_chroot (outside the jail):
# #!/bin/sh
# chroot /var/chroot/postgresql /bin/mount /proc $1
# chroot /var/chroot/postgresql /etc/init.d/postgresql $1
# tested with postgresql 7.1
makejail-0.0.5/examples/sshd.py 0100644 0000000 0000000 00000004305 07555121451 015130 0 ustar root root # Makejail configuration file for sshd
#
# Created by Javier Fernandez-sanguino Peņa
# Thu, 29 Aug 2002 23:44:51 +0200
#
chroot="/var/chroot/sshd"
forceCopy=["/etc/ssh/ssh_host*","/etc/ssh/sshd*","/etc/ssh/moduli",
"/etc/pam.conf","/etc/security/*","/etc/pam.d/ssh","/etc/pam.d/other",
"/etc/hosts","/etc/nsswitch.conf",
"/var/run/sshd","/lib/security/*",
"/etc/shells", "/etc/nologin","/etc/environment","/etc/motd",
"/etc/shadow","/etc/hosts*",
"/bin/*sh", "/lib/libnss*",
"/dev/pt*","/dev/ttyp[0-9]*"]
# Remove this if you want to make configuration changes *outside* of the
# chroot environment
# preserve=["/etc/","/home/","/dev/"]
# otherwise just do this:
preserve=["/dev/","/home"]
# Besides the sshd user (needed after 3.4p1) any user which is going to
# be granted access to the ssh daemon should be added to 'users' and
# 'groups'.
userFiles=["/etc/passwd","/etc/shadow"]
groupFiles=["/etc/group","/etc/gshadow"]
users=["sshd"]
groups=["sshd"]
testCommandsInsideJail=["start-stop-daemon --start --quiet --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd"]
testCommandsOutsideJail=["ssh localhost"]
processNames=["sshd"]
# Changes to do to jail sshd:
# 1.- start makejail with this configuration file
# it might not be able to start the daemon since the daemon tries to
# access /dev/log (handled by syslogd)
#
# 2.- In init.d's startup script (/etc/init.d/sshd):
# replace "start-stop-daemon ..." with "chroot /var/chroot/sshd start-stop-daemon ..."
#
# 3.- configure syslog to also listen to the socket /var/chroot/sshd/dev/log,
# restart sysklogd.
# (for Debian) This can be done by changing the SYSLOGD option in
# /etc/init.d/syslogd to
# SYSLOGD="-p /dev/log -p /var/chroot/sshd/dev/log"
#
# 4.- Create the user directories under /home and copy their files there
#
# 5.- Users will not be able to a single thing in the restricted environment
# besides running their shell. You will have to add some utilities
# to the chrooted environement. Try adding this to the configuration
# packages=["fileutils"]
# You can add any other Debian packages you want users to have access
# to.
#
# WARNING: this configuration file has only been slightly tested. not yet thoroughly tested yet.
makejail-0.0.5/manpage.sgml 0100644 0000000 0000000 00000057373 07561105120 014300 0 ustar root root manpage.1'. You may view
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
less'. A typical entry in a Makefile or Makefile.am is:
manpage.1: manpage.sgml
docbook-to-man $< > $@
-->
Tesio">
Alain">
November 02, 2002">
8">
alain@onesite.org">
MAKEJAIL">
Debian GNU/Linux">
GNU">
]>
&dhemail;
&dhfirstname;
&dhsurname;
2002&dhusername;
&dhdate;
&dhucpackage;
&dhsection;
&dhpackage;Helps creating and maintaining a chroot jail&dhpackage;configuration_fileOverviewThe objective of makejail is to help an administrator creating and updating a chroot jail with short configuration files.Makejails attempts to guess and install into the jail all files required by the daemon.You have to understand how it works to configure it efficiently.Detailed mechanismThe list of these files is built from several sources:- the main method is to trace what files the daemon attempts to access, add them into the jail and restart again until no further file is found.- a list of files manually given in the configuration file.- the files which belongs to a package and eventually the packages it requires.When a file is added into the jail:- the shared librairies it needs (given by ldd) are added too.- upper directories are created if needed.- if the file is a symbolic link, the target is added too.- all the checks to determine what files a file needs are recursive.- all files are copied maintaining the originals' ownerships and permissions.Some files are handled with a special method:- when the file is below /proc, the procfs filesystem is mounted inside the jail.- when the file is a socket, it's not copied.- when the file is the shared library cache, it's not copied, ldconfig is run at the end.The steps of makejail are:- eventually remove the files in the jail first.- if you specified some packages, add all the files which belongs to them.- if you specified some paths to include, add the files matching these patterns.- start the daemon inside the jail, and trace it with strace, add the files it attempts to open which exist outside the jail, kill it and start again until no more file is found.- start the daemon inside the jail, and trace it while running some test processes outside the jail, see with strace what files the daemon attempts to open.Configuration filesThe file must be written in a correct python syntax. The good news is that the syntax is simple, and you can eventually write some python code to define the syntax.Some default directives may be defined in /etc/makejail, the configuration file given on the command line has predecence.All paths you use in the configuration file must be absolute.Configuration directives - BasicsDefaults won't work, you must define specific values for these directives.The path to the chroot. The directory must exist and have correct permissions and ownerships.Format: "/path/to/jail"Default: NoneThe commands used to start the daemon, a good starting point may be the command used in the startup script in /etc/init.dFormat: ["command1","command2"]Default: []The name of the runnning processes after the daemon has been started.Format: ["process1","process2"]Default: []Configuration directives - TestsAfter the daemon itself has been chrooted successfully, some commands can be executed from outside the jail to test the daemon.The test commands which should be executed.Format: ["command1","command2"]Default: []Whether makejail should pause so you can stress the daemon yourself.Use only if makejail is run interactively, and don't redirect its outputs.Format: 1 (prompt) or 0 (don't prompt)Default: 0Whether makejail should loop while running tests until you tell it it's over.Use only if makejail is run interactively, and don't redirect its outputs.Format: 1 (prompt) or 0 (don't prompt)Default: 0Maximum number of times a command is executed before aborting.Format: integerDefault: 100Configuration directives - Copying filesDo not copy the files matching these patterns according to the rules used by the Unix shell.No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.Format: ["path1","path2"]Default: ["/usr/share/doc","/usr/share/info","/usr/share/man","/etc/fstab","/etc/mtab"]When initializing the jail, copy the files matching these patterns according to the rules used by the Unix shell.No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.Format: ["path1","path2"]Default: []Whether makejail should remove files in jail first.Format: 0 to do nothing or 1 to remove files from the jail.Default: 1Useful only if cleanJailFirst=1, makejail won't remove files or directories if their path begins with one of the strings in this list.When updating a jail, you should for example put the locations of log files here.Format: ["path1","path2"]Default: []Useful only if cleanJailFirst=1, makejail aborts if it's about to remove more than this number of files from the jail.This may prevent makejail from erasing unwanted files if you wrote chroot="/usr" or if you have mounted a partition in the jail.Format: integerDefault: 500Makejail will filter the files listed in the directive userFiles and copy only lines matching these users, which means lines starting with "user:"You can use ["*"] to disable filtering and copy the whole file.Format: ["user1","user2"]Default: []Makejail will filter the files listed in the directive groupFiles and copy only lines matching these groups, which means lines starting with "group:"You can use ["*"] to disable filtering and copy the whole file.Format: ["group1","group2"]Default: []Configuration directives - TimingThese times are in seconds, the values are the duration of sleeps at various stages of makejail.Duration of sleep after starting the daemon, after this delay makejail considers it's in a correctly running state.Format: floating numberDefault: 2Duration of sleep after a test command has been run, after this delay makejail considers the daemon has finished its tasks related to this command.Format: floating numberDefault: 2Duration of sleep after killing the daemon processes.Format: floating numberDefault: 1Duration of sleep after attaching strace to a running process id.Format: floating numberDefault: 0.2Configuration directives - Debian specificI initially thought with starting with the package description, but this method usually installs a bunch of files you won't need.The name of the packages. It will copy the files which belongs to the package according to the file /var/lib/dpkg/info/$package.list.Format: ["package1","package2"]Default: []If you want to also install other packages required by the the initial list you specified.It looks at the line "Depends:" in the output of `dpkg -p $package`.Format: 1 (use depends) or 0 (don't use depends)Default: 0Useful only if useDepends=1, it prevents the installation of these packages even if dpkg says they are required.Format: ["package1","package2"]Default: []Path to the dpkg $package.list files, "%s" will be replaced by the name of the package.Format: "/path/to/info/files/%s.list"Default: "/var/lib/dpkg/info/%s.list"Configuration directives - Paths so specific files and commandsPath to the executable ldconfig, used to generate the shared librairies cache. ldconfig is executed in the jail to regenerate this cache.Format: "/path/to/ldconfig"Default: "/sbin/ldconfig"The path to the configuration files used by ldconfig, which says which directories should be scanned searching for shared librairies.Set this to None if your system doesn't use such a file.Format: "/path/to/ld.so.conf"Default: "/etc/ld.so.conf"The path to the shared librairies cache generated by ldconfig.Format: "/path/to/ld.so.cache"Default: "/etc/ld.so.cache"The path to the procfs filesystem.Format: "/path/to/proc"Default: "/proc"List of the files whose contents should be filtered, to keep only the users listed in the directive "users".Format: ["file1","file2]Default: ["/etc/passwd","/etc/shadow"]List of the files whose contents should be filtered, to keep only the groups listed in the directive "groups".Format: ["file1","file2]Default:["/etc/group","/etc/gshadow"]The temporary directory where makejail can write temporary files.There may be a lot of files generated here if keepStraceOutputs=1.Format: "/temp/directory"Default: "/tmp/makejail_logs"The command line used to list running processes.The output must include the pid and the name of the process.Format: "ps [options]"Default: "ps -e"In which columns of the output of psCommand are the ids and the name of the processes.Spaces separate the columns, the first column is numbered 1.Format: (columnPid,columnProcessName)Default: [1,4]Configuration directives - Commands to run to trace processesHere you can configure the commands which must be run to trace processes. These are called strace though you can use another program, like ktrace on OpenBSD.The defaults should be suitable for systems using strace. "-f" means strace should trace process children too. Though it's interested only in file accesses, it doesn't use "-e trace=file" because with this option it doesn't catch calls for "bind" and "connect" to sockets.String describing the strace command when executing a command line. "%command" will be replaced by the command to execute, and "%file" by the path to the temporary trace file.Format: "strace_command [options] %command > %file"Default: "strace -f %command >/dev/null 2>>%file"String describing the strace command when attaching itself to a running process. "%pid" will be replaced by the id of the process to trace, and "%file" by the path to the temporary trace file.Format: "strace_command [options] %pid > %file"Default: "strace -f -p %pid >/dev/null 2>>%file"Command to execute to stop the tracing.Format: "strace_stop_command"Default: "killall -9 strace"Set this to None if the trace output files can be read directly, or the command line to execute which prints the trace on stdout. "%file" will be replaced by the name of this file.Format: "strace_command_viewer [options] %file"Default: NoneWhether makejail should remove the outputs of strace from the directory tempDir.Format: 0 (to remove the files) or 1 (to keep them)Default: 0Configuration directives - Patterns in the trace outputsThese are three patterns which should match failed attempts to access a file in the traces.You must define a group (between parenthesis) which will be matched by the path of the file.The syntax of the regular expressions in python is detailed here: http://py-howto.sourceforge.net/regex/regex.htmlIf the match on a line means it is a failed attempt only if the next line matches another expression (typically a return code, no group needed), you can use an array of two strings instead of one string, the first string is the main expression, and the second one is the expression which must match the next line. See global.OpenBSD in the examples directory.Regular expressions to detect a failed attempt at accessing a file.If the file exists outside the jail makejail will copy it into the jail.Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]Default: ['.*\("([^"]*)",.*\) .* ENOENT .*']Regular expressions to detect a failed attempt at creating a file.If the directory where the file should be created exists outside the jail, it will create it inside the jail.Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]Default: ['.*\("([^"]*)",.*O_CREAT.*\) .* ENOENT .*','bind\(.* path="([^"]*)".* ENOENT .*']Regular expressions to detect a failed attempt at accessing a socket.makejail can't create the socket, it will just print a warning.Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]Default: ['connect\(.* path="([^"]*)".* ENOENT .*']AUTHORThis manual page was written by &dhusername;, alain@onesite.orgThis software comes with no warranty.REPORTING BUGSReport bugs to makejail@floc.net
makejail-0.0.5/makejail.8 0100644 0000000 0000000 00000036420 07561105120 013640 0 ustar root root .\" This -*- nroff -*- file has been generated from
.\" DocBook SGML with docbook-to-man on Debian GNU/Linux.
...\"
...\" transcript compatibility for postscript use.
...\"
...\" synopsis: .P!
...\"
.de P!
\\&.
.fl \" force out current output buffer
\\!%PB
\\!/showpage{}def
...\" the following is from Ken Flowers -- it prevents dictionary overflows
\\!/tempdict 200 dict def tempdict begin
.fl \" prolog
.sy cat \\$1\" bring in postscript file
...\" the following line matches the tempdict above
\\!end % tempdict %
\\!PE
\\!.
.sp \\$2u \" move below the image
..
.de pF
.ie \\*(f1 .ds f1 \\n(.f
.el .ie \\*(f2 .ds f2 \\n(.f
.el .ie \\*(f3 .ds f3 \\n(.f
.el .ie \\*(f4 .ds f4 \\n(.f
.el .tm ? font overflow
.ft \\$1
..
.de fP
.ie !\\*(f4 \{\
. ft \\*(f4
. ds f4\"
' br \}
.el .ie !\\*(f3 \{\
. ft \\*(f3
. ds f3\"
' br \}
.el .ie !\\*(f2 \{\
. ft \\*(f2
. ds f2\"
' br \}
.el .ie !\\*(f1 \{\
. ft \\*(f1
. ds f1\"
' br \}
.el .tm ? font underflow
..
.ds f1\"
.ds f2\"
.ds f3\"
.ds f4\"
'\" t
.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n
.TH "MAKEJAIL" "8"
.SH "NAME"
makejail \(em Helps creating and maintaining a chroot jail
.SH "SYNOPSIS"
.PP
\fBmakejail\fP [\fIconfiguration_file\fP]
.SH "Overview"
.PP
The objective of makejail is to help an administrator creating and updating a chroot jail with short configuration files.
.PP
Makejails attempts to guess and install into the jail all files required by the daemon.
.PP
You have to understand how it works to configure it efficiently.
.SH "Detailed mechanism"
.PP
The list of these files is built from several sources:
.PP
- the main method is to trace what files the daemon attempts to access, add them into the jail and restart again until no further file is found.
.PP
- a list of files manually given in the configuration file.
.PP
- the files which belongs to a package and eventually the packages it requires.
.PP
When a file is added into the jail:
.PP
- the shared librairies it needs (given by ldd) are added too.
.PP
- upper directories are created if needed.
.PP
- if the file is a symbolic link, the target is added too.
.PP
- all the checks to determine what files a file needs are recursive.
.PP
- all files are copied maintaining the originals' ownerships and permissions.
.PP
Some files are handled with a special method:
.PP
- when the file is below /proc, the procfs filesystem is mounted inside the jail.
.PP
- when the file is a socket, it's not copied.
.PP
- when the file is the shared library cache, it's not copied, ldconfig is run at the end.
.PP
The steps of makejail are:
.PP
- eventually remove the files in the jail first.
.PP
- if you specified some packages, add all the files which belongs to them.
.PP
- if you specified some paths to include, add the files matching these patterns.
.PP
- start the daemon inside the jail, and trace it with strace, add the files it attempts to open which exist outside the jail, kill it and start again until no more file is found.
.PP
- start the daemon inside the jail, and trace it while running some test processes outside the jail, see with strace what files the daemon attempts to open.
.SH "Configuration files"
.PP
The file must be written in a correct python syntax. The good news is that the syntax is simple, and you can eventually write some python code to define the syntax.
.PP
Some default directives may be defined in /etc/makejail, the configuration file given on the command line has predecence.
.PP
All paths you use in the configuration file must be absolute.
.SH "Configuration directives - Basics"
.PP
Defaults won't work, you must define specific values for these directives.
.IP "\fBchroot\fP" 10
The path to the chroot. The directory must exist and have correct permissions and ownerships.
.IP "" 10
Format: "/path/to/jail"
.IP "" 10
Default: None
.IP "\fBtestCommandsInsideJail\fP" 10
The commands used to start the daemon, a good starting point may be the command used in the startup script in /etc/init.d
.IP "" 10
Format: ["command1","command2"]
.IP "" 10
Default: []
.IP "\fBprocessNames\fP" 10
The name of the runnning processes after the daemon has been started.
.IP "" 10
Format: ["process1","process2"]
.IP "" 10
Default: []
.SH "Configuration directives - Tests"
.PP
After the daemon itself has been chrooted successfully, some commands can be executed from outside the jail to test the daemon.
.IP "\fBtestCommandsOutsideJail\fP" 10
The test commands which should be executed.
.IP "" 10
Format: ["command1","command2"]
.IP "" 10
Default: []
.IP "\fBpromptForInteractiveTests\fP" 10
Whether makejail should pause so you can stress the daemon yourself.
.IP "" 10
Use only if makejail is run interactively, and don't redirect its outputs.
.IP "" 10
Format: 1 (prompt) or 0 (don't prompt)
.IP "" 10
Default: 0
.IP "\fBpromptForSomeMoreTests=0\fP" 10
Whether makejail should loop while running tests until you tell it it's over.
.IP "" 10
Use only if makejail is run interactively, and don't redirect its outputs.
.IP "" 10
Format: 1 (prompt) or 0 (don't prompt)
.IP "" 10
Default: 0
.IP "\fBmaxExecutions\fP" 10
Maximum number of times a command is executed before aborting.
.IP "" 10
Format: integer
.IP "" 10
Default: 100
.SH "Configuration directives - Copying files"
.IP "\fBdoNotCopy\fP" 10
Do not copy the files matching these patterns according to the rules used by the Unix shell.
.IP "" 10
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
.IP "" 10
Format: ["path1","path2"]
.IP "" 10
Default: ["/usr/share/doc","/usr/share/info","/usr/share/man","/etc/fstab","/etc/mtab"]
.IP "\fBforceCopy\fP" 10
When initializing the jail, copy the files matching these patterns according to the rules used by the Unix shell.
.IP "" 10
No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
.IP "" 10
Format: ["path1","path2"]
.IP "" 10
Default: []
.IP "\fBcleanJailFirst\fP" 10
Whether makejail should remove files in jail first.
.IP "" 10
Format: 0 to do nothing or 1 to remove files from the jail.
.IP "" 10
Default: 1
.IP "\fBpreserve\fP" 10
Useful only if cleanJailFirst=1, makejail won't remove files or directories if their path begins with one of the strings in this list.
.IP "" 10
When updating a jail, you should for example put the locations of log files here.
.IP "" 10
Format: ["path1","path2"]
.IP "" 10
Default: []
.IP "\fBmaxRemove\fP" 10
Useful only if cleanJailFirst=1, makejail aborts if it's about to remove more than this number of files from the jail.
.IP "" 10
This may prevent makejail from erasing unwanted files if you wrote chroot="/usr" or if you have mounted a partition in the jail.
.IP "" 10
Format: integer
.IP "" 10
Default: 500
.IP "\fBusers\fP" 10
Makejail will filter the files listed in the directive userFiles and copy only lines matching these users, which means lines starting with "user:"
.IP "" 10
You can use ["*"] to disable filtering and copy the whole file.
.IP "" 10
Format: ["user1","user2"]
.IP "" 10
Default: []
.IP "\fBgroups\fP" 10
Makejail will filter the files listed in the directive groupFiles and copy only lines matching these groups, which means lines starting with "group:"
.IP "" 10
You can use ["*"] to disable filtering and copy the whole file.
.IP "" 10
Format: ["group1","group2"]
.IP "" 10
Default: []
.SH "Configuration directives - Timing"
.PP
These times are in seconds, the values are the duration of sleeps at various stages of makejail.
.IP "\fBsleepAfterStartCommand\fP" 10
Duration of sleep after starting the daemon, after this delay makejail considers it's in a correctly running state.
.IP "" 10
Format: floating number
.IP "" 10
Default: 2
.IP "\fBsleepAfterTest\fP" 10
Duration of sleep after a test command has been run, after this delay makejail considers the daemon has finished its tasks related to this command.
.IP "" 10
Format: floating number
.IP "" 10
Default: 2
.IP "\fBsleepAfterKillall\fP" 10
Duration of sleep after killing the daemon processes.
.IP "" 10
Format: floating number
.IP "" 10
Default: 1
.IP "\fBsleepAfterStraceAttachPid\fP" 10
Duration of sleep after attaching strace to a running process id.
.IP "" 10
Format: floating number
.IP "" 10
Default: 0.2
.SH "Configuration directives - Debian specific"
.PP
I initially thought with starting with the package description, but this method usually installs a bunch of files you won't need.
.IP "\fBpackages\fP" 10
The name of the packages. It will copy the files which belongs to the package according to the file /var/lib/dpkg/info/$package.list.
.IP "" 10
Format: ["package1","package2"]
.IP "" 10
Default: []
.IP "\fBuseDepends\fP" 10
If you want to also install other packages required by the the initial list you specified.
.IP "" 10
It looks at the line "Depends:" in the output of `dpkg -p $package`.
.IP "" 10
Format: 1 (use depends) or 0 (don't use depends)
.IP "" 10
Default: 0
.IP "\fBblockDepends\fP" 10
Useful only if useDepends=1, it prevents the installation of these packages even if dpkg says they are required.
.IP "" 10
Format: ["package1","package2"]
.IP "" 10
Default: []
.IP "\fBdebianDpkgInfoDir\fP" 10
Path to the dpkg $package.list files, "%s" will be replaced by the name of the package.
.IP "" 10
Format: "/path/to/info/files/%s.list"
.IP "" 10
Default: "/var/lib/dpkg/info/%s.list"
.SH "Configuration directives - Paths so specific files and commands"
.IP "\fBpathToLdConfig\fP" 10
Path to the executable ldconfig, used to generate the shared librairies cache. ldconfig is executed in the jail to regenerate this cache.
.IP "" 10
Format: "/path/to/ldconfig"
.IP "" 10
Default: "/sbin/ldconfig"
.IP "\fBpathToLdSoConf\fP" 10
The path to the configuration files used by ldconfig, which says which directories should be scanned searching for shared librairies.
.IP "" 10
Set this to None if your system doesn't use such a file.
.IP "" 10
Format: "/path/to/ld.so.conf"
.IP "" 10
Default: "/etc/ld.so.conf"
.IP "\fBpathToLdSoCache\fP" 10
The path to the shared librairies cache generated by ldconfig.
.IP "" 10
Format: "/path/to/ld.so.cache"
.IP "" 10
Default: "/etc/ld.so.cache"
.IP "\fBprocPath\fP" 10
The path to the procfs filesystem.
.IP "" 10
Format: "/path/to/proc"
.IP "" 10
Default: "/proc"
.IP "\fBuserFiles\fP" 10
List of the files whose contents should be filtered, to keep only the users listed in the directive "users".
.IP "" 10
Format: ["file1","file2]
.IP "" 10
Default: ["/etc/passwd","/etc/shadow"]
.IP "\fBgroupFiles\fP" 10
List of the files whose contents should be filtered, to keep only the groups listed in the directive "groups".
.IP "" 10
Format: ["file1","file2]
.IP "" 10
Default:["/etc/group","/etc/gshadow"]
.IP "\fBtempDir\fP" 10
The temporary directory where makejail can write temporary files.
.IP "" 10
There may be a lot of files generated here if keepStraceOutputs=1.
.IP "" 10
Format: "/temp/directory"
.IP "" 10
Default: "/tmp/makejail_logs"
.IP "\fBpsCommand\fP" 10
The command line used to list running processes.
.IP "" 10
The output must include the pid and the name of the process.
.IP "" 10
Format: "ps [options]"
.IP "" 10
Default: "ps -e"
.IP "\fBpsColumns\fP" 10
In which columns of the output of psCommand are the ids and the name of the processes.
.IP "" 10
Spaces separate the columns, the first column is numbered 1.
.IP "" 10
Format: (columnPid,columnProcessName)
.IP "" 10
Default: [1,4]
.SH "Configuration directives - Commands to run to trace processes"
.PP
Here you can configure the commands which must be run to trace processes. These are called strace though you can use another program, like ktrace on OpenBSD.
.PP
The defaults should be suitable for systems using strace. "-f" means strace should trace process children too. Though it's interested only in file accesses, it doesn't use "-e trace=file" because with this option it doesn't catch calls for "bind" and "connect" to sockets.
.IP "\fBstraceCommand\fP" 10
String describing the strace command when executing a command line. "%command" will be replaced by the command to execute, and "%file" by the path to the temporary trace file.
.IP "" 10
Format: "strace_command [options] %command > %file"
.IP "" 10
Default: "strace -f %command >/dev/null 2>>%file"
.IP "\fBstraceCommandPid\fP" 10
String describing the strace command when attaching itself to a running process. "%pid" will be replaced by the id of the process to trace, and "%file" by the path to the temporary trace file.
.IP "" 10
Format: "strace_command [options] %pid > %file"
.IP "" 10
Default: "strace -f -p %pid >/dev/null 2>>%file"
.IP "\fB straceCommandStop\fP" 10
Command to execute to stop the tracing.
.IP "" 10
Format: "strace_stop_command"
.IP "" 10
Default: "killall -9 strace"
.IP "\fBstraceCommandView\fP" 10
Set this to None if the trace output files can be read directly, or the command line to execute which prints the trace on stdout. "%file" will be replaced by the name of this file.
.IP "" 10
Format: "strace_command_viewer [options] %file"
.IP "" 10
Default: None
.IP "\fBkeepStraceOutputs\fP" 10
Whether makejail should remove the outputs of strace from the directory tempDir.
.IP "" 10
Format: 0 (to remove the files) or 1 (to keep them)
.IP "" 10
Default: 0
.SH "Configuration directives - Patterns in the trace outputs"
.PP
These are three patterns which should match failed attempts to access a file in the traces.
.PP
You must define a group (between parenthesis) which will be matched by the path of the file.
.PP
The syntax of the regular expressions in python is detailed here: http://py-howto.sourceforge.net/regex/regex.html
.PP
If the match on a line means it is a failed attempt only if the next line matches another expression (typically a return code, no group needed), you can use an array of two strings instead of one string, the first string is the main expression, and the second one is the expression which must match the next line. See global.OpenBSD in the examples directory.
.IP "\fBstracePatterns\fP" 10
Regular expressions to detect a failed attempt at accessing a file.
.IP "" 10
If the file exists outside the jail makejail will copy it into the jail.
.IP "" 10
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
.IP "" 10
Default: ['.*\("([
"]*)",.*\) .* ENOENT .*']
.IP "\fBstraceCreatePatterns\fP" 10
Regular expressions to detect a failed attempt at creating a file.
.IP "" 10
If the directory where the file should be created exists outside the jail, it will create it inside the jail.
.IP "" 10
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
.IP "" 10
Default: ['.*\("([
"]*)",.*O_CREAT.*\) .* ENOENT .*','bind\(.* path="([
"]*)".* ENOENT .*']
.IP "\fBstraceSocketPatterns\fP" 10
Regular expressions to detect a failed attempt at accessing a socket.
.IP "" 10
makejail can't create the socket, it will just print a warning.
.IP "" 10
Format: ["regexp1","regexp2",["regexp3","regexp3 for the next line"]]
.IP "" 10
Default: ['connect\(.* path="([
"]*)".* ENOENT .*']
.SH "AUTHOR"
.PP
This manual page was written by Alain Tesio, alain@onesite.org
.PP
This software comes with no warranty.
.SH "REPORTING BUGS"
.PP
Report bugs to makejail@floc.net
...\" created by instant / docbook-to-man, Sat 02 Nov 2002, 19:30