之前我对lnmp组合一直诟病的是无法像lamp一样提供suexec环境,那么便有切实存在的安全隐患。今天恰好找到了近似解决途径,遂实践之。
本文基于Debian 8 jessie系统,其他素三鲜皆用apt库中的最新稳定版构成,尽最大可能不从源代码编译,本人特反感编译安装。
首先update系统的apt库以及习惯性的系统调整这些就不啰唆了,之前文章都有,直接后面的步骤:
一,安装相关软件:
apt-get install -y update-inetd nginx-extras php5-cgi php5-fpm php-pear php5-gd php5-imap php5-mcrypt php5-xmlrpc php5-xsl php5-mysql php5-curl php5-common php5-dev php5-imagick php5-memcache php5-pspell php5-recode php5-sqlite php5-tidy libnet-ssleay-perl libauthen-pam-perl libio-pty-perl proftpd ucf php-db mysql-server-5.5 mysql-client-5.5
中途会要求输入mysql的root密码和选择proftpd的运行模式。
二,根据自身需要对配置文件进行修改:
首先改动/etc/nginx/nginx.conf文件,我自用的配置如下:
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
use epoll;
worker_connections 200000;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
sendfile on;
keepalive_timeout 120;
tcp_nodelay on;
types_hash_max_size 2048;
gzip on;
gzip_min_length 1k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
server_names_hash_bucket_size 1024; #服务器名字的hash表大小
proxy_headers_hash_max_size 51200; #设置头部哈希表的最大值,不能小于你后端服务器设置的头部总数
proxy_headers_hash_bucket_size 6400;#设置头部哈希表大小
send_timeout 600;
more_set_headers "Server: www.tingtao.org_US_new";
server_tokens off;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}然后在/etc/mysql/my.cnf 文件对这几行进行修改或者增加:
#bind-address = 127.0.0.1 #添加 character-set-server=gbk default-storage-engine=MYISAM skip-name-resolve lower_case_table_names = 1 max_connections=1000 #修改 max_allowed_packet = 10000M
授权root用户远程登录:
#授权root远程登录,密码是7758,各位自行修改 mysql -u root -p7758 grant all privileges on *.* to root@"%" identified by '7758' with grant option; exit; /etc/init.d/mysql restart
Proftpd的修改我忘记具体内容了,我是直接用自己编辑好的模板:
wget http://soft.tingtao.org/proftpd/proftpd_debian8.txt -O /etc/proftpd/proftpd.conf /etc/init.d/proftpd restart
第二阶段到此结束。
三:配置nginx与php的亲密接触:
命令:
echo 'fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/:/usr/share/php/";' >> /etc/nginx/fastcgi_params echo 'fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/:/usr/share/php/";' >> /etc/nginx/fastcgi.conf echo "php_admin_value[open_basedir]=/var/www/:/proc/:/tmp/:/usr/share/php/" >> /etc/php5/fpm/php-fpm.conf
这些就是之前我没找到的细节,可以将php程序限定在一些特定目录,其中“:/usr/share/php/”这个路径是我有个php程序特别需要的,一般来说用不到这个。
站点配置的模板文件:
#######################################################
# www.tingtao.org
server {
listen 80;
server_name www.tingtao.org;
keepalive_timeout 120;
listen 443 ssl;
#修改1
ssl_certificate /var/www/ca/www.tingtao.org/Nginx/1_www.tingtao.org_bundle.crt;
ssl_certificate_key /var/www/ca/www.tingtao.org/Nginx/2_www.tingtao.org.key;
##############################################
#修改2
access_log /var/www/logs/www.tingtao.org.log;
error_log /var/www/logs/www.tingtao.org_err.log;
#修改3
root /var/www/www.tingtao.org;
location ~ ^.+\.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
#修改4
fastcgi_pass unix:/var/run/php5-fpm-www.tingtao.org.sock;
fastcgi_index index.php;
#修改5
fastcgi_param SCRIPT_FILENAME /var/www/www.tingtao.org$fastcgi_script_name;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root/:/tmp/:/proc/";
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort on;
fastcgi_read_timeout 180;
}
location / {
#定义首页索引文件的名称
index index.php index.html index.htm;
#下面这行和后面的跟wordpress有关,非wp程序用不到
try_files $uri $uri/ /index.php?$args;
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
}
站点相关的目录创建、用户设置等内容:
useradd www.tingtao.org -s /sbin/nologin || exit 1 echo www.tingtao.org:密码|chpasswd groupadd -f www.tingtao.org usermod -G www.tingtao.org -a www-data usermod -G www.tingtao.org -a proftpd mkdir /var/www/www.tingtao.org usermod -d /var/www/www.tingtao.org www.tingtao.org chown -R www.tingtao.org:www.tingtao.org /var/www/www.tingtao.org chmod -R 755 /var/www/www.tingtao.org
www.tingtao.org这个用户我放进两个组里面,一个是跟web服务器相关的,一个是跟ftp相关的,这样会方便许多。
为这个站点搞一个独立的php配置:
cat > /etc/php5/fpm/pool.d/www.tingtao.org.conf <<- _EOF1_ [www.tingtao.org] user = www.tingtao.org group = www.tingtao.org listen = /var/run/php5-fpm-www.tingtao.org.sock listen.owner = www-data listen.group = www-data php_admin_value[include_path] = .:/var/www/globals/www.3ha.net/lib php_admin_value[open_basedir] = /var/www/www.tingtao.org:/tmp php_admin_value[upload_max_filesize] = 50M php_admin_value[max_execution_time] = 30 php_admin_value[max_input_time] = 60 php_admin_value[memory_limit] = 128M php_admin_value[output_buffering] = 4096 php_admin_value[disable_functions] = 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 php_admin_flag[allow_url_fopen] = off php_admin_flag[expose_php] = Off php_admin_flag[display_errors] = Off pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 chdir = / _EOF1_
简单解释一下。listen与nginx站点配置中的fastcgi_pass相对应,否则连不上的。listen的组和用户与nginx相同,如此方能确保不会受到权限阻碍。该站点的php永远运行在该站点自身账号权限下,这样上传什么的不会有阻碍,同时每个站点搞这么一个独立的php环境,也不会影响其他站点的安全性和稳定性。
最后,重启一下php-fpm和nginx即可:
/etc/init.d/php-fpm restart /etc/init.d/nginx restart
如此这般呢,可以确认的是,首先通过ftp上传的文件是属于www.tingtao.org的,然后站点运行的身份也是这个用户,那么对于几乎所有php程序来说都不存在权限方面的问题,同时确保安全性。
确认一下是否符合预期:

可以看到,这个php-fpm的运行身份确实是该站点账户,那么基于文件系统的acl则会阻挡非法的跨目录权限,关于这一点我没测试,我认为也不必测试,但需要注意的是,其实上面的755权限不太适合出售空间的情况,如果你提供虚拟空间给别人的话,应该用750好些。
然后呢,这个方案可以很简单的实现php多版本,在我这没必要,各位需要的话略微修改就可以了。
就个人观察的情况来说,在我这两颗至强,4G内存,SSD硬盘加上200M独享带宽的服务器环境上,不知道是不是错觉,总感觉响应速度和apache+php没啥区别;内存占用方面,php-fpm似乎还高于apache的fcgid,确实有点不理解……
按照经验来推测的话,在低配服务器上的效果应该会强于lamp的。
