标签 linux 下的文章

apache 记录来访日志,并按照日期进行分割

逐个对每个虚拟主机进行配置的,找到一个虚拟主机,添加如下内容

LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
CustomLog "/usr/logs/logs/access_log" combined

然后,这样的话当前的虚拟主机的日志就会放到/data/wwwlogs/apache/

<VirtualHost *:80>
...
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
LogFormat "%h %l %u %t "%r" %>s %b" common
CustomLog "/data/wwwlogs/apache/access_log" combined
</VirtualHost>

如果要添加按照日期进行划分,如下请修改:

CustomLog "/backup/logs/access_log" combined
CustomLog "|/usr/local/apache/bin/rotatelogs /data/wwwlogs/apache/access.%Y%m%d 86400" common

 

/usr/local/apache/                    apache路径

/data/wwwlogs/apache/           日志路径

access                                       日志前缀

%Y%m%d                                    后缀格式

86400                                       分割时长

具体日志命名如下:access.20140608

Linux 删除指定日期之前的文件

要删除系统中就的备份文件,就需要使用命令了:

#find /tmp -mtime +30 -type f -name *.sh[ab] -exec rm -f {} ;

 

假如在一个目录中保留最近30天的文件,30天前的文件自动删除

#find /tmp -mtime +30 -type f -name *.sh[ab] -exec rm -f {} ;

 

/tmp –设置查找的目录;

-mtime +30 –设置时间为30天前;

-type f –设置查找的类型为文件;

-name *.sh[ab] –设置文件名称中包含sha或者shb;

-exec rm -f –查找完毕后执行删除操作;

提示:将此命令写入crontab后即可自动完成查找并删除的工作

另外的方法大同小异

#find . -mtime +30 -type f | xargs rm -rf

 

我的操作是:先ls -ltr 查看时间,没有太久的所以就用 -cmin n查找系统中最后N分钟被改变文件状态的文件。具体命令:

$ find /home/oracle/test6 -cmin +20 -type f -name *.xml -exec rm -f { } ;

 

另外的方法大同小异

#find . -mtime +30 -type f | xargs rm -rf

$find . -type f -cmin +10 -exec rm -rf *.xml {} ;

find . type f -name "debug*" -atime +3 -exec rm -f {} ;

 

首先cd进入目录:

find . -name "*~" -exec rm {} ;

find . -ctime +n -exec -exec rm -vi {} ;

 

这里的+n是指多少天以前,比如:+7

find . -ctime +7 -exec -exec rm -vi {} ;

 

如果不想手动确认,把命令中的-vi改成-fv

请详查find命令。

使用find时要区分清楚atime,ctime,mtime的区别,一般都使用mtime来查找,因为在ls -al显示出来的就是mtime时间戳,可以使用:

# find $PAHT -mtime +3 -ok rm {} ;

 

在交互模式下删除比较保险。

一、按照一定日期格式命名文件

1、按照一定的格式输出日期:

date +”%y%m%d”

格式说明:

% : 印出 %

%n : 下一行

%t : 跳格

%H : 小时(00-23)

%I : 小时(01-12)

%k : 小时(0-23)

%l : 小时(1-12)

%M : 分钟(00-59)

%p : 显示本地 AM 或 PM

%r : 直接显示时间 (12 小时制,格式为 hh:mm:ss [AP]M)

%s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数

%S : 秒(00-60)

%T : 直接显示时间 (24 小时制)

%X : 相当于 %H:%M:%S

%Z : 显示时区

日期方面 :

%a : 星期几 (Sun-Sat)

%A : 星期几 (Sunday-Saturday)

%b : 月份 (Jan-Dec)

%B : 月份 (January-December)

%c : 直接显示日期与时间

%d : 日 (01-31)

%D : 直接显示日期 (mm/dd/yy)

%h : 同 %b

%j : 一年中的第几天 (001-366)

%m : 月份 (01-12)

%U : 一年中的第几周 (00-53) (以 Sunday 为一周的第一天的情形)

%w : 一周中的第几天 (0-6)

%W : 一年中的第几周 (00-53) (以 Monday 为一周的第一天的情形)

%x : 直接显示日期 (mm/dd/yy)

%y : 年份的最后两位数字 (00.99)

%Y : 完整年份 (0000-9999)

