之前我对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的。