# lidsadm -A -o /some/file -j READ
This will prevent anyone (including root) from modifying or deleting /some/file
as long as LIDS is enabled. If you are in an LFS, you are free to modify /some/file
assuming you have appropriate file system permissions and the partition isn't mounted read-only.
Same as above, only specify /some/directory
# lidsadm -A -o /some/directory -j READ
When the object is a directory, LIDS protects the directory itself, and it recursively protects everything underneath it within the same file system. (e.g. LIDS ACLs do not cross file system boundaries!
) This is very important to remember so you don't accidentally leave part of your system unprotected.
A directory that you may want to protect as read only is the /etc
directory.
# lidsadm -A -o /etc -j READ
# lidsadm -A -o /some/file_or_directory -j DENYAgain, this will prevent even root from accessing it. And, if it is a directory, all files and directories underneath it are also hidden (within the same file system, of course).
# lidsadm -A -o /some/log/file -j APPENDThis will allow someone to write to the end of the file while at the same time preventing him/her from erasing or modifying its existing contents.
An easy way to protect your system logs as append only would be:
# lidsadm -A -o /var/log -j APPEND
This will protect all files under /var/log
as append only. As with READ and DENY, this target is also recursive.
In order to allow users to authenticate themselves to the system, it is necessary to give certain programs read only access to the /etc/shadow
. Some of the programs you may want to consider giving read access to are: login, sshd, su,
and vlock
.
To allow the login program to read /etc/shadow
, use the following ACL:
# lidsadm -A -s /bin/login -o /etc/shadow -j READThe "-s" option specifies a subject, which is
/bin/login
in this case. We are giving the subject read only access to the object (/etc/shadow
in this case).
It won't. To fix this problem, you can remove the /etc/mtab
file and replace it with a symbolic link to /proc/mounts
. In order for this to work, you must modify your startup scripts to use the "-n" option with every mount
and umount
command. This tells mount
and umount
not to update the /etc/mtab
file.
For example, if you find:
mount -av -t nonfs,noproc
in your init scripts, you will need to change it to:
mount -av -n -t nonfs,noproc
These mount
commands may be scattered throughout your init scripts. Use grep to make sure you catch them all. You will also want to modify all of the umount
commands in the same manner.
This happens when you protect /lib
as read only (a good thing to do). The error received is something similar to:
LIDS: depmod (3 12 inode 16119) pid 13203 user (0/0) on tty2: Try to open /lib/modules/2.2.18/modules.dep for writing,flag=578
This occurs during startup because the /etc/rc.d/rc.sysinit
init script tries to recreate all of your module dependencies. Normally this is not needed because the module dependencies don't change unless you add, change, or delete modules. The error is harmless, but if you don't like seeing it, you can simply comment out the line in your /etc/rc.d/rc.sysinit
script that recreates the module dependencies (Look for depmod -a
or something similar).
It won't. Log rotation is something that will have to be done manually by executing your log rotation utility when LIDS_GLOBAL is disabled. You should disable the cron job that initiates log rotation. (See below for a possible alternative).
You can, but it's not recommended. If someone were to break into your system, even though they couldn't modify your logs, they could rotate them enough times (by executing the log rotation utility manually) that the log containing the information gathered during the intrusion is dropped off the face of the earth. This is part of the price you pay for high security.
An alternative solution to giving your log rotation utility write access to /var/log
, is to give the cron daemon write access to /var/log and make it inheritable:
lidsadm -A -s /usr/sbin/crond -i -o /var/log -j WRITE
This prevents someone from manually executing your log rotation utility, but will allow it to work when it is executed by the cron daemon.
WARNING: If a vulnerability is found in your cron daemon, someone could exploit it and wipe your logs since cron would have write access to /var/log
. This defeats the purpose of using MAC in the first place since your access controls can now be circumvented if a vulnerability is found. Use this option at your own discretion!
This happens when you have disabled the CAP_SYS_ADMIN capability globally and have not given the proper authority to unmount your file systems to your shutdown script(s). For example, on Red Hat 6.2, the /etc/rc.d/init.d/halt
script unmounts your file systems. You must give it the CAP_SYS_ADMIN capability so it can unmount your file systems:
# lidsadm -A -s /etc/rc.d/init.d/halt -o CAP_SYS_ADMIN -i 1 -j GRANT
The target "GRANT" tells LIDS to grant the subject (/etc/rc.d/init.d/halt
in this case) the CAP_SYS_ADMIN capability. The "-i 1" option sets the "inheritance level" of the ACL to 1.
Beware that this also allows anyone who can execute your /etc/rc.d/init.d/halt
script to unmount your file systems. If you have physical access to your box, you may just want to turn off LIDS_GLOBAL before shutting down your system rather than grant capabilities to your shutdown scripts. However, if you have a UPS that can shutdown your system in case of power failure, you may not be around to disable LIDS_GLOBAL.
Services that run a privileged port (those below 1024) require the CAP_NET_BIND_SERVICE capability in order to bind to the port. If you have disabled this capability globally in the /etc/lids/lids.cap
file, you must either grant the program that capability
# lidsadm -A -s /usr/local/bin/apache -o CAP_NET_BIND_SERVICE -j GRANTor, start the service when LIDS_GLOBAL is disabled.
An LFS applies to a single terminal session. A daemon forks itself in order to separate itself from the controlling terminal. Once this happens, it is no longer connected to the LFS on your terminal and is now protected by LIDS.
The /etc/lids/lids.cap
file contains a list of all the capabilities available under a LIDS enhanced Linux kernel. Those that have a "+" in front of them are enabled, and those with a "-" in front of them are disabled. To change the status of a capability, simply edit the text file and change the "+" to a "-" to disable a capability and vice-versa to enable it. After you're done editing the file, you must tell LIDS to
reload the configuration files.
The X server that you are using requires the CAP_SYS_RAWIO capability. Try
# lidsadm -A -s /path/to/your/X_server -o CAP_SYS_RAWIO -j GRANT
It is recommended that you create a shell script of all the ACLs that you wish to add to your system. That way you don't accidentally leave something unprotected when you make changes to your system. You can start the script out by flushing your old ACLs so you don't create duplicates.
# lidsadm -Z
To protect this shell script, you can either create an ACL to DENY access to it, or put it in the /etc/lids
directory since it is automatically protected as DENY.
LIDS automatically protects the /etc/lids
directory with DENY.
Unfortunately, there isn't much you can do about this. Because init
recreates this file each time you boot, it will have a different inode number every time. This makes it difficult for LIDS to handle. It is a harmless error, and your system will still function properly without /etc/initrunlvl
.
Yes. Up until version 0.9.12-2.2.18, this was the default behavior. Now the default is for children not to inherit the file ACLs from their parents. To allow a file ACL to be passed from a parent process to a child process, you must use the "-i <inheritance level>" option.
Where "inheritance level" (a.k.a. TTL) determines how far the ACL is inherited. If the TTL specified is 1, then the subject specified in the ACL and all of its children will inherit the ACL. However, the children's children (a.k.a. a grandchild of the subject in the ACL) will not inherit the ACL (a TTL of 2 would be needed for this to occur).
Note: These same inheritance rules apply to ACLs that grant capabilities.
The first thing to do is simply try running the program and see what violations get reported by LIDS. However, many times this doesn't give you enough information. When this happens, you can try using strace to follow the program through and see which system call fails. This will usually give you a good indication as to which capability is being violated.
NOTE: If you have disabled CAP_SYS_PTRACE globally, you will need to temporarily give strace the CAP_SET_PTRACE capability so it can trace your program while LIDS is enabled.
Unfortunately there isn't an easy solution. This is because the passwd
utility recreates the /etc/shadow
file every time you change your password. Because of this, it will start on a different inode each time you use the passwd
utility successfully.
For the system administrator, there is an easy work around. Start an LFS and use the passwd
utility from within the LFS. If there are users that need to change their passwords, LDAP can provide an alternate means of client authentication that will allow users to change their passwords.
There is an option available that will allow users to change their system passwords when using the standard unix system filesUNIX authentication, but it's not recommended. /usr/bin/passwd
can be given write access to /etc so it can always modify the shadow file regardless of it's inode number.
WARNING: If someone were to find a vulnerability in /usr/bin/passwd
, or any of the libraries/PAM modules that it uses, he/she could potentially gain write access to your /etc
directory.
This defeats the purpose of using MAC in the first place since your access controls can now be circumvented if a vulnerability is found. Use this option at your own discretion!
If you are going to give /usr/bin/passwd
write access to /etc
, it is recommended that you create ACLs to protect every file and directory under /etc
that you don't want /usr/bin/passwd
to be able to modify.
This will significantly reduce the risk (and possibly completely remove it if done correctly) mentioned above.
For example:
/sbin/lidsadm -A -s /usr/bin/passwd -o /etc/hosts.allow -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/hosts.deny -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc0.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc1.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc2.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc3.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc4.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc5.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/rc6.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/init.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/cron.d -j READ /sbin/lidsadm -A -s /usr/bin/passwd -o /etc/pam.d -j READ ...
The above is not a complete list by any stretch of the imaginiation, but it's a start. Also keep in mind that anytime you add a file or directory to /etc
that you don't want passwd
to have access to, you must create a new ACL to protect it.
A note about updating inodes:
If you have defined ACLs to grant access to /etc/shadow
or /etc/passwd
you must make sure to tell lids to
update the inodes and then
reload it's config files. Otherwise you may encounter problems.
For example: Assume /etc/passwd
is protected as DENY, and /bin/login
can read /etc/passwd
. If the inodes aren't updated after changing a password, problems may arise the next time someone tries to log in. /bin/login
won't be able to read /etc/passwd
and you won't be able to log in, or worse yet, you will be able to login by just pressing the <ENTER> key.
By default, ssh/scp try to use a privileged port for the source port when creating an outgoing connection. This requires the CAP_NET_BIND_SERVICE capability. However, you can specify the following option in the ssh_config
file to force it to use a port above 1023 for the source port:
UsePrivilegedPort No
Or, you can grant CAP_NET_BIND_SERVICE to ssh (since scp uses ssh, it will work also):
lidsadm -A -s /usr/bin/ssh -o CAP_NET_BIND_SERVICE -j GRANT
bash
tried to access a hidden file. How can I fix this?
This can happen when you protect your private keys with a default policy of DENY. The init script provided in the openssh-server rpm checks to see if the private key files exist under /etc/ssh
. If the script can't find them, it executes ssh-kegen to generate them. Beckeygenthe keys are actually there, ssh-keygen fails and the startup script exits.
To fix this, remove the check for the key files in the startup script:
start) # Create keys if necessary #do_rsa_keygen; <------------ Comment out these lines #do_dsa_keygen; echo -n "Starting sshd: " if [ ! -f $PID_FILE ] ; then sshd RETVAL=$? if [ "$RETVAL" = "0" ] ; then success "sshd startup" touch /var/lock/subsys/sshd else failure "sshd startup" fi fi echo ;;
NOTE: This means the private keys will have to be generated manually prior to starting sshd. Otherwise, it will fail to start.
A hidden process can still be killed if you know it's process id (pid). Many systems store the pid of all the processes started at boot time somewhere under /var
(/var/run
is commonly used). Your shutdown scripts can be modified to read the pids from these files and send them the appropriate signals.
For example, if your system stores the pids in /var/run/<process_name>.pid
, then you can add the following lines to your shutdown scripts:
for p in `ls /var/run/*.pid` do kill -15 `cat $p` done sleep 5 sync;sync;sync for p in `ls /var/run/*.pid` do kill -9 `cat $p` done sleep 5 sync;sync;syncThe CAP_KILL and CAP_INIT_KILL capabilities must be granted to the shutdown script containing these lines. It is probably a good idea to hide the
/var/run
directory from everything but the init scripts too.
Another option would be to just send every process the TERM and KILL signals.
MAX_PROC=65535 trap : 1 2 15 I=1;while (( $I < $MAX_PROC ));do I=$(($I+1)); if (( $$ != $I ));then kill -15 $I; fi; done sleep 5 sync;sync;sync; I=1; while (( $I < $MAX_PROC ));do I=$(($I+1)); if (( $$ != $I ));then kill -9 $I; fi; done sync;sync;sync
Nenad Micic wrote his own C program to kill hidden processes at shutdown.
A good starting point would be to protect your system binaries and libraries:
/sbin/lidsadm -A -o /bin -j READ /sbin/lidsadm -A -o /sbin -j READ /sbin/lidsadm -A -o /lib -j READ /sbin/lidsadm -A -o /usr/bin -j READ /sbin/lidsadm -A -o /usr/sbin -j READ /sbin/lidsadm -A -o /usr/lib -j READ
If /usr/local
is on a separate partition, add the following ACLs also:
/sbin/lidsadm -A -o /usr/local/bin -j READ /sbin/lidsadm -A -o /usr/local/sbin -j READ /sbin/lidsadm -A -o /usr/local/lib -j READ
You should also disable CAP_SYS_RAWIO and CAP_SYS_PTRACE in the /etc/lids/lids.cap
file. If you don't disable CAP_SYS_RAWIO, then someone can override the above file protections by writing directly to your devices.
If you are running the X Window System, please see above about getting X to work under LIDS.