LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: AMD处理器

[推荐]UNIX 系统(3月30日更新 请勿灌水。谢谢!)

[复制链接]
 楼主| 发表于 2005-4-30 18:49:14 | 显示全部楼层
[推荐]系统调用-文件操作
UNIX系统开发-系统调用-文件操作
基本上所有的系统调用成功时返回0或正数,失败时返回负值。
文件的创建与删除
create系统调用的格式
#include <fcntl.h>
int creat(path,mode)
const char *path; /*文件路径名*/
int mode; /*文件存取权*/
参数与功能说明:
该调用创建名为path的文件。如果path已存在,则创建文件的进程对文目录应有执行权限, 并且对该文件有写权限。执行成功时,原先path文件的内容被清除,其长度被设置为0,原先文件的 mode,uid,gid被保留,而新指定的mode不起作用。成功时返回文件描述符。
remove系统调用的格式
#include <stdio.h>
int remove(path)
const char *path; /*文件路径名*/
unlink系统调用的格式
#include <stdio.h>
int unlink(path)
const char *path; /*文件路径名*/
参数与功能说明:
一个文件可以有若干个路径名,unlink的作用是删除某个文件的一个名为path 的路径名,并将文件i接点的连接计数减一。当计数为0时,若仍有进程在打开文件,文件不能立即被删除。
文件的打开与关闭
open系统调用的格式
#include <fcntl.h>
int open(path,oflag[,mode])
const char *path; /*文件路径名*/
int oflag,mode; /*打开方式和存取标志*/
参数与功能说明:
按给定的oflag打开path所指定的文件,可选参数mode一般在创建新文件时使用,其意义与creat调用中的mode一样。Oflag可取值为
O_RDONLY,O_WRONLY,O_RDWR,O_NDEALY,O_CREAT,O_TRUNC,O_EXCL,O_APPEND,O_SYNC,成功时返回文件描述符。
close系统调用的格式
#include <unistd.h>
int close(fd)
int fd; /*文件描述符*/
参数与功能说明:
释放指定的文件文件描述符fd,fd意义是用creat.open,dup,fcntl.pipe调用得到的一个文件描述符。
文件的读写操作
read系统调用的格式
#include <unistd.h>
int read(fd,buf,nbytes)
int fd; /*文件描述符*/
char *buf; /*缓冲区地址*/
unsigned nbytes /*要读的字节数*/
参数与功能说明:
执行成功返回读入的字节数。
write系统调用的格式
#include < unistd.h>
int write(fd,buf,nbytes)
int fd; /*文件描述符*/
char *buf; /*缓冲区地址*/
unsigned nbytes /*要读的字节数*/
参数与功能说明:
执行成功返回写入的字节数。
文件的随机存取
lseek系统调用的格式
#include < unistd.h>
long lseek(fd,offset,inter)
int fd; /*文件描述符*/
int offset; /*文件偏移量*/
int inter; /*对文件偏移量的解释*/
参数与功能说明:
调整文件的读写指针,调整方式有inter给出。Inter可选用的值为SEEK_SET,SEEK_CUT,SEEK_END
文件控制
fcntl系统调用的格式
#include < fcntl.h>
int fcntl (fd,offset,inter)
int fd; /*文件描述符*/
int cmd; /*命令*/
int arg; /*参数*/
参数与功能说明:
对打开的文件进行控制。Arg根据不同的cmd取不同的值。可取为F_DUPFD,F_GETFD,F_GETFL,F_SETFL;;F_GETLK,F_SETLK,F_SETLKW。
flock结构如下:
struct flock
{
short l_type;
short l_whence;
long l_start;
long l_len;
short l_pid;
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:50:56 | 显示全部楼层
[推荐]系统调用-进程间通信
UNIX系统开发-系统调用-进程间通信
基本上所有的系统调用成功时返回0或正数,失败时返回负值。
进程的用户标志号管理
系统调用的格式
#include <unistd.h>
unsigned short getuid()
unsigned short getgid()
unsigned short geteuid()
unsigned short getegid()
int setuid(int uid)
int setgid(int gid)
int seteuid(int euid)
int setegid(int egid)
参数与功能说明:
前四个系统调用返回进程的实际用户标志号,有效用户标志号,实际用户组标志号和有效组标志号。这些调用总能成功。setuid和setgid用于设置进程的实际用户(组)标志号和有效用户(组)标志号。如果调用进程的有效用户标志号是超级用户标志号,则将调用进程的实际用户(组)标志号和有效用户(组)标志号设为uid和gid;如果调用进程的有效用户标志号不是超级用户标志号,但他的实际用户(组)标志号为uid(gid)时,则其有效用户(组)标志号设为uid或gid。如果调用进程的有效用户标志号不是超级用户标志号,且他的实际用户(组)标志号不为uid(gid)时,则调用失败。Seteuid 和setegid与setuid,setgid类似,只不过只对有效用户(组)标志号起作用。
进程标志号管理
系统调用的格式
#include <sys/types.h>
#include <unistd.h>
int getpid()
int getpgrp()
int getppid()
int setpgrp()
int setsid()
参数与功能说明:
前三个系统调用分别返回进程的进程标志号,进程组标志号和其父进程标志号。他们总能成功返回。第四,五个调用设置进程组标志号,他将调用进程的进程组标志号改为调用进程的进程标志号,使其成为进程组首进程,并返回这一新的进程组标志号。
信号机构
signal系统调用的格式
#include <signal.h>
void (*signal(sig,func))()
int sig; /*信号值 */
void (*func)(); /*信号处理方式*/
参数与功能说明:
按函数func的定义设置调用进程对信号sig的处理方式。执行成功时,返回调用进程先前对信号sig处理方式的值,失败时返回-1。参数func的取值为SIG_DFL,SIG_IGN或用户信号处理函数地址,分别表示缺省方式,或略方式和捕获方式。
sig的取值有(重要的列出)
SIGHUP 挂起。当终端挂起时,该信号发送到和该终端相关的所有进程。当进程组中的首进程因某种原因中断时,也向该组的每个进程发送该信号
SIGINT 中断。当敲击中断键时该信号发送到和该终端相关的所有进程
SIGQUIT 退出。当敲击(ctrl+\)键时该信号发送到和该终端相关的所有进程
SIGKILL 杀死。杀死进程的信号,他不能被ignore
SIGSEGV 段违例
SIGPIPE 写管道错。当进程向一个没有任何读进程的管道写数据时,发送该信号
SIGALRM 报警时钟。
SIGTERM 软件终止信号
SIGUSR1 自定义信号
SIGUSR2 自定义信号
SIGCLD 子进程消亡。当子进程因某种原因而消亡时,它向父进程发送该信号。
SIGURG 紧急的套接口条件
SIGPOLL 在一条流上发生了用户指定的事件时,流控制机制发送该信号到用户进程
pause系统调用的格式
int pause()
参数与功能说明:
使调用进程睡眠直到其接收到一信号为止。该调用的结果依赖进程对接收到的信号的处理方式。
却省方式时,终止调用进程,pause无返回值
或略方式时,调用进程继续睡眠
捕获方式时,调用进程从信号处理函数返回后,继续往下执行,此时其调用的返回值为-1,errno为EINTR
kill系统调用的格式
int kill(pid,sig)
int pid,sig;
参数与功能说明:
把一个信号值为sig的信号发送给进程标志号为pid的相关进程。该调用执行成功与否,依赖于调用进程的有效用户标志号和参数pid的值。
Pid>0:将信号发给进程号等于pid的进程
Pid=0:将信号发给调用进程的同组进程
Pid=-1:将信号发给实际用户号等于调用进程的有效用户标志号的所有进程
非-1的负数:将信号发给进程组标志号为pid绝对值的所有进程
系统调用的格式
#include <signal.h>
void (*sigset(sig,func))()
int sig;
void (* func)();
int sighold(int sig)
int sigrelse(int sig)
int sigignore(int sig)
int sigpause(int sig)
参数与功能说明:
sigset与signal功能基本相同,不同的是sigset 解决了signal系统调用需要重复设置信号捕获函数的问题。
sighold和sigrelse用来建立代码临界区,sigrelse恢复先前由sigset设置的信号方式。
sigignore设置调用进程对信号sig的方式为SIG_IGN,相当与signal(sig,SIG_IGN);
sigpause使调用进程睡眠,直到他接收到一信号为止,类似于pause
跟踪机构
ptrace系统调用的格式
#include <unistd.h>
int ptrace(request,pid,addr,data)
int request,pid,addr,data;
参数与功能说明:
该调用按参数request所提出的请求完成各种操作,参数pid代表需跟踪的进程号,参数addr是子进程地址空间的某一地址,参数data是在addr地址位置上需写入的数值。
管道文件操作
pipe系统调用的格式
#include <unistd.h>
int pipe(pfd)
int pfd[2]
参数与功能说明:
该调用为调用进程创建一个pipe文件,分配两个文件描述符来标志该pipe文件,这两个文件描述符分别放在pfd[0],pfd[1]中,进程用pfd[0]从pipe文件中读数据,而用pfd[1]往pipe文件中写数据。调用成功返回0,失败时返回-1。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:52:10 | 显示全部楼层
[推荐]系统调用-进程间高级通信
UNIX系统开发-系统调用-进程间高级通信
基本上所有的系统调用成功时返回0或正数,失败时返回负值。
消息通信
每个消息队列都有一个msqid_ds类型的控制结构,该结构中包括对消息队列的访问权限,其数据结构如下:
struct msqid_ds
{
struct ipc_perm msg_perm; /*操作权限结构 */
struct msg msg_first; /*指向消息队列的第一个结构*/
struct msg msg_last; /*指向消息队列的最后一个结构*/
ushort msg_cbytes; /*队列中当前字节数*/
ushort msg_qnum; /*队列中消息数*/
ushort msg_qbytes; /*队列可容纳的最大字节数*/
ushort msg_lspid; /*最后发送消息的进程号*/
ushort msg_lrpid; /*最后接收消息的进程号*/
ushort msg_stime; /*最后发送时间*/
ushort msg_rtime; /*最后接收时间*/
time_t msg_ctime; /*消息队列最后修改时间*/
};
msgget系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key,msgflg)
key_t key; /*消息队列关键字*/
int msgflags; /*创建标志和访问方式(类似于文件访问权限)*/
参数与功能说明:
msgflg低9位类似于文件访问权限的低9位,其他位指明消息队列的建立方式:
若指定的关键字消息队列不存在,msgflg&IPC_CREAT为真,则为他建立一个新的消息队列; msgflg&IPC_CREAT为假,返回-1。若指定的关键字消息队列存在,则返回该消息队列的描述符。
若msgflg&IPC_CREAT&IPC_EXCL为真,若指定的关键字消息队列不存在,失败返回-1;否则正常返回。
若key等于IPC_PRIVATE,则msgget调用总是成功的。
msgsnd系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(msqid,msgp,msgsz,msgflg)
int msqid; /*消息队列关键字*/
struct msgbuf msgp; /指向消息缓冲的指针*/
int msgsz,msgflg; /*消息大小、发送标志*/
参数与功能说明:
发送一个消息到相关的消息队列上。其中msgp指向消息结构,他的基本格式是:
struct msgbuf
{
int mtype; /*消息类型*/
char mtext[];/*消息正文*/
}
msgflg具体含义为:
msgflg&IPC_NOWAIT为真,那么如果操作条件不满足,则出错返回-1;
msgflg&IPC_NOWAIT为假,那么如果操作条件不满足,则睡眠等待。;
msgrcv系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(msqid,msgp,msgsz,msgtyp,msgflg)
int msqid; /*消息队列关键字*/
struct msgbuf msgp; /指向消息缓冲的指针*/
int msgsz,msgflg; /*消息大小、发送标志*/
long msgtyp; /*消息接收类型*/
参数与功能说明:
从消息队列中接收一个消息。其中msgp指向消息结构,他的基本格式是:
struct msgbuf
{
int mtype; /*消息类型*/
char mtext[];/*消息正文*/
}
msgflg具体含义为:
msgflg&IPC_NOWAIT为真,那么如果接收的消息没有到达,则出错返回-1;
msgflg&IPC_NOWAIT为假,那么如果接收的消息没有到达,则睡眠等待。;
msgflg&MSG_NOERROR为真,那么如果msgrcv中的msgsz参数小于所接收的消息正文的长度,则本次可以接收msgsz字节,并且不把这种情况视为出错。
msgtyp的取值及含义为:]
msgtyp>0时,接收消息队列中类型为msgtyp的第一个消息。
msgtyp=0时,接收消息队列中的第一个消息。
msgtyp<0时,接收消息队列中类型值msgtyp最小且<=|mstyp|的第一个消息。
msgctl系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(msqid,cmd,buf)
int msqid; /*消息队列关键字*/
int cmd ; /控制命令*/
struct msqid_ds *buf; /*指向消息队列控制块的指针*/
参数与功能说明:
根据控制命令cmd对msqid消息队列进行相应的控制。参数buf是指向用户程序地址空间中一个msqid_ds结构的指针,以便将相关控制信息在核心和用户地址空间之间进行传送。
cmd控制命令的取值及含义如下:
IPC_STAT:将指定消息队列的控制块信息写到buf结构中。
IPC_SET:将buf中信息写到指定消息队列的控制块中。
IPC_RMID:删除指定消息队列,释放消息队列标志符。
共享内存段
每个共享内存段都有一个shmid_ds类型的控制结构,该结构中包括对共享内存段的访问权限,其数据结构如下:
struct shmid_ds
{
struct ipc_perm shm_perm; /*操作权限结构 */
int shm_segsz; /*以字节为单位的共享段大小*/
struct region *shm_reg; /*指向共享段的指针*/
char pad[4]; /*系统使用*/
ushort shm_lpid; /*最后使用shmop的时间*/
ushort shm_cpid; /*创建进程的id*/
ushort shm_nattch; /*系统使用*/
ushort shm_cnattc; /*系统使用*/
time_t shm_atime; /*最后使用shmat的时间*/
time_t shm_dtime; /*最后使用shmdt的时间*/
time_t shm_ctime; /*共享内存段最后修改时间*/
};
shmget系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key,size,shmflg)
key_t key; /*共享内存段关键字*/
int size; /*共享内存段大小*/
int shmflag; /*创建标志和访问方式(类似于文件访问权限)*/
参数与功能说明:
shmflg低9位类似于文件访问权限的低9位,其他位指明消息队列的建立方式:
若指定的关键字消息队列不存在,shmflg&IPC_CREAT为真,则为他建立一个新的消息队列; shmflg&IPC_CREAT为假,返回-1。若指定的关键字消息队列存在,则返回该消息队列的描述符。
若shmflg&IPC_CREAT&IPC_EXCL为真,若指定的关键字消息队列不存在,失败返回-1;否则正常返回。
若key等于IPC_PRIVATE,则shmget调用总是成功的。
shmat系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmat(shmid,addr,shmflg)
int shmid; /*共享内存段标志符*/
char *addr; /*用户指定的一个进程虚拟空间的地址,该共享内存段附在这个地址之后*/
int shmflg; /*创建标志和访问方式(类似于文件访问权限)*/
参数与功能说明:
shmat调用将标志符为shmid的共享内存段映射到进程的虚拟数据空间中,其首地址与参数addr有关。Shmflg为映射标志,说明以何种方式映射及映射到何处。Shmat正常返回该共享内存段在进程虚拟数据空间中的首地址,并且共享内存段访问计数加一;错误返回-1。
shmdt系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmdt(addr)
char *addr; /*用户指定的一个进程虚拟空间的地址,该共享内存段附在这个地址之后*/
参数与功能说明:
shmdt调用将共享内存段脱离到进程的虚拟数据空间中,参数addr是shmat的返回值。shmdt正常返回0,并且共享内存段访问计数减一;错误返回-1。
shmctl系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(shmid,cmd,buf)
int shmid; /*共享内存段关键字*/
int cmd ; /控制命令*/
struct shmid_ds *buf; /*指向共享内存段控制块的指针*/
参数与功能说明:
根据控制命令cmd对shmid所指定的共享内存段进行相应的控制。参数buf是指向用户程序地址空间中一个shmid_ds结构的指针,以便将相关控制信息在核心和用户地址空间之间进行传送。
cmd控制命令的取值及含义如下:
IPC_STAT:将指定共享内存段的控制块信息写到buf结构中。
IPC_SET:将buf中信息写到指定共享内存段的控制块中。
IPC_RMID:删除指定共享内存段,释放共享内存段标志符。
SHM_LOCK:将共享内存段锁定在内存,禁止换出(只有特权用户才能这样用)
SHM_UNLOCK:将共享内存段解锁,允许换出(只有特权用户才能这样用)
信号量
每个信号量组都有一个semid_ds类型的控制结构,该结构中包括对信号量组的访问权限,其数据结构如下:
struct semid_ds
{
struct ipc_perm sem_perm; /*操作权限结构 */
struct sem sem_base; /*指向信号量组的第一个信号量*/
ushort sem_nsems; /*信号量数*/
time_t sem_otime; /*最后使用semop的时间*/
time_t sem_ctime; /*共享内存段最后修改时间*/
};
semget系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key,nsems,shmflg)
key_t key; /*信号量组关键字*/
int nsems; /*信号量组 个数*/
int shmflag; /*创建标志和访问方式(类似于文件访问权限)*/
参数与功能说明:
semget用来创建一个信号量组,其中包含了nsems个信号量,他们的编号是0—nsems-1。信号量组的创建方式及访问权限由semflg决定,其取值与含义与msgget中的msgflg类似。
semop系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(semid,sops,nsops)
int semid; /*信号量组标志符*/
struct sembuf *sops; /*信号量操作缓冲区*/
unsigned nsops; /*操作的信号量个数*/
参数与功能说明:
semop完成对标志符为semid的信号量组中信号量的操作。每次调用semop可以对指定信号量组中的若干信号量进行操作,这被称为信号量”块操作”。参数nsops说明信号量块操作时信号量的个数。Sops是指向sembuf结构的指针,该结构定义了信号量块操作时要操作的信号量编号及操作数。
struct sembuf
{
int sem_num; /*信号量编号*/
int semop; /*信号量操作数*/
int sem_flg; /*操作标志 */
} *sops[nsops];
该结构中的sem_flg为操作标志,sem_op为信号量操作数,该操作对semid信号量组中编号为sem_num的信号量进行操作。Sem_op允许取三种值,其含义如下:
sem_op > 0:将相应信号量的值增加sem_op,如果sem_flg&SEM_UNDO为真,则信号量的调整值件去sem_op;
sem_op = 0:本次操作要对信号量的值做测试,若为0,则立即正常返回。若不为0,则进程开始睡眠,直到其值为0。当sem_flg设置标志IPC_NOWAIT时,进程并不睡眠,而是返回错误。
sem_op < 0:此时的操作依据以下两个条件分别处理:
若信号量当前值>=|sem_op|,则信号量的当前值便减去|sem_op|成为该信号量的新值,又若sem_flg&SEM_UNDO为真,则信号量的调整值加上|sem_op|。
若信号量当前值<|sem_op|,且sem_flg&IPC_NOWAIT为假,那么进程开始睡眠,直当信号量的值大于|sem_op|时,才被唤醒
若信号量当前值<|sem_op|,且sem_flg&IPC_NOWAIT为真,则立即返回。
semctl系统调用的格式
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(semid,semnum.cmd,arg)
int semid; /*信号量组关键字*/
int semnum; /* 信号量编号*/
int cmd ; /控制命令*/
union semun
{
int val;
struct semid_ds *buf; /指向信号量组控制块的指针*/
ushort array[];
}arg; /*控制操作参数*/
参数与功能说明:
用来对指定的信号量组或组中编号为semnum的信号量进行控制。
cmd控制命令的取值及含义如下:
GETVAL:取信号量(semid,semnum)的当前值到arg.val
SETVAL:将信号量(semid,semnum)的当前值置为arg.val的值。
GETPID:把对信号量(semid,semnum)作最后操作的进程pid的值取到arg.val中。
GETNCNT:把在信号量(semid,semnum)上因资源不够,而睡眠的进程个数的值取到arg.val中。
GETZCNT:把在信号量(semid,semnum)上因还有共享资源而睡眠的进程个数的值取到arg.val中。
GETALL:把信号量组中所有信号量的当前值取到arg.array[]中。
SETALL:把信号量组中所有信号量的值分别设为arg.array[]中的值。
IPC_STAT:将指定信号量组的控制块信息写到buf结构中。
IPC_SET:将buf中信息写到指定信号量组的控制块中。
IPC_RMID:删除指定信号量组,释放信号量组标志符。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:53:01 | 显示全部楼层
[推荐]系统调用-STREAM机制
UNIX系统开发-系统调用-STREAM机制
基本上所有的系统调用成功时返回0或正数,失败时返回负值。
流的高级操作
poll系统调用的格式
#include <stropts.h>
#include <poll>
int poll(fds,nfds,timeout)
struct pollfd fds[]; /*流组描述结构*/
unsigned long nfds; /*流个数*/
int timeout; /*查询超时时间*/
参数与功能说明:
参数nfds指出流组中流的个数,而fds是一个流组描述结构,他的格式如下:
struct pollfd
{
int fd; /*流描述符*/
short events; /*用户期望的事件*/
short revents; /*流上发生的事件*/
}fds[nfds];
其功能是查询流组中各条流上是否发生了用户期望的事件。若有事件发生,则将发生的事件登记在流组描述结构的revents域中,返回给用户。如果没有任何事件发生,则睡眠等待直到有事件发生或等待超时。超时时间有参数timeout给出,单位为毫秒。Timeout为-1时,表示timeout取值无穷大,可以无限止地等待。
用户期望的事件有三类,他们的取值及含义如下:
POLLIN:期望相应流上能到达一个数据消息。
POLLOUT:期望能向相应流上发送一个数据消息。
POLLPRI:期望相应流上能到达一个高优先权数据消息(高优先权是一个控制消息)
Revents取值有三种情形:0、已发生的事件、出错事件。
0表示相应流上没有发生任何期望的事件。已发生的事件即是对该流期望的事件;出错事件是poll调用出错时设置的值,他可有三种取值,在revents中可能是这三种值的“或”。出错事件的取值及其含义如下:
POLLERR:流上到达一个错误消息,以后对流的操作不能继续进行。
POLLHUP:流上出现了挂起条件,此后不能对流再发送消息。
POLLNVAL:非法流描述符。
ioctl系统调用的格式
#include <unistd.h>
int ioctl(fd,I_SETSIG,events)
int fd; /*流描述符*/
short events; /*用户设置的期望事件*/
参数与功能说明:
当指定流上发生期望事件时,系统向调用进程发送一个SIGPOLL信号。I_SETSIG命令能设置的期望事件如下:
S_INPUT:流首到达了一个数据消息,在它到达之前,流首没有数据消息存在。
S_OUTPUT:含义同POLLOUT。
S_HIPRI:含义同POLLPRI。
S_MSG:流首到达了含有SIGPOLL信号消息的消息。
putmsg,getmsg系统调用的格式
#include <stropts.h>
int putmsg(fd,ctlptr,dataptr,flags)
int fd; /*流描述符*/
struct strbuf ctlptr; /*控制信息缓冲*/
struct strbuf *dataptr; /*数据信息缓冲*/
int flags ; /*发送标志*/
int getmsg(fd,ctlptr,dataptr,flags)
int fd; /*流描述符*/
struct strbuf ctlptr; /*控制信息缓冲*/
struct strbuf *dataptr; /*数据信息缓冲*/
int flags ; /*接收标志*/
参数与功能说明:
putmsg将具有控制信息和数据信息的消息顺流向下发送,控制信息放入由ctlptr指出的具有strbuf结构形式的缓冲区中,而数据信息放入由 dataptr指出的具有strbuf结构形式的缓冲区中;getmsg与putmsg相反,它从流首接收消息,将数据信息和控制信息分别放入由 dataptr,ctlptr指出的缓冲区中。Strbuf的结构形式如下:
struct strbuf
{
int maxlen; /*缓冲区最大长度*/
int len; /*缓冲区中已有信息的字节数*/
char *buf; /*指向缓冲区的指针*/
}
select系统调用的格式
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
int select(maxfdpl,readfds, writefds,exceptfds,timeout)
int maxfdpl; /*需要轮询的最大描述符*/
fd_set *readfds; /*读就绪描述符*/
fd_set *writefds; /*写就绪描述符*/
fd_set *exceptfds; /*异常条件*/
struct timeval *timeout; /*等待时间*/
参数与功能说明:
本系统调用通过修改readfds,writefds,exceptfds这三个参数来指示各参数中的哪些描述符已对指定的条件就绪。这三个参数也是值结果参数,调用者应使用FD_ISSET宏测试fd_set结构中的指定位。本系统调用返回就绪的描述符总数,如果在任何描述符前定时器值已到,则返回0 值。通常出错时返回值是-1。
select调用涉及到几个宏,现分述如下:
FD_ZERO(fd_set *fdset):在fd_set中清掉所有位。
FD_SET(int fd, fd_set *fdset):在fd_set中把fd位置上。
FD_CLR(int fd,fd_set *fdset):在fd_set中把fd位清掉。
FD_ISSET(int fd,fd_set *fdset):测试fd_set中fd位是否置上。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:53:57 | 显示全部楼层
[推荐]系统调用-time系统调用
UNIX系统开发-系统调用-time系统调用
在计算机的硬件中包含一个系统时钟,系统引导的时候读取该时钟,然后维持它自己的时钟计数器,利用时钟计数器对系统内的事件,如文件的创建或用户登录等给出时间记录。时钟值也可以利用time()系统调用供你自己的程序使用:
#include <sys/types/h>
#include (time.h>
time_t time(time_t *loc);
这个系统调用返回一个time_t值,如果参数loc是指向这种类型的变量的指针,则返回值也被拷贝到这个指针所指的变量中。
数据类型time_t实际上由typedef定义,可以通过<time.h>访问,它的基本数据类型是long。因此time()系统调用返回一个长型整数作为当前时钟的时间值,但是,这是一种奇怪格式,即从格林威治时间1970年1月1日午夜起所经过的秒数(我假定这个时钟必定在某一时刻开始...)。
有一个枝节问题是:它用一个长型整数可以记录多长时间?如果限制在32位长的正整数范围内(负值对时间没有任何意义!),则它刚好超过68年,或者说直到2038年初(还有充裕的时间想一个替代办法)。
这种时间格式实际上相当有用,如果你想要解决两个事件之间(例如你的登录时间和退出系统的时间)经过了多长时间,你只要从较早时间减去较晚时间就得到两个事件之间的秒数。
但是,在你想要显示日,月年或者当天的时间的情况下,这种时间格式就不太方便。为了简化这些操作,标准库中包含一些有用的函数为你进行转换。两个这样的函数是:
#include <time.h>
struct tm *gmtime(time_t *loc);
struct tm *localtime(time_t *loc);
这两个函数都取一个参数loc,它是指向包含‘自1970年以来的秒数’值的变量的指针。这里两个函数都返回指向一个结构的指针,该结构的域包含有要求的信息:
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_lsdst;
}
域tm_hour,tm_min,和tm_sec以24小时的时钟格式给出时钟时间,tm_mday是在1到31范围内的该月的日子,tm_mon是范围为0-11月数,一月(January)作为0,tm_year是自1900以来的年数,tm_wday是范围为0到6的一周的日子,星期天(Sunday)为0,tm_yday是范围为0到365该年的日子,一月一日(1 January)作为0,tm_isdst是一个标志规定夏时制是否有效(如果该信息可供使用)。
这两个函数的主要差别是gmtime()给出的它的相对于格林威治时间(GMT)的时间信息,而localtime()给出的它的相对你的本地时区的时间信息(在系统安装和配置期间设置本地时区)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:54:52 | 显示全部楼层
推荐]系统开发-守护进程
UNIX系统开发-守护进程
守护进程(Demons)是在后台运行而有无终端或者登录shell和它结合在一起的进程。有许多标准的守护进程,其中的一些周期地运行来完成特定的任务(像atrun,典型地由cron每五分钟执行一次),而其余的则连续地运行,等待处理某些特定的事件(像inetd和lpd)。
1.原理
有几种启动守护进程的方法。最常用的是:
在引导系统时启动。在这时运行的守护进程通常在系统启动script的执行周期间被启动。这些script典型地被存放在目录/etc/rc.d中。
手工地,从shell提示符启动.对任何具有相应的执行权限的用户可以用这种方法启动守护进程
由crond守护进程启动。这个程序查询通常存放在/var/spool/crontabs目录中的一组文件,它们规定了要执行的周期性任务
由执行at命令启动。这将使一个程序在规定的日期和时间执行一次。
为了做到完全稳定可靠,一个守护进程应该能够在所有的这些方式下被正确地执行。唯一问题是其中的一些启动方法使守护进程处于一种脆弱状态。它可能受到在它运行之前为它设置的环境的影响。你将要写的将普通程序转换成守护程序的大部分代码将涉及到把你的程序与这些环境影响隔离开。除此之外,准备作为守护进程使用的程序通常必须比普通的用户程序更可靠。你常常需要这样去编写程序,使得当它作为守护程序运行时,即使出现各种类型的系统错误,也不至于引起程序的崩溃。
2.实践
在启动守护进程的过程中,包含了比你能想象的更多的步骤,虽然它们全部可能只用极少的代码去完成。本节的其余部分将逐步介绍这一过程的更重要的方面。
2.1 关闭文件描述符
第一项任务是关闭所有不必要的文件描述符。如果你的守护进程留下一个普通文件处于打开状态,这将阻止该文件被任何其他进程从文件系统中删除。它也阻止包含该打开文件的已装配的文件系统被卸下。在终端文件(通常是stdin,stdout和stderr)的情况下,关闭不必要的连接更加重要。因为当在该终端上的用户退出系统后,将执行vhangup()系统调用,守护进程访问该终端的权利将被撤消。这表示守护进程虽然由它认为处于打开状态的文件描述符,事实上它已不再能通过这些文件描述符访问该终端。
最简单的做法是关闭所有的文件描述符,它将使守护进程和这些问题隔离开。将close()系统调用用在没有打开的文件描述符上不存在任何问题,所以下列的代码段可以被使用:
#include <sys/parm.h>
for (id=1;i<NOFILE;++i)
close(i);
符号常量NOFILE给出一个进程一次可以打开的文件的最大个数。
2.2 甩开控制终端
如果一个进程是从登录对话过程中被启动,而它将从对话过程中继承与它结合的控制终端。对于守护进程来说,其结果是它可以接收由该控制终端产生的信号(诸如 SIGINT和SIGQUIT),如果这些信号不被捕获,将结束该进程。这个问题可以由守护进程忽略所有它可能忽略的信号而加以克服,但是这将阻止守护进程利用信号作为简单的进程间通信手段使用。一个较好的解决方式是使用守护进程本身和控制终端分开,使得这些信号首先不传播到守护进程。
在linux下这样做的一种方法是打开文件/dev/tty,并且使用ioctl()在该文件上执行TIOCNOTTY命令。它使得每一个具有控制终端的进程通过文件/dev/tty访问那个终端。
简短的代码如下:
if((fd=open("/dev/tty",D_RDWR))>=0)
{
ioctr(fd,TIOCNOTTY,0);
close(fd);
}
在LIUNX下,这不是使进程本身和它的控制终端分离的唯一的方法。事实上,在下一节中我们将看到做这件事的更简单的方法。
2.3 脱离对话过程和进程组
进程从它的双亲进程获得它的对话过程和进程组识别号。由于它属于一个对话过程和一个进程组,一个进程将接收到任何作为整体发送给该对话过程或进程组的信号。这类似于从控制终端接收信号的问题,并且实际的解决方法也是同样的,即将进程和这一环境影响分开。
在POSIX中存在一个单一的系统调用,它将进程和它的当前的对话过程和进程组分离开,并且把它设置为一个新的对话过程的领头进程(leader)。这个系统调用设置对话过程识别号:
setsid()
由于一个控制终端仅可以和单一的对话过程相联,作为setsid()调用的副作用,它也把进程和它的控制终端(如果它有控制终端的话)分离开。
setsid()的唯一问题是:只有执行它的守护进程不是对话过程的领头进程(leader)时,它才能发挥作用。在我们的情况下,容易假定该守护进程不是对话过程的领头进程,但是这不能保证,除非采取特殊步骤使它成为这样。你可以毫无疑问地这样说:如果一个特定的对话过程的领头进程执行了fork()系统调用,则默认地这一子女进程应该不是对话过程的领头进程。这提供了确保执行setsid()的守护进程不是对话过程的领头进程的机制。守护进程需要做的只是按如下所示的执行fork()调用,然后在双亲进程中执行exit(),并且在子女进程中执行sesid():
/*(在这以后,子女进程不再是对话过程的领头进程)*/
if (fork())
/*不管它的状态如何结束双亲进程*/
exit(0);
/*(把子女进程和对话过程,进程组及tty分离)*/
setsid();
即使采取了这些措施,还没有彻底解决将守护进程和它的控制终端分离的全部问题。这是由于当一个没有控制终端的对话过程的领头进程(就像我们限现在的情况)打开其本身还不是另一个对话过程的控制终端的终端设备时,该终端将自动变成新的对话过程的控制终端。
但是注意,以这种方式获得控制终端仅可以由对话过程的领头进程完成。因此,明显的解决办法是要确保我们的进程不再是对话过程的领头进程。这可以由第二次执行fork()以及再次结束双亲进程来完成。这留下一个不属于其原始对话过程或进程组的子女进程,它没有控制终端,而且现在也不能再重新获得一个控制终端。所要求的代码如下:
/*(启动新的对话过程,脱离旧的的对话过程和进程组)*/
if (fork())
exit(0);
/*(把进程组和控制终端分离)*/
setsid();
/*(变成一个非对话过程的领头进程)*/
/*(使它不可能重新获得控制终端)*/
if (fork())
exit(0);
2.4 改变工作目录
在进程存在期间,内核(kernel)保存系统中的任何进程打开的当前工作目录。在正常的情况下,这不成为一个问题。但是如果该进程在已经装配的文件系统上有一个当前工作目录,则该文件系统被标记为“在使用的(in use)'状态,而且它不可以被卸下。为了允许系统超级用户(superuser)卸下文件系统,守护进程可以执行:
chdir("/");
为了正确的进行操作,一个守护进程也可能必须用chdir()改变到一个特定的目录。 其中服务程序可以提供的所有文件都放在守护进程的当前的工作目录中。在这种情况下,你不得不接收限制,或者由系统管理员在根(root)文件系统中提供守护进程可以运行的一个位置。将当前工作目录改变到根目录可能出现的一个问题。如果出现守护进程结束运行和卸出一个核心(core)文件的情况下,内核将试图打开当前目录中的文件。如果这是根目录,则操作将失败,除非守护进程正在用超级用户的权限运行。
为了克服这个问题,下面将使用/tmp作为当前目录。通常它只是根文件系统的一个子目录,并且所有进程都有写的权限;
chdir("/tmp");
2.5 重新设置文件的创建掩码
进程一开始,它继承它的双亲进程的文件创建掩码。典型地,它具有022值,表示由守护进程创建的任何文件将不把写的权限给组和其他用户,不管守护进程本身规定什么权限位。依赖于守护进程的性质,这个操作可能或不可能成为问题。但是,将下列行包括在你的代码中,取消由双亲进程设置的文件创建掩码值产生的效果将是一件简单的事情,无论它当前是什么值:
umask(0);
即使到现在,仍然存在从双亲进程继承的环境中的一些特性。它们可以使守护进程产生某些问题。例如,nice()进程设置的优先权,或者用alarm()设置的闹钟信号留下的时间。但是,虽然这些事情是可能的,它应该是相当恶意的双亲进程给粗心大意的守护进程设置的陷阱。
2.6 处理SIGCHLD信号
有时守护进程被写成创建子女进程。在此情况下,双亲进程保持循环接收更多的客户连接,而子女进程服务客户的请求。注意,双亲进程不执行wait()系统调用等待它的子女进程的结束。默认地,在这个情况下的子女进程将变成zombie,直到将来某个进程(很可能是init)等待它们为止。在这些情况下 zombie的创建浪费系统资源。在LINUX下有几种方法可以绕过这个问题。最简单的是按照如下的方式将SIGGHLD信号的操作设置为 SIG_IGN;
signal(SIGGHLD,SIG_IGN);
这是SIGCHLD信号的特殊的特征,它告诉内核(kernel)不从调用进程的子女进程中产生zombie。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:56:06 | 显示全部楼层
推荐]UNIX系统编程常用库函数说明
系统管理-UNIX编程-UNIX系统编程常用库函数说明
UNIX系统为程序员提供了许多子程序,这些子程序可存取各种安全属性.有 些是信息子程序,返回文件属性,实际的和有效的UID,GID等信息.有些子程序可 改变文件属性.UID,GID等有些处理口令文件和小组文件,还有些完成加密和解密. 本文主要讨论有关系统子程序,标准C库子程序的安全,如何写安全的C程序 并从root的角度介绍程序设计(仅能被root调用的子程序).
1.系统子程序
(1)I/O子程序
*creat():建立一个新文件或重写一个暂存文件. 需要两个参数:文件名和存取许可值(8进制方式).如: creat ("/usr/pat/read_write",0666) /* 建立存取许可方式为0666的文件 */ 调用此子程序的进程必须要有建立的文件的所在目录的写和执行许可,置 给creat()的许可方式变量将被umask()设置的文件建立屏蔽值所修改,新 文件的所有者和小组由有效的UID和 GID决定. 返回值为新建文件的文件描述符.
*fstat():见后面的stat().
*open():在C程序内部打开文件. 需要两个参数:文件路径名和打开方式(I,O,I&O). 如果调用此子程序的进程没有对于要打开的文件的正确存取许可(包括文 件路径上所有目录分量的搜索许可),将会引起执行失败. 如果此子程序被调用去打开不存在的文件,除非设置了O_CREAT标志,调用 将不成功.此时,新文件的存取许可作为第三个参数(可被用户的umask修 改).
当文件被进程打开后再改变该文件或该文件所在目录的存取许可,不影响对该文件的I/O操作.
*read():从已由open()打开并用作输入的文件中读信息. 它并不关心该文件的存取许可.一旦文件作为输入打开,即可从该文件中读 取信息.
*write():输出信息到已由open()打开并用作输出的文件中.同read()一样 它也不关心该文件的存取许可.
(2)进程控制
*exec()族:包括execl(),execv(),execle(),execve(),execlp()和execvp() 可将一可执行模快拷贝到调用进程占有的存贮空间.正被调用进 程执行的程序将不复存在,新程序取代其位置. 这是UNIX系统中一个程序被执行的唯一方式:用将执行的程序复盖原有的 程序.
安全注意事项:
. 实际的和有效的UID和GID传递给由exec()调入的不具有SUID和SGID许 可的程序.
. 如果由exec()调入的程序有SUID和SGID许可,则有效的UID和GID将设 置给该程序的所有者或小组
. 文件建立屏蔽值将传递给新程序.
. 除设了对exec()关闭标志的文件外,所有打开的文件都传递给新程序. 用fcntl()子程序可设置对exec()的关闭标志.
*fork():用来建立新进程.其建立的子进程是与调用fork()的进程(父进程) 完全相同的拷贝(除了进程号外)
安全注意事项:
. 子进程将继承父进程的实际和有效的UID和GID. . 子进程继承文件方式建立屏蔽值.
. 所有打开的文件传给子进程.
*signal():允许进程处理可能发生的意外事件和中断. 需要两个参数:信号编号和信号发生时要调用的子程序. 信号编号定义在signal.h 中. 信号发生时要调用的子程序可由用户编写,也可用系统给的值,如:SIG_IGN 则信号将被忽略,SIG_DFL则信号将按系统的缺省方式处理.  如许多与安全有关的程序禁止终端发中断信息(BREAK和DELETE),以免自己 被用户终端终止运行. 有些信号使UNIX系统的产生进程的核心转储 (进程接收到信号时所占内存 的内容,有时含有重要信息),此系统子程序可用于禁止核心转储.
(3)文件属性
*access():检测指定文件的存取能力是否符合指定的存取类型. 需要两个参数:文件名和要检测的存取类型(整数).
存取类型定义如下:
0: 检查文件是否存在
1: 检查是否可执行(搜索)
2: 检查是否可写
3: 检查是否可写和执行
4: 检查是否可读
5: 检查是否可读和执行
6: 检查是否可读可写可执行
这些数字的意义和chmod命令中规定许可方式的数字意义相同. 此子程序使用实际的UID和GID检测文件的存取能力(一般有效的UID和GID 用于检查文件存取能力). 返回值: 0:许可 -1:不许可.
*chmod():将指定文件或目录的存取许可方式改成新的许可方式. 需要两个参数:文件名和新的存取许可方式.
*chown():同时改变指定文件的所有者和小组的UID和GID.(与chown命令不 同). 由于此子程序同时改变文件的所有者和小组,故必须取消所操作文件的SUID 和SGID许可,以防止用户建立SUID和SGID程序,然后运行chown()去获得别 人的权限.
*stat():返回文件的状态(属性). 需要两个参数:文件路径名和一个结构指针,指向状态信息的存放 的位置. 结构定义如下: st_mode:  文件类型和存取许可方式 st_ino: I节点号 st_dev: 文件所在设备的ID st_rdev: 特别文件的ID st_nlink: 文件链接数 st_uid: 文件所有者的UID st_gid: 文件小组的GID st_size: 按字节计数的文件大小 st_atime: 最后存取时间(读) st_mtime: 最后修改时间(写)和最后状态的改变 st_ctime: 最后的状态修改时间 返回值: 0:成功 1:失败
*umask():将调用进程及其子进程的文件建立屏蔽值设置为指定的存取许可. 需要一个参数: 新的文件建立屏值.
(4)UID和GID的处理
*getuid():返回进程的实际UID.
*getgid():返回进程的实际GID. 以上两个子程序可用于确定是谁在运行进程.
*geteuid():返回进程的有效UID.
*getegid():返回进程的有效GID. 以上两个子程序可在一个程序不得不确定它是否在运行某用户而不是运行 它的用户的SUID程序时很有用,可调用它们来检查确认本程序的确是以该 用户的SUID许可在运行.
*setuid():用于改变有效的UID. 对于一般用户,此子程序仅对要在有效和实际的UID之间变换的SUID程序才 有用(从原有效UID变换为实际UID),以保护进程不受到安全危害.实际上该 进程不再是SUID方式运行. *setgid():用于改变有效的GID.
2.标准C库
(1)标准I/O
*fopen():打开一个文件供读或写,安全方面的考虑同open()一样.
*fread(),getc(),fgetc(),gets(),scanf()和fscanf():从已由fopen()打 开供读的文件中读取信息.它们并不关心文件的存取许可.这一点 同read().
*fwrite(),put(),fputc(),puts,fputs(),printf(),fprintf():写信息到 已由fopen()打开供写的文件中.它们也不关心文件的存取许可. 同write().
*getpass():从终端上读至多8个字符长的口令,不回显用户输入的字符. 需要一个参数: 提示信息. 该子程序将提示信息显示在终端上,禁止字符回显功能,从/dev/tty读取口 令,然后再恢复字符回显功能,返回刚敲入的口令的指针.
*popen():将在(5)运行shell中介绍.
(2)/etc/passwd处理
有一组子程序可对/etc/passwd文件进行方便的存取,可对文件读取到入口 项或写新的入口项或更新等等.
*getpwuid():从/etc/passwd文件中获取指定的UID的入口项.
*getpwnam():对于指定的登录名,在/etc/passwd文件检索入口项.
以上两个子程序返回一指向passwd结构的指针,该结构定义在 /usr/include/pwd.h中,定义如下: struct passwd {
char * pw_name; /* 登录名 */
char * pw_passwd; /* 加密后的口令 */
uid_t pw_uid; /* UID */
gid_t pw_gid; /* GID */
char * pw_age; /* 代理信息 */
char * pw_comment; /* 注释 */
char * pw_gecos;
char * pw_dir; /* 主目录 */
char * pw_shell; /* 使用的shell */
};
*getpwent(),setpwent(),endpwent():对口令文件作后续处理.
首次调用getpwent(),打开/etc/passwd并返回指向文件中第一个入口项的 指针,保持调用之间文件的打开状态. 再调用 getpwent()可顺序地返回口令文件中的各入口项. 调用setpwent()把口令文件的指针重新置为文件的开始处. 使用完口令文件后调用 endpwent()关闭口令文件.
*putpwent():修改或增加/etc/passwd文件中的入口项.
此子程序将入口项写到一个指定的文件中,一般是一个临时文件,直接写口令文件是很危险的.最好在执行前做文件封锁,使两个程序不能同时写一个 文件.
算法如下:
. 建立一个独立的临时文件,即/etc/passnnn,nnn是PID号.
. 建立新产生的临时文件和标准临时文件/etc/ptmp的链,若建链失败, 则为有人正在使用/etc/ptmp,等待直到/etc/ptmp可用为止或退出.
. 将/etc/passwd拷贝到/etc/ptmp,可对此文件做任何修改.
. 将/etc/passwd移到备份文件/etc/opasswd.
. 建立/etc/ptmp和/etc/passwd的链.
. 断开/etc/passnnn与/etc/ptmp的链.
注意:临时文件应建立在/etc目录,才能保证文件处于同一文件系统中,建 链才能成功,且临时文件不会不安全.此外,若新文件已存在,即便建 链的是 root用户,也将失败,从而保证了一旦临时文件成功地建链后 没有人能再插进来干扰.当然,使用临时文件的程序应确保清除所有 临时文件,正确地捕捉信号.
(3)/etc/group的处理
有一组类似于前面的子程序处理/etc/group的信息,使用时必须用include 语句将/usr/include/grp.h文件加入到自己的程序中.该文件定义了group 结构,将由getgrnam(),getgrgid(),getgrent()返回group结构指针.
*getgrnam():在/etc/group文件中搜索指定的小组名,然后返回指向小组入 口项的指针.
*getgrgid():类似于前一子程序,不同的是搜索指定的GID.
*getgrent():返回group文件中的下一个入口项.
*setgrent():将group文件的文件指针恢复到文件的起点.
*endgrent():用于完成工作后,关闭group文件.
*getuid():返回调用进程的实际UID.
*getpruid():以getuid()返回的实际UID为参数,确定与实际UID相应的登录 名,或指定一UID为参数.
*getlogin():返回在终端上登录的用户的指针. 系统依次检查STDIN,STDOUT,STDERR是否与终端相联,与终端相联的标准输 入用于确定终端名,终端名用于查找列于/etc/utmp文件中的用户,该文件 由login维护,由who程序用来确认用户.
*cuserid():首先调用getlogin(),若getlogin()返回NULL指针,再调用 getpwuid(getuid()).
*以下为命令:
*logname:列出登录进终端的用户名.
*who am I:显示出运行这条命令的用户的登录名.
*id:显示实际的UID和GID(若有效的UID和GID和实际的不同时也显示有效的 UID和GID)和相应的登录名.
(4)加密子程序
1977年1月,NBS宣布一个用于美国联邦政府ADP系统的网络的标准加密法:数 据加密标准即DES用于非机密应用方面.DES一次处理64BITS的块,56位的加 密键.
*setkey(),encrypt():提供用户对DES的存取.
此两子程序都取64BITS长的字符数组,数组中的每个元素代表一个位,为0 或1.setkey()设置将按DES处理的加密键,忽略每第8位构成一个 56位的加 密键.encrypt()然后加密或解密给定的64BITS长的一块,加密或解密取决 于该子程序的第二个变元,0:加密 1:解密.
*crypt():是UNIX系统中的口令加密程序,也被/usr/lib/makekey命令调用. Crypt()子程序与crypt命令无关,它与 /usr/lib/makekey一样取8个字符长 的关键词,2个salt字符.关键词送给setkey(),salt字符用于混合encrypt()  中的DES算法,最终调用encrypt()重复25次加密一个相同的字符串. 返回加密后的字符串指针.
(5)运行shell
*system():运行/bin/sh执行其参数指定的命令,当指定命令完成时返回.
*popen():类似于system(),不同的是命令运行时,其标准输入或输出联到由 popen()返回的文件指针. 二者都调用fork(), exec(),popen()还调用pipe(),完成各自的工作,因而 fork()和exec()的安全方面的考虑开始起作用.
3.写安全的C程序
一般有两方面的安全问题,在写程序时必须考虑:
(1)确保自己建立的任何临时文件不含有机密数据,如果有机密数据,设置 临时文件仅对自己可读/写.确保建立临时文件的目录仅对自己可写.
(2)确保自己要运行的任何命令(通过system(),popen(),execlp(), execvp()运行的命令)的确是自己要运行的命令,而不是其它什么命 令,尤其是自己的程序为SUID或SGID许可时要小心.
第一方面比较简单,在程序开始前调用umask(077).若要使文件对其他人可 读,可再调chmod(),也可用下述语名建立一个"不可见"的临时文件.
Creat("/tmp/xxx",0);
file=open("/tmp/xxx",O_RDWR);
unlink("/tmp/xxx");
文件/tmp/xxx建立后,打开,然后断开链,但是分配给该文件的存储器并未删 除,直到最终指向该文件的文件通道被关闭时才被删除.打开该文件的进程  和它的任何子进程都可存取这个临时文件,而其它进程不能存取该文件,因 为它在/tmp中的目录项已被unlink()删除.
第二方面比较复杂而微妙,由于system(),popen(),execlp(),execvp()执行 时,若不给出执行命令的全路径,就能"骗"用户的程序去执行不同的命令.因 为系统子程序是根据PATH变量确定哪种顺序搜索哪些目录,以寻找指定的命 令,这称为SUID陷井.最安全的办法是在调用system()前将有效UID改变成实 际UID,另一种比较好的方法是以全路径名命令作为参数.execl(),execv(), execle (),execve()都要求全路径名作为参数.有关SUID陷井的另一方式是 在程序中设置PATH,由于system()和popen()都启动 shell,故可使用shell句 法.
如:
system("ATH=/bin:/usr/bin cd");
这样允许用户运行系统命令而不必知道要执行的命令在哪个目录中,但这种 方法不能用于execlp(),execvp()中,因为它们不能启动shell执行调用序列 传递的命令字符串.
关于shell解释传递给system()和popen()的命令行的方式,有两个其它的问 题:
*shell使用IFS shell变量中的字符,将命令行分解成单词(通常这个 shell变量中是空格,tab,换行),如IFS中是/,字符串/bin/ed被解释成单词 bin,接下来是单词ed,从而引起命令行的曲解.
再强调一次:在通过自己的程序运行另一个程序前,应将有效UID改为实际的 UID,等另一个程序退出后,再将有效UID改回原来的有效UID.
SUID/SGID程序指导准则
(1)不要写SUID/SGID程序,大多数时候无此必要.
(2)设置SGID许可,不要设置SUID许可.应独自建立一个新的小组.
(3)不要用exec()执行任何程序.记住exec()也被system()和popen()调用.
. 若要调用exec()(或system(),popen()),应事先用setgid(getgid()) 将有效GID置加实际GID. . 若不能用setgid(),则调用system()或popen()时,应设置IFS: popen("IFS=\t\n;export IFS; /bin/ls","r");
. 使用要执行的命令的全路径名.
. 若不能使用全路径名,则应在命令前先设置PATH: popen("IFS=\t\n;export IFSATH=/bin:/usr/bin;/bin/ls","r");
. 不要将用户规定的参数传给system()或popen();若无法避免则应检查 变元字符串中是否有特殊的shell字符.
. 若用户有个大程序,调用exec()执行许多其它程序,这种情况下不要将 大程序设置为SGID许可.可以写一个(或多个)更小,更简单的SGID程序 执行必须具有SGID许可的任务,然后由大程序执行这些小SGID程序.
(4)若用户必须使用SUID而不是SGID,以相同的顺序记住(2),(3)项内容,并 相应调整.不要设置root的SUID许可.选一个其它户头.
(5)若用户想给予其他人执行自己的shell程序的许可,但又不想让他们能 读该程序,可将程序设置为仅执行许可,并只能通过自己的shell程序来 运行.
编译,安装SUID/SGID程序时应按下面的方法
(1)确保所有的SUID(SGID)程序是对于小组和其他用户都是不可写的,存取 权限的限制低于4755(2755)将带来麻烦.只能更严格.4111(2111)将使 其他人无法寻找程序中的安全漏洞.
(2)警惕外来的编码和make/install方法
. 某些make/install方法不加选择地建立SUID/SGID程序.
. 检查违背上述指导原则的SUID/SGID许可的编码.
. 检查makefile文件中可能建立SUID/SGID文件的命令.
4.root程序的设计
有若干个子程序可以从有效UID为0的进程中调用.许多前面提到的子程序, 当从root进程中调用时,将完成和原来不同的处理.主要是忽略了许可权限的检 查. 由root用户运行的程序当然是root进程(SUID除外),因有效UID用于确定文 件的存取权限,所以从具有root的程序中,调用 fork()产生的进程,也是root进程.
(1)setuid():从root进程调用setuid()时,其处理有所不同,setuid()将把有 效的和实际的UID都置为指定的值.这个值可以是任何整型数.而对非root 进程则仅能以实际UID或本进程原来有效的UID为变量值调用setuid().
(2)setgid():在系统进程中调用setgid()时,与setuid()类似,将实际和有效 的GID都改变成其参数指定的值. * 调用以上两个子程序时,应当注意下面几点: . 调用一次setuid()(setgid())将同时设置有效和实际UID(GID),独立分 别设置有效或实际 UID(GID)固然很好,但无法做到这点. . Setuid()(setgid())可将有效和实际UID(GID)设置成任何整型数,其数 值不必一定与/etc/passwd(/etc/group)中用户(小组)相关联. . 一旦程序以一个用户的UID了setuid(),该程序就不再做为 root运行,也 不可能再获root特权.
(3)chown():当root进程运行chown()时,chown()将不删除文件的SUID和/或 SGID许可,但当非root进程运行chown()时,chown()将取消文件的SUID和/ 或SGID许可.
(4)chroot():改变进程对根目录的概念,调用chroot()后,进程就不能把当前 工作目录改变到新的根目录以上的任一目录,所有以/开始的路径搜索,都 从新的根目录开始.
(5)mknod():用于建立一个文件,类似于creat(),差别是mknod()不返回所打开 文件的文件描述符,并且能建立任何类型的文件(普通文件,特殊文件,目录 文件).若从非root进程调用mknod()将执行失败,只有建立FIFO特别文件 (有名管道文件)时例外,其它任何情况下, 必须从root进程调用mknod().由 于creat()仅能建立普通文件,mknod()是建立目录文件的唯一途径,因而仅 有root能建立目录,这就是为什么mkdir命令具有SUID许可并属root所有. 一般不从程序中调用mknod().通常用/etc/mknod命令建立特别设备文件而 这些文件一般不能在使用着时建立和删除,mkdir命令用于建立目录.当用 mknod()建立特别文件时,应当注意确从所建的特别文件不允许存取内存, 磁盘,终端和其它设备.
(6)unlink():用于删除文件.参数是要删除文件的路径名指针.当指定了目录 时,必须从root进程调用unlink(),这是必须从root进程调用unlink()的唯 一情况,这就是为什么rmdir命令具有root的SGID许可的原因.
(7)mount(),umount():由root进程调用,分别用于安装和拆卸文件系统.这两 个子程序也被mount和umount命令调用,其参数基本和命令的参数相同.调 用mount(),需要给出一个特别文件和一个目录的指针,特别文件上的文件 系统就将安装在该目录下,调用时还要给出一个标识选项,指定被安装的文 件系统要被读/写(0)还是仅读(1).umount()的参数是要一个要拆卸的特别 文件的指针.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 18:58:29 | 显示全部楼层
[推荐]系统安全(系统管理员篇)
系统安全-文章-系统安全(系统管理员篇)
本文从系统管理员的角度讨论安全问题.系统管理员是管理系统的人:启动系统,停止系统运行,安装新软件,增加新用户,删除老用户,以及完成保持系统发
展和运行的日常事务工作.
1.安全管理
安全管理主要分为四个方面:
(1)防止未授权存取:这是计算机安全最重要的问题:未被使用系统的人进入系
统.用户意识,良好的口令管理(由系统管理员和用户双方配合),登录活动
记录和报告,用户和网络活动的周期检查,这些都是防止未授权存取的关键.
(2)防止泄密:这也是计算机安全的一个重要问题.防止已授权或未授权的用户
相互存取相互的重要信息.文件系统查帐,su登录和报告,用户意识,加密都
是防止泄密的关键.
(3)防止用户拒绝系统的管理:这一方面的安全应由操作系统来完成.一个系统
不应被一个有意试图使用过多资源的用户损害.不幸的是,UNIX不能很好地
限制用户对资源的使用,一个用户能够使用文件系统的整个磁盘空间,而
UNIX基本不能阻止用户这样做.系统管理员最好用PS命令,记帐程序df和du周期地检查系统.查出过多占用CUP的进程和大量占用磁盘的文件.
(4)防止丢失系统的完整性:这一安全方面与一个好系统管理员的实际工作(例如:周期地备份文件系统,系统崩溃后运行fsck检查,修复文件系统,当有新
用户时,检测该用户是否可能使系统崩溃的软件)和保持一个可靠的操作系
统有关(即用户不能经常性地使系统崩溃).
本文其余部分主要涉及前两个问题,第三个问题在"安全查帐"一节讨论.
2.超级用户
一些系统管理命令只能由超级用户运行.超级用户拥有其他用户所没有的特
权,超级用户不管文件存取许可方式如何,都可以读,写任何文件,运行任何程序.
系统管理员通常使用命令: /bin/su 或以 root 进入系统从而成为超级用户.在
后面文章中以#表示应敲入必须由超级用户运行的命令,用$表示应敲入由所有其
他用户运行的命令.
3.文件系统安全
(1)UNIX文件系统概述
UNIX文件系统是UNIX系统的心脏部分,提供了层次结构的目录和文件.文
件系统将磁盘空间划分为每1024个字节一组,称为块(block)(也有用512字节
为一块的,如:SCO XENIX).编号从0到整个磁盘的最大块数.
全部块可划分为四个部分,块0称为引导块,文件系统不用该块;块1称为专
用块,专用块含有许多信息,其中有磁盘大小和全部块的其它两部分的大小.从
块2开始是i节点表,i节点表中含有i节点,表的块数是可变的,后面将做讨论.
i节点表之后是空闲存储块(数据存储块),可用于存放文件内容.
文件的逻辑结构和物理结构是十分不同的,逻辑结构是用户敲入cat命令
后所看到的文件,用户可得到表示文件内容的字符流.物理结构是文件实际上
如何存放在磁盘上的存储格式.用户认为自己的文件是边疆的字符流,但实际
上文件可能并不是以边疆的方式存放在磁盘上的,长于一块的文件通常将分散
地存放在盘上.然而当用户存取文件时,UNIX文件系统将以正确的顺序取各块,
给用户提供文件的逻辑结构.
当然,在UNIX系统的某处一定会有一个表,告诉文件系统如何将物理结构
转换为逻辑结构.这就涉及到i节点了.i节点是一个64字节长的表,含有有关一个文件的信息,其中有文件大小,文件所有者,文件存取许可方式,以及文件为普通文件,目录文件还是特别文件等.在i节点中最重要的一项是磁盘地址表.该表中有13个块号.前10个块号是文件前10块的存放地址.这10个块号能给出一个至多10块长的文件的逻辑结构,文件将以块号在磁盘地址表中出现的顺序依次取相应的块.
当文件长于10块时又怎样呢?磁盘地址表中的第十一项给出一个块号,这个块号指出的块中含有256个块号,至此,这种方法满足了至多长于266块的文
件(272,384字节).如果文件大于266块,磁盘地址表的第十二项给出一个块号,
这个块号指出的块中含有256个块号,这256个块号的每一个块号又指出一块,块中含256个块号,这些块号才用于取文件的内容.磁盘地址中和第十三项索引寻址方式与第十二项类似,只是多一级间接索引.
这样,在UNIX系统中,文件的最大长度是16,842,762块,即17,246,988,288
字节,有幸是是UNIX系统对文件的最大长度(一般为1到2M字节)加了更实际的限制,使用户不会无意中建立一个用完整个磁盘窨所有块的文件.
文件系统将文件名转换为i节点的方法实际上相当简单.一个目录实际上
是一个含有目录表的文件:对于目录中的每个文件,在目录表中有一个入口项,入口项中含有文件名和与文件相应的i节点号.当用户敲入cat xxx时,文件系
统就在当前目录表中查找名为xxx的入口项,得到与文件xxx相应的i节点号,然后开始取含有文件xxx的内容的块.
(2)设备文件
UNIX系统与边在本系统上的各种设备之间的通讯,通过特别文件来实现,
就程序而言,磁盘是文件,MODEM是文件,甚至内存也是文件.所有连接到系统上的设备都在/dev目录中有一个文件与其对应.当在这些文件上执行I/O 操作时,由UNIX系统将I/O操作转换成实际设备的动作.例如,文件/dev/mem是系统的内存,如果cat这个文件,实际上是在终端显示系统的内存.为了安全起见,这个文件对普通用户是不可读的.因为在任一给定时间,内存区可能含有用户登录口令或运行程序的口令,某部分文件的编辑缓冲区,缓冲区可能含有用ed -x命令解密后的文本,以及用户不愿让其他人存取的种种信息.在/dev中的文件通常称为设备文件,用ls /dev命令可以看看系统中的一些设备:
acuo 呼叫自动拨号器
console 系统控制台
dsknn 块方式操作磁盘分区
kmem 核心内存
mem 内存
lp 打印机
mto 块方式操作磁带
rdsknn 流方式操作的磁盘分区
rmto 流方式操作的磁带
swap 交换区
syscon 系统终端
ttynn 终端口
x25 网络端口
等等
(3)/etc/mknod命令
用于建立设备文件.只有root能使用这个命令建立设备文件.其参数是文
件名,字母c或b分别代表字符特别文件或块特别文件,主设备号,次设备号.块特别文件是像磁带,磁盘这样一些以块为单位存取数据的设备.字符特别文件.是如像终端,打印机,MODEM,或者其它任何与系统通讯时,一次传输一个字符的
设备,包括模仿对磁盘进行字符方式存取的磁盘驱动器.主设备号指定了系统
子程序(设备驱动程序),当在设备上执行I/O时,系统将调用这个驱动程序.调
用设备驱动程序时,次设备号将传递给该驱动程序(次设备规定具体的磁盘驱
动器,带驱动器,信号线编号,或磁盘分区).每种类型的设备一般都有自己的设
备驱动程序.
文件系统将主设备号和次设备号存放在i节点中的磁盘地址表内,所以没
有磁盘空间分配给设备文件(除i节点本身占用的磁盘区外).当程序试图在设
备文件上执行I/O操作时,系统识别出该文件是一个特别文件,并调用由主设备号指定的设备驱动程序,次设备号作为调用设备驱动程序的参数.
(4)安全考虑
将设备处理成文件,使得UNIX程序独立于设备,即程序不必一定要了解正
使用的设备的任何特性,存取设备也不需要记录长度,块大小,传输速度,网络
协议等这样一些信息,所有烦人的细节由设备驱动程序去关心考虑,要存取设
备,程序只须打开设备文件,然后作为普通的UNIX文件来使用.从安全的观点来看这样处理很好,因为任何设备上进行的I/O操作只经过了少量的渠道(即设备文件).用户不能直接地存取设备.所以如果正确地设置了磁盘分区的存取许可,用户就只能通过UNIX文件系统存取磁盘.文件系统有内部安全机制(文件许可).不幸的是,如果磁盘分区设备得不正确,任何用户都能够写一个程序读磁盘分区中的每个文件,作法很简单:读一i节点,然后以磁盘地址表中块号出现的顺序,依次读这些块号指出的存有文件内容的块.故除了root以外,决不要使盘分区对任何人可写.因为所有者,文件存取许可方式这样一些信息存放于i节点中,任何人只要具有已安装分区的写许可,就能设置任何文件的SUID许可,而不管文件的所有者是谁,也不必用chmod()命令,还可避过系统建立的安全检查.以上所述对内存文件mem,kmem和对换文件swap也是一样的.这些文件含有用户信息,一个"耐心"的程序可以将用户信息提取出来.
要避免磁盘分区(以及其它设备)可读可写,应当在建立设备文件前先用
umask命令设置文件建立屏蔽值.
一般情况下,UNIX系统上的终端口对任何人都是可写的,从而使用户可以
用write命令发送信息.虽然write命令易引起安全方面的问题,但大多数用户
觉得用write得到其他用户的信息很方便,所以系统将终端设备的存取许可设置成对所有用户可写./dev目录应当是755存取许可方式,且属root所有.
不允许除root外的任何用户读或写盘分区的原则有一例外,即一些程序
(通常是数据库系统)要求对磁盘分区直接存取,解决这个问题的经验的盘分区应当由这种程序专用(不安装文件系统),而且应当告知使用这种程序的用户,文件安全保护将由程序自己而不是UNIX文件系统完成.
(5)find命令
find命令用于搜索目录树,并对目录树上的所有文件执行某种操作,参数
是目录名表(指出从哪些起点开始搜索),还可给出一个或多个选项,规定对每
个文件执行什么操作.
find . -print 将列出当前工作目录下的目录树的每一个文件.
find / -user bob -print 将列出在系统中可找到的属于bob用户的所有文件.
find /usr/bob -perm 666 -print 将列出/usr/bob目录树下所有存取许
可为666的文件.若将666改为-666则将列出所有具有包含了666在内
的存取许可方式的文件(如777).
find /usr/bob -type b -print 将列出/usr/bob目录树下所有块特别文
件(c为字符特别文件).
find / -user root -perm -4000 -exec ls -l {} \; 是一个较复杂一
点的命令,-exec COMMAND \;允许对所找到的每个文件运行指定的
命令COMMAND.若COMMAND中含有{},则{}将由find所找到的文件名替换.COMMAND必须以\;结束.
以上举例介绍find的用法,各选项可组合使用以达到更强的功能.
(6)secure程序
系统管理员应当做一个程序以定期检查系统中的各个系统文件,包括检查
设备文件和SUID,SGID程序,尤其要注意检查SUID,SGID程序,检查/etc/passwd和/etc/group文件,寻找久未登录的户头和校验各重要文件是否被修改.(源程序清单将在今后发表)
(7)ncheck命令
用于检查文件系统,只用一个磁盘分区名作为参数,将列出i节点号及相应
的文件名.i节点相同的文件为建链文件.注意:所列出的清单文件名与mount命令的第一个域相同的文件名前部分将不会列出来.因为是做文件系统内部的检查,ncheck并不知道文件系统安装点以上部分的目录.也可用此命令来搜索文件系统中所有的SUID和SGID程序和设备文件,使用
-s选项来完成此项功能.
(8)安装和拆卸文件系统
UNIX文件系统是可安装的,这意味着每个文件系统可以连接到整个目录树
的任意节点上(根目录总是被安装上的).安装文件系统的目录称为安装点.
/etc/mount命令用于安装文件系统,用这条命令可将文件系统安装在现有
目录结构的任意处.安装文件系统时,安装点的文件和目录都是不可存取的,因此未安装文件系统时,不要将文件存入安装点目录.文件系统安装后,安装点的存取许可方式和所有者将改变为所安装的文件根目录的许可方式和所有者.
安装文件系统时要小心:安装点的属性会改变!还要注意新建的文件,除非
新文件系统是由标准文件建立的,系统标准文件会设置适当的存取许可方式,
否则新文件系统的存取许可将是777!可用-r选项将文件系统安装成只读文件系统.需要写保护的带驱动器和磁盘应当以这种方式来安装.不带任何参数的 /etc/mount可获得系统中所安装的文件系统的有关信息.包括:文件系统被安装的安装点目录,对应/dev中的哪个设备,只读或可读写,安装时间和日期等.从安全的观点来讲,可安装系统的危险来自用户可能请求系统管理员为其
安装用户自己的文件系统.如果安装了用户的文件系统,则应在允许用户存取
文件系统前,先扫描用户的文件系统,搜索SUID/SGID程序和设备文件.在除了root外任何人不能执行的目录中安装文件系统,用find命令或 secure列出可疑文件,删除不属用户所有的文件的SUID/SGID许可.用户的文件系统用完后,可用umount命令卸下文件系统.并将安装点目录的所有者改回root,存取许可改为755.
(9)系统目录和文件
UNIX系统中有许多文件不允许用户写,如:/bin,/usr/bin,/usr/lbin,
/etc/passwd,/usr/lib/crontab,/unix,/etc/rc,/etc/inittab这样一些文件和目录(大多数的系统目录),可写的目录允许移动文件,会引起安全问题.系统管理员应经常检查系统文件和目录的许可权限和所有者.可做一个程序根据系统提供的规则文件(在 /etc/permlist文件中)所描述的文件所有者和许可权规则检查各文件.(源程序清单将在今后发表)注意:如果系统的安全管理不好,或系统是新安装的,其安全程序不够高,可以用make方式在安全强的系统上运行上述程序,将许可规则文件拷贝到新系统来,再以设置方式在新系统上运行上述程序,就可提高本系统的安全程序.但要记住,两个系统必须运行相同的UNIX系统版本.
4.作为root运行的程序
在UNIX系统中,有些程序由系统作为root进程运行.这些程序并不总是具有SUID许可,因为其不少程序仅由root运行,系统管理员需要清楚这些程序做什么,以及这些程序还将运行其它什么程序.
(1)启动系统
当某些UNIX系统(如SCO UNIX/XENIX)启动时,是以被称为单用户的方式运行,在这种方式中普通用户不能登录,唯有的进程是init, swapper,以及一些由系统管理员从控制台运行的进程.UNIX系统的单用户方式启动,使系统管理员能在允许普通用户登录以前,先检查系统操作,确保系统一切正常,当系统处于单用户方式时,控制台作为超级用户,命令揭示是"#",有些UNIX系统不要确认超级用户口令就认可控制台是root,给出#提示符.这就可能成为一个安全问题.
(2)init进程
UNIX系统总是以某种方式或称为某种级运行,系统有若干种运行级,这些运行级由init进程控制.UNIX系统启动时以单用户方式运行,也叫1级或S级.
对于其他用户登录进入系统,UNIX有一种多用户运行方式,也叫2级.init进程控制系统运行级,它读入文件/etc/inittab,该文件详细地规定了哪些进程在哪一级运行.当root敲入init n(数字),系统就进入n级.init读该文件以确定终止哪些进程,启动哪些进程.有效的运行级的数值是从0到6与s.注意:由init建立的进程以UID为0运行(root)从/etc/inittab运行的程序也作为root运行,所以系统管理员要确保自己知道/etc/inittab中的程序做什么工作,确保这些程序以及这些程序所在的目录直到/和/etc/inittab除root外无人可写.
(3)进入多用户
当UNIX系统进入多用户方式时,将寝化一系列事件,接着开始执行gettys,
允许其他用户登录进入系统.如果再看看/etc/inittab文件,会看到gettys定义在运行级2,至少三个shell程序/etc/brc, /etc/bcheckrc,/etc/rc*也定义在运行级2.这些程序都在gettys启动前运行.这些shell程序作为root运行,也不能仅对 root可写还应当检查shell程序运行的命令,因为这些命令也将作为root运行.
(4)shutdown命令
用shutdown命令关系统,shutdown shell程序发送警告通知所有用户离开
系统,在"给定的期限时间"到了后,就终止进程,拆卸文件系统,进入单用户方
式或关机状态.一旦进入单用户方式,所有的gettys停止运行,用户再不能登录.
进入关机状态后可将系统关电.shutdown仅能由作为root登录的用户从系统控制台上运行.所以任何的shutdown运行的命令仅能对root可写.
(5)系统V的cron程序
cron在UNIX系统是多用户方式时运行,根据规定的时间安排执行指定的命
令,每隔一分钟检查一次文件/usr/lib/crontab,寻找是否有应当运行的程序?如果找到要运行的程序,就运行该程序,否则睡眠等待一分钟.实 /usr/lib/crontab用于根据全天的规则时间表运行程序,也可在夜晚运行白天不愿运行怕降低其他用户速度的程序.通常由cron运行的程序是如记帐,存文件这样的程序.cron一般在系统进入多用户后由/etc/rc启动,当shutdown运行killall命令时便终止运行.由cron运行的程序作为root,所以应当注意放什么程序在crontab中,还要确保/usr/lib/crontab和该表中列出的任何程序对任何人不可写.如果用户需要由cron执行一个程序,系统管理员可用su命令在crontab表
中建立一个入口,使用户的程序不能获得root的权限.
(6)系统V版本2之后的cron程序
在系统V版本2中,cron被修改成允许用户建立自己的crontab入口,
/usr/lib/crontab文件不再存在,由目录/usr/spool/cron/crontabs中的文件
代替.这些文件的格式与crontab相同,但每个文件与系统中的一个用户对应,
并以某用户的名义由cron运行.如果想限制能建立crontab的用户,可在文件/usr/lib/cron/cron.allow文件中列出允许运行 crontab命令的用户.任何未列于该文件的用户不能运行crontab.反之,若更愿意列出不允许运行crontab命令的用户,则可将他们列入 /usr/lib/cron/cron.deny文件中,未列于该文件的其他用户将被允许建立crontab.
注意:若两个文件都存在,系统将使用cron.allow,忽略cron.deny.如果两
个文件都不存在,则只有root可运行crontab.所以,若要允许系统中的所有用
户都可运行crontab命令,应当建立一个空的cron.deny文件,如果cron.allow
也存在,则删除该文件.这个版本的cron命令的安全程度比前一个高,因为用户只能看自己的crontab,系统管理员也不必担心其他用户的程序是否会作为root运行,由于允许每个系统登录用户有自己的crontab,也简化了对程序必须由cron运行,但不必作为root运行的系统程序的处理.必须确保root的crontab文件仅对root可写,并且该文件所在的目录及所有的父目录也仅对root可写.
(7)/etc/profile
每当用户(包括root在内)登录时,由shell执行/etc/profile文件,应确保这个文件以及从这个文件运行的程序和命令都仅对root可写.
5./etc/passwd文件
/etc/passwd文件是UNIX安全的关键文件之一.该文件用于用户登录时校验
用户的口令,当然应当仅对root可写.文件中每行的一般格式为OGNAMEASSWORD:UID:GID:USERINFO:HOME:SHELL
每行的头两项是登录名和加密后的口令,后面的两个数是UID和GID,接着的一项是系统管理员想写入的有关该用户的任何信息,最后两项是两个路径名:一个是分配给用户的HOME目录,第二个是用户登录后将执行的shell(若为空格则缺省为/bin/sh).
(1) 口令时效
/etc/passwd文件的格式使系统管理员能要求用户定期地改变他们的口令.
在口令文件中可以看到,有些加密后的口令有逗号,逗号后有几个字符和一个
冒号.如:
steve:xyDfccTrt180x,M.y8:0:0:admin:/:/bin/sh
restrict:pomJk109Jky41,.1:0:0:admin:/:/bin/sh
pat:xmotTVoyumjls:0:0:admin:/:/bin/sh
可以看到,steve的口令逗号后有4个字符,restrict有2个,pat没有逗号.
逗号后第一个字符是口令有效期的最大周数,第二个字符决定了用户再次
修改口信之前,原口令应使用的最小周数(这就防止了用户改了新口令后立刻
又改回成老口令).其余字符表明口令最新修改时间.要能读懂口令中逗号后的信息,必须首先知道如何用passwd_esc计数,计数的方法是: .= 0 /=1 0-9=2-11 A-Z=12-37 a-z=38-63系统管理员必须将前两个字符放进/etc/passwd文件,以要求用户定期的修改口令,另外两个字符当用户修改口令时,由passwd命令填入.注意:若想让用户修改口令,可在最后一次口令被修改时,放两个".",则下一次用户登录时将被要求修改自己的口令.有两种特殊情况:. 最大周数(第一个字符)小于最小周数(第二个字符),则不允许用户修改口令,仅超级用户可以修改用户的口令.. 第一个字符和第二个字符都是".",这时用户下次登录时被要求修改口令,修改口令后,passwd命令将"."删除,此后再不会要求用户修改口令.
(2)UID和GID
/etc/passwd中UID信息很重要,系统使用UID而不是登录名区别用户.一般
来说,用户的UID应当是独一无二的,其他用户不应当有相同的UID数值.根据惯例,从0到99的UID保留用作系统用户的UID(root,bin,uucp等).
如果在/etc/passwd文件中有两个不同的入口项有相同的UID,则这两个用
户对相互的文件具有相同的存取权限.
6./etc/group文件
/etc/group文件含有关于小组的信息,/etc/passwd中的每个GID在本文件中
应当有相应的入口项,入口项中列出了小组名和小组中的用户.这样可方便地了解每个小组的用户,否则必须根据GID在/etc/passwd文件中从头至尾地寻找同组用户.
/etc/group文件对小组的许可权限的控制并不是必要的,因为系统用UID,GID
(取自/etc/passwd)决定文件存取权限,即使/etc/group文件不存在于系统中,具
有相同的GID用户也可以小组的存取许可权限共享文件.小组就像登录用户一样可以有口令.如果/etc/group文件入口项的第二个域为非空,则将被认为是加密口令,newgrp命令将要求用户给出口令,然后将口令加密,再与该域的加密口令比较.给小组建立口令一般不是个好作法.第一,如果小组内共享文件,若有某人猜着小组口令,则该组的所有用户的文件就可能泄漏;其次,管理小组口令很费事,因为对于小组没有类似的passwd命令.可用 /usr/lib/makekey生成一个口令写入
/etc/group.
以下情况必须建立新组:
(1)可能要增加新用户,该用户不属于任何一个现有的小组.
(2)有的用户可能时常需要独自为一个小组.
(3)有的用户可能有一个SGID程序,需要独自为一个小组.
(4)有时可能要安装运行SGID的软件系统,该软件系统需要建立一个新组.
要增加一个新组,必须编辑该文件,为新组加一个入口项.
由于用户登录时,系统从/etc/passwd文件中取GID,而不是从/etc/group中
取GID,所以group文件和口令文件应当具有一致性.对于一个用户的小组,UID和GID应当是相同的.多用户小组的GID应当不同于任何用户的 UID,一般为5位数,这样在查看/etc/passwd文件时,就可根据5位数据的GID识别多用户小组,这将减少增加新组,新用户时可能产生的混淆.
8.安全检查
像find和secure这样的程序称为检查程序,它们搜索文件系统,寻找出SUID/
SGID文件,设备文件,任何人可写的系统文件,设有口令的登录用户,具有相同UID/GID的用户等等.
(1)记帐
UNIX记帐软件包可用作安全检查工具,除最后登录时间的记录外,记帐系
统还能保存全天运行的所有进程的完整记录,对于一个进程所存贮的信息包括UID,命令名,进程开始执行与结束的时间,CPU时间和实际消耗的时间,该进程是否是root进程,这将有助于系统管理员了解系统中的用户在干什么.acctcom命令可以列出一天的帐目表.有明,系统中有多个记帐数据文件,记帐信息保存在文件/usr/adm/pacct*中,/usr/adm/pacct是当前记录文件,/usr/adm/pacctn是以前的记帐文件(n为整型数).若有若干个记帐文件要查看,可在acctcom命令中指定文件名: acctcom /usr/adm/pacct?  /usr/adm/pacct
要检查的问题的其中之一是:在acctcom的输出中查找一个用户过多的登
录过程,若有,则说明可能有人一遍遍地尝试登录,猜测口令,企图非法进入系统.此外,还应查看root进程,除了系统管理员用su命令从终端进入 root,系统启动,系统停止时间,以及由init(通常init只启动getty,login,登录shell),cron启动的进程和具有 root SUID许可的命令外,不应当有任何root进程.由记帐系统也可获得有关每个用户的CPU利用率,运行的进程数等统计数据.
(2)其它检查命令
*du:报告在层次目录结构(当前工作目录或指定目录起)中各目录占用的磁盘块数.可用于检查用户对文件系统的使用情况.*df:报告整个文件系统当前的空间使用情况.可用于合理调整磁盘空间的使用和管理.*ps:检查当前系统中正在运行的所有进程.对于用了大量CPU时间的进程,同时运行了许多进程的用户,运行了很长时间但用了很少CPU时间的用户进程应当深入检查.还可以查出运行了一个无限制循环的后台进程的用户,未注销户头就关终端的用户(一般发生在直接连线的终端).*who:可以告诉系统管理员系统中工作的进展情况等等许多信息,检查用户的登录时间,登录终端.*su:每当用户试图使用su命令进入系统用户时,命令将在/usr/adm/sulog文件中写一条信息,若该文件记录了大量试图用su进入root的无效操作信息,则表明了可能有人企图破译root口令.*login:在一些系统中,login程序记录了无效的登录企图(若本系统的login程序不做这项工作而系统中有login源程序,则应修改login).每天总有少量的无效登录,若无效登录的次数突然增加了两倍,则表明可能有人企图通过猜测登录名和口令,非法进入系统.这里最重要的一点是:系统管理没越熟悉自己的用户和用户的工作习惯,就越能快速发现系统中任何不寻常的事件,而不寻常的事件意味着系统已被人窃密.
(3)安全检查程序的问题
关于以上的检查方法的一个警告,若有诱骗,则这些方法中没有几个能防诱骗.如find命令,如果碰到路径名长于256个字符的文件或含有多于200个文件的目录,将放弃处理该文件或目录,用户就有可能利用建立多层目录结构或大目录隐藏SUID程序,使其逃避检查(但find命令会给出一个错误信息,系统管理员应手工检查这些目录和文件).也可用ncheck命令搜索文件系统,但它没有find命令指定搜索哪种文件的功能.如果定期存取.profile文件,则检查久未登录用户的方法就不奏效了.而用户用su命令时,除非用参数-,否则su不读用户的.profile.有三种方法可寻找久未登录的帐户:  UNIX记帐系统在文件/usr/adm/acct/sum/login中为每个用户保留了最后一次登录日期.用这个文件的好处是,该文件由系统维护, 所以可完全肯定登录日期是准确的.缺点是必须在系统上运行记帐程序以更新loginlog文件,如果在清晨(午夜后)运行记帐程序,一天的登录日期可能就被清除了.. /etc/passwd文件中的口令时效域将能告诉系统管理员,用户的口令是否过期了,若过期,则意味着自过期以来,户头再未被用过.这一方法的好处在于系统记录了久未用的户头,检查过程简单,且不需要记帐系统所需要的磁盘资源,缺点是也许系统管理员不想在系统上设置口令时效,而且这一方法仅在口令的最大有效期(只有几周)才是准确的.. 系统管理员可以写一个程序,每天(和重新引导系统时)扫描/etc/wtmp,自己保留下用户最后登录时间记录,这一方法的好处是不需要记帐程序,并且时间准确,缺点是要自己写程序.以上任何方法都可和/usr/adm/sulog文件结合起来,查出由 login或su登录户头的最后登录时间.如果有人存心破坏系统安全,第一件要做的事就是寻找检查程序.破坏者将修改检查程序,使其不能报告任何异常事件,也可能停止系统记帐,删除记帐文件,使系统管理员不能发现破坏者干了些什么.
(4)系统泄密后怎么办?
发现有人已经破坏了系统安全的时候,这时系统管理员首先应做的是面对肇事用户.如果该用户所做的事不是蓄意的,而且公司没有关于"破坏安全"的规章,也未造成损坏,则系统管理员只需清理系统,并留心该用户一段时间.如果该用户造成了某些损坏,则应当报告有关人士,并且应尽可能地将系统恢复到原来的状态.如果肇事者是非授权用户,那就得做最坏的假设了:肇事者已设法成为root且本系统的文件和程序已经泄密了.系统管理员应当想法查出谁是肇事者,他造成了什么损坏?还应当对整个文件做一次全面的检查,并不只是检查SUID和SGID,设备文件.如果系统安全被一个敌对的用户破坏了,应当采用下面的步骤:.  关系统,然后重新引导,不要进入多用户方式,进入单用户方式.. 安装含有本系统原始UNIX版本的带和软盘.. 将/bin,/usr/bin, /etc,/usr/lib中的文件拷贝到一个暂存目录中.. 将暂存目录中所有文件的校验和(用原始版本的suM程序拷贝做校验和,不要用/bin中的 suM程序做)与系统中所有对就的文件的校验和进行比较,如果有任何差别,要查清差别产生的原因.如果两个校验和不同,是由于安装了新版本的程序,确认一相是否的确是安装了新版本程序.如果不能找出校验和不同的原因,用暂存目录中的命令替换系统中的原有命令.
. 在确认系统中的命令还未被窜改之前,不要用系统中原命令.用暂存目录中的shell,并将PATH设置为仅在暂存目录中搜索命令.. 根据暂存目录中所有系统命令的存取许可,检查系统中所有命令的存取许可.. 检查所有系统目录的存取许可,如果用了perms,检查permlist文件是否被窜改过.
. 如果系统UNIX(/unix)的校验和不同于原版的校验和,并且系统管理员从未修改过核心,则应当认为,一个非法者"很能干",从暂存缓冲区重新装入系统.系统管理员可以从逐步增加的文件系统备份中恢复用户的文件,但是在检查备份中的"有趣"文件之前,不能做文件恢复.. 改变系统中的所有口令,通知用户他们的口令已改变,应找系统管理员得到新口令.. 当用户来要新口令时,告诉用户发生了一次安全事故,他们应查看自己的文件和目录是否潜伏着危害 (如SUID文件,特洛依木马,任何人可写的目录),并报告系统管理员任何异乎寻常的情况.. 设法查清安全破坏是如何发生的?如果没有肇事者说明,这也许是不可能弄清的.如果能发现肇事者如何进入系统,设法堵住这个安全漏洞.
第一次安装UNIX系统时,可以将shell,sum命令,所有文件的校验和存放在
安全的介质上(带,软盘,硬盘和任何可以卸下并锁焉起来的介质).于是不必再
从原版系统带上重新装入文件,可以安装备份介质,装入shell和sum,将存在带上的校验和与系统中文件的校验和进行比较.系统管理员也许想自己写一个计算校验和的程序,破坏者将不能知道该程序的算法,如果将该程序及校验和保存在带上,这一方法的保密问题就减小到一个物理的安全问题,即只需将带锁起来.
9.加限制的环境
(1)加限制的shell(rsh)
该shell几乎与普通的shell相同,但是该shell的设计能限制一个用户的
能力,不允许用户有某些标准shell所允许的行为:
. 不能改变工作目录(cd).
. 不能改变PATH或SHELL shell变量.
. 不能使用含有"/"的命令名.
. 不能重定向输出(>和>>).
. 不能用exec执行程序.
用户在登录时,招待.profile文件后系统就强加上了这些限制,如果用在.profile文件正被解释时按了BREAK键或DELETE键,该用户将被注销.这些简单的限制,使用写受限制用户的.profile文件的系统管理员可以对用户能使用什么命令,进行完全的控制.应当注意:系统V加限制的 shell实际上不是很安全,在敌对的用户时不要用.系统V版本2以后的版本中加限制的shell更安全些.但若允许受限制的用户使用某些命令(如 env,cp,ln),用户将能逃避加限制的shell,进入非限制的shell.
(2)用chroot()限制用户
如果的确想限制一个用户,可用chroot()子程序为用户建立一个完全隔离
的环境,改变了进程对根目录的概念,因此可用于将一个用户封在整个文件系
统的某一层目录结构中,使用户无法用cd命令转出该层目录结构,不能存取文件系统中其余部分的任何文件.这种限制方式比加限制的shell好得多.用户使用的命令应由系统管理员在新的root目录中建立一个bin目录,并建立用户可用命令的链到系统的/bin目录中相应命令文件上(若在不同的文件系统则应拷贝命令文件).还应建立新的passwd文件,保留系统登录户头(为了使ls -l正确地报告与受限制的子文件系统中的文件相关的正确登录名)和用户帐户,但系统帐户的口令改为NOLOGIN以使受限制的用户不能取得系统登录的真实口令,使"破密"程序的任何企图成为泡影.utmp文件是who所需要的,该文件含有系统中已登录用户的列表.新的/etc/profile文件也不是建链文件,以便受限制的用户可以执行不同的启动命令./dev目录中的终端设备文件被链接到新的/dev目录下,因为命令who产生输出时要查看这些文件.在系统V及以后的UNIX版本中,login命令有chroot()的功能.如果口令文件中用户入口项的登录shell域(最后一个域)是*,login将调用chroot()把用户的根目录设置成为口令文件中用户入口项登录目录域指定的目录.然后再调用exec()执行login,新的login将在新子系统文件中执行该用户的登录.
chroot()并不是把root封锁在一个子文件系统中,所以给受限制用户用的
命令时应加以考虑,具有root的SUID许可的程序可能会给予用户root的能力.应当将这种可能减低到最小程度,交给用户使用的命令应当取自清除了 SUID陷井的系统命令.链接文件可减少磁盘占用区,但要记住,当与敌对用户打交道时链接到chroot目录结构(尤其是命令)的系统文件是很危险的.
如果建立一个像这样的限制环境,应确保对安装到新的/bin的每条命令都
做过测试,有些程序可能有系统管理员未曾想到的出乎意料的执行结果.为了
使这些命令能运行,还得在加限制的子文件系统中加服务目录或文件如:/tmp,
/etc/termcap,/usr/lib/terminfo,/dev/mem,/dev/kmem,/dev/swap,用户所
登录的/dev中的tty文件以及/unix.有些程序在子文件系统中运行时不会很好,如果将假脱机程序和网络命令拷贝到加限制的子文件系统中,并放在为两条命令专建的目录层结构下,它们可能也运行不了.
10.小系统安全
任何足够小,运行于办公室的UNIX系统就是小系统.这类小系统也包括所有
台式UNIX机器.根据安全观点,使小系统很特别而值得特别的有以下几点:
. 小系统的用户比大系统的用户少,通常是很小一组用户,使系统管理员能熟悉每个人,安全问题可以直接地面对面处理.. 由于小UNIX系统管理更简单, 可能只需要一个系统管理员,因而维护系统安全的责任只有一个人担负.. 如果既是用户又是系统管理员,将不能花大量时间考虑系统安全.. 如果自己拥有系统并且是系统管理员,就可能有权直接将违反规的用户从系统中删除,而没有几个大系统的管理员能有这种权利. 如果自己是系统的唯一用户,则将既是用户又是管理员,维护系统安全的任务就很简单了,只须确保系统中所有登录户头的口令是好的.. 如果不能将系统锁起来,就把敏感的数据存放在软盘上,把软盘锁起来.. 即使系统中有若干个用户,但如果系统的终端之产是有线连接,并且用户们保持门上锁,则系统也将是安全的,至少在本组用户内是安全的.. 小系统通常有可移动的介质(软盘),可用mount命令将其安装到系统上,提供一种安全的方法让用户自己在系统上安装软盘,否则系统管理员要一天到晚地干这些琐碎的安装盘事务.允许用户安装软盘的通常做法是给用户一个SUID程序,该程序基本完成与系统管理员安装用户软盘同样的操作,首先检查软盘上有无 SUID/SGID/设备文件,若发现任何奇怪的文件,则拒绝安装该软盘.. 当小系统开电源后,系统一般在从硬盘引导以前,先试图从软盘引导.这就意味着计算机将首先试图从软盘装入程序,若软盘不在驱动器中,系统将从硬盘装入UNIX内核.软盘几乎可以含有任何程序,包括在控制台启动
root shell的UNIX系统版本.如果破坏者有一把螺丝起子和有关系统内部的一些知识,则即便系统有被认为防止安全事故发生的特殊"微码"口令, 也可能被诱骗去从软盘引导.即使小系统晚上不锁,凡从不将个人的或秘密的信息存放在大系统上的人他们不可能认识所有系统上的用户),也不会想把这样的信息存放在小系统上. 小系统的系统管理员在使用UNIX系统方面常不如大系统管理员有经验,而安全地管理系统需要一定的使用系统的知识.
11.物理安全
对于运行任何操作系统的小型或大型计算机,物理安全都是一个要考虑的重
要问题,物理安全包括:锁上放置计算机的屋子,报警系统,警卫,所有安置在不能上锁的地方的通讯设施,包括有线通讯线,电话线,局域网,远程网,应答 MODEM,钥匙或信用卡识别设备,给用户的口令和钥匙分配,任何前置通讯设施的加密装置,文件保护,备份或恢复方案(称为安全保险方案,用作应付偶然的或蓄意的数据或计算设备被破坏的情况),上锁的输出仃,上锁的废物箱和碎纸机.物理安全中所饮食的总考虑应是:在安全方案上所付出的代价不应当多于值得保护的(硬件或软件的)价值.
下面着重讨论保护用户的各种通讯线.对于任何可在不上锁的地方存取的系
统,通讯是特别严重的安全薄弱环节.当允许用户通过挂到地方电话公司的拨号MODEM存取系统时,系统的安全程度就将大大地削弱,有电话和MODEM的任何人就可能非法进入该系统.应当避免这一情况,要确保MODEM的电话号码不被列于电话薄上,并且最好将电话号码放在不同于本公司普通电话号码所在的交换机上.总之,不要假设没人知道自己的拨入号码!大多数家庭计算机都能编程用一个MODEM整天地依次调用拨号码,记录下连接上其它MODEM的号码.如果可能,安装一个局域PBX,使得对外界的拨号产生一秒钟的拨号蜂音,并且必须输入一个与MODEM相关联的扩展号码.
12.用户意识
UNIX系统管理员的职责之一是保证用户安全.这其中一部分工作是由用户的管理部门来完成,但是作为系统管理员,有责任发现和报告系统的安全问题,因为系统管理员负责系统的运行.避免系统安全事故的方法是预防性的,当用户登录时,其shell在给出提示前先执行/etc/profile文件,要确保该文件中的PATH指定最后搜索当前工作目录,这样将减少用户能运行特洛依木马的机会.将文件建立屏蔽值的设置放在该文件中也是很合适的,可将其值设置成至少将防止用户无意中建立任何人都能写的文件(022/026).要小心选择此值,如果限制太严,则用户会在自己的.profile中重新调用umask以抵制系统管理员的意愿,如果用户大量使用小组权限共享文件,系统管理员就一要设置限制小组存取权限的屏蔽值.系统管理员必须建立系统安全和用户的"痛苦量"间的平衡(痛苦量是安全限制引起的愤怒的函数).定期地用grep命令查看用户.profile文件中的umask,可了解系统安全限制是否超过了用户痛苦极限.系统管理员可每星期随机抽选一个用户,将该用户的安全检查结果(用户的
登录情况简报,SUID/SGID文件列表等)发送给他的管理部门和他本人.主要有四个目的: 大多数用户会收到至少有一个文件检查情况的邮件,这将引起用户考虑安全问题(虽然并不意味着用户们会采取加强安全的行动).
有大量可写文件的用户,将一星期得到一次邮件,直到他们取消可写文件的写许可为止.冗长的烦人的邮件信息也许足以促使这些用户采取措施,删除文件的写许可.. 邮件将列出用户的SUID程序,引起用户注意自己有SUID程序,使用户知道是否有不是自己建立的SUID程序.
送安全检查表可供用户管理自己的文件,并使用户知道对文件的管理关系
到数据安全.如果系统管理员打算这样做,应事先让用户知道,以便他们了解安全检查邮件的目的.发送邮件是让用户具有安全意识,不要抱怨发送邮件.
管理意识是提高安全性的另一个重要因素.如果用户的管理部门对安全要求
不强烈,系统管理员可能也忘记强化安全规则.最好让管理部门建立一套每个人都必须遵守的安全标准,如果系统管理员在此基础上再建立自己的安全规则,就强化了安全.管理有助于加强用户意识,让用户明确,信息是有价值的资产.系统管理员应当使安全保护方法对用户尽可能地简单,提供一些提高安全的工具,如:公布锁终端的lock程序,让用户自己运行secure程序,将pwexp(检查用户口令信息的程序)放入/etc/profile中,使用户知道自己的口令时间.多教给用户一些关于系统安全的知识,确保用户知道自己的许可权限和umask命令的设置值.如果注意到用户在做蠢事,就给他们一些应当怎样做才对的提示.用户知道的关于安全的知识越多,系统管理员在保护用户利益方面做的事就越少.
13.系统管理员意识
(1)保持系统管理员个人的登录安全
若系统管理员的登录口令泄密了,则窃密者离窃取root只有一步之遥了,
因为系统管理员经常作为root运行,窃密者非法进入到系统管理员的户头后,
将用特洛依木马替换系统管理员的某些程序,系统管理员将作为root运行这些已被替换的程序.正是因为这个原因,在UNIX系统中,管理员的户头最常受到攻击.即使su命令通常要在任何都不可读的文件中记录所有想成为root的企图,还可用记帐数据或ps命令识别运行su命令的用户.也是如此,系统管理员作为root运行程序时应当特别小心,因为最微小的疏忽也可能"沉船".下列一些指导规则可使系统管理员驾驶一艘"坚固的船":. 不要作为root或以自己的登录户头运行其他用户的程序,首先用su命令进入用户的户头.. 决不要把当前工作目录排在PATH路径表的前边,那样实际是招引特洛依木马.当系统管理员用su命令进入root时,他的PATH将会改变,就让PATH保持这样,以避免特洛依木马的侵入.. 敲入/bin/su执行su命令.若有 su源码,将其改成必须用全路径名运行(即su要确认argv[0]的头一个字符是"/"才运行).随着时间的推移,用户和管理员将养成敲/bin/su 的习惯.不要未注销户头就离开终端,特别是作为root用户时更不能这样.当系统管理员作为root用户时,命令提示符是"#",这个提示符对某些人来说可能是个红灯标志.
. 不允许root在除控制台外的任何终端登录(这是login的编译时的选项),如果没有login源码,就将登录名root改成别的名,使破坏者不能在root登录名下猜测各种可能的口令,从而非法进入root的户头.
. 经常改变root的口令.
确认su命令记下的想运行su企图的记录/usr/adm/sulog,该记录文件的许可方式是600,并属root所有.这是非法者喜欢选择来替换成特洛依木马的文件. 不要让某人作为root运行,即使是几分钟,即使是系统管理员在一旁注视着也不行!
(2)保持系统安全
考虑系统中一些关键的薄弱环节:
a. 系统是否有MODEM?电话号码是否公布?
b. 系统是否连接到?还有什么系统也连接到该网络?
c. 系统管理员是否使用未知来处或来处不可靠的程序?
d. 系统管理员是否将重要信息放在系统中?
e. 系统的用户是熟悉系统的使用还是新手?
f. 用户是否很重视关心安全?
g. 用户的管理部门是否重视安全?
. 保持系统文件安全的完整性.检查所有系统文件的存取许可,任何具有
SUID许可的程序都是非法者想偷换的选择对象.
. 要特别注意设备文件的存取许可.
. 要审查用户目录中具有系统ID/系统小组的SUID/SGID许可的文件.
. 在未检查用户的文件系统的SUID/SGID程序和设备文件之前,不要安装用
户的文件系统.
. 将磁盘的备份存放在安全的地方.
. 设置口令时效,如果能存取UNIX的源码,将加密口令和信息移到仅对root
可读的文件中,并修改系统的口令处理子程序.这样可增加口令的安全.修
改passwd,使passwd能删去口令打头和末尾的数字,然后根据spell词典和
/etc/passwd中用户的个人信息,检查用户的新口令,也检查用户新口令中
子串等于登录名的情况.如果新口令是spell词典中的单词,或/etc/passwd
中的入口项的某项值,或是登录名的子串,passwd将不允许用户改变口令.
. 记录本系统的用户及其授权使用的系统.
. 查出久未使用的登录户头,并取消该户头.
. 确保没有无口令的登录户头.
. 启动记帐系统.
. 查出不寻常的系统使用情况,如大量的占用磁盘,大量的使用CPU时间,大
量的进程,大量的使用su的企图,大量无效的登录,大量的到某一系统的网
络传输,奇怪的uucp请求.
修改shell,使其等待了一定时间而无任务时终止运行.
. 修改login,使其打印出用户登录的最后时间,三次无效登录后,将通讯线
挂起,以便系统管理员能检查出是否有人试图非法进入系统.确保login不
让root在除控制台外的任何地方登录.
. 修改su,使得只有root能以过期口令通过su进入某一户头.
. 当安装来源不可靠的软件时,要检查源码和makefile文件,查看特殊的子
程序调用或命令.
. 即使是安装来源可靠的软件,也要检查是否有SUID(SGID)程序,确认这些
许可的确是必要的.如果可能,不要让这些程序具有系统ID(或组)的SUID
(SGID)许可,而应该建立一个新用户(或给)供该软件运行.
. 如果系统在办公室中,门应上锁,将重要数据保存在软盘上或带上,并锁起
来.将secure,perms和任何其它做安全检查的shell程序存取许可置为仅执行,更好的是将这些shell程序存于可拆卸的介质上.
记住,只要系统有任何人都可调用的拨号线,系统就不可能真正的安全.系
统管理员可以很好地防止系统受到偶然的破坏.但是那些有耐心,有计划,
知道自己在干什么的破坏者,对系统直接的有预谋的攻击却常常能成功.
. 如果系统管理员认为系统已经泄密,则应当设法查出肇事者.若肇事者是
本系统的用户,与用户的管理部门联系,并检查该用户的文件,查找任何可
疑的文件,然后对该用户的登录小心地监督几个星期.如果肇事者不是本
系统的用户,可让本公司采取合法的措施,并要求所有的用户改变口令,让
用户知道出了安全事故,用户们应当检查自己的文件是否有被窜改的迹象.
如果系统管理员认为系统软件已被更改了,就应当从原版系统带(或;软盘
)上重装入所有系统软件,保持系统安全比道歉更好.
7.增加,删除,移走用户
(1)增加用户
增加用户有三个过程:
. 在/etc/passwd文件中写入新用户的入口项.
. 为新登录用户建立一个HOME目录.
. 在/etc/group中为新用户增加一个入口项.
在/etc/passwd文件中写入新的入口项时,口令部分可先设置为NOLOGIN,
以免有人做为此新用户登录.在修改文件前,应mkdir /etc/ptmp,以免他人同
时修改此文件.新用户一般独立为一个新组,GID号与UID号相同(除非他要加入目前已存在的一个新组),UID号必须和其他人不同,HOME目录一般设置在/usr或/home目录下建立一个以用户登录名为名称的目录做为其主目录.
(2)删除用户
删除用户与加用户的工作正好相反,首先在/etc/passwd和/etc/group文件中删除用户的入口项,然后删除用户的HOME目录和所有文件. rm -r /usr/loginname 删除整个目录树.如果用户在/usr/spool/cron/crontabs中有crontab文件,也应当删除.
(3)将用户移到另一个系统
这是一个复杂的问题,不只是拷贝用户的文件和用户在/etc/passwd文件
中的入口项.首先一个问题是用户的UID和GID可能已经用于另一个系统,若是出现这种情况,必须给要移的用户分配另外的UID和GID,如果改变了用户的UID和GID,则必须搜索该用户的全部文件,将文件的原UID和GID改成新的UID和GID.
用find命令可以完成这一修改:
find . -user olduid -exec chown newuid {} \;
find . -group oldgid -exec chgrp newgid {} \;
也许还要为用户移走其它一些文件:
/usr/mail/user和/usr/spool/cron/crontabs/user.
如果用户从一个不是本系统管理员的系统移来,则应对该用户的目录结构
运行程序来检查.一个不安全系统的用户,可能有与该用户其它文件存在一起
的SUID/SGID程序,而这个SUID/SGID程序属于另一个用户.在这种情况下,如果用cpio或tar命令将用户的目录结构拷贝到本系统, SUID/SGID程序也将会拷贝到本系统而没有任何警告信息.应当在允许用户使用新系统以前先删除这种文件的SUID/SGID许可.总之,始终坚持检查所移用户的文件总是更安全些.也可以用su命令进入用户的户头,再拷贝用户文件,这样文件的所有者就是该用户,而不是root.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 19:00:45 | 显示全部楼层
[推荐]系统安全(用户篇)
UNIX系统管理-系统安全-系统安全(用户篇)
本文从用户角度讨论UNIX系统安全,阐述口令,文
件保护,目录保护,与用户程序有关的某些特殊特性和
使用crypt命令加密,并给出一些重要的安全忠告,以帮
助用户保护自己的户头安全.
1.口令安全
UNIX系统中的/etc/passwd文件含有全部系统需要知道的关于每个用户的信息(加密后的口令也可能存于/etc/shadow文件中).
/etc/passwd中包含有用户的登录名,经过加密的口令,用户号,用户组号,用户注释,用户主目录和用户所用的shell程序.其中用户号(UID)和用户组号(GID)
用于UNIX系统唯一地标识用户和同组用户及用户的访问权限.
/etc/passwd中存放的加密的口令用于用户登录时输入的口令经计算后相比较,符合则允许登录,否则拒绝用户登录.用户可用passwd命令修改自己的口令,不能直接修改/etc/passwd中的口令部份.一个好的口令应当至少有6个字符长,不要取用个人信息(如生日,名字,反向拼写的登录名,房间中可见的东西),普通的英语单词也不好(因为可用字典攻击法),口令中最好有一些非字母(如数字,标点符号,控制字符等),还要好记一些,不能写在纸上或计算机中的文件中,选择口令的一个好方法是将两个不相关的词用一个数字或控制字符相连,并截断为8个字符.当然,如果你能记住8位乱码自然更好.应使用同一个口令在不同机器中使用,特别是在不同级别的用户上使用同一口令,会引起全盘崩溃.用户应定期改变口令,至少6个月要改变一次,系统管理员可以强制用户定期做口令修改.为防止眼明手快的人窃取口令,在输入口令时应确认无人在身边.
2.文件许可权
文件属性决定了文件的被访问权限,即谁能存取或执行该文件.用ls -l可以列出详细的文件信息,如:
-rwxrwxrwx 1 pat cs440 70 Jul 28 21:12 zombin
包括了文件许可,文件联结数,文件所有者名,文件相关组名,文件长度,上次存取日期和文件名.其中文件许可分为四部分:
-:表示文件类型.
第一个rwx:表示文件属主的访问权限.
第二个rwx:表示文件同组用户的访问权限.
第三个rwx:表示其他用户的访问权限.
若某种许可被限制则相应的字母换为-.
在许可权限的执行许可位置上,可能是其它字母,s,S,t,T.s和S可出现在所有者和同组用户许可模式位置上,与特殊的许可有关,后面将要讨论,t和T 可出现在其他用户的许可模式位置上,与"粘贴位"有关而与安全无关.小写字母(x,s,t)表示执行许可为允许,负号或大写字母(-,S或T)表示执行许可为不允许.改变许可方式可使用chmod命令,并以新许可方式和该文件名为参数.新许可方式以3位8进制数给出,r为4,w为2,x为1.如rwxr- xr--为754.chmod也有其它方式的参数可直接对某组参数修改,在此不再多说,详见UNIX系统的联机手册.文件许可权可用于防止偶然性地重写或删除一个重要文件(即使是属主自己)!改变文件的属主和组名可用chown和chgrp,但修改后原属主和组员就无法修改回来了.
3.目录许可
在UNIX系统中,目录也是一个文件,用ls -l列出时,目录文件的属性前面带一个d,目录许可也类似于文件许可,用ls列目录要有读许可,在目录中增删文
件要有写许可,进入目录或将该目录作路径分量时要有执行许可,故要使用任一个文件,必须有该文件及找到该文件的路径上所有目录分量的相应许可.仅当要打开一个文件时,文件的许可才开始起作用,而rm,mv只要有目录的搜索和写许可,不需文件的许可,这一点应注意.
4.umask命令
umask设置用户文件和目录的文件创建缺省屏蔽值,若将此命令放入.profile文件,就可控制该用户后续所建文件的存取许可.umask命令与chmod命令的作用正好相反,它告诉系统在创建文件时不给予什么存取许可.
5.设置用户ID和同组用户ID许可
用户ID许可(SUID)设置和同组用户ID许可(SGID)可给予可执行的目标文件(只有可执行文件才有意义)当一个进程执行时就被赋于4个编号,以标识该进程隶属于谁,分别为实际和有效的UID,实际和有效的GID.有效的UID和GID一般和实际的UID和GID相同,有效的UID和GID用于系统确定该进程对于文件的存取许可.而设置可执行文件的SUID许可将改变上述情况,当设置了SUID时,进程的有效UID为该可执行文件的所有者的有效 UID,而不是执行该程序的用户的有效UID,因此,由该程序创建的都有与该程序所有者相同的存取许可.这样,程序的所有者将可通过程序的控制在有限的范围内向用户发表不允许被公众访问的信息.同样,SGID是设置有效GID.用chmod u+s 文件名和chmod u-s文件名来设置和取消SUID 设置.用chmod g+s 文件名和chmod g-s文件名来设置和取消SGID设置.当文件设置了SUID和SGID后,chown和chgrp命令将全部取消这些许可.
6.cp mv ln和cpio命令
cp拷贝文件时,若目的文件不存在则将同时拷贝源文件的存取许可,包括SUID和SGID许可.新拷贝的文件属拷贝的用户所有,故拷贝另人的文件时应小心,不要被其他用户的SUID程序破坏自己的文件安全.mv移文件时,新移的文件存取许可与原文件相同,mv仅改变文件名.只要用户有目录的写和搜索许可,就可移走该目录中某人的SUID程序且不改变其存取许可.
若目录许可设置不正确,则用户的SUID程序可被移到一个他不能修改和删除的目录中,将出现安全漏洞.ln为现有文件建立一个链,即建立一个引用同一文件的新名字.如目的文件已经存在,则该文件被删除而代之以新的链,或存在的目的文件不允许用户写它,则请求用户确认是否删除该文件,只允许在同一文件系统内建链.若要删除一个SUID文件,就要确认文件的链接数,只有一个链才能确保该文件被删除.若SUID文件已有多个链,一种方法是改变其存取许可方式,将同时修改所有链的存取许可,也可以chmod 000 文件名,不仅取消了文件的SUID和SGID许可,而且也取消了文件的全部链.要想找到谁与自己的 SUID程序建立了链,不要立刻删除该程序,系统管理员可用ncheck命令找到该程序的其它链.cpio命令用于将目录结构拷贝到一个普通文件中,而后可再用cpio命令将该普通文件转成目录结构.用-i选项时,cpio从标准输入设备读文件和目录名表,并将其内容按档案格式拷贝到标准输出设备,使用- o选项时,cpio从标准输入设备读取先已建好的档案,重建目录结构.cpio命令常用以下命令做一完整的目录系统档案:
find fromdir -print|cpio -o > archive
根据档案文件重建一个目录结构命令为:
cpio -id < archive
cpio的安全约定如下:
(1)档案文件存放每个文件的信息,包括文件所有者,小组用户,最后修改时间,最后存取时间,文件存取许可方式.*根据档案建立的文件保持存放于档案中的取许可方式.*从档案中提取的每个文件的所有者和小组用户设置给运行cpio -i命令的用户,而不是设置给档案中指出的所有者和小组用户.*当运行 cpio -i命令的用户是root时,被建立的文件的所有者和小组用户是档案文件所指出的.*档案中的SUID/SGID文件被重建时,保持SUID和 SGID许可,如果重建文件的用户不是root,SUID/SGID许可是档案文件指出的用户/小组的许可.
(2)现存文件与cpio档案中的文件同名时,若现存文件比档案中的文件更新,这些文件将不被重写.
(3)如果用修改选项U,则同名的现存的文件将被重写.可能会发生一件很奇怪的事:如被重写的文件原与另一个文件建了链,文件被重写后链并不断开,换言之,该文件的链将保持,因此,该文件的所有链实际指向从档案中提取出来的文件,运行cpio无条件地重写现存文件以及改变链的指向.
(4)cpio档案中可含的全路径名或父目录名给出的文件.
7.su和newgrp命令
(1)su命令:可不必注销户头而将另一用户又登录进入系统,作为另一用户工作.它将启动一新的shell并将有效和实际的UID和GID设置给另一用户.因此必须严格将root口令保密.
(2)newgrp命令:与su相似,用于修改当前所处的组名.
8.文件加密
crypt命令可提供给用户以加密文件,使用一个关键词将标准输入的信息编码为不可读的杂乱字符串,送到标准输出设备.再次使用此命令,用同一关键词作用于加密后的文件,可恢复文件内容.一般来说,在文件加密后,应删除原始文件,只留下加密后的版本,且不能忘记加密关键词.在vi中一般都有加密功能,用 vi -x命令可编辑加密后的文件.关于加密关键词的选取规则与口令的选取规则相同.由于crypt程序可能被做成特洛依木马,故不宜用口令做为关键词. 最好在加密前用pack或compress命令对文件进行压缩后再加密.
9.其它安全问题
(1)用户的.profile文件
由于用户的HOME目录下的.profile文件在用户登录时就被执行.若该文件对其他人是可写的则系统的任何用户都能修改此文件,使其按自己的要求工作.这样可能使得其他用户具有该用户相同的权限.
(2)ls -a
此命令用于列出当前目录中的全部文件,包括文件名以.开头的文件,查看所有文件的存取许可方式和文件所有者,任何不属于自己但存在于自己的目录中的文件都应怀疑和追究.
(3).exrc文件
为编辑程序的初始化文件,使用编辑文件后,首先查找$HOME/.exrc文件和./.exrc文件,若该文件是在$HOME目录中找到,则可像. profile一样控制它的存取方式,若在一个自己不能控制的目录中,运行编辑程序,则可能运行其他人的exrc文件,或许该.exrc文件存在那里正是为了损害他人的文件安全.为了保证所编辑文件的安全,最好不要在不属于自己或其他人可写的目录中运行任何编辑程序.
(4)暂存文件和目录
在UNIX系统中暂存目录为/tmp和/usr/tmp,对于程序员和许多系统命令都使用它们,如果用这些目录存放暂存文件,别的用户可能会破坏这些文件.使用暂存文件最好将文件屏蔽值定义为007,但最保险的方法是建立自己的暂存文件和目录HOME/tmp,不要将重要文件存放于公共的暂存目录.
(5)UUCP和其它网络
UUCP命令用于将文件从一个UNIX系统传送到另一个UNIX系统,通过UUCP传送的文件通常存于 /usr/spool/uucppublic/login目录,login是用户的登录名,该目录存取许可为777,通过网络传输并存放于此目录的文件属于UUCP所有,文件存取许可为666和777,用户应当将通过UUCP传送的文件加密,并尽快移到自己的目录中.其它网络将文件传送到用户HOME目录下的rjc目录中.该目录应对其他人是可写可搜索的,但不必是可读的,因而用户的rjc目录的存取许可方式应为733,允许程序在其中建立文件.同样,传送的文件也应加密并尽快移到自己的目录中.
(6)特络依木马
在UNIX系统安全中,用特络依木马来代表和种程序,这种程序在完成某种具有明显意图的功能时,还破坏用户的安全.如果PATH设置为先搜索系统目录,则受特络依木马的攻击会大大减少.如模似的crypt程序.
(7)诱骗
类似于特络依木马,模似一些东西使用户泄漏一些信息,不同的是,它由某人执行,等待无警觉的用户来上当.如模似的login.
(8)计算机病毒
计算机病毒通过把其它程序变成病毒从而传染系统的,可以迅速地扩散,特别是系统管理员的粗心大意,作为root运行一个被感染的程序时.实验表明,一个病毒可在一个小时内(平均少于30分钟)取得root权限.
(9)要离开自己已登录的终端
除非能对终端上锁,否则一定要注销户头.
(10)智能终端
由于智能终端有send和enter换码序列,告诉终端送当前行给系统,就像是用户敲入的一样.这是一种危险的能力,其他人可用write命令发送信息给本用户终端,信息中如含有以下的换码序列:移光标到新行(换行)在屏幕上显示"rm -r *"将该行送给系统后果大家可以想象.禁止其他用户发送信息的方法是使用mesg命令,mesg n不允许其他用户发信息,mesg y允许其他用户发信息.
即使如此仍是有换码序列的问题存在,任何一个用户用mail命令发送同样一组换码序列,不同的要用!rm -r *替换rm -r *.mail将以!开头的行解释为一条shell命令,启动shell,由shell解释该行的其它部分,这被称为shell换码.为避免mail命令发送换码序列到自己的终端,可建立一个过滤程序,在读mail文件之前先运行过滤程序,对mail文件进行处理:
myname="$LOGNAME";
tr -d[\001-\007][-\013-\037]<
/usr/mail/$myname >> $HOME/mailbox;
> /usr/mail/$myname;
mail -f $HOME/mailbox
其中tr将标准输入的字符转换手写到标准输出中.这只是一个简单的思路,从原则上来说,此程序应为一C程序,以避免破坏正发送到的文件,可用锁文件方式实现.
(11)断开与系统的联接
用户应在看到系统确认用户登录注销后再离开以免在用户未注销时由他人潜入.
(12)cu命令
该命令使用户能从一个UNIX系统登录到另一个UNIX系统,此时,在远地系统中注销用户后还必须输入"~"后回车,以断开cu和远地系统
的联接.cu还有两个安全问题:*如本机安全性弱于远地机,不提倡用cu去登
录远地机,以免由于本地机的不安全而影响较安全的远地机.*由于cu的老版本处理"~"的方法不完善,从安全性强的系统调用安全性弱的系统时,会使弱系统的用户使用强系统用户的cu传送强系统的/etc/passwd文件,除非确信正在使用的cu是正确版本,否则不要调用弱系统.
10.保持户头安全的要点
(1)保持口令的安全
*不要将口令写下来.
*不要将口令存于终端功能键或MODEM的字符串存储器中
*不要选取显而易见的信息作口令.
*不要让别人知道.
*不要交替使用两个口令.
*不要在不同系统上使用同一口令.
*不要让人看见自己在输入口令.
(2)不要让自己的文件或目录可被他人写.
*如果不信任本组用户,umask设置为022.*确保自己的.profile除自己外对他人都不可读写.
*暂存目录最好不用于存放重要文件.
*确保HOME目录对任何人不可写.
*uucp传输的文件应加密,并尽快私人化.
(3)若不想要其他用户读自己的文件或目录,就要使自己的文件和目录不允许任何人读.*umask设置为006/007.*若不允许同组用户存取自己的文件和目录,umask设置为077.*暂存文件按当前umask设置,存放重要数据到暂存文件的程序,就被写成能确保暂存文件对其他用户不可读.
*确保HOME目录对每个用户不可读.
(4)不要写SUID/SGID程序.
(5)小心地拷贝和移文件.
*cp拷贝文件时,记住目的文件的许可方式将和文件相同,包括SUID/SGID许可在内,如目的文件已存在,则目的文件的存取许可和所有者均不变.
*mv移文件时,记住目的文件的许可方式将和文件相同,包括SUID/SGID许可在内,若在同一文件系统内移文件,目的文件的所有者和小组都不变,否则,目的文件的所有者和小组将设置成本用户的有效UID和GID.
*小心使用cpio命令,它能复盖不在本用户当前目录结构中的文件,可用t选项首先列出要被拷贝的文件.
(6)删除一个SUID/SGID程序时,先检查该程序的链接数,如有多个链,则将存取许可方式改为000,然后再删除该程序,或先写空该程序再删除,也可将该程序的i结点号给系统管理员去查找其他链.
(7)用crypt加密不愿让任何用户(包括超级用户)看的文件.
*不要将关键词做为命令变量.
*用ed -x或vi -x编辑加密文件.
(8)除了信任的用户外,不要运行其他用户的程序.
(9)在自己的PATH中,将系统目录放在前面.
(10)不要离开自己登录的终端.
(11)若有智能终端,当心来自其他用户,包括write命令,mail命令和其他用户文件的信息中有换码序列.
(12)用CTRL+D或exit退出后,在断开与系统的联接前等待看到login:提示.
(13)注意cu版本.
*不要用cu调用安全性更强的系统.
*除非确信cu不会被诱骗去发送文件,否则
不要用cu调用安全性较弱的系统.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-30 19:01:28 | 显示全部楼层
[推荐]网络安全技术与黑客攻击威胁
UNIX系统管理-系统安全-网络安全技术与黑客攻击威胁
引言
企业网络安全的核心是企业信息的安全。为防止非法用户利用网络系统的安全缺陷进行数据的窃取、伪造和破坏,必须建立企业网络信息系统的安全服务体系。关于计算机信息系统安全性的定义到目前为止还没有统一,国际标准化组织(ISO)的定义为:“为数据处理系统建立和采用的技术和管理的安全保护,保护计算机硬件、软件和数据不因偶然和恶意的原因遭到破坏、更改和泄露”。计算机安全包括物理安全和逻辑安全,其中物理安全指系统设备及相关设施的物理保护以免于被破坏和丢失,逻辑安全是指信息的可用性、完整性和保密性三要素。 信息安全的隐患存在于信息的共享和传递过程中。目前,浏览器/服务器技术已广泛应用于企业网络信息系统中,而其基础协议就存在着不少的安全漏洞。 一种基本的安全系统&#0;&#0;网络安全系统,也称为防火墙系统,可以设置在公用网络系统和企业内部网络之间,或者设置在内部网络的不同网段之间,用以保护企业的核心秘密并抵御外来非法攻击。随着企业网上业务的不断扩大和电子商务的发展,对网络的安全服务提出了新的要求。像用户认证、信息的加密存贮、信息的加密传输、信息的不可否认性、信息的不可修改性等要求,要用密码技术、数字签名、数字邮戳、数字凭证和认证中心等技术和手段构成安全电子商务体系。
黑客攻击企业信息系统的手段
2.1 TCP/IP协议存在安全漏洞
目前使用最广泛的网络协议是TCP/IP协议,而TCP/IP协议恰恰存在安全漏洞。如IP层协议就有许多安全缺陷。IP地址可以软件设置,这就造成了地址假冒和地址欺骗两类安全隐患;IP协议支持源路由方式,即源点可以指定信息包传送到目的节点的中间路由,这就提供了源路由攻击的条件。再如应用层协议 Telnet、FTP、SMTP等协议缺乏认证和保密措施,这就为否认、拒绝等欺瞒行为开了方便之门。 对运行TCP/IP协议的网络系统,存在着如下五种类型的威胁和攻击:欺骗攻击、否认服务、拒绝服务、数据截取和数据纂改。
2.2 黑客攻击网络信息系统的手段
黑客攻击的目标不相同,有的黑客注意焦点是美国国防部五角大楼,有的关心是安全局、银行或者重要企业的信息中心,但他们采用的攻击方式和手段却有一定的共同性。一般黑客的攻击大体有如下三个步骤:
信息收集→对系统的安全弱点探测与分析→实施攻击。
2.2.1 信息收集
信息收集的目的是为了进入所要攻击的目标网络的数据库。黑客会利用下列的公开协议或工具,收集驻留在网络系统中的各个主机系统的相关信息。
&#8226;SNMP协议 用来查阅网络系统路由器的路由表,从而了解目标主机所在网络的拓扑结构及其内部细节。
&#8226;TraceRoute程序 能够用该程序获得到达目标主机所要经过的网络数和路由器数。
&#8226;Whois协议 该协议的服务信息能提供所有有关的DNS域和相关的管理参数。
&#8226;DNS服务器 该服务器提供了系统中可以访问的主机的IP地址表和它们所对应的主机名。
&#8226;Finger协议 可以用Finger来获取一个指定主 机上的所有用户的详细信息(如用户注册名、电话号码、最后 注册时间以及他们有没有读邮件等等)。
&#8226ing实用程序 可以用来确定一个指定的主机的位置。
&#8226;自动Wardialing软件 可以向目标站点一次连续拨出大批电话号码,直到遇到某一正确的号码使其MODEM响应。
2.2.2 系统安全弱点的探测
在收集到攻击目标的一批网络信息之后,黑客会探测网络上的每台主机,以寻求该系统的安全漏洞或安全弱点,黑客可能使用下列方式自动扫描驻留网络上的主机。
&#8226; 自编程序 对某些产品或者系统,已经发现了一些安全漏洞,该产品或系统的厂商或组织会提供一些“补丁”程序给予弥补。但是用户并不一定及时使用这些“补丁”程序。黑客发现这些“补丁”程序的接口后会自己编写程序,通过该接口进入目标系统,这时该目标系统对于黑客来讲就变得一览无余了。
&#8226; 利用公开的工具 象Internet的电子安全扫描程序IIS(InternetSecurity Scanner)、审计网络用的安全分析工具 SATAN(Security Analysis Toolfor Auditing Network)等这样的工具,可以对整个网络或子网进行扫描,寻找安全漏洞。这些工具有两面性,就看是什么人在使用它们。系统管理员可以使用它们,以帮助发现其管理的网络系统内部隐藏的安全漏洞,从而确定系统中那些主机需要用“补丁”程序去堵塞漏洞。而黑客也可以利用这些工具,收集目标系统的信息,获取攻击目标系统的非法访问权。
2.2.3 网络攻击
黑客使用上述方法,收集或探测到一些“有用”信息之后,就可能会对目标系统实施攻击。黑客一旦获得了对攻击的目标系统的访问权后,又可能有下述多种选择:
&#8226;该黑客可能试图毁掉攻击入侵的痕迹,并在受到损害的系统上建立另外的新的安全漏洞或后门,以便在先前的攻击点被发现之后,继续访问这个系统。
&#8226;该黑客可能在目标系统中安装探测器软件,包括特洛伊木马程序,用来窥探所在系统的活动,收集黑客感兴趣的一切信息,如Telnet和FTP的帐号名和口令等等。
&#8226;该黑客可能进一步发现受损系统在网络中的信任等级,这样黑客就可以通过该系统信任级展开对整个系统的攻击。
&#8226;如果该黑客在这台受损系统上获得了特许访问权,那么它就可以读取邮件,搜索和盗窃私人文件,毁坏重要数据,破坏整个系统的信息,造成不堪设想的后果。
防火墙的基本思想
如果网络在没有防火墙的环境中,网络安全性完全依赖主系统的安全性。在一定意义上,所有主系统必须通力协作来实现均匀一致的高级安全性。子网越大,把所有主系统保持在相同的安全性水平上的可管理能力就越小,随着安全性的失策和失误越来越普遍,入侵就时有发生。 防火墙有助于提高主系统总体安全性。 防火墙的基本思想&#0;&#0;不是对每台主机系统进行保护,而是让所有对系统的访问通过某一点,并且保护这一点,并尽可能地对外界屏蔽保护网络的信息和结构。它是设置在可信任的内部网络和不可信任的外界之间的一道屏障,它可以实施比较广泛的安全政策来控制信息流,防止不可预料的潜在的入侵破坏。 防火墙系统可以是路由器,也可以是个人机、主系统或者是一批主系统,专门用于把网点或子网同那些可能被子网外的主系统滥用的协议和服务隔绝。 防火墙可以从通信协议的各个层次以及应用中获取、存储并管理相关的信息,以便实施系统的访问安全决策控制。 防火墙的技术已经经历了三个阶段,即包过滤技术、代理技术和状态监视技术。
包过滤技术
包过滤防火墙的安全性是基于对包的IP地址的校验。在Internet上,所有信息都是以包的形式传输的,信息包中包含发送方的IP地址和接收方的IP地址。包过滤防火墙将所有通过的信息包中发送方IP地址、接收方IP地址、TCP端口、TCP链路状态等信息读出,并按照预先设定的过滤原则过滤信息包。那些不符合规定的IP地址的信息包会被防火墙过滤掉,以保证网络系统的安全。这是一种基于网络层的安全技术,对于应用层的黑客行为是无能为力的。
代理技术
代理服务器接收客户请求后会检查验证其合法性,如其合法,代理服务器象一台客户机一样取回所需的信息再转发给客户。它将内部系统与外界隔离开来,从外面只能看到代理服务器而看不到任何内部资源。代理服务器只允许有代理的服务通过,而其他所有服务都完全被封锁住。这一点对系统安全是很重要的,只有那些被认为 “可信赖的”服务才允许通过防火墙。另外代理服务还可以过滤协议,如可以过滤FTP连接,拒绝使用FTP put(放置)命令,以保证用户不能将文件写到匿名服务器。 代理服务具有信息隐蔽、保证有效的认证和登录、简化了过滤规则等优点。 网络地址转换服务 (NATNetwork Address Translation)可以屏蔽内部网络的IP地址,使网络结构对外部来讲是不可见的。
状态监视技术
这是第三代网络安全技术。状态监视服务的监视模块在不影响网络安全正常工作的前提下,采用抽取相关数据的方法对网络通信的各个层次实行监测,并作安全决策的依据。监视模块支持多种网络协议和应用协议,可以方便地实现应用和服务的扩充。状态监视服务可以监视RPC(远程过程调用)和UDP(用户数据报)端口信息,而包过滤和代理服务则都无法做到。
防火墙的类型
4.1 按实现的网络层次分
Internet采用TCP/IP协议,设置在不同网络层次上的电子屏障构成了不同类型的防火墙:
包过滤型防火墙(Packet Firewall)、电路网关(Circuit Gateway)和应用网关(Application Gateway)。
安全策略是防火墙的灵魂和基础。在建立防火墙之前要在安全现状、风险评估和商业需求的基础上提出一个完备的总体安全策略,这是配制防火墙的关键。 安全策略可以按如下两个逻辑来制订:
&#8226;准许访问除明确拒绝以外的全部访问&#0;&#0;所有未被禁止的都允许访问。
&#8226;拒绝访问除明确准许的全部访问&#0;&#0;所有未被允许的都禁止访问。
可以看出后一逻辑限制性大,前一逻辑比较宽松。
4.1.1 包过滤防火墙
(1)包过滤防火墙实施步骤
包过滤防火墙是基于路由器来实现的。它利用数据包的头信息(源IP地址、封装协议、端口号等)判定与过滤规则相匹配与否来决定舍取。建立这类防火墙需按如下步骤去做。
&#8226;建立安全策略&#0;&#0;写出所允许的和禁止的任务;
&#8226;将安全策略转化为数据包分组字段的逻辑表达式;
&#8226;用供货商提供的句法重写逻辑表达式并设置之。
(2)包过滤防火墙针对典型攻击的过滤规则
包过滤防火墙主要是防止外来攻击,其过滤规则大体有:
&#8226;对付源IP地址欺骗式攻击(Source IP Address Spoofing Attacks) 对入侵者假冒内部主机,从外部传输一个源IP地址为内部网络IP地址的数据包的这类攻击,防火墙只需把来自外部端口的使用内部源地址的数据包统统丢弃掉。 &#8226;对付源路由攻击(Source Rowing Attacks) 源站点指定了数据包在Internet中的传递路线,以躲过安全检查,使数据包循着一条不可预料的路径到达目的地。对付这类攻击,防火墙应丢弃所有包含源路由选项的数据包。
&#8226; 对付残片攻击(Tiny Fragment Attacks) 入侵者使用TCP/IP数据包的分段特性,创建极小的分段并强行将TCP头信息分成多个数据包,以绕过用户防火墙的过滤规则。黑客期望防火墙只检查第一个分段而允许其余的分段通过。对付这类攻击,防火墙只需将TCP/IP协议片断位移植 (Fragment Offset)为1的数据包全部丢弃即可。
(3)包过滤防火墙的优缺点
包过滤防火墙的优点是简单、透明,其缺点是:
&#8226;该防火墙需从建立安全策略和过滤规则集入手,需要花费大量的时间和人力,还要不断根据新情况不断更新过滤规则集。同时,规则集的复杂性又没有测试工具来检验其正确性,难免仍会出现漏洞,给黑客以可乘之机。
&#8226;对于采用动态分配端口的服务,如很多RPC(远程过程调用)服务相关联的服务器在系统启动时随机分配端口的,就很难进行有效地过滤。
&#8226;包过滤防火墙只按规则丢弃数据包而不作记录和报告,没有日志功能,没有审计性。同时它不能识别相同IP地址的不同用户,不具备用户身份认证功能,不具备检测通过高层协议(如应用层)实现的安全攻击的能力。
包过滤防火墙是保护网络安全的必不可少的重要工具,更重要的是要理解这些问题并着手解决。
4.1.2电路级网关
电路级网关又称线路级网关,它工作在会话层。它在两个主机首次建立TCP连接时创立一个电子屏障。它作为服务器接收外来请求,转发请求;与被保护的主机连接时则担当客户机角色、起代理服务的作用。它监视两主机建立连接时的握手信息,如Syn、Ack和序列数据等是否合乎逻辑,判定该会话请求是否合法。一旦会话连接有效后网关仅复制、传递数据,而不进行过滤。电路网关中特殊的客户程序只在初次连接时进行安全协商控制,其后就透明了。只有懂得如何与该电路网关通信的客户机才能到达防火墙另一边的服务器。 在不同方向上拒绝发送放置和取得命令,就可限制FTP服务的使用。如不允许放置命令输入,外部用户就不能写到FTP服务器破坏其内容;如不允许放置命令输出,则不可能将信息存储在网点外部的FTP服务器了。 电路级网关的防火墙的安全性比较高,但它仍不能检查应用层的数据包以消除应用层攻击的威胁。
4.1.3 应用级网关
应用级网关使用软件来转发和过滤特定的应用服务,如TELNET、FTP等服务的连接。这是一种代理服务。它只允许有代理的服务通过,也就是说只有那些被认为“可信赖的”服务才被允许通过防火墙。另外代理服务还可以过滤协议,如过滤FTP连接、拒绝使用FTP放置命令等。 应用级网关具有登记、日记、统计和报告功能,有很好的审计功能。还可以具有严格的用户认证功能。 应用级网关的安全性高,其不足是要为每种应用提供专门的代理服务程序。
4.2 按实现的硬件环境分
根据实现防火墙的硬件环境,可分为基于路由器的防火墙和基于主机系统的防火墙。 包过滤防火墙可基于路由器或基于主机系统来实现,而电路级网关和应用级网关只能由主机系统来实现。
4.3 按拓扑结构分
4.3.1 双穴网关(Dual Homed Gateway)
主机系统作为网关,其中安装两块网络接口分别连接到Internet和Intranet。在该双穴网关中,从包过滤到应用级的代理服务、监视服务都可以用来实现系统的安全策略。 对双穴网关的最大威胁是直接登录到该主机后实施攻击,因此双穴网关对不可信任的外部主机的登录应进行严格的身份验证。
4.3.2 屏蔽主机网关
屏蔽主机网关由一个运行代理服务的双宿网关和一个具有包过滤功能的路由器组成,功能的分开提高了防护系统的效率。
4.3.3 屏蔽子网网关
一个独立的屏蔽子网位于Intranet与Internet之间,起保护隔离作用。它由两台过滤路由器和一台代理服务主机构成。路由器过滤掉禁止或不能识别的信息,将合法的信息送到代理服务主机上,并让其检查,并向内或向外转发符合安全要求的信息。 该方案安全性能很高,但管理也最复杂,成本也很高,应用于高安全要求的场合。
先进的认证技术
先进的认证措施,如智能卡、认证令牌、生物统计学和基于软件的工具已被用来克服传统口令的弱点。尽管认证技术各不相同,但它们产生的认证信息不能让通过非法监视连接的攻击者重新使用。在目前黑客智能程度越来越高的情况之下,一个可访问Internet的防火墙,如果不使用先进认证装置或者不包含使用先进验证装置的挂接工具的话,这样防火墙几乎是没有意义的。 当今使用的一些比较流行的先进认证装置叫做一次性口令系统。例如,智能卡或认证令牌产生一个主系统可以用来取代传统口令的响应信号,由于智能卡或认证令牌是与主系统上的软件或硬件协同工作的,因此,所产生的响应对每次注册都是独一无二的。其结果是产生一种一次性口令。这种口令即使被入侵者获得,也不可能被入侵者重新使用来获得某一帐户,就非常有效地保护了Intranet网络。 由于防火墙可以集中并控制网络的访问,因而防火墙是安装先进认证系统的合理场所。
结束语
Intrnaet必须受到保护,防火墙是最重要的手段之一。现代防火墙必须采用综合安全技术,有时还需加入信息的加密存贮和加密传输技术,方能有效地保护系统的安全。对于电子商务还需采用数字签名、数字邮戳、数字凭证等安全技术方能有效地保护企业的利益。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表