2、命名带有日期的文件:filename`date +%y%m%d`,此处的”`”不是单引号。

二、以创建文件日期为界线删除文件

1、find命令简解

find pathname -options [-print -exec -ok …]

 

pathname: find命令所查找的目录路径。例如用。来表示当前目录,用/来表示系统根目录。

-print: find命令将匹配的文件输出到标准输出。

-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为’command’ { } ;,注意{ }和;之间的空格。

-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

options:

-name

按照文件名查找文件。

-perm

按照文件权限来查找文件。

-prune

使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。

-user

按照文件属主来查找文件。

-group

按照文件所属的组来查找文件。

-mtime -n +n

按照文件的更改时间来查找文件, – n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。

-nogroup

查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。

-nouser

查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。

-newer file1 ! file2

查找更改时间比文件file1新但比文件file2旧的文件。

-type

查找某一类型的文件,诸如:

b – 块设备文件。

d – 目录。

c – 字符设备文件。

p – 管道文件。

l – 符号链接文件。

f – 普通文件。

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。

-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。

-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。

-mount:在查找文件时不跨越文件系统mount点。

-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。

-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。

对于时间相关的参数,有以下补充:

-amin n

查找系统中最后N分钟访问的文件

-atime n

查找系统中最后n*24小时访问的文件

-cmin n

查找系统中最后N分钟被改变文件状态的文件

-ctime n

查找系统中最后n*24小时被改变文件状态的文件

-mmin n

查找系统中最后N分钟被改变文件数据的文件

-mtime n

查找系统中最后n*24小时被改变文件数据的文件

2、删除固定日期以前的文件

find logs -type f -mtime +5 -exec rm { } ;

 

linux crontab 定时执行任务

*  *  *  *  *
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache
名称 : crontab
使用权限 : 所有使用者
使用方式 :
crontab file [-u user]-用指定的文件替代目前的crontab。
crontab-[-u user]-用标准输入替代目前的crontab.
crontab-1[user]-列出用户目前的crontab.
crontab-e[user]-编辑用户目前的crontab.
crontab-d[user]-删除用户目前的crontab.
crontab-c dir- 指定crontab的目录。
crontab文件的格式:M H D m d cmd.
M: 分钟(0-59)。
H:小时(0-23)。
D:天(1-31)。
m: 月(1-12)。
d: 一星期内的天(0~6,0为星期天)。
cmd要运行的程序,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量
说明 :
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。-u user 是指设定指定
user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设
定自己的时程表。
参数 :
crontab -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数
来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
crontab -r : 删除目前的时程表
crontab -l : 列出目前的时程表
crontab file [-u user]-用指定的文件替代目前的crontab。
时程表的格式如下 :
f1 f2 f3 f4 f5 program
其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执
行的程序。
当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推
当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
当 f1 为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,f2 为 a, b, c,… 时表示第 a, b, c…个小时要执行,其馀类推
使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。
例子 :
#每天早上7点执行一次 /bin/ls :
0 7 * * * /bin/ls
在 12 月内, 每天的早上 6 点到 12 点中,每隔3个小时执行一次 /usr/bin/backup :
0 6-12/3 * 12 * /usr/bin/backup
周一到周五每天下午 5:00 寄一封信给 alex@domain.name :
0 17 * * 1-5 mail -s “hi” alex@domain.name < /tmp/maildata
每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分….执行 echo “haha”
20 0-23/2 * * * echo “haha”
注意 :
当程序在你所指定的时间执行后,系统会寄一封信给你,显示该程序执行的内容,若是你不希望收到这样的信,请在每一行空一格之
后加上 > /dev/null 2>&1 即可
例子2 :
#每天早上6点10分
10 6 * * * date
#每两个小时
0 */2 * * * date
#晚上11点到早上8点之间每两个小时,早上8点
0 23-7/2,8 * * * date
#每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * mon-wed date
#1月份日早上4点
0 4 1 jan * date
范例
$crontab -l 列出用户目前的crontab.

sed 取某时段内apache的访问日志

导出 2013-05-24 15:00:00 ~ 2013-05-28 16:00:00 之间的apache访问日志

Apache日志格式为:

222.92.115.194 - - [28
/May/2013
:17:01:00 +0800] 
"GET /media/js/jquery.eislideshow.js HTTP/1.1"

 

304 -
222.92.115.194 - - [28
/May/2013
:17:01:00 +0800] 
"GET /media/style/tpl/tpl_buy_left/tpl_buy_left.js HTTP/1.1"

 

304 -
222.92.115.194 - - [28
/May/2013
:17:01:01 +0800] 
"GET /favicon.ico HTTP/1.1"

 

404 17846
222.92.115.194 - - [28
/May/2013
:17:01:01 +0800] 
"GET /large-display/interactive/ HTTP/1.1"

 

200 21382
222.92.115.194 - - [28
/May/2013
:17:01:02 +0800] 
"GET /favicon.ico HTTP/1.1"

 

404 17846
222.92.115.194 - - [28
/May/2013
:17:01:04 +0800] 
"GET /large-display/single/ HTTP/1.1"
200 21386
222.92.115.194 - - [28
/May/2013
:17:01:04 +0800] 
"GET /favicon.ico HTTP/1.1"

 

404 17846
222.92.115.195 - - [28
/May/2013
:17:01:05 +0800] 
"GET /dsc/ HTTP/1.1"

 

200 34530
222.92.115.195 - - [28
/May/2013
:17:01:05 +0800] 
"GET /media/img/channel_icon.jpg HTTP/1.1"

 

404 17846
222.92.115.195 - - [28
/May/2013
:17:01:06 +0800] 
"GET /favicon.ico HTTP/1.1"

 

404 17846

截取命令:

[root@style logs]# sed

 

-n
'/24/May/2013:15:00:01/,/28/May/2013:16:59:58/p' xxxx-access_log > 20130524.15-20130528.16-access_log.txt

PS:需要注意的是如果起始时间在日志中不存在,则整个截取将返回 0 行结果。而如果结束时间在日志中不存在,则会截取到日志的最后一条。所以在截取前得要找到最日志中最合适的起始点和结束点。
我的做法是先使用grep去找到两个点  再使用sed去截取

# 找出 2013-05-24 15点第一条记录的时间
[root@style logs]# grep '24/May/2013:15' xxxx-access_log | head

 

-1
10.200.114.183 - - [24/May/2013:15:00:01 +0800] "GET /gp10/pic_259_218_1368781965.png HTTP/1.0" 401 484
# 找出 2013-05-28 16点最后一条记录的时间
[root@style logs]# grep '28/May/2013:16' xxxx-access_log | tail

 

-1
222.92.115.195 - - [28/May/2013:16:59:58 +0800] "GET /favicon.ico HTTP/1.1" 404 17846
# 然后取这两个时间段之间的记录

一步一步加固自己的linux系统

介绍

这个教程将一步步的指引你,使你的Linux系统变得安全。
任何默认安装的操作系统都是不够安全的,本文将指引你如何建立一个
相对安全的Linux系统。
========================================================================
1.BIOS
你应该总是在系统启动的时候设置一个BIOS密码和禁用从CD-ROM和软盘引导。
这将防止一些人未经允许访问你的系统和更改BIOS设置

2.SSH安全
SSH是一个协议,利用它可以登录到一个远程系统或远程执行系统命令,
默认允许root登录,并且sshv1存在缺陷,我们应该在
sshd_config禁止root访问和使用sshv2来让ssh更加安全。

方法:

vi /etc/ssh/sshd_config
把协议改为2

PermitRootLogin = no
重启

sshd /etc/rc.d/init.d/sshd restart

 

3.禁用telnet
早期的Linux默认开启telnet服务,telnet,ftp,rlogin都是明文传输的协议
是容易被嗅探到的,这就是为什么推荐使用安全的版本(sftp,scp,ssh)的原因
如果你必须要使用telnet,那么至少应该隐藏banner信息

方法:
修改

/etc/xinetd.d/telnet
disable=yes
4.禁用代码编译
你可以禁用代码编译并且只把编译的权限分配给一个用户组
方法:
添加编译用户组

/usr/sbin/groupadd compiler ,cd /usr/bin
把常见的编译器所属组赋给编译用户组

chgrp compiler *cc*
chgrp compiler *++*
chgrp compiler ld
chgrp compiler as
设置mysqlaccess的访问

chgrp root mysqlaccess
设置权限

chmod 750 *cc*
chmod 750 *++*
chmod 750 ld
chmod 750 as
chmod 755 mysqlaccess
把用户添加到组里
修改/etc/group

compiler:x:520:user1,user2
5.ProFTP
你可以通过修改proftpd.conf来禁止root登陆
方法:
修改/etc/proftpd.conf

Add RootLogin off
重启

proftpd /sbin/service proftpd stop
/sbin/service proftpd start
6.TCP wrappers
编辑hosts.allow和hosts.deny可以限制或允许访问inet服务

方法:
限制访问inet服务
修改/etc/hosts.allow
建议格式:

#Approved IP addresses
ALL:192.168.0.1
ALL:192.168.5.2
#CSV uploader machine
proftpd:10.0.0.5
#pop3 from antwhere
ipop3:ALL
修改/etc/hosts.deny

ALL:ALL EXCEPT localhostENY
7.创建SU用户组
因为我们在SSH禁止了root用户访问并且禁用了telnet,所有我们应该
分配给一些用户su权限来获取root特权

方法:
vi /etc/group
添加一行 wheel:x:10:root,user1,user2

chgrp wheel /bin/su
chmod o-rwx /bin/su
8.root通知
当一个具有root权限的用户登录的时候发mail
方法:
编辑/root下的.bashrc ,当有root权限的用户登录时发生email通知

echo ‘ALERT ? Root Shell Access (Server Name) on:’ `date` `who` | mail -s “Alert: Root Access from `who | cut -d”(” -f2 | cut -d”)” -f1`” your@email.com
9.history安全
这是一个避免删除.bash_history或重定向到/dev/null的好主意
因此他不能清除或删除他最后执行的命令
方法:

chattr +a .bash_history
chattr +i .bash_history
获取用户的人会知道他的历史命令锁定并且要同意才可以使用服务

10.使用欢迎信息
你必须提供一些信息让攻击者知道该系统不对公众开放。
在国外有类似案件,攻击者入侵一个系统并且系统没有这些信息,
这种情况下法院不能做任何裁决,因为系统说welcome

方法:
删除/etc/redhat-release
编辑/etc/issue /etc/motd并显示警告信息

11.禁用所有特殊账户
你应该从系统中删除所有默认用户和组
例如news,lp,sync,shutdown,uucp,games,halt 等
方法:
删除账户userdel name
删除组 groupdel name
锁定特定账户:

/usr/sbin/usermod -L -s /bin/false user
12.chmod危险文件
这可能是限制不具有root权限的用户执行下面这些命令的好主意
方法:

chmod 700 /bin/ping
chmod 700 /usr/bin/finger
chmod 700 /usr/bin/who
chmod 700 /usr/bin/w
chmod 700 /usr/bin/locate
chmod 700 /usr/bin/whereis
chmod 700 /sbin/ifconfig
chmod 700 /usr/bin/pico
chmod 700 /usr/bin/vi
chmod 700 /usr/bin/which
chmod 700 /usr/bin/gcc
chmod 700 /usr/bin/make
chmod 700 /bin/rpm
13.指定允许root登陆的TTY设备
/etc/securetty文件允许你指定root可以从哪个TTY设备登录
方法:

vi /etc/securetty
只留2个连接

tty1
tty2
14.选择一个安全的密码
在/etc/login.defs文件中定义了shadow密码的具体配置
默认密码长度最短为5字符,你应该至少设置为8
方法:

vi /etc/login.defs
PASS_MIN_LEN 8
15.检测Rootkit
用chkrootkit或rkhunter,以chkrootkit为例
方法:

wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.md5
首先检查md5校验值: md5sum chkrootkit.tar.gz
然后解压安装

tar -zxvf chkrootkit.tar.gz
cd chkrootkit
./configure
make sense
然后运行./chkrootkit
我们可以将其添加到contrab使其每天自动扫描:

vi /etc/cron.daily/chkrootkit.sh
#!/bin/bash
# 输入chkrootkit的安装目录

cd /root/chkrootkit/
# 输入你想收到检测报告的email

./chkrootkit | mail -s “Daily chkrootkit from Server Name” your@email.com
16.安装补丁
你要经常检查更新以修复某些缺陷或系统稳定性的改进
否则你存在漏洞的系统将会不时的遭受新的攻击
方法:

列出可用更新:up2date -l
安装未排除的更新:up2date -u
安装包括排除的更新up2date -uf
17.隐藏Apache信息
你应该隐藏Apache的banner信息使攻击者不知道Apache的版本,从而使他们难以利用漏洞
方法:
修改/etc/httpd/conf/httpd.conf
改变服务器签名:

ServerSignature Off
重启Apache /sbin/service httpd restart

18.隐藏php信息
你应该隐藏php的banner信息,原因同上
方法:
修改php.ini
改变

expose_php=Off
重启Apache

19.关闭不用的服务
你应该把任何未使用的服务关闭,可以在/etc/xinetd.d文件夹里找到
方法:

cd /etc/xinetd.d
grep disable *
这将显示所有服务开启或关闭的状态,然后根据需要来开启或关闭服务

20.检测监听的端口
检测是否有必要开放端口是非常重要的
方法:

netstat -tulp或
lsof -i -n | egrep ‘COMMAND|LISTEN|UDP’或
nmap!
21.关闭端口和服务
重点是关闭在系统启动时打开的不需要的端口
方法:
对于正在运行的服务,可以执行chkconfig -list | grep on
禁用服务可以执行chkconfig servicename off
然后停止正在运行的服务:/etc/init.d/service stop

22.删除不用的rpm包
首先应该清楚你的系统的作用,它是web,mail,file服务器或其他
然后觉得哪些包是必要的,之后删除不需要的软件包
方法:
首先列出安装列表rpm -qa
更详细的信息rpm -qi rpmname
还可以检测删除包可能出现的冲突rpm -e ?test rpmname

23.禁用危险的php函数
你应该禁用php的危险函数防止在网站上执行系统命令
方法:

whereis php.ini
vi /usr/local/lib/php.ini
编辑

disable_functions = “symlink,shell_exec,exec,proc_close,proc_open,popen,
system,dl,passthru,escapeshellarg, escapeshellcmd”
24.安装配置防火墙
高级策略防火墙(APF)是一种IP表(网络过滤),它是基于当今互联网部署服务器防火墙系统的基本需要和客户部署LINUX安装的唯一需要而设计的。 它是最好的开源防

火墙之一。

配置APF防火墙方法:
下载APF:wget http://www.r-fx.ca/downloads/apf-current.tar.gz
解压安装:

tar -zxvf apf-current.tar.gz
cd apf-0.9.7-1
./install.sh
然后我们配置它vi /etc/apf/conf.apf
一般配置:
启用防火墙使用DShield.org块列表
USE_DS=”1″
然后我将列出常规的配置和CPanel配置方式,因为CPanel是应该最广泛的虚拟主机管理软件

1.常规配置(DNS,Mail,Web,FTP)

Common ingress (inbound)
# Common ingress (inbound) TCP ports -3000_3500 = passive port range for Pure FTPD IG_TCP_CPORTS=”21,22,25,53,80,110,143,443,995″
#
# Common ingress (inbound) UDP ports IG_UDP_CPORTS=”53″
# Egress filtering [0 = Disabled / 1 = Enabled]
EGF=”1″
# Common egress (outbound) TCP ports
EG_TCP_CPORTS=”21,25,80,443,43″
#
# Common egress (outbound) UDP ports
EG_UDP_CPORTS=”20,21,53″
2.CPanel配置
Common ingress (inbound) ports
# Common ingress (inbound) TCP ports -3000_3500 = passive port range for Pure FTPD IG_TCP_CPORTS=”21,22,25,53,80,110,143,443,2082,2083, 2086,2087,
2095, 2096,3000_3500″
#
# Common ingress (inbound) UDP ports
IG_UDP_CPORTS=”53″
Common egress (outbound) ports
# Egress filtering [0 = Disabled / 1 = Enabled]
EGF=”1″
# Common egress (outbound) TCP ports
EG_TCP_CPORTS=”21,25,80,443,43,2089″
#
# Common egress (outbound) UDP ports
EG_UDP_CPORTS=”20,21,53″
之后启动防火墙 /etc/apf/apf -s
如果运行良好我在回去修改配置文件,使DEVM=”0″
然后我们配置APF的AntiDos: vi /etc/apf/ad/conf.antidos

找到下面的内容并替换成你的资料

# Organization name to display on outgoing alert emails
CONAME=”Your Company”
# Send out user defined attack alerts [0=off,1=on]
USR_ALERT=”0″
#
# User for alerts to be mailed to
USR=you@yourco.com
你应把USR_ALERT改为1
保存后重启APF:/etc/apf/apf ?r

To make the firewall start with the Operating System: chkconfig ?level 2345 apf on
APF开机自启动:chkconfig ?level 2345 apf on
禁止一个IP用/etc/apf/apf -d ip或vi /etc/apf/deny_hosts.rules
允许一个IP用/etc/apf/apf -a ip或vi /etc/apf/deny_hosts.rules

25.安装配置BFD(暴力破解检测)
BFD是一个用于分析应用日志和检测验证失败的模块化shell脚本
而且安装配置和用法都是非常容易的。使用BFD的原因很简单。
其实在LINUX领域几乎没有结合防火墙或实时设备来监控不验证和
暴力攻击审计的程序。在用BFD之前你必须安装APF防火墙。

方法:

wget http://www.r-fx.ca/downloads/bfd-current.tar.gz
tar -zxvf bfd-current.tar.gz
cd bfd-0.9
然后我们来配置它 vi /usr/local/bfd/conf.bfd
把以下内容改为你的资料

# Enable/disable user alerts [0 = off; 1 = on]
ALERT_USR=”1″
#
# User alert email address
EMAIL_USR=”your@mail.com”
#
# User alert email; subject
SUBJ_USR=”Brute Force Warning for $HOSTNAME”
#
然后vi /usr/local/bfd/ignore.hosts
把你的IP设置成允许主机,避免意外的锁定自己。
之后重启BFD /usr/local/sbin/bfd -s

26.内核加固(sysctl.conf)
sysctl.conf用来加固内核,目的是避免DOS和欺骗攻击
方法:
到/proc/sys目录或sysctl -a命令了解下当前配置的大概情况
然后vi /etc/sysctl.conf
添加如下内容:

# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1
#Prevent SYN attack
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# Disables packet forwarding
net.ipv4.ip_forward=0
# Disables IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Enable Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.lo.log_martians = 1
net.ipv4.conf.eth0.log_martians = 1
# Disables IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
14
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Disables the magic-sysrq key
kernel.sysrq = 0
# Modify system limits for Ensim WEBppliance
fs.file-max = 65000
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 15
# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1800
# Turn off the tcp_window_scaling
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack
net.ipv4.tcp_sack = 0
# Turn off the tcp_timestamps
net.ipv4.tcp_timestamps = 0
# Enable TCP SYN Cookie Protection
net.ipv4.tcp_syncookies = 1
# Enable ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Enable bad error message Protection
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 1
# Set maximum amount of memory allocated to shm to 256MB
kernel.shmmax = 268435456
# Improve file system performance
vm.bdflush = 100 1200 128 512 15 5000 500 1884 2
# Improve virtual memory performance
vm.buffermem = 90 10 60
# Increases the size of the socket queue (effectively, q0).
net.ipv4.tcp_max_syn_backlog = 1024
# Increase the maximum total TCP buffer-space allocatable
net.ipv4.tcp_mem = 57344 57344 65536
# Increase the maximum TCP write-buffer-space allocatable
net.ipv4.tcp_wmem = 32768 65536 524288
15
# Increase the maximum TCP read-buffer space allocatable
net.ipv4.tcp_rmem = 98304 196608 1572864
# Increase the maximum and default receive socket buffer size
net.core.rmem_max = 524280
net.core.rmem_default = 524280
# Increase the maximum and default send socket buffer size
net.core.wmem_max = 524280
net.core.wmem_default = 524280
# Increase the tcp-time-wait buckets pool size
net.ipv4.tcp_max_tw_buckets = 1440000
# Allowed local port range
net.ipv4.ip_local_port_range = 16384 65536
# Increase the maximum memory used to reassemble IP fragments
net.ipv4.ipfrag_high_thresh = 512000
net.ipv4.ipfrag_low_thresh = 446464
# Increase the maximum amount of option memory buffers
net.core.optmem_max = 57344
# Increase the maximum number of skb-heads to be cached
net.core.hot_list_length = 1024
## DO NOT REMOVE THE FOLLOWING LINE!
## nsobuild:20051206
重启后生效
/sbin/sysctl -p

sysctl -w net.ipv4.route.flush=1
27.更改SSH端口
更改SSH默认端口号在一定程度上可以提高安全性
方法:
vi /etc/ssh/sshd_config
Port 22改为其他端口
当然不要忘记把更改的端口加进防火墙
然后重启生效/etc/init.d/ssh restart
如果安装了APF并把端口添加之后,还要重启APF:/etc/init.d/apf restart

28./tmp,/var/tmp,/dev/shm分区的安全
/tmp,/var/tmp,/dev/shm目录是不安全的,任何用户都可以执行脚本。
最好的解决办法是挂载ncexec和nosuid选项的参数
注意:不建议在CPanel使用
方法:
/tmp目录:
cd /dev
创建 100M (“count”) 的存储文件:
dd if=/dev/zero of=tmpMnt bs=1024 count=100000
设为一个扩展的文件系统:

/sbin/mke2fs /dev/tmpMnt (“…is not a block special device. continue?”回答yes)
备份现有临时文件:

cp -R /tmp/ /tmp_backup
用noexec挂载新文件系统:

mount -o loop,rw,nosuid,noexec /dev/tmpMnt /tmp
chmod 0777 /tmp
把备份的文件拷贝回去:

cp -R /tmp_backup/* /tmp/
删除备份:

rm -rf /tmp_backup
修改/etc/fstab 添加下面的条目使其在引导时仍然有效

/dev/tmpMnt /tmp ext2 loop,rw,nosuid,noexec 0 0
/var/tmp目录:

mv /var/tmp /var/tmpbak
ln -s /tmp /var/tmp
cp /var/tmpbak/* /tmp/
/dev/shm目录:
编辑/etc/fstab
把 none /dev/shm tmpfs defaults,rw 0 0
改为

none /dev/shm tmpfs defaults,nosuid,noexec,rw 0 0

Linux防火墙iptables简明教程

Linux防火墙iptables简明教程

  1. 安装iptables
  2. 查看现有的iptables规则
  3. 删除某iptables规则
  4. 清除现有iptables规则
  5. 创建规则
  6. 设置开机启动
  7. 保存iptables规则
  8. iptables在手动防CC攻击中的简单应用

 

1.安装iptables

很多Linux已经默认安装iptables,可使用后文的查看命令测试是否安装

CentOS/RedHat下执行:

yum install iptables

Debian/Ubuntu下执行:

apt-get install iptables

 

2.查看现有的iptables规则

命令后面的line-number为显示行号(将规则一则一则输出,并显示行号),可选,方便后文的删除指令。

iptables -L -n –line-numbers

 

3.删除某iptables规则

例如,删除第12行的规则,行号可由之前的命令查看

iptables -D INPUT 12

 

4.清除现有iptables规则

iptables -F
iptables -X
iptables -Z

 

5.创建规则

a).开放端口

命令iptables -A INPUT -j REJECT将屏蔽其他未授权的端口,因此请务必开放22端口以保障SSH连接正常~

#允许本机访问
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
# 允许已建立的或相关连的通行
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
#允许所有本机向外的访问
iptables -A OUTPUT -j ACCEPT
# 允许访问22端口
iptables -A INPUT -p tcp –dport 22 -j ACCEPT
#允许访问80端口
iptables -A INPUT -p tcp –dport 80 -j ACCEPT
#允许FTP服务的21和20端口
iptables -A INPUT -p tcp –dport 21 -j ACCEPT
iptables -A INPUT -p tcp –dport 20 -j ACCEPT
#如果有其他端口的话,规则也类似,稍微修改上述语句就行
#禁止其他未允许的规则访问
iptables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT

b).屏蔽ip

iptables -I INPUT -s 123.123.123.123 -j DROP

可通过更换上述ip为ip段来达到屏蔽ip段的目的~

若需屏蔽整个ip段(123.0.0.1到123.255.255.254)则换为123.0.0.0/8
若需屏蔽ip段123.123.0.1到123.123.255.254,则换为124.123.0.0/16
若需屏蔽ip段123.123.123.1到123.123.123.254则换为123.123.123.0/24

 

6.设置开机启动

一般在安装iptables完成后,开机启动会自动设置成功,但在个别CentOS系统上,貌似还有些问题,可以使用如下命令手动设置

chkconfig –level 345 iptables on

 

7.保存iptables规则

service iptables save

 

8.iptables在手动防CC攻击中的简单应用

关于获取攻击者ip的方法,可以通过很多方法获取,如查看网站日志等,本文不再赘述。

a).建立要屏蔽的ip/ip段文件,名为ip.txt

#屏蔽的ip
123.4.5.6
#屏蔽的ip段(编写方法,同前文)
123.4.5.6/24

b).建立block_ip.sh脚本文件

#!/bin/sh
# Filename: block_ip.sh
# Purpose:  blocks all IP address/network found in a text file
#               The text file must have one IP address or network per line
#################################################################

# Change the following path/filename to match yours
IP_LIST_FILE=/path/to/ip.txt

#################################################################
# Don't change anything below unless you are a smarty pant!
#################################################################
IPTABLES_BIN=/sbin/iptables

# Get the IP address/network from the file and ignore any line starting with # (comments)
BAD_IP_ADDR_LIST=$(grep -Ev "^#" $IP_LIST_FILE)

# Now loop through the IP address/network list and ban them using iptabels
for i in $BAD_IP_ADDR_LIST
do

echo -n "Blocking $i ...";
$IPTABLES_BIN -A    INPUT -s $i -j DROP
$IPTABLES_BIN -A OUTPUT -d $i -j DROP

echo "DONE.";
done
##################################################################
# END OF SCRIPT - NOTHING TO SEE HERE - THAT'S ALL FOLKS!
##################################################################

c).运行脚本

sh /path/to/block_ip.sh

PHP 5.4 内置Web服务器

PHP是一种脚本语言,它需要PHP解释器来分析运行PHP文件。当把PHP做为CGI服务Web请求时,它需要被嵌入到某种Web服务器里,最常见的是集成到Apache或IIS里,这就是说,在使用PHP前,你需要安装Apache或IIS,并且正确的配置它们和PHP集成的参数。虽然这种配置已经很规范,文档非常丰富,但我们还是经常在安装Apache和PHP集成时遇到问题,而且,有时候我们只想测试一个简单的PHP特征,不想就为此安装、启动Apache服务。但据官方文档上说,这个内置的Web服务器只是提供开发测试使用,不推荐使用中生产环境中。因为这个服务器接受处理请求时顺序执行的,不能并发处理。

这个内置的web服务器使用起来非常的方便,你只需要执行下面的命令:

  1. $ php -S localhost:8000

然后就可以访问了。这样启动后,默认的web服务目录是执行命令的当前目录,如果不想使用当前目录,你需要使用 -t 参数来指定。

例 #1 启动Web服务器

  1. $ cd ~/public_html
  2. $ php -S localhost:8000

终端输出信息:

  1. PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
  2. Listening on localhost:8000
  3. Document root is /home/me/public_html
  4. Press Ctrl-C to quit

当请求了 http://localhost:8000/ 和 http://localhost:8000/myscript.html 地址后,终端输出类似如下的信息:

  1. PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
  2. Listening on localhost:8000
  3. Document root is /home/me/public_html
  4. Press Ctrl-C to quit.
  5. [Thu Jul 21 10:48:48 2011] ::1:39144 GET /favicon.ico – Request read
  6. [Thu Jul 21 10:48:50 2011] ::1:39146 GET / – Request read
  7. [Thu Jul 21 10:48:50 2011] ::1:39147 GET /favicon.ico – Request read
  8. [Thu Jul 21 10:48:52 2011] ::1:39148 GET /myscript.html – Request read
  9. [Thu Jul 21 10:48:52 2011] ::1:39149 GET /favicon.ico – Request read

例 #2 启动web服务器时指定文档的根目录

  1. $ cd ~/public_html
  2. $ php -S localhost:8000 -t foo/

终端显示信息:

  1. PHP 5.4.0 Development Server started at Thu Jul 21 10:50:26 2011
  2. Listening on localhost:8000
  3. Document root is /home/me/public_html/foo
  4. Press Ctrl-C to quit

如果你在启动命令行后面附加一个php脚本文件,那这个文件将会被当成一个“路由器”脚本。这个脚本将负责所有的HTTP请求,如果这个脚本执行时返回FALSE,则被请求的资源会正常的返回。如果不是FALSE,浏览里显示的将会是这个脚本产生的内容。

例 #3 使用路由器脚本

在这个例子中,对图片的请求会返回相应的图片,但对HTML文件的请求会显示“Welcome to PHP”:

  1. < php span>
  2. // router.php
  3. if (preg_match(‘/.(?:png|jpg|jpeg|gif)$/’, $_SERVER[“REQUEST_URI”])) {
  4. return false;    // serve the requested resource as-is.
  5. } else {
  6. echo”Welcome to PHP”;
  7. }
  8. ?<
  1. $ php -Slocalhost:8000 router.php

例 #4 判断是否是在使用内置web服务器

通过程序判断来调整同一个PHP路由器脚本在内置Web服务器中和在生产服务器中的不同行为:

  1. < php span>
  2. // router.php
  3. if (php_sapi_name() == ‘cli-server’) {
  4. /* route static assets and return false */
  5. }
  6. /* go on with normal index.php operations */
  7. ?<
  1. $ php -S localhost:8000 router.php

这个内置的web服务器能识别一些标准的MIME类型资源,它们的扩展有:.css, .gif, .htm, .html, .jpe, .jpeg, .jpg, .js, .png, .svg, and .txt。对.htm 和 .svg 扩展到支持是在PHP 5.4.4之后才支持的。

例 #5 处理不支持的文件类型

如果你希望这个Web服务器能够正确的处理不被支持的MIME文件类型,这样做:

  1. < php span>
  2. // router.php
  3. $path = pathinfo($_SERVER[“SCRIPT_FILENAME”]);
  4. if ($path[“extension”] == “ogg”) {
  5. header(“Content-Type: video/ogg”);
  6. readfile($_SERVER[“SCRIPT_FILENAME”]);
  7. }
  8. else {
  9. return FALSE;
  10. }
  11. ?<
  1. $ php -S localhost:8000 router.php

如果你希望能远程的访问这个内置的web服务器,你的启动命令需要改成下面这样:

例 #6 远程访问这个内置Web服务器

  1. $ php -S 0.0.0.0:8000

这样你就可以通过 8000 端口远程的访问这个内置的web服务器了

Python 错误和异常小结

1.Python异常类

Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不用Python了)。

异常 描述
NameError 尝试访问一个没有申明的变量
ZeroDivisionError 除数为0
SyntaxError 语法错误
IndexError 索引超出序列范围
KeyError 请求一个不存在的字典关键字
IOError 输入输出错误(比如你要读的文件不存在)
AttributeError 尝试访问未知的对象属性
ValueError 传给函数的参数类型不正确,比如给int()函数传入字符串形

 

2.捕获异常

Python完整的捕获异常的语句有点像:

 

try:
    try_suite
except Exception1,Exception2,...,Argument:
    exception_suite
......   #other exception block
else:
    no_exceptions_detected_suite
finally:
    always_execute_suite

额…是不是很复杂?当然,当我们要捕获异常的时候,并不是必须要按照上面那种格式完全写下来,我们可以丢掉else语句,或者finally语句;甚至不要exception语句,而保留finally语句。额,晕了?好吧,下面,我们就来一一说明啦。

 

2.1.try…except…语句

try_suite不消我说大家也知道,是我们需要进行捕获异常的代码。而except语句是关键,我们try捕获了代码段try_suite里的异常后,将交给except来处理。

try…except语句最简单的形式如下:

try:
    try_suite
except:
    exception block

上面except子句不跟任何异常和异常参数,所以无论try捕获了任何异常,都将交给except子句的exception block来处理。如果我们要处理特定的异常,比如说,我们只想处理除零异常,如果其他异常出现,就让其抛出不做处理,该怎么办呢?这个时候,我们就要给except子句传入异常参数啦!那个ExceptionN就是我们要给except子句的异常类(请参考异常类那个表格),表示如果捕获到这类异常,就交给这个except子句来处理。比如:

 

 

try:
    try_suite
except Exception:
    exception block

举个例子:

 

 

>>> try:
...     res = 2/0
... except ZeroDivisionError:
...     print "Error:Divisor must not be zero!"
... 
Error:Divisor must not be zero!

 

看,我们真的捕获到了ZeroDivisionError异常!那如果我想捕获并处理多个异常怎么办呢?有两种办法,一种是给一个except子句传入多个异常类参数,另外一种是写多个except子句,每个子句都传入你想要处理的异常类参数。甚至,这两种用法可以混搭呢!下面我就来举个例子。

 

try:
    floatnum = float(raw_input("Please input a float:"))
    intnum = int(floatnum)
    print 100/intnum
except ZeroDivisionError:
    print "Error:you must input a float num which is large or equal then 1!"
except ValueError:
    print "Error:you must input a float num!"

[root@Cherish tmp]# python test.py 
Please input a float:fjia
Error:you must input a float num!
[root@Cherish tmp]# python test.py 
Please input a float:0.9999
Error:you must input a float num which is large or equal then 1!
[root@Cherish tmp]# python test.py 
Please input a float:25.091
4

上面的例子大家一看都懂,就不再解释了。只要大家明白,我们的except可以处理一种异常,多种异常,甚至所有异常就可以了。

 

大家可能注意到了,我们还没解释except子句后面那个Argument是什么东西?别着急,听我一一道来。这个Argument其实是一个异常类的实例(别告诉我你不知到什么是实例),包含了来自异常代码的诊断信息。也就是说,如果你捕获了一个异常,你就可以通过这个异常类的实例来获取更多的关于这个异常的信息。例如:

 

>>> try:
...     1/0
... except ZeroDivisionError,reason:
...     pass
... 
>>> type(reason)
<type 'exceptions.ZeroDivisionError'>
>>> print reason
integer division or modulo by zero
>>> reason
ZeroDivisionError('integer division or modulo by zero',)
>>> reason.__class__
<type 'exceptions.ZeroDivisionError'>
>>> reason.__class__.__doc__
'Second argument to a division or modulo operation was zero.'
>>> reason.__class__.__name__
'ZeroDivisionError'

上面这个例子,我们捕获了除零异常,但是什么都没做。那个reason就是异常类ZeroDivisionError的实例,通过type就可以看出。

 

2.2try … except…else语句

现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:

 

>>> import syslog
>>> try:
...     f = open("/root/test.py")
... except IOError,e:
...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
...     syslog.syslog(syslog.LOG_INFO,"no exception caughtn")
... 
>>> f.close()

 

2.3 finally子句

finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try…finally,也可以配合except等使用。

例如2.2的例子,如果出现其他异常,无法捕获,程序异常退出,那么文件 f 就没有被正常关闭。这不是我们所希望看到的结果,但是如果我们把f.close语句放到finally语句中,无论是否有异常,都会正常关闭这个文件,岂不是很 妙

 

>>> import syslog
>>> try:
...     f = open("/root/test.py")
... except IOError,e:
...     syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
...     syslog.syslog(syslog.LOG_INFO,"no exception caughtn")
... finally: 
>>>     f.close()

大家看到了没,我们上面那个例子竟然用到了try,except,else,finally这四个子句!:-),是不是很有趣?到现在,你就基本上已经学会了如何在Python中捕获常规异常并处理之。

 

3.两个特殊的处理异常的简便方法

3.1断言(assert)

什么是断言,先看语法:

 

assert expression[,reason]

 

其中assert是断言的关键字。执行该语句的时候,先判断表达式expression,如果表达式为真,则什么都不做;如果表达式不为真,则抛出异常。reason跟我们之前谈到的异常类的实例一样。不懂?没关系,举例子!最实在!

 

>>> assert len('love') == len('like')
>>> assert 1==1
>>> assert 1==2,"1 is not equal 2!"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: 1 is not equal 2!

我们可以看到,如果assert后面的表达式为真,则什么都不做,如果不为真,就会抛出AssertionErro异常,而且我们传进去的字符串会作为异常类的实例的具体信息存在。其实,assert异常也可以被try块捕获:

 

 

>>> try:
...     assert 1 == 2 , "1 is not equal 2!"
... except AssertionError,reason:
...     print "%s:%s"%(reason.__class__.__name__,reason)
... 
AssertionError:1 is not equal 2!
>>> type(reason)
<type 'exceptions.AssertionError'>

 

3.2.上下文管理(with语句)

如果你使用try,except,finally代码仅仅是为了保证共享资源(如文件,数据)的唯一分配,并在任务结束后释放它,那么你就有福了!这个with语句可以让你从try,except,finally中解放出来!语法如下:

 

with context_expr [as var]:
    with_suite

是不是不明白?很正常,举个例子来!

 

>>> with open('/root/test.py') as f:
...     for line in f:
...         print line

上面这几行代码干了什么?

(1)打开文件/root/test.py

(2)将文件对象赋值给  f

(3)将文件所有行输出

(4)无论代码中是否出现异常,Python都会为我们关闭这个文件,我们不需要关心这些细节。

这下,是不是明白了,使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表:

file

decimal.Context

thread.LockType

threading.Lock

threading.RLock

threading.Condition

threading.Semaphore

threading.BoundedSemaphore

至于什么是上下文管理协议,如果你不只关心怎么用with,以及哪些对象可以使用with,那么我们就不比太关心这个问题:)

4.抛出异常(raise)

如果我们想要在自己编写的程序中主动抛出异常,该怎么办呢?raise语句可以帮助我们达到目的。其基本语法如下:

 

raise [SomeException [, args [,traceback]]

第一个参数,SomeException必须是一个异常类,或异常类的实例

 

第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。

第三个参数traceback很少用,主要是用来提供一个跟中记录对象(traceback)

下面我们就来举几个例子。

 

>>> raise NameError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError
>>> raise NameError()  #异常类的实例
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError
>>> raise NameError,("There is a name error","in test.py")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
>>> raise NameError("There is a name error","in test.py")  #注意跟上面一个例子的区别
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')
>>> raise NameError,NameError("There is a name error","in test.py")  #注意跟上面一个例子的区别
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: ('There is a name error', 'in test.py')

其实,我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。如上面第三个例子。

 

5.异常和sys模块

另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟中记录对象)

 

>>> try:
...     1/0
... except:
...     import sys
...     tuple = sys.exc_info()
... 
>>> print tuple
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x7f538a318b48>)
>>> for i in tuple:
...     print i
... 
<type 'exceptions.ZeroDivisionError'> #异常类    
integer division or modulo by zero #异常类的实例
<traceback object at 0x7f538a318b48> #跟踪记录对象

linux ps命令参数和使用详解

PS是LINUX下最常用的也是非常强大的进程查看命令

1. ps简介

前面介绍的两个命令都是用于查看当前系统用户的情况,下面就来看看进程的情况,这也是本章的主题。

要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本

同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、

进程有没有僵死、哪些进程占用了过多的资源等等。总之大部分信息都是可以通过执行该命令得到的。

2. ps命令及其参数

ps命令最常用的还是用于监控后台进程的工作情况,因为后台进程是不和屏幕键盘这些标准输入/输出设

备进行通信的,所以如果需要检测其情况,便可以使用ps命令了。

该命令语法格式如下:

ps [选项]

下面对命令选项进行说明:

-e 显示所有进程。

-f 全格式。

-h 不显示标题。

-l 长格式。

-w 宽输出。

a 显示终端上的所有进程,包括其他用户的进程。

r 只显示正在运行的进程。

x 显示没有控制终端的进程。

O[+|-] k1 [,[+|-] k2 [,…]] 根据SHORT KEYS、k1、k2中快捷键指定的多级排序顺序显示进程列表。

对于ps的不同格式都存在着默认的顺序指定。这些默认顺序可以被用户的指定所覆盖。其中“+”字符是可选

的,“-”字符是倒转指定键的方向。

pids 只列出付ń 痰那榭觥8鹘 蘄D之间使用逗号分隔。该进程列表必须在命令行参数的最后一个选项

后面紧接着给出,中间不能插入空格。比如:ps -f1,4,5。

以下介绍长命令行选项,这些选项都使用“--”开头:

--sort X[+|-] key [,[+|-] key [,…]] 从SORT KEYS段中选一个多字母键。“+”字符是可选的,因

为默认的方向就是按数字升序或者词典顺序。比如: ps -jax -sort=uid,-ppid,+pid。

--help 显示帮助信息。

--version 显示该命令的版本信息。

在前面的选项说明中提到了排序键,接下来对排序键作进一步说明。需要注意的是排序中使用的值是ps使

用的内部值,并非仅用于某些输出格式的伪值。排序键列表见表4-3。

表4-3 排序键列表

短格式 
长格式 
说 明 

c 
cmd 
可执行的简单名称 

C 
cmdline 
完整命令行 

f 
flags 
长模式标志 

g 
pgrp 
进程的组ID 

G 
tpgid 
控制tty进程组ID 

j 
cutime 
累计用户时间 

J 
cstime 
累计系统时间 

k 
utime 
用户时间 

K 
stime 
系统时间 

m 
min_flt 
次要页错误的数量 

M 
maj_flt 
主要页错误的数量 

n 
cmin_flt 
累计次要页错误 

N 
cmaj_flt 
累计主要页错误 

o 
session 
对话ID 

p 
pid 
进程ID 

P 
ppid 
父进程ID 

r 
rss 
驻留大小 

R 
resident 
驻留页 

s 
size 
内存大小(千字节) 

S 
share 
共享页的数量 

t 
tty 
tty次要设备号 

T 
start_time 
进程启动的时间 

U 
uid 
UID 

u 
user 
用户名 

v 
vsize 
总的虚拟内存数量(字节) 

y 
priority 
内核调度优先级 

3. 常用ps命令参数

前面两节介绍的参数可能让读者觉得有些可怕,实际上这是一个非常容易使用的命令,一般的用户只

需掌握一些最常用的命令参数就可以了。

最常用的三个参数是u、a、x,下面将通过例子来说明其具体用法。

[例20] 以root身份登录系统,查看当前进程状况

$ ps

PID TTY TIME COMMAND

5800 ttyp0 00:00:00 bash

5835 ttyp0 00:00:00 ps

可以看到,显示的项目共分为四项,依次为PID(进程ID)、TTY(终端名称)、TIME(进程执行时间)

、COMMAND(该进程的命令行输入)。

可以使用u选项来查看进程所有者及其他一些详细信息,如下所示:

$ ps u

USER PID %CPU %MEM USZ RSS TTY STAT START TIME COMMAND

test 5800 0.0 0.4 1892 1040 ttyp0 S Nov27 0:00 -bash

test 5836 0.0 0.3 2528 856 ttyp0 R Nov27 0:00 ps u

在bash进程前面有条横线,意味着该进程便是用户的登录shell,所以对于一个登录用户来说带短横线的进

程只有一个。还可以看到%CPU、%MEM两个选项,前者指该进程占用的CPU时间和总时间的百分比;后者指该进程

占用的内存和总内存的百分比。

在这种情况下看到了所有控制终端的进程;但是对于其他那些没有控制终端的进程还是没有观察到,所以这

时就需要使用x选项。使用x选项可以观察到所有的进程情况。

Centos使用rsyslog+loganalyzer监控交换机日志

公司需要对机房交换机的日志进行监控,搭建了个rsyslog日至服务器来监控,现将搭建过程记录如下:
1.安装Lamp环境

yum install httpd mysql mysql-server mysql-devel php php-mysql php-gd –y
service httpd start
service mysqld start
chkconfig httpd on
chkconfig mysqld on

2.安装 rsyslog

yum install rsyslog rsyslog-mysql -y
service rsyslog start
chkconfig rsyslog on

编辑 rsyslog配置文件 /etc/rsyslog.conf

取消下边两行注释
$ModLoad imudp
$UDPServerRun 514 (允许从udp 514 端口接收及发送日志,也可以取消tcp 注释行,通过tcp 端口发送)

检查防火墙514 端口是否开启
添加mysql 模块及信息用以链接数据库

$ModLoad ommysql

*.* :<删除我>ommysql:localhost,Syslog,root,password (localhost:服务器,root:数据库用户,nian:数据库用户对应密码)

重启rsyslog 服务

service rsyslog restart

将数据库文件导入数据库 (此数据库用来存日志)

mysql –u root –p < /usr/share/doc/rsyslog/CreateDB.sql

3. 挂接web接口用以图形化管理
下载loganalyzer,解压后将src目录下所有内容拷贝到/var/www/syslog
创建 config.php 文件并且给予读取权限

touch config.php
chmod o+w config.php

4.创建loganalyzer数据库 loganalyzer (loganalyzer 次数据库存放管理员等用户信息)

mysql -uroot -ppasswd
mysql> create database loganalyzer;

在浏览器中安装 http://IP/syslog

5.loagnalyzer默认没有显示来源IP,但是我们可以通过修改添加数据库字段来实现
修改rsyslog.conf 配置文件 添加sql语句,添加IP字段

$template insertpl,”insert into SystemEvents (Message, Facility, FromHost, FromIP, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (‘%msg%’, %syslogfacility%, ‘%HOSTNAME%’, ‘%fromhost-ip%’, %syslogpriority%, ‘%timereported:::date-mysql%’, ‘%timegenerated:::date-mysql%’, %iut%, ‘%syslogtag%’)”,SQL

$ModLoad ommysql
*.* :<删除我>ommysql:localhost,Syslog,root,passwd;insertpl

6.在web管理页面中修改
(1)在Fields中添加 IP
(2)在Views 中添加 NewSyslog 添加 Date, Facility, Severity, Host, IP, Syslogtag, Messagetype, Message
(3)在DBMappings中 添加NewSyslog 继续添加字段

Date => devicereportedtime, uID => id, Host => fromhost, IP => fromip, Messagetype => infounitid, Message => message, Facility => facility, Severity => priority, Syslogtag => syslogtag, ProcessID => processid, Event ID => 1, Eventlog Type => eventlogtype, Event Source => eventsource, Event Category => eventcategory, Event User => eventuser, SystemID => systemid, Checksum => checksum

(4)在Source 的数据源中修改Table type 为NewSyslog
7.客户端配置:
安装rsyslog 服务 修改配置文件,
取消下边两行注释

$ModLoad imudp
$UDPServerRun 514 (允许从udp 514 端口接收及发送日志)

在底部添加
*.* @remote-IP (*.* 为发送的日志级别, @ 为通过udp端口发送 @@ 为通过tcp端口发)

此时就可以监控到客户端的日志了,默认是存在数据库中的

8.自定义设备来源日志文件
如果要把不同服务器发送过来的日志保存到不同的文件, 可以这样操作:
修改/etc/rsyslog.conf

:fromhost-ip, isequal, “192.168.0.160″ /var/log/switch/192.168.0.160.log
:FROMHOST-IP, isequal, “192.168.0.161″ /var/log/switch/192.168.0.161
:FROMHOST-IP, startswith, “192.168.1.1” /var/log/switch/192.168.1.1
:FROMHOST-IP, startswith, “192.168.1.2” /var/log/switch/192.168.1.2

重启 服务

service rsyslog restart

然后在/var/log/目录下就会自动创建日志文件

客户端测试日志命令:

logger –p user.info “XXX”

一定要给/var/log/switch 文件夹添加读写权限,不然loganalyzer 无法读取
chmod -R o+wr /var/log/switch
在loganalyzer 的source 中添加数据来源为Diskfile,然后就可以单独管理每台客户端的日志了!