本文所列内容在Linode和Vultr的VPS上面均测试通过。

 

1,初步说明

Debian和Ubuntu系统是比较常用的Linux服务器操作系统,本文将指引读者构建一个安全、稳定并且运行效率高的Apache/PHP/MySQL(LAMP)环境,文中内容在Debian 6、7和Ubuntu 14.04系统上测试通过。本文以Debian为主,Ubuntu在细节方面略有差别,文中会特别注明。

系统组件包括Apache2、PHP5、Proftpd和MySQL在apt stable中的最新版本,具体什么子版本不重要,操作上无差别。

本文是我几年前所开发的主机管理系统的一部分内容,从Debia 4.0至现在的7.6都是通过的,细节方面无差别,唯有Proftpd会报错,因为7.6系统安装的Proftpd默认启用ssl模块,而这个并不是我们所需的,如果你不启用ssl连接的话,那么这个错误可以忽视,因为它仅仅是一个warn,不是一个error

本文假定你已经“干净”安装了Debian或Ubuntu系统,安装中仅选择了SSH服务器,其他都没选中(standard环境可选可不选),并且你所设置的主机名已经写入/etc/hosts和/etc/hostname中,如果主机名的设置不正确,会导致ftp和一些服务无法启动。

2,安装与配置

首先一次性安装所有需要的软件包:

apt-get install libapache2-mod-fcgid apache2-mpm-worker mysql-server mysql-client libmysqlclient15-dev php5-cgi php-pear php5-gd php5-imap php5-mcrypt php5-mhash php5-xmlrpc php5-xsl php5-mysql php5-curl php5-common php5-dev php5-imagick php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy libnet-ssleay-perl libauthen-pam-perl libio-pty-perl proftpd ucf apache2-suexec sysv-rc-conf htop ifstat unzip nano

中途会要求输入两次MySQL的root密码,并且选择Proftpd的运行模式,默认是Stand模式,直接回车即可。

 

设置MySQL:

nano /etc/mysql/my.cnf

做如下修改:

#bind-address = 127.0.0.1 #屏蔽此行
max_allowed_packet = 1000M #添加此行

最后重启mysql:

/etc/init.d/mysql restart

设置Proftpd:

nano /etc/proftpd/proftpd.conf

做如下设置:

#添加如下设置:
MaxHostsPerUser 3
MaxClients 200
MaxClientsPerHost 3
AllowStoreRestart on
AllowRetrieveRestart on
DefaultRoot ~
ServerIdent on "old.tingtao.org FTP Server ready."
UseReverseDNS off
IdentLookups off
WtmpLog on
TimeoutIdle 300
RequireValidShell Off

#如果你想限制FTP速度,按照下面设置
#限速上传8M(整机)
TransferRate STOR 800
#限速下载1M(整机)
TransferRate RETR 100

#修改默认的pasv端口范围:
PassivePorts 65000 65530
#如果你想关闭IPV6,那么修改下面这个地方:
UseIPv6 off

最后重启Proftpd:

/etc/init.d/proftpd restart

 

设置PHP:

nano /etc/php5/cgi/php.ini

有三项需要修改:

expose_php = Off #执行错误时是否输出详细内容
upload_max_filesize = 50M #上传文件最大容量
disable_functions = phpinfo,system,exec,shell_exec,passthru,error_log,dl,sys_getloadavg,pfsockopen,openlog,syslog,readlink,symlink,link,leak,popen,escapeshellcmd,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,escapeshellarg,pcntl_exec,show_source,highlight_file,ini_restore,apache_child_terminate,apache_get_modules,apache_get_version,apache_getenv,apache_note,apache_setenv,virtual,mb_send_mail,set_time_limit,max_execution_time,php_uname,disk_free_space,diskfreespace,stream_copy_to_stream
#禁用的函数列表

其实这个设置也可以忽略,因为这是全局设置,后面每个站点会有各自详细设置,而站点设置会覆盖全局设置的。

 

设置Apache2:

nano /etc/apache2/apache2.conf

做如下更改:

<Directory /var/www/>
Options Indexes FollowSymLinks #//这里将Indexes删掉
AllowOverride None #这里将None改成All
Require all granted
</Directory>

注意,如果是Ubuntu系统,那么按照下面的改:

