在CentOS或RHEL上如何为LAMP服务器保驾护航
时间:2014-09-04 22:25 来源:linux.it.net.cn 作者:布加迪编译 51CTO.com
LAMP是一套软件架构,包括这几大部分:Linux(作为基础层的操作系统),Apache(“位于操作系统之上”的网站服务器),MySQL(或MariaDB,作为关系数据库管理系统),最后是PHP(这种服务器端脚本语言用来处理和显示存储在数据库中的信息)。
我们在本文中假设这套架构的每个部分都已经搭建并运行起来,因而专门着重介绍为一台或多台LAMP服务器保驾护航。不过必须要强调的是,服务器端安全是个庞大繁杂的课题,因而别指望仅仅用一篇文章就能充分而全面地加以论述。
我们在本文中将探讨为LAMP软件架构的每个部分保驾护航所要做的基本事项。
确保Linux安全
你可能想通过ssh来管理自己的CentOS服务器,那就应该考虑下面这些小贴士:通过编辑/etc/ssh/sshd_config配置文件,确保安全地远程访问服务器。
1)只要有可能,尽量使用基于密钥的验证远程登录到服务器,而不是使用基本的验证机制(用户名和密码)。我们假设你已经在客户机上建立了密钥对和用户名,并拷贝到服务器上。
PasswordAuthentication no
RSAAuthentication yes
PubkeyAuthentication yes
2)更改sshd将侦听的端口。建议使用高于1024的端口:
Port XXXX
3)只允许协议版本2:
Protocol 2
4)配置验证超时,不允许root登录,并且限制哪些用户可以通过ssh登录:
LoginGraceTime 2m
PermitRootLogin no
AllowUsers gacanepa
5)只允许特定的主机(及/或特定的网络)通过ssh登录:
在/etc/hosts.deny文件中:
sshd: ALL
在/etc/hosts.allow文件中:
sshd: XXX.YYY.ZZZ. AAA.BBB.CCC.DDD
其中XXX.YYY.ZZZ.代表IPv4网络地址的头3个8位位组,而AAA.BBB.CCC.DDD是个IPv4地址。有了这种设置后,只有来自网络XXX.YYY.ZZZ.0/24的主机和主机AAA.BBB.CCC.DDD才可以通过ssh进行连接。其他的所有主机还没有进入到登录提示符就被断开,会收到类似这样的错误信息:
(别忘了重启sshd后台程序让这些变更内容生效:service sshd restart)。
我们必须要强调的是,说到阻止访问你服务器的入站连接,这种方法快捷又简单,不过有点原始。想获得进一步的定制性、扩展性和灵活性,应该考虑使用普通iptables及/或fail2ban。
确保Apache安全
1)确保运行Apache网站服务器的系统用户无法访问外壳:
# grep -i apache /etc/passwd
要是用户apache有默认外壳(比如/bin/sh),我们必须将它更改成/bin/false或/sbin/nologin:
# usermod -s /sbin/nologin apache
下列建议(2到5)针对/etc/httpd/conf/httpd.conf文件:
2)禁止目录列表:如果目录里面没有index.html,这将防止浏览器显示该目录的内容。
删除Options指令中的单词Indexes:
# Options指令既复杂又重要。请参阅
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# 了解更多信息。
# Options Indexes FollowSymLinks
应显示为:
Options None
此外,你需要确保目录和虚拟主机的设置并没有覆盖这个全局配置。
请注意上述这个例子,如果我们检查设置、查找/var/www/icons目录,就会看到“Indexes MultiViews FollowSymLinks”应该被更改成了“None”。
更改前:
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
更改后:
Options None
AllowOverride None
Order allow,deny
Allow from all
3)隐藏Apache版本,并隐藏出错页面(比如Not Found和Forbidden页面)中的模块/操作系统信息。
ServerTokens Prod # 这意味着http响应头只返回“Apache”,而不返回版本号
ServerSignature Off # 操作系统信息隐藏起来
4)通过注释掉声明不需要模块的对应行,禁用那些模块:
小提示:如果目录列表中没有index.html文件,禁用autoindex_module是隐藏目录列表的另一个方法。
5)限制HTTP请求大小(请求主体和请求头),并设置连接超时:
想了解更多指令以及设置指令方面的说明,请参阅Apache文档(http://httpd.apache.org/docs/)。
确保MySQL服务器安全
我们首先运行mysql-server软件包随带的mysql_secure_installation脚本。
1)如果我们在安装过程中没有为MySQL服务器设置root密码,现在可以设置root密码了,另外要记住:这在生产环境中必不可少。
继续这个过程:
2)删除匿名用户:
3)只允许root从本地主机来连接:
4)删除名为test的默认数据库:
5)让变更内容生效:
6)下一步,我们将编辑/etc/my.cnf文件中的一些变量:
[mysqld]
bind-address=127.0.0.1 # MySQL将只接受来自本地主机的连接
local-infile=0 # Disable direct filesystem access log=/var/log/mysqld.log # 启用日志文件以留意恶意活动
别忘了使用‘service mysqld restart’,重启MySQL服务器。
现在,说到日常数据库管理,你会发现下列建议很有用:
•要是由于某个原因我们需要远程管理数据库,我们可以首先通过ssh连接到服务器,本地执行必要的查询和管理任务,以实现远程管理。
•我们之后可能需要启用直接访问文件系统的功能,比如说为了需要将文件批量导入到数据库中。
•保存日志不像上面两点来得重要,但许多日志对于为数据库排查故障及/或留意不熟悉的活动大有帮助。
•千万不要以明文格式存储敏感信息,比如密码、信用卡号、银行PIN等等。可以考虑使用散列函数来加密这些信息。
•确保针对特定应用程序的数据库只能由该应用程序为此创建的相应用户访问:
想调整MySQL用户的访问权限,请使用这些指令。
首先,检索来自用户表的用户列表:
gacanepa@centos:~$ mysql -u root -p
Enter password: [Your root password here]
mysql> SELECT User,Host FROM mysql.user;
确保每个用户只能访问它所需要的数据库,并确保每个用户只有最基本的权限。在下面这个示例中,我们将检查用户db_usuario的权限:
mysql> SHOW GRANTS FOR 'db_usuario'@'localhost';
你随后可以根据需要撤销权限和访问权。
确保PHP安全
由于本文旨在为LAMP架构的几个部分保驾护航,我们在编程方面不会深入介绍。我们假设我们的Web应用程序很安全,因为开发人员已不怕麻烦地确保没有留下为跨站脚本攻击(XSS)或SQL注入攻击等常见攻击可趁之机的任何安全漏洞。
1) 禁用不必要的模块:
我们可以使用下面这个命令:php -m,显示当前编译模块列表:
然后禁用不需要的那些模块,为此只要删除或更名/etc/php.d目录中的相应文件。
比如说,由于自PHP v5.5.0起mysql扩展部分已被废弃(将来会被删除),我们需要禁用它:
# php -m | grep mysql
# mv /etc/php.d/mysql.ini /etc/php.d/mysql.ini.disabled
2) 隐藏PHP版本信息:
# echo "expose_php=off" >> /etc/php.d/security.ini [or modify the security.ini file if it already exists]
3)将open_basedir设置成几个特定的目录(在php.ini中),目的是为了限制对底层文件系统的访问:
4)禁用远程代码/命令执行以及容易被利用的函数,比如exec()、system()、passthru()和eval()等函数(在php.ini)中:
allow_url_fopen = Off
allow_url_include = Off
disable_functions = "exec, system, passthru, eval"
结束语
1)将软件包更新到最新版本(比较下列命令的输出和‘yum info [package]’的输出):
下列命令返回Apache、MySQL和PHP的当前版本:
# httpd -v
# mysql -V (capital V)
# php -v
然后,‘yum update [package]’可用于更新软件包,以便拥有最新的安全补丁。
2) 确保配置文件只能被root帐户写入:
# ls -l /etc/httpd/conf/httpd.conf
# ls -l /etc/my.cnf
# ls -l /etc/php.ini /etc/php.d/security.ini
3)最后,如果你有机会的话,在不同的物理机或虚拟机中(通过防火墙来保护这些机器之间的联系),运行这些服务(网站服务器、数据库服务器和应用服务器),那样万一某一项服务受到了危及,攻击者也无法立即访问其他服务。如果真出现攻击者能立即访问其他服务这种情况,就得改动本文中讨论的一些配置。请注意:有多种方案可以用来增强LAMP服务器的安全性,本文介绍的仅仅是其中之一。
(责任编辑:IT)
LAMP是一套软件架构,包括这几大部分:Linux(作为基础层的操作系统),Apache(“位于操作系统之上”的网站服务器),MySQL(或MariaDB,作为关系数据库管理系统),最后是PHP(这种服务器端脚本语言用来处理和显示存储在数据库中的信息)。 我们在本文中假设这套架构的每个部分都已经搭建并运行起来,因而专门着重介绍为一台或多台LAMP服务器保驾护航。不过必须要强调的是,服务器端安全是个庞大繁杂的课题,因而别指望仅仅用一篇文章就能充分而全面地加以论述。 我们在本文中将探讨为LAMP软件架构的每个部分保驾护航所要做的基本事项。 确保Linux安全 你可能想通过ssh来管理自己的CentOS服务器,那就应该考虑下面这些小贴士:通过编辑/etc/ssh/sshd_config配置文件,确保安全地远程访问服务器。 1)只要有可能,尽量使用基于密钥的验证远程登录到服务器,而不是使用基本的验证机制(用户名和密码)。我们假设你已经在客户机上建立了密钥对和用户名,并拷贝到服务器上。 PasswordAuthentication no RSAAuthentication yes PubkeyAuthentication yes 2)更改sshd将侦听的端口。建议使用高于1024的端口: Port XXXX 3)只允许协议版本2: Protocol 2 4)配置验证超时,不允许root登录,并且限制哪些用户可以通过ssh登录: LoginGraceTime 2m PermitRootLogin no AllowUsers gacanepa 5)只允许特定的主机(及/或特定的网络)通过ssh登录: 在/etc/hosts.deny文件中: sshd: ALL 在/etc/hosts.allow文件中: sshd: XXX.YYY.ZZZ. AAA.BBB.CCC.DDD 其中XXX.YYY.ZZZ.代表IPv4网络地址的头3个8位位组,而AAA.BBB.CCC.DDD是个IPv4地址。有了这种设置后,只有来自网络XXX.YYY.ZZZ.0/24的主机和主机AAA.BBB.CCC.DDD才可以通过ssh进行连接。其他的所有主机还没有进入到登录提示符就被断开,会收到类似这样的错误信息:
(别忘了重启sshd后台程序让这些变更内容生效:service sshd restart)。 我们必须要强调的是,说到阻止访问你服务器的入站连接,这种方法快捷又简单,不过有点原始。想获得进一步的定制性、扩展性和灵活性,应该考虑使用普通iptables及/或fail2ban。 确保Apache安全 1)确保运行Apache网站服务器的系统用户无法访问外壳: # grep -i apache /etc/passwd 要是用户apache有默认外壳(比如/bin/sh),我们必须将它更改成/bin/false或/sbin/nologin: # usermod -s /sbin/nologin apache
下列建议(2到5)针对/etc/httpd/conf/httpd.conf文件: 2)禁止目录列表:如果目录里面没有index.html,这将防止浏览器显示该目录的内容。 删除Options指令中的单词Indexes: # Options指令既复杂又重要。请参阅 # http://httpd.apache.org/docs/2.2/mod/core.html#options # 了解更多信息。 # Options Indexes FollowSymLinks 应显示为: Options None
此外,你需要确保目录和虚拟主机的设置并没有覆盖这个全局配置。 请注意上述这个例子,如果我们检查设置、查找/var/www/icons目录,就会看到“Indexes MultiViews FollowSymLinks”应该被更改成了“None”。 更改前: Options Indexes MultiViews FollowSymLinks AllowOverride None Order allow,deny Allow from all 更改后: Options None AllowOverride None Order allow,deny Allow from all 3)隐藏Apache版本,并隐藏出错页面(比如Not Found和Forbidden页面)中的模块/操作系统信息。 ServerTokens Prod # 这意味着http响应头只返回“Apache”,而不返回版本号 ServerSignature Off # 操作系统信息隐藏起来
4)通过注释掉声明不需要模块的对应行,禁用那些模块:
小提示:如果目录列表中没有index.html文件,禁用autoindex_module是隐藏目录列表的另一个方法。 5)限制HTTP请求大小(请求主体和请求头),并设置连接超时:
想了解更多指令以及设置指令方面的说明,请参阅Apache文档(http://httpd.apache.org/docs/)。 确保MySQL服务器安全 我们首先运行mysql-server软件包随带的mysql_secure_installation脚本。 1)如果我们在安装过程中没有为MySQL服务器设置root密码,现在可以设置root密码了,另外要记住:这在生产环境中必不可少。
继续这个过程:
2)删除匿名用户:
3)只允许root从本地主机来连接:
4)删除名为test的默认数据库:
5)让变更内容生效:
6)下一步,我们将编辑/etc/my.cnf文件中的一些变量: [mysqld] bind-address=127.0.0.1 # MySQL将只接受来自本地主机的连接 local-infile=0 # Disable direct filesystem access log=/var/log/mysqld.log # 启用日志文件以留意恶意活动 别忘了使用‘service mysqld restart’,重启MySQL服务器。 现在,说到日常数据库管理,你会发现下列建议很有用: •要是由于某个原因我们需要远程管理数据库,我们可以首先通过ssh连接到服务器,本地执行必要的查询和管理任务,以实现远程管理。 •我们之后可能需要启用直接访问文件系统的功能,比如说为了需要将文件批量导入到数据库中。 •保存日志不像上面两点来得重要,但许多日志对于为数据库排查故障及/或留意不熟悉的活动大有帮助。 •千万不要以明文格式存储敏感信息,比如密码、信用卡号、银行PIN等等。可以考虑使用散列函数来加密这些信息。 •确保针对特定应用程序的数据库只能由该应用程序为此创建的相应用户访问: 想调整MySQL用户的访问权限,请使用这些指令。 首先,检索来自用户表的用户列表: gacanepa@centos:~$ mysql -u root -p Enter password: [Your root password here] mysql> SELECT User,Host FROM mysql.user;
确保每个用户只能访问它所需要的数据库,并确保每个用户只有最基本的权限。在下面这个示例中,我们将检查用户db_usuario的权限: mysql> SHOW GRANTS FOR 'db_usuario'@'localhost';
你随后可以根据需要撤销权限和访问权。 确保PHP安全 由于本文旨在为LAMP架构的几个部分保驾护航,我们在编程方面不会深入介绍。我们假设我们的Web应用程序很安全,因为开发人员已不怕麻烦地确保没有留下为跨站脚本攻击(XSS)或SQL注入攻击等常见攻击可趁之机的任何安全漏洞。 1) 禁用不必要的模块: 我们可以使用下面这个命令:php -m,显示当前编译模块列表:
然后禁用不需要的那些模块,为此只要删除或更名/etc/php.d目录中的相应文件。 比如说,由于自PHP v5.5.0起mysql扩展部分已被废弃(将来会被删除),我们需要禁用它: # php -m | grep mysql # mv /etc/php.d/mysql.ini /etc/php.d/mysql.ini.disabled
2) 隐藏PHP版本信息: # echo "expose_php=off" >> /etc/php.d/security.ini [or modify the security.ini file if it already exists]
3)将open_basedir设置成几个特定的目录(在php.ini中),目的是为了限制对底层文件系统的访问:
4)禁用远程代码/命令执行以及容易被利用的函数,比如exec()、system()、passthru()和eval()等函数(在php.ini)中: allow_url_fopen = Off allow_url_include = Off disable_functions = "exec, system, passthru, eval"
结束语 1)将软件包更新到最新版本(比较下列命令的输出和‘yum info [package]’的输出): 下列命令返回Apache、MySQL和PHP的当前版本: # httpd -v # mysql -V (capital V) # php -v
然后,‘yum update [package]’可用于更新软件包,以便拥有最新的安全补丁。 2) 确保配置文件只能被root帐户写入: # ls -l /etc/httpd/conf/httpd.conf # ls -l /etc/my.cnf # ls -l /etc/php.ini /etc/php.d/security.ini
3)最后,如果你有机会的话,在不同的物理机或虚拟机中(通过防火墙来保护这些机器之间的联系),运行这些服务(网站服务器、数据库服务器和应用服务器),那样万一某一项服务受到了危及,攻击者也无法立即访问其他服务。如果真出现攻击者能立即访问其他服务这种情况,就得改动本文中讨论的一些配置。请注意:有多种方案可以用来增强LAMP服务器的安全性,本文介绍的仅仅是其中之一。 (责任编辑:IT) |