解决nginx跨站浏览问题

解决nginx跨站浏览有两种方法:
1、为每一个网站定义一个pool,然后使用chroot指令,但这种方法的缺点是,当你需要建立很多虚拟主机时,消耗的内存是非常大的。
2、修改php源代码。这种通过修改php源代码的方法可以很好的解决这个问题而不必像第一种额外的内存消耗。
下面开始介绍第二种方法。
下载php源码,执行./configure命令,然后开始修改main/fopen_wrappers.c文件

  1. /* {{{ php_check_open_basedir
  2. */
  3. PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
  4. {
  5.         /* Only check when open_basedir is available */
  6.         if (PG(open_basedir) && *PG(open_basedir)) {
  7.                 char *pathbuf;
  8.                 char *ptr;
  9.                 char *end;
  10.                 // add by anxsoft.com
  11.                 char *env_doc_root;
  12.                 if(PG(doc_root)){
  13.                         env_doc_root = estrdup(PG(doc_root));
  14.                 }else{
  15.                         env_doc_root = sapi_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
  16.                 }
  17.                 if(env_doc_root){
  18.                         int        res_root = php_check_specific_open_basedir(env_doc_root, path TSRMLS_CC);
  19.                         efree(env_doc_root);
  20.                         if (res_root == 0) {
  21.                                 return 0;
  22.                         }
  23.                         if (res_root == -2) {
  24.                                 errno = EPERM;
  25.                                 return -1;
  26.                         }
  27.                 }
  28.                 // add by anxsoft.com
  29.  
  30.  
  31.                 pathbuf = estrdup(PG(open_basedir));
  32.  
  33.                 ptr = pathbuf;
  34.  
  35.                 while (ptr && *ptr) {
  36.                         end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
  37.                         if (end != NULL) {
  38.                                 *end = ”;
  39.                                 end++;
  40.                         }
  41.  
  42.                         if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
  43.                                 efree(pathbuf);
  44.                                 return 0;
  45.                         }
  46.  
  47.                         ptr = end;
  48.                 }
  49.                 if (warn) {
  50.                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir));
  51.                 }
  52.                 efree(pathbuf);
  53.                 errno = EPERM; /* we deny permission to open it */
  54.                 return -1;
  55.         }
  56.  
  57.         /* Nothing to check… */
  58.         return 0;
  59. }
  60. /* }}} */

两个 add by anxsoft.com 中间的是修改加上去的,然后保存,退出。之后make 和make install 即可。
然后修改php.ini文件:

  1. open_basedir = "/tmp/:/var/tmp/"

经测试php5.2和php5.3同样适用。
参考:http://www.hostloc.com/thread-6546-1-1.html

使用logrotate轮询nginx和apache日志

使用logrotate轮询日志很方便,配置也很简单。

配置nginx

1、建立/etc/logrotate.d/nginx文件

  1. vi /etc/logrotate.d/nginx

