使用 PAM Limits 模块限制资源

通过 PAM 的 Limits 模块可以限制指定用户或组的资源使用,如核心文件大小(core)、数据段(data)、文件长度(fsize)、锁定内存地址空间(memlock)、打开文件数量(nofile)、栈长度(stack)、CPU时间(cpu)、进程数量(nproc)、地址空间长度(as)、登录数(maxlogins)、系统登录数(maxsyslogins)、优先级(priority)、锁定文件数(locks)、等待信号数(sigpending)、消息队列长度(msqqueue)、Nice(nice)、实时优先级(rtprio),chroot(chroot)。

这些限制可以通过修改 /etc/security/limits.conf 文件来实现,也可以在 /etc/security/limits.d/ 目录中增加一个配置文件来实现,这里我推荐后者,这处可以把限制更好的分类,便于查看和调整。

以几个实例简单介绍一下 limits.conf 配置文件语法,详细可以看 man limits.conf。

*		soft	nofile	10	# 软限制所有用户最大打开文件数为 10
*		hard	stack	1024	# 硬限制所有用户最大栈空间为 1M
fwd		hard	nproc	20	# 硬限制 fwd 用户最大进程数为 20
@sftp		hard	as	20480	# 硬限制 sftp 组最大地址空间为 20M

Over!

映射 Socket 到 Standard IO

演示一下 Unix 系统的 C 程序中如何将 Socket 映射到标准IO。

/* sock2stdio.c
 * Heiher <admin@heiher.info>
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
 
int main(int argc, char * argv[])
{
	int sock, client, addrlen;
	struct sockaddr_in this_addr, peer_addr;
	unsigned short port = 9000;
	pid_t cpid;
 
	addrlen = sizeof(struct sockaddr_in);
	memset(&this_addr, 0, addrlen);
	memset(&peer_addr, 0, addrlen);
 
	this_addr.sin_port = htons(port);
	this_addr.sin_family = AF_INET;
	this_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	bind(sock, (struct sockaddr*)&this_addr, addrlen);
	listen(sock, 5);
 
	while(-1 != (client=accept(sock, (struct sockaddr*)&peer_addr, &addrlen)))
	{
		cpid = fork();
		if(0 > cpid)
		{
			perror("fork() failed!");
 
			return 1;
		}
		else if(0 == cpid)	/* child */
		{
			close(0);
			close(1);
			close(2);
			dup2(client, 0);
			dup2(client, 1);
			dup2(client, 2);
			close(client);
 
			execl("/bin/dd", "/bin/dd", "bs=1", NULL);
 
			return 0;
		}
	}
 
	return 0;
}
gcc -o sock2stdio sock2stdio.c
./sock2stdio
nc localhost 9000
hello  # Input
hello  # Output

Over!