网站目录文件权限的简单安全设置

网站目录文件权限的设置对网站的安全至关重要,下面简单介绍网站目录文件权限的基本设定。
我们假设http服务器运行的用户和用户组是www,网站用户为centos,网站根目录是/home/centos/web。
1、我们首先设定网站目录和文件的所有者和所有组为centos,www,如下命令:

  1. chown -R centos:www /home/centos/web

2、设置网站目录权限为750,750是centos用户对目录拥有读写执行的权限,这样centos用户可以在任何目录下创建文件,用户组有有读执行权限,这样才能进入目录,其它用户没有任何权限。

  1. find -type d -exec chmod 750 {} ;

3、设置网站文件权限为640,640指只有centos用户对网站文件有更改的权限,http服务器只有读取文件的权限,无法更改文件,其它用户无任何权限。

  1. find -not -type d -exec chmod 640 {} ;

4、针对个别目录设置可写权限。比如网站的一些缓存目录就需要给http服务有写入权限。例如discuz x2的/data/目录就必须要写入权限。

  1. find data -type d -exec chmod 770 {} ;

logrotate无法自动轮询日志的原因

上次介绍使用logrotate轮询nginx日志的方法。配置好之后,连续两天都没发现logrotate轮询nginx的日志,于是开始检查配置文件是否有问题,结果是配置文件一切正常。怀疑是cron没执行,查看了cron的日志,发现有一条Dec 7 04:02:01 www crond[18959]: (root) CMD (run-parts /etc/cron.daily)这样的日志,证明cron在04:02分时已经执行/etc/cron.daily目录下的程序。接着查看/etc/cron.daily/logrotate的内容:

  1. #!/bin/sh
  2.  
  3. /usr/sbin/logrotate /etc/logrotate.conf
  4. EXITVALUE=$?
  5. if [ $EXITVALUE != 0 ]; then
  6.     /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
  7. fi
  8. exit 0

没有发现异常,系统日志等都是由这个脚本轮询的,一切运行正常,脚本应该就没问题。直接执行命令/usr/sbin/logrotate /etc/logrotate.conf系统日志是正常轮询了,但nginx日志却没反应。
再man logrotate看下说明发现一个选项-f (–force),大概意思是:强行启动记录文件维护操作,纵使logrotate指令认为没有需要亦然。
那应该有可能是logroate认为nginx日志太小,不进行轮询,但我们需要轮询,加-f选项即可。即

  1. /usr/sbin/logrotate -f /etc/logrotate.conf

不清楚logrotate轮询的条件是什么,还要强制轮询才行,搞不懂。

解决mysql 5.5.x占用虚拟内存过高的问题

5,5默认存储引擎是innodb,所以一起动就占用了三百多的虚拟内存,我们一般用的存储引擎是MyISAM,需要禁用innodb,设置默认的引擎为MyISAM。
解决方法:
在[mysqld]里面加入

  1. default-storage-engine = MyISAM
  2. innodb=OFF
  3. skip-innodb

重启mysql即可。

libmysqlclient.so.18: 无法打开共享对象文件: 没有那个文件或目录

执行mysqlhotcopy的时候出现install_driver(mysql) failed: Can’t load ‘/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/DBD/mysql/mysql.so’ for module DBD::mysql: libmysqlclient.so.18: 无法打开共享对象文件: 没有那个文件或目录 at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 230.错误。这个错误是找不到libmysqlclient.so.18文件,于是find找了一下,发现在/usr/local/mysql/lib/libmysqlclient.so.18。

  1. 解决方法:cp /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib/

隐藏nginx版本号

隐藏nginx版本号是为了防止黑客利用特定版本出现的漏洞攻击,现在介绍方法,主要修改两个地方。
1、修改nginx.conf文件,在httpd区域中加入server_tokens off;如:

  1. http {
  2. ……省略
  3. sendfile on;
  4. tcp_nopush on;
  5. keepalive_timeout 60;
  6. tcp_nodelay on;
  7. server_tokens off;
  8. …….省略
  9. }

2、修改/usr/local/nginx/conf/下的php-fpm配置文件。

  1. 找到:
  2. fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
  3. 改为:
  4. fastcgi_param SERVER_SOFTWARE nginx;

最后重载nginx即可。

解决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,再登录就正常了。