Hack 19 Enforce User and Group Resource Limits

figs/moderate.gif figs/hack19.gif

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.