<Directory /var/www/>
Options Indexes FollowSymLinks #//这里将Indexes删掉
AllowOverride None #这里将None改成All
Require all granted
</Directory>
#.....
<Directory />
Options FollowSymLinks
AllowOverride None #这里将None改成All
Require all denied
</Directory>

下面屏蔽掉服务器信息的回显:

nano /etc/apache2/conf.d/security

注意,如果是Ubuntu系统,那么是下面的文件:

nano /etc/apache2/conf-enabled/security.conf

更改下面两个选项:

ServerTokens Prod
ServerSignature Off

然后设置worker工作模式的配置,Ubuntu在这里需要首先切换一下工作模式,下面是合并以后的命令:

#Debian:
nano /etc/apache2/apache2.conf

#Ubuntu:
a2dismod mpm_event
a2enmod mpm_worker
nano /etc/apache2/mods-enabled/mpm_worker.conf

屏蔽掉<fModule mpm_worker_module>这个段,用以下内容替换:

<IfModule mpm_worker_module>
ServerLimit 20000
StartServers 5
MaxClients 20000
MinSpareThreads 75
MaxSpareThreads 300
ThreadsPerChild 50
MaxRequestsPerChild 80000
</IfModule>

设置一下fcgid的最大提交内容为15M:

nano /etc/apache2/mods-available/fcgid.conf

加入下面一行:

MaxRequestLen 15728640

最后,调整一下Apache2的模块,将不需要的模块关掉,并启用需要用的,这样可以提高性能与安全性,命令:

echo -e "\ncgi.fix_pathinfo = 1" >> /etc/php5/cgi/php.ini
a2enmod actions
a2enmod alias
a2enmod include
a2enmod mime
a2enmod rewrite
a2enmod suexec
a2dismod cgid
a2enmod fcgid
a2dismod auth_basic
a2dismod auth_digest
a2enmod cband
a2dismod negotiation
a2dismod authz_user
a2dismod authz_groupfile
a2dismod authz_default
a2dismod authn_file
a2enmod vhost_alias
/etc/init.d/apache2 force-reload

注:第一行是php需要用的,后面的模块有些并不存在,但是为了保持兼容性,所以这些命令全部列出了,不管执行中是否出错都不用在意。

最后,略微提升一下系统性能,关闭用不上的默认内部邮件系统exim4:

sysv-rc-conf

如果列出的表内有exim4的话,用上下箭头选择行,用左右箭头和空格确保该行的每一列都留空,最后按q键退出即可。这个exim4不一定会在每个系统上都有,因为有的是vps,有的是云主机,有的是物理服务器,所以有些系统安装的时候我们看不到具体内容。所以如果你没看到exim4,那么就不管他。

到这里就完成了环境配置,这时应该重启一下系统:

reboot

 

3,开通主机步骤

这里说明一下思路,基于安全的理由,我们应当将每一个站点的运行环境进行限制,比如用户登录ftp,那么就应当只能访问自己站点的内容,用户浏览web,也应当只能访问站点内文件,如果这方面没有配置好,那么一个php木马就可以消灭你的服务器了,下面的内容与上面的设置是相辅相成的,你只需要将下面内容里的“tingtao”换成你想要的ftp用户名,将123456换成你想要的ftp密码,最后再改一下站点域名就可以了,下面是以听涛主站old.tingtao.org为例列出的命令,你做相应替换即可。另外需要注意的是,可以这样理解,Apache2的配置里面,ServerName可以视作主域名,ServerAlias可以视作附加域名,如果没有附加的则屏蔽掉那一行即可,如果有多个附加域名,则用空格分开即可。

useradd tingtao -s /sbin/nologin || exit 1
echo tingtao:123456|chpasswd
groupadd -f tingtao
usermod -G tingtao -a www-data
usermod -G tingtao -a proftpd
mkdir /var/www/tingtao
mkdir /var/www/tingtao/logs
mkdir /var/www/globals
mkdir /var/www/globals/tingtao
mkdir /var/www/globals/tingtao/wrapper
mkdir /var/www/globals/tingtao/conf
mkdir /var/www/globals/tingtao/lib
usermod -d /var/www/tingtao tingtao

