Enforce User and Group Resource Limits Hack #19 - Security
Security isn't a noun, it's a verb; not a product, but a process. Today, learn the hacks involved in reducing the risks involved in offering services on a Unix-based system. This the second part of chapter one in Network Security Hacks, by Andrew Lockhart (ISBN 0-596-00643-8, O'Reilly & Associates, 2004).
Make sure resource-hungry users don’t bring down your entire system.
Whether it’s through malicious intent or an unintentional slip, having a user bring your system down to a slow crawl by using too much memory or CPU time is no fun at all. One popular way of limiting resource usage is to use the ulimit command. This method relies on a shell to limit its child processes, and it is difficult to use when you want to give different levels of usage to different users and groups. Another, more flexible way of limiting resource usage is with the PAM module pam_limits.
pam_limits is preconfigured on most systems that have PAM installed. All you should need to do is edit /etc/security/limits.conf to configure specific limits for users and groups.
The limits.conf configuration file consists of single-line entries describing a single type of limit for a user or group of users. The general format for an entry is:
domain type resource value
The domain portion specifies to whom the limit applies. Single users may be specified here by name, and groups can be specified by prefixing the group name with an @. In addition, the wildcard character * may be used to apply the limit globally to all users except for root. The type portion of the entry specifies whether the limit is a soft or hard resource limit. Soft limits may be increased by the user, whereas hard limits can be changed only by root. There are many types of resources that can be specified for the resource portion of the entry. Some of the more useful ones are cpu, memlock, nproc, and fsize. These allow you to limit CPU time, total locked-in memory, number of processes, and file size, respectively. CPU time is expressed in minutes, and sizes are in kilobytes. Another useful limit is maxlogins, which allows you to specify the maximum number of concurrent logins that are permitted.
One nice feature of pam_limits is that it can work together with ulimit to allow the user to raise her limit from the soft limit to the imposed hard limit.
Let’s try a quick test to see how it works. First we’ll limit the number of open files for the guest user by adding these entries to limits.conf:
guest soft nofile 1000 guest hard nofile 2000
Now the guest account has a soft limit of 1,000 concurrently open files and a hard limit of 2,000. Let’s test it out:
# su – guest $ ulimit –a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1000 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 1024 virtual memory (kbytes, -v) unlimited $ ulimit –n 2000 $ ulimit –n 2000 $ ulimit –n 2001 -bash: ulimit: open files: cannot modify limit: Operation not permitted
There you have it. In addition to open files, you can create resource limits for any number of other resources and apply them to specific users or entire groups. As you can see, pam_limits is quite powerful and useful in that it doesn’t rely upon the shell for enforcement.