2、写入如下内容:

  1. /var/log/nginx/*log {
  2.     daily
  3.     rotate 10
  4.     missingok
  5.     notifempty
  6.     compress
  7.     sharedscripts
  8.     postrotate
  9.         [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
  10.     endscript
  11. }

注释:
/var/log/nginx/*log:需要轮询日志路径
daily:每天轮询
rotate 10:保留最多10次滚动的日志
missingok:如果日志丢失,不报错继续滚动下一个日志
notifempty:当日志为空时不进行滚动
compress:旧日志默认用gzip压缩
/var/run/nginx.pid:nginx主进程pid

配置apache

  1. /var/log/httpd/*log {
  2.     missingok
  3.     notifempty
  4.     sharedscripts
  5.     postrotate
  6.         /sbin/service httpd reload > /dev/null 2>/dev/null || true
  7.     endscript
  8. }

Linux Web服务器网站故障分析常用的命令

系统连接状态篇:

1.查看TCP连接状态

  1. netstat -nat |awk ‘{print $6}’|sort|uniq -c|sort -rn
  2. netstat -n | awk ‘/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}’
  3. netstat -n | awk ‘/^tcp/ {++state[$NF]}; END {for(key in state) print key,"t",state[key]}’
  4. netstat -n | awk ‘/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"t",arr[k]}’
  5. netstat -n |awk ‘/^tcp/ {print $NF}’|sort|uniq -c|sort -rn
  6. netstat -ant | awk ‘{print $NF}’ | grep -v ‘[a-z]’ | sort | uniq -c

2.查找请求数请20个IP(常用于查找攻来源):

  1. netstat -anlp|grep 80|grep tcp|awk ‘{print $5}’|awk -F: ‘{print $1}’|sort|uniq -c|sort -nr|head -n20
  2. netstat -ant |awk ‘/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}’ |sort -rn|head -n20

3.用tcpdump嗅探80端口的访问看看谁最高

  1. tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." ‘{print $1"."$2"."$3"."$4}’ | sort | uniq -c | sort -nr |head -20

4.查找较多time_wait连接

  1. netstat -n|grep TIME_WAIT|awk ‘{print $5}’|sort|uniq -c|sort -rn|head -n20

5.找查较多的SYN连接

  1. netstat -an | grep SYN | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more

6.根据端口列进程

  1. netstat -ntlp | grep 80 | awk ‘{print $7}’ | cut -d/ -f1

网站日志分析篇1(Apache):

1.获得访问前10位的ip地址

  1. cat access.log|awk ‘{print $1}’|sort|uniq -c|sort -nr|head -10
  2. cat access.log|awk ‘{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}’

2.访问次数最多的文件或页面,取前20

  1. cat access.log|awk ‘{print $11}’|sort|uniq -c|sort -nr|head -20

3.列出传输最大的几个exe文件(分析下载站的时候常用)

  1. cat access.log |awk ‘($7~/.exe/){print $10 " " $1 " " $4 " " $7}’|sort -nr|head -20

4.列出输出大于200000byte(约200kb)的exe文件以及对应文件发生次数

  1. cat access.log |awk ‘($10 > 200000 && $7~/.exe/){print $7}’|sort -n|uniq -c|sort -nr|head -100

5.如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面

  1. cat access.log |awk  ‘($7~/.php/){print $NF " " $1 " " $4 " " $7}’|sort -nr|head -100

6.列出最最耗时的页面(超过60秒的)的以及对应页面发生次数

  1. cat access.log |awk ‘($NF > 60 && $7~/.php/){print $7}’|sort -n|uniq -c|sort -nr|head -100

7.列出传输时间超过 30 秒的文件

  1. cat access.log |awk ‘($NF > 30){print $7}’|sort -n|uniq -c|sort -nr|head -20

8.统计网站流量(G)

  1. cat access.log |awk ‘{sum+=$10} END {print sum/1024/1024/1024}’

9.统计404的连接

  1. awk ‘($9 ~/404/)’ access.log | awk ‘{print $9,$7}’ | sort

10. 统计http status

cat access.log |awk ‘{counts[$(9)]+=1}; END {for(coolcode in counts) print coolcode, counts}’
cat access.log |awk ‘{print $9}’|sort|uniq -c|sort -rn

10.蜘蛛分析,查看是哪些蜘蛛在抓取内容。

/usr/sbin/tcpdump -i eth0 -l -s 0 -w – dst port 80 | strings | grep -i user-agent | grep -i -E ‘bot|crawler|slurp|spider’

网站日分析2(Squid篇)按域统计流量

zcat squid_access.log.tar.gz| awk ‘{print $10,$7}’ |awk ‘BEGIN{FS=”[ /]”}{trfc[$4]+=$1}END{for(domain in trfc){printf “%st%dn”,domain,trfc[domain]}}’

数据库篇

1.查看数据库执行的sql

/usr/sbin/tcpdump -i eth0 -s 0 -l -w – dst port 3306 | strings | egrep -i ‘SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL’

系统Debug分析篇

1.调试命令
strace -p pid
2.跟踪指定进程的PID
gdb -p pid
转自:http://www.ha97.com/4392.html

平滑升级nginx

这篇文章主要介绍如何在不停止旧nginx的基础上升级nginx。
1、到http://nginx.org/en/download.html下载最新稳定版本的nginx。
2、备份nginx二进制文件和配置文件

  1. cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_old
  2. cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.old

3、执行./configure命令,如

  1. ./configure –with-http_ssl_module –with-openssl=/path/to/openssl_src

可以执行/usr/local/nginx/sbin/nginx -V命令查看以前的编译参数。
4、执行make install clean来安装新的nginx。
5、为旧的nginx主进程发送USR2信号,这会启动新的nginx主进程而保留旧的nginx主进程。

  1. kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`

6、发送WINCH信号到旧的nginx主进程以杀掉旧的nginx子进程。假设旧的主进程pid是123。

  1. kill -WINCH 123

7、现在你可以测试网站访问是否正常,如果正常,执行以下命令退出旧的nginx主进程;如果不正常,请看第8步。

  1. kill -QUIT 123

8、如果发现nginx不能正常服务,假设新的nginx主进程pid是321,分别执行以下命令以旧nginx替代新nginx。

  1. kill -HUP 123 – 这会让旧的nginx主进程重新生成子进程继续服务
  2. kill -QUIT 321 – 关闭新的nginx进程
  3. kill -TERM 321 -强制退出nginx进程

然后你就可以保证服务器继续上线来检查升级失败的原因。
参考:http://www.softwareprojects.com/resources/programming/t-recompileupgrade-nginx-binary-with-no-down-time-1520.html

解决CentOS 64位系统vsftpd 530 login incorrect的问题

今天在centos 6 64位测试安装vsftpd时发现能正常启动,但用本地用户登录时,发现出现vsftpd 530 login incorrect,出现这种错误会有很多原因。于是开始查看日志/var/log/vsftpd.log,也没发现有价值的信息。再查看/var/log/secure,发现问题了。部分错误代码如下:

  1. Dec  1 08:07:30 localhost vsftpd: PAM adding faulty module: /lib/security/pam_listfile.so
  2. Dec  1 08:07:30 localhost vsftpd: PAM unable to dlopen(/lib/security/pam_unix.so): /lib/security/pam_unix.so: cannot open shared objec
  3. t file: No such file or directory
  4. Dec  1 08:07:30 localhost vsftpd: PAM adding faulty module: /lib/security/pam_unix.so
  5. Dec  1 08:07:30 localhost vsftpd: PAM unable to dlopen(/lib/security/pam_shells.so): /lib/security/pam_shells.so: cannot open shared o
  6. bject file: No such file or directory
  7. Dec  1 08:07:30 localhost vsftpd: PAM adding faulty module: /lib/security/pam_shells.so
  8. Dec  1 08:10:12 localhost vsftpd: PAM unable to dlopen(/lib/security/pam_listfile.so): /lib/security/pam_listfile.so: cannot open shar
  9. ed object file: No such file or directory
  10. Dec  1 08:10:12 localhost vsftpd: PAM adding faulty module: /lib/security/pam_listfile.so
  11. Dec  1 08:10:12 localhost vsftpd: PAM unable to dlopen(/lib/security/pam_unix.so): /lib/security/pam_unix.so: cannot open shared objec
  12. t file: No such file or directory
  13. Dec  1 08:10:12 localhost vsftpd: PAM adding faulty module: /lib/security/pam_unix.so
  14. Dec  1 08:10:12 localhost vsftpd: PAM unable to dlopen(/lib/security/pam_shells.so): /lib/security/pam_shells.so: cannot open shared o
  15. bject file: No such file or directory
  16. Dec  1 08:10:12 localhost vsftpd: PAM adding faulty module: /lib/security/pam_shells.so

错误的意思是相关的安全验证文件找不到,通过find查找发现都在/lib64目录下,于是打开文件/etc/pam.d/vsftpd把/lib全部替换成/lib64,重启vsftpd,再登录就正常了。

调整Linux磁盘分区大小

在使用linux的过程中, 有时会出现因为安装系统时分区不当导致有的分区空间不足,而有的分区空间过剩的情况.比如: 我在安装系统时给/usr/local分配器了5G的空间,但使用一段过程后发现, /usr/local最多只用到了1G.这样可以将/usr/local大小调整为1G. 空出4G留作他用.本文归纳了在不破快文件系统数据的前提下对文件系统大小进行调整的方法.这里采用的是”拆东墙, 补西墙”的方法. 当然, 如果你的磁盘中有未分区的空闲空间, 你就不用减小某个分区的空间了. 这实际上是一个特例.减小一个分区的大小:[ partition ][ partition | free space ]增加一个分区的大小:[ partition a1 | partition b | free space ][ partition a2 | | partition a2 ]
当然如果有第三方磁盘,那就简单了。
1 挂载新磁盘
2. 把 tar -cf opt.tar /opt ; tar -cf usr.tar /usr
3. 卸载 /usr /opt 马上 fdisk -l 重新分区及格式化
4. 重新挂载 /usr /opt
5. tar xvf opt.tar -C /opt ; tar xvf usr.tar -C /usr
重启一下测试一下就好了

准备工作

——————————————————————————–
(一) 备份

首先组好备份要更改的分区中的文件. 对磁盘的操作也许会导致数据的丢失. 开始工作之前最好将重要的数据保存到别的分区.

(二) 获取相关信息.

1, 运行 $ df , 查看文件系统信息. 记下你想要调整的分区对应的挂载点和设备文件.
这一步是为了查看/usr/local对应/dev/中的哪个设备文件. 本文以/dev/hda7为例.

2, 运行 # sudo fdisk /dev/sda . 进入fdisk , 按下p, 查看磁盘分区信息. 记下/dev/sda8的起始柱面号, 终止柱面号. 设他们分别为start, end. 并记下一个”Unit”包含多少字节.

注意, 文件系统大小和磁盘分区大小是不能等同的: 起码他们的计量单位不同. 在文件系统中, 一般用KB, MB, GB为单位. 但在fdisk中, 是以磁盘的”unit”值(即一个柱面中包含的字节数)来计算的. 我们运行 # fdisk /dev/sda后, fdisk显示如下信息:

Disk /dev/sda: 163.9 GB, 163928604672 bytes
255 heads, 63 sectors/track, 19929 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

(三)计算终止柱面号

e.g: 原先/usr/local的大小为5000 MB, 起始柱面号为2550, 终止柱面号为3157. 那么我现在要将它的大小改为1000MB, 应该这样计算终止柱面号( [3.2] = 4 ):

终止柱面号 = 2550 + [(1000 * 1024 * 1024 ) / 8225280] = 2678

使用fdisk删除原来的分区(以前分区的数据不会丢失!). 然后新建一个分区, 新分区于旧分区唯一的区别就在于分区大小不一样, 这表现在他们终止柱面号不同.
增加分区大小: 终止柱面号设置为空闲空间的最后一个柱面号.
减小分区大小: 终止柱面号由计算得出.

开始调整

——————————————————————————–
在开始调整之前, 最好拿一张纸记下要调整的分区的下列信息:
调整前大小, 调整后大小. 它挂载在哪个目录, 对应于/dev/中的哪个设备. 起始, 终止柱面.

e.g: 调整前: 5G, 调整后: 1G, 挂载点: /usr/local, 对应于/dev/hda7. 起始,终止柱面分别为2550, 3157.

1, 卸载分区
最好在runlevel = 1的情况下卸载.

  1. # umount /dev/<partition to resize>

2, 检查文件系统的一致性

  1. # fsck -n /dev/<partition to resize>

3, 如够是ext3系统, 还要去除日志

  1. # tune2fs -O ^has_journal /dev/<partition to resize>

注意: 取出日志后的ext3系统是无法挂载的, 使用

  1. # tune2fs -j /dev/<resized partition>重建日志.

4, 调整文件系统大小

  1. # resize_reiserfs -s 1000M /dev/hda7

调整完文件系统的大小以后,再使用以下命令以文件系统进行全面的检查:

  1. # reiserfsck –check –fix-fixable /dev/hda7

5, 进入fdisk, 调整分区大小.

  1. # fdisk /dev/hda

由于内核仍然使用旧的分区表, 重启之后再进行后面的步骤.

通过以上步骤,我们已经完成了硬盘分区大小调整的操作,接下来回到重新调整文件系统大小的问题上来。 由于硬盘分区是按照柱面来计划的,我们要在 resize_reiserfs步骤上就一步到位调整文件系统大小与硬盘分区大小正好相等是比较困难的事情。所以一般是调硬盘分区比文件系统要大一点点, 然后再通过以下命令进行同步(当然如果你不在意硬盘分区里面存在部分空间的话也可以忽略以下步骤):

  1. # umount /home/
  2. # resize_reiserfs /dev/hda6

这样, 就将/usr/local的大小调整为1G, 留下了4G的空闲磁盘空间.
来自:http://bbs.51cto.com/thread-475486-1.html

Linux shell快速查找PHP木马

一句话查找PHP木马

  1. # find ./ -name "*.php" |xargs egrep "phpspy|c99sh|milw0rm|eval(gunerpress|eval(base64_decoolcode|spider_bc"> /tmp/php.txt
  2.  
  3. # grep -r –include=*.php  ‘[^a-z]eval($_POST’ . > /tmp/eval.txt
  4.  
  5. # grep -r –include=*.php  ‘file_put_contents(.*$_POST[.*]);’ . > /tmp/file_put_contents.txt
  6.  
  7. # find ./ -name "*.php" -type f -print0 | xargs -0 egrep "(phpspy|c99sh|milw0rm|eval(gzuncompress(base64_decoolcode|eval(base64_decoolcode|spider_bc|gzinflate)" | awk -F: ‘{print $1}’ | sort | uniq

查找最近一天被修改的PHP文件

  1. #   find -mtime -1 -type f -name *.php

修改网站的权限

  1. # find -type f -name *.php -exec chmod 444 {} ;
  2.  
  3. # find ./ -type d -exec chmod 555{} ;

转自:http://www.xtgly.com/2011/11/21/linux-shell%E5%BF%AB%E9%80%9F%E6%9F%A5%E6%89%BEphp%E6%9C%A8%E9%A9%AC.htm

Linux下的fdisk用法

Linux下的fdisk功能是极其强大的,用它可以划分出最复杂的分区,下面简要介绍一下它的用法:

对于IDE硬盘,每块盘有一个设备名:对应于主板的四个IDE接口,设备名依次为:/dev/hda,/dev/hdb,/dev/hdc,/dev/hdd等,如果还有IDE Raid卡,则依次为:/dev/hde,/dev/hdf,/dev/hdg,/dev/hdh。对于SCSI硬盘,则设备名依次为/dev/sda,/dev/sdb…等等

fdisk的命令行用法为: fdisk 硬盘设备名

进入fdisk后,首先键入’m’,即可显示fdisk全部菜单。

再键入’p’,显示当前分区表状态。

键入’n’,增加一个分区,然后会提示你选择分区类型(基本分区或扩展分区),再选择分区号(1-4)。注:每块硬盘最多可划分四个主分区(包括基本分区和扩展分区),其中:基本分区最多可划分四个,扩展分区最多可划分一个,但扩展分区内可再划分多个逻辑分区(最多几个我没试过,总之很多)。选中你要建立的分区类型和分区号后,会提示输入起始柱面,从1开始;然后再输入终止柱面,此时可输入实际的柱面数,也可用”+分区尺寸”的方式输入,如:+1024M表示在起始柱面后加上1024M。主分区的设备名依次为:/dev/hda1,/dev/hda2,/dev/hda3,/dev/hda4,逻辑分区的设备名依次为:/dev/hda5,/dev/hda6,/dev/hda7…等等。

键入’d‘,删除分区,输入分区号即可删除。注意,删除扩展分区时,将会同时删除所有的逻辑分区。

键入’t‘,改变分区标志(这是Linux的fdisk最精华的部份!),新建的分区默认标志是83(Linux Ext2),你可以把它改为82(Linux 交换区)、或是’b'(FAT32)、’f'(FAT32 Extend,只限于扩展分区)、’86′(NTFS)。。。等几十种类型。这样一来,使用多操作系统的朋友们就可以用Linux的fdisk划分出你想要的所有分区了!

键入’a’,切换分区激活开关。请注意:每键入一次,被选的分区就会在激活与非激活间变化一次,但你必须保证最后只有一个分区被激活。这时就用得到’p’命令了,被激活的分区上会有个’*’号。

除以上的几个命令外,还有其它几个,但不太常用。

最后,键入’w’,你对分区所做的改变被写入硬盘;键入’q’,则放弃所有的修改。

灵活应用fdisk,还可以修复一些损坏的分区表,前提是你必须准确记住原有每个分区的起始柱面和终止柱面。

再附加一下对硬盘进行格式化的方法:
要把分区格式化成Linux Ext2格式,用: mkext2fs /dev/hda?
要把分区格式化成FAT32格式,用: mkfs.vfat /dev/hda?    

linux 备份与恢复分区表

1.备份全部的分区信息

  1. #fdisk /dev/sda -l > /tmp/hda.txt

2.备份MBR

  1. #dd if=/dev/hda of=/tmp/mbr bs=512 count=1

主引导记录512字节,前446是程序代码,后64字节包含分区表信息,最后2字节标识是MBR
3.恢复分区表

  1. #dd if=/tmp/mbr of=/dev/hda bs=1 skip=446 count=66

补充:第一步可以把整个硬盘的分区信息备份下来。第二步可以把MBR上的分区表备份下来,第三步是恢复MBR上的分区信息。第一步得到的分区信息非常重要,倘若全部分区信息丢失,只恢复MBR上的分区信息也不能得到全面的分区,这时就可以通过fdisk程序按照hda.txt的内容重新建立分区表,参数要一样。这样可以恢复所有分区表信息。因为分区只修改部分扇区(Linux下叫块),并不影响正常的文件系统。此项操作具有一定风险,请不要随意进行。
分区表丢失并不代表数据丢失,重新建立分区表,只要不出差错,数据应该可以正常读取。
来源:http://861017.blog.51cto.com/235260/231847

使用CentOS网易yum源

1、首先备份/etc/yum.repos.d/CentOS-Base.repo

  1. mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

2、根据CentOS版本选择操作
CentOS-5

  1. wget http://mirrors.163.com/.help/CentOS5-Base-163.repo -O /etc/yum.repos.d/CentOS-Base.repo
  2. yum makecache

CentOS-6

  1. wget http://mirrors.163.com/.help/CentOS6-Base-163.repo  -O /etc/yum.repos.d/CentOS-Base.repo
  2. yum makecache