#下面是默认首页,你也可以跳过这一行
touch /var/www/tingtao/index.html
#下面是默认的出错页面,你可以定制个性化出错页面,也可以跳过
touch /var/www/tingtao/403.html
touch /var/www/tingtao/404.html
touch /var/www/tingtao/500.html
touch /var/www/tingtao/503.html

cat > /var/www/globals/tingtao/wrapper/wrapper <<- _EOF1_
#!/bin/sh
export PHPRC=/var/www/globals/tingtao/conf
export PHP_FCGI_CHILDREN=1
export PHP_FCGI_MAX_REQUESTS=5000
exec /usr/bin/php5-cgi
_EOF1_

cat > /var/www/globals/tingtao/conf/php.ini <<- _EOF2_
include_path = ".:/var/www/globals/tingtao/lib"
open_basedir = "/var/www/tingtao:/tmp"
expose_php = Off
allow_url_fopen=yes
display_errors=yes
upload_max_filesize = 50M
post_max_size=50M
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
output_buffering = 4096
disable_functions = phpinfo,system,exec,shell_exec,passthru,error_log,dl,sys_getloadavg,pfsockopen,openlog,syslog,readlink,symlink,link,leak,popen,escapeshellcmd,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,escapeshellarg,pcntl_exec,show_source,highlight_file,ini_restore,apache_child_terminate,apache_get_modules,apache_get_version,apache_getenv,apache_note,apache_setenv,virtual,mb_send_mail,set_time_limit,max_execution_time,php_uname,disk_free_space,diskfreespace,stream_copy_to_stream
_EOF2_

chown -R tingtao:tingtao /var/www/tingtao
chown -R tingtao:tingtao /var/www/globals/tingtao
chown www-data:tingtao /var/www/tingtao/logs
touch /var/www/tingtao/logs/access.log
touch /var/www/tingtao/logs/error.log

chmod -R 750 /var/www/tingtao
chmod -R 750 /var/www/globals/tingtao
chmod 640 /var/www/tingtao/index.html
chmod 640 /var/www/globals/tingtao/conf/php.ini
chmod 640 /var/www/tingtao/logs/*

touch /etc/apache2/sites-available/tingtao.conf

cat > /etc/apache2/sites-available/tingtao.conf <<- _EOF3_
<VirtualHost *:80>
SuexecUserGroup tingtao tingtao
ServerName tingtao.org
ServerAlias old.tingtao.org
DocumentRoot "/var/www/tingtao"
ScriptAlias /cgi-bin/ /var/www/tingtao/cgi-bin/
<Directory />
DirectoryIndex index.htm index.html index.php index.shtml
Options -Indexes +IncludesNoExec
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorDocument 403 /403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /500.html
ErrorDocument 503 /503.html
CustomLog /var/log/apache2/vhost_access.log combined
CustomLog /var/www/tingtao/logs/access.log combined
ErrorLog /var/www/tingtao/logs/error.log
AddHandler php-fcgi .php
Action php-fcgi /fcgi-bin/wrapper
Alias /fcgi-bin/ /var/www/globals/tingtao/wrapper/
<Location /fcgi-bin/>
SetHandler fcgid-script
Options +ExecCGI
</Location>
ReWriteEngine On
ReWriteRule ^/fcgi-bin/[^/]*$ / [PT] </VirtualHost>

_EOF3_

a2ensite tingtao.conf

当你执行了上面命令以后,需要通知apache2重新加载配置:

/etc/init.d/apache2 reload

#有时候reload不太给力,那么用下面的也可以

/etc/init.d/apache2 force-reload

 

4,附加说明

首先,本文内容是原创,所以禁止转载或者复制。

然后,本文所提供的环境相当安全,在Apache、Proftpd、MySQL不出现自身漏洞的情况下,本文所构建的环境不会被黑客远程攻破(当然你的密码丢了或者WEB程序有漏洞这种我没办法),你可以上传phpshell测试一下安全性的。

接着,如果两个系统单选的话,强烈建议选择Debian,因为Ubuntu越来越像Windows了,无关内容太多,而服务器不应该有非必须程序在运行,这样只会降低性能、安全性和稳定性。

最后,上面的设置是允许远程连接MySQL的,但是root用户还不能远程连接,如果你需要的话,可以用phpmyadmin来复制一个roo用户,主机为%即可。

作者 听涛

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注