=>  Releases

Stable: 1.5.0

  • 4.4.y

Patched kernels
Includes vanilla kernel with the RSBAC patch

  • 4.4.20
  • 4.4.21

Latest diffs
Produced after each commit or rebase to new upstream version

Enhanced kernels
Combined patches with RSBAC and PaX, less well tested

External RSBAC+PaX
Maintained by m-privacy

RSBAC source code, can be unstable sometimes

=>  Events

No events planned

General impression of RSBAC

  • Pros
    • Very powerful enhancement of LINUX kernel
    • Nice design, which allows bunch off cool features like transaction, secure_delete, fd hiding...
    • Cool community, still small but efficient and reactive
  • Cons
    • The lack of documentations for some modules
    • You need strong knowledge of UNIX system to setup well RSBAC policies
    • For a best enforcement, small changes must be done to distribution (like restoring dynamic fd (/proc, /dev, shm))
    • Their isn’t any reference policies for now


Howto use rsbac git repository

Here is a quick’N dirty way to follow rsbac code sources:

step Command Desc
1 git clone git://rsbac.org/linux-2.6 linux-2.6-rsbac Like svk mirror
2 git branch -a List available branches
3 git checkout -t remotes/origin/rsbac-1.4-2.6.33 -t means track this branch
4 git log Check if it’s what we wanted
5 make menuconfig, .... ...
6 git pull Get branche update, goto step 4
7 git pull -a Get all branches update, goto step 2

Here is how I send patch:

step Command Desc
1 checkout -b mybranch ie checkout -b rc-learning-fixes
2 editing, messing up with the tree, ... ...
3 git commit -a clear commit log (fix/add/mod/del)
4 *tests* goto step 2 if it does not work
5 git format-patch -1 -s –subject-prefix=’PATCH][BUILD’ generate the patch
6 mail the generated new files to last upstream commit author step 5 tell you the patch name

Howto restore read only filesystem attributes

RSBAC does handle generic lists in memory for RO fs such as squashfs, but during the umount it has no way to store them on disk. We’ll go trought the steps for making that possible.

System architectures examples

Host system with rsbac kernel
|->/home/vm/			; Directory for vm mountpoints
|          /dns/		; DNS vm mountpoint
|          /dns_data/		; DNS '/var' mountpoint for persistant data
|          /web/
|          /web_data/
|->/home/fs/			; Directory for vm root squashfs
|          /root.squash	; RO vm root filesystem

The boot process is:

  • First host boot
  • Then mount ro vm root fs:
    • link /home/fs/root.squash to /dev/loop7
    • mount /dev/loop7 /home/vm/dns
    • mount /dev/loop7 /home/vm/web
  • prepare vm chroot:
    • mount -o bind dns_data to /home/vm/dns/var
    • mount proc, dev, ...
  • run services in chroot

And the shutdown process is:

  • kill services
  • umount vm chroot
  • losetup -d /dev/loop7
  • Host can halt

Revelant rsbac logs are:

Log Desc
read_list(): list fd_gen on device 07:07 not found no rsbac.dat on /dev/loop7
rsbac_auth_p_capset_member(): adding AUTH capability... setting new AUTH cap during vm boot
rsbac_get_vfsmount(): unknown device squashfs return unknown device on get_vfsmount
do_umount() [sys_umount()]: umount failed → calling rsbac_mount for Device 07:07 on last umount RSBAC did not save attributes

We do not want to run rsbac with auth_learning mode always activated. This is how I manage to store attributes and restore them on startup.

Attributes saving

Squashfs files attributes are currently store in ram and linked to the device 07:07 (/dev/loop7). That is a good point for our purpose, because memory stored lists access are blazing fast.

Before shutdown and once in a while:

  • Mount /dev/loop7 to a temporary mountpoint
  • Then save rsbac backup tools output on that mountpoint, ie: ‘chroot /mnt/tmp-loop auth_back_cap -r / 2>&1 | grep -v ‘RSBAC_EINVALIDTARGET$’ > policy.commands’
  • Finaly unmount the temporary mountpoint

Then the shutdown process can happen. Let see how to restore the policy.

Note: Obviously, the policy.commands file should be protected by another security policy.

Attributes restoring

Rsbac will keep attributes for our device until every mountpoints are umount.

The vm start process is now:

  • link /home/fs/root.squash to /dev/loop7
  • mount /dev/loop7 to /mnt/tmp-loop
  • restore_policy, a small C program which does:
    • read the previously saved policy.commands files
    • chroot to /mnt/tmp-loop
    • setuid to secoff
    • restore every attributes
  • continue start process
  • umount /mnt/tmp-loop

And voila !

Howto protect sshd

Setup UM

First we need to setup RSBAC User Management modules. In /etc/nsswitch.conf we may have ‘[passwd|shadow|group]: compat rsbac’, and in /etc/pam.d/system-auth ‘[auth|account|password|session] sufficient pam_rsbac.so’ before any pam_unix.so lines. Then :

secoff$ rsbac_useradd -O && rsbac_groupadd -O
secoff$ rsbac_passwd -n secoff

Grant sshd

Sshd must be allow to change his identity during key exchange

secoff$ for user in 0 22; do
                for param in "" "-e" "-f"; do
                        auth_set_cap $param FD add /usr/sbin/sshd $user

Now we want sshd to be allow to change his identity only to an user who have been properly authenticated (by entering his password).

secoff$ attr_set_fd AUTH FD auth_may_setuid 3 /usr/sbin/sshd

Note: if you use CONFIG_RSBAC_AUTH_DAC_*, CONFIG_RSBAC_DAC_* you must add caps for allowed user, because they don’t use the special auth_may_setuid value : ‘Last Auth...’

secoff$ for user in 400 "1000 3000"; do
                for param in "-e" "-f"; do
                        auth_set_cap $param FD add /usr/sbin/sshd $user

Run sshd

Add the following parameter to sshd init script:

-o "HostbasedAuthentication no" -o "PasswordAuthentication yes" -o "ChallengeResponseAuthentication no" -o "UsePAM yes" -o "UsePrivilegeSeparation yes" -o "PermitRootLogin no"


ssh secoff@your_server

If you use the unix password, then you’ll get : ‘rsbac_adf_request(): request CHANGE_OWNER, ..., prog_name sshd, prog_file /usr/sbin/sshd, uid 0, remote ip ..., target_type PROCESS, ...., attr owner, value 400, result NOT_GRANTED by AUTH’. Now you have to use the rsbac password, like that the kernel will know that secoff have been authenticate, then he’ll allow sshd to change his identity.


This is a pretty good security measure, because even if sshd get’s cracked, it won’t be able to gain secoff credential without his passw ord.

Howto use RES module

RES allows to enforce user limits (ulimit). Here are somes examples:

secoff$ for user in -4 root; do
attr_set_user RES $user res_max fsize 250000   # user won t create file more than 1G (block size = 4096)
attr_set_user RES $user res_max stack 100000   # user stack won t get bigger than 100 KB
attr_set_user RES $user res_max nofile 1024    # user won t open more than 1024 fds at a time
attr_set_user RES $user res_min core -1        # user will coredump by default
attr_set_user RES $user res_max nproc 200      # user won t start more than 200 process
attr_set_user RES $user res_max as 100000000   # user s process won t get bigger than 100MB
secoff$ attr_set_user RES root res_role 0

And that’s it !

user$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) 976
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
stack size              (kbytes, -s) 97
cpu time               (seconds, -t) unlimited
max user processes              (-u) 200
virtual memory          (kbytes, -v) 97656
file locks                      (-x) unlimited
user$ ulimit -u 1024
-sh: ulimit: max user processes: cannot modify limit: Operation not permitted
user$ for i in `seq 0 250`; do sleep 5& done
[195] 12759
-sh: fork: Resource temporarily unavailable

Howto protect Kernel code against tampering

Howto protect /boot device

In this example, we don’t want anyone, except secoff, to be able to update kernel in /boot.

First, let’s protect /boot directory with RC

# We create a new FD rc_type
rc_set_item TYPE `rc_get_item list_unused_fd_type_nr` type_fd_name BOOT_FD
# We allow secoff to access this type
rc_set_item ROLE 1 type_comp_fd $BOOT_FD A
# We set /boot rc_type_fd
attr_set_fd RC FD rc_type_fd $BOOT_FD /boot    
# Repeat this last one after mounting the device: When a directory get s mounted, 
#its attributes are replaced by the ones of the new device's root.

This is good, but root can still access boot data directly through /dev/sda1.

# We create a new DEV rc_type
rc_set_item TYPE `rc_get_item list_unused_dev_type_nr` type_dev_name BOOT_Device
# We allow secoff to access this type
rc_set_item ROLE 1 type_comp_dev $BOOT_Device A
# We set /dev/sda1 rc_type
attr_set_file_dir -d DEV b8:1 rc_type $BOOT_Device

Finally we wan’t secoff to be able to mount the device:

# Let s fool mount
attr_set_fd GEN FD fake_root_uid 3 /bin/mount
# And allow secoff to changes files in /boot, the GEN way:
attr_set_fd GEN FD linux_dac_disable 1 /boot    # do that when /boot is mounted !
# or the CAP way:
attr_set_user -a CAP secoff min_caps FS_MASK

Howto use RSBAC transactions

How transactions works

RSBAC transactions works pretty much the same as SQL databases transactions... It ease policies development, for example you can do without loads of NOT_GRANTED:

  • set rc_type BIN_FD /bin
  • set roles type_comp_fd 0 -EXECUTE -MAP_EXEC
  • set roles type_comp_fd $BIN_FD EXECUTE MAP_EXEC
  • rsbac_list_ta commit

There are four commands to use :

  • rsbac_list_ta -t 900 begin: this creates a new transaction valid for 15 minutes
  • rsbac_list_ta -t 900 -N ta_number refresh: this resets the transaction timeout
  • rsbac_list_ta -N ta_number commit: this makes all the changes effective
  • rsbac_list_ta -N ta_number forget: this discards all the changes done in transaction

To monitor what’s going on, read the ‘/proc/rsbac-info/gen_lists’ file

finally, there are two way to change attributes in a transaction, you can either

  • pass the transaction number to the tool:
attr_set_fd -N ta_number RC FD rc_type 2 /whatever
  • set the environment variable RSBAC_TA
`rsbac_list_ta -b -t 900 begin`
rsbac_menu ...
export RSBAC_TA=ta_number

User creation examples

Here is a small script which show how to use transaction for user creation purposes.


function abord { echo -e "\n\e[1;33m*\e[1;32m $1\e[0;37m"; rsbac_list_ta -N $RSBAC_TA forget; exit 1 }
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
if [ -z "$1" ]; then echo "usage: $0 username"; exit 1; fi;
export RSBAC_TA="`rsbac_list_ta -t 10 begin`"
rsbac_useradd -x 60 -w 30 -g users -p '' $1 || myabord "Could not create user"
rsbac_usermod -l 0 $1 || myabord "Could not usermod"
attr_set_user RC $1 rc_def_role `rc_get_item list_roles | grep ' Remote_Users$' | awk '{print $1}'` || myabord "Could not set def role"
attr_set_user CAP $1 min_caps IPC_LOCK || myabord "attr_set_user"
attr_set_user CAP $1 cap_ld_env 1 || myabord "attr_set_user"
rsbac_list_ta -N $RSBAC_TA commit || myabord "rsbac_list_ta"
mkdir -m 700 /home/$1
chown $1 /home/$1

Howto use network template

How networks templates works

First some documentation. For each network access, the adf will try to match the object with a network template from lowest to highest ordering number until it matches one. So general purpose templates should have high numbers, and more detailed templates should have low numbers.

  • When a socket is created, it emits a CREATE request over a network object with unknown local and remote address. The template matching uses the local address.
  • If the socket is binded/listened, it emits a BIND/LISTEN request over a network object with the desired local address and an unknown remote address. The template matching uses the local address. Then when a client connects to the server, all matching are done with the remote address and remote port. Except for GET_STATUS_DATA request, matching is done with remote address but local port.
  • If the socket is connected and used with another endpoint, it emits CONNECT/SEND/RECEIVE requests, and the template matching uses the remote address.
  • Finally, when the socket is closed, it emits a NET_SHUTDOWN/CLOSE request, and the template matching uses the remote address

Web server example

Let’s try to enforce network access of a web server First, we create network template, with rsbac_nettemp_def_menu, and for each template we create a new rc_netobj_type with the name + _NETOBJ

Name Nr Family Type Address Protocol Ports
DNS_SRV 53 INET DGRAM nameserver/32 UDP 53:53
HTTPS 200443 INET STREAM TCP 443:443

The NETLINK socket is a special socket family for asking network configuration to the kernel. So first, we must allow apache to access this template.

Then apache will create a TCP socket. At this point the netobj is defined as follow : ‘INET STREAM proto TCP local remote’. So the TCP template will match.

Then apache will bind this socket. The netobj is defined as follow: ‘INET STREAM proto TCP local remote, attr sock_type, value STREAM’, aka HTTPS

Finally, when a browser connects to the server, the netobj is defined as follow : ‘INET STREAM proto TCP local eth0:SRV_ADDR:443 remote CLIENT_ADDR:35967’ aka LAN_TCP

So here is the list of necessary type_comp apache needs to be available for lan clients:

Netobj Access

And here you go !


wiki/experiences/tweety.txt · Last modified: 2010/07/08 23:15 by tweety
This website is kindly hosted by m-privacy