There are many articles on Security Configuration of independent sites for nginx + fastcgi + php virtual hosts on the Internet.
This article describes the directory permission control of Nginx + PHP virtual hosts in detail. There are many methods, including setting special directories and preparing independent sites and directories through open_basedir. You can also write all the site directories in open_basedir. However, no special directory name is used for the site. Others do not know the directory. You cannot go in. Modify the php source code, add the root_path restriction, and access the directory.
So I am writing this article and don't want to worry about limiting it to a directory. What I want to talk about is :,
1. php. ini Security Configuration
2. How to implement flexible configuration by starting multiple php-cgi
3. How to control the distribution of nginx fastcgi_pass to different fastcgi
If you are clear about this, skip the following.
1. php. ini Security Configuration
Preparation Project |
Description |
Allow_url_fopen = Off Allow_url_include = Off |
Disable remote inclusion |
Register_globals = Off |
Disable Automatic Registration of global variables |
Open_basedir = "\ tmp :" |
Restrict the path of the Operation file (specific path of the specific site) |
Safe_mode = Off Safe_mode_gid = Off |
Disable safe Mode |
Max_execution_time = 30 Max_input_time = 60 |
Restrict script execution time (avoid time consumption limit statement) |
Memory_limit = 32 M Upload_max_filesize = 5 M Post_max_size = 8 M Max_input_nesting_levels = 64 |
Limited Memory and file size |
Display_errors = Off Log_errors = On Error_log = "/var/log/nginx/phperror. log" |
Security error preparation |
Fastcgi. logging = 0 Cgi. fix_pathinfo = 0 |
Disable fastcgi pathinfo The recent nginx vulnerability is found here |
Expose_php = Off |
Hide php version information |
Enable_dl = Off |
Disable dl Parameters |
Disable_functions = phpinfo, exec, passthru, shell_exec, system, proc_open, Popen, curl_exec, curl_multi_exec, parse_ini_file, show_source |
Disable malicious function execution |
I am not going to talk about the above. For the parameter meanings, see the php manual.
2. fastcgi Startup Script
A. Create an independent user for each site, which belongs to the same group
[Root @ localhost ~] # Groupadd webuser
[Root @ localhost ~] # Useradd-M-G webuser-s/sbin/nologin web-a.com
B. Create a common fastcgi Startup Script
[Root @ www] # egrep-v '#. * | ^ $' php-cgi.sh
./Etc/rc. d/init. d/functions
SPAWNFCGI = "/usr/local/bin/spawn-fcgi"
FCGIPROGRAM = "/usr/bin/php-cgi"
FCGIPROGRAM2 = "$ FCGIPROGRAM $ CGI_OPTIONS"
PHP_FCGI_MAX_REQUESTS = 500
FCGI_WEB_SERVER_ADDRS = "127.0.0.1"
ALLOWED_ENV = "shell path user"
If test x $ PHP_FCGI_CHILDREN = x; then
PHP_FCGI_CHILDREN = 5
Fi
Prog = "$ {tmpfile %. *}-fcgi"
FCGI_SOCKET = "/tmp/$ prog. sock"
FCGI_PIDFILE = "/var/run/$ prog. pid"
FCGI_LOCKFILE = "/var/lock/subsys/$ prog"
Export PHP_FCGI_MAX_REQUESTS
Export FCGI_WEB_SERVER_ADDRS
ALLOWED_ENV = "$ ALLOWED_ENV PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS"
If test x $ UID = x0; then
EX = "$ SPAWNFCGI-s $ FCGI_SOCKET-f \" $ FCGIPROGRAM2 \ "-u $ USERID-g $ GROUPID-C $ PHP_FCGI_CHILDREN-P $ FCGI_PIDFILE"
Else
EX = "$ SPAWNFCGI-s $ FCGI_SOCKET-f \" $ FCGIPROGRAM2 \ "-C $ PHP_FCGI_CHILDREN-P $ FCGI_PIDFILE"
Fi
E =
For I in $ ALLOWED_ENV; do
E = "$ E $ I =$ {! I }"
Done
RETVAL = 0
Status (){
Local pid
Echo $ "Usage: status {program }"
Return 1
Fi
Pid = 'pgrep $ base-u $ USERID | sed's/\ n/\ t/g''
If [-n "$ pid"]; then
Echo $ "$ {prog} (pid $ pid) is running ..."
Return 0
Fi
If [-f $ FCGI_PIDFILE]; then
Read pid <$ FCGI_PIDFILE
If [-n "$ pid"]; then
Echo $ "$ {prog} dead but pid file exists"
Return 1
Fi
Fi
If [-f $ FCGI_LOCKFILE]; then
Echo $ "$ {prog} dead but subsys locked"
Return 2
Fi
Echo $ "$ {prog} is stopped"
Return 3
}
Start (){
Echo-n $ "Starting $ prog :"
Daemon env-$ E $ EX
Chmod 777 $ FCGI_SOCKET
RETVAL =$?
Echo
[$ RETVAL-eq 0] & touch $ FCGI_LOCKFILE
Return $ RETVAL
}
Stop (){
Echo-n $ "Stopping $ prog :"
Rm-f $ FCGI_PIDFILE $ FCGI_SOCKET
RETVAL =$?
["$ RETVAL"-eq 0] & success "startup" | failure "startup"
Echo
[$ RETVAL-eq 0] & rm-f $ FCGI_LOCKFILE
Return $ RETVAL
}
Case "$1" in
Start)
Start
;;
Stop)
Stop
;;
Restart)
Stop
Start
;;
Condrestart)
If [-f $ FCGI_LOCKFILE]; then
Stop
Start
Fi
;;
Status)
Status $ FCGIPROGRAM
RETVAL =$?
;;
*)
Echo $ "Usage: $0 {start | stop | restart | condrestart | status }"
RETVAL = 1
Esac
Exit $ RETVAL
The above script is transformed from an online script. It is mainly modified. When it is restarted or stopped, all sites are actually stopped by php-cgi. This does not conform to the independent management principles of independent virtual hosts.
C. Independent site Startup Script
Web-chaohao.com universal include script:
[Root @ www] # egrep-v '#. * | ^ $' www.a.com. sh
Export PATH =/usr/bin:/usr/local/bin:/usr/X11R6/bin;
Export LANG = zh_CN.GB2312;
# Number of startup php-cgi threads
PHP_FCGI_CHILDREN = 30;
# Start an account
USERID = web-a.com;
# Start a group
GROUPID = webuser;
CGI_OPTIONS = "-d open_basedir =/home/www/a/:/tmp/-C ";
TMPPATH = 'dirname $0 ';
. $ TMPPATH/php-cgi.sh;
From the script above it should be seen that this is a script for each site, then the script, containing the general script php-cgi.sh
Www.a.com. sh contains a CGI_OPTIONS configuration option to control the sites allowed by open_basedir. Of course, you can also configure other php. ini key = value parameters.
It is worth noting that:
I. Multiple-d parameters can be used for configuration. -D open_basedir =/tmp-d display_errors = on will overwrite the configuration in php. ini. It's easy.
Ii. It is strange that when php-v version is: 5.1.6 does not seem to work, it will take effect after upgrade to 5.2.6. If the settings after php-cgi-d do not take effect, check your php version.
Iii. php-cgi.sh and Site Script www.a.com. sh put in the same directory.
D. Start the site
Chmod + x www.a.com. sh
./Www.a.com. sh
Usage:./www.chaohao.com. sh {start | stop | restart | condrestart | status}
It can contain parameters.
./Www.a.com. sh start
Starting www.a.com-fcgi: [OK]
Ps aux | grep php-cgi
The script has been started.
0.2 0.1 82040 7692? Ss/usr/bin/php-cgi-d open_basedir =/home/www/html/www.a.com/:/tmp/-C
................
E. Script Parsing
The above script will be automatically created
/Var/run/script file name-fcgi. pid
/Tmp/script file name-fcgi. sock
File. If the execution script is www.a.com. sh
The created file corresponds to/var/run/www.a.com-fcgi. pid and/tmp/www.a.com-fcgi. sock.
It is recommended that the site name be consistent with the user name and Script Name. If your website is www. B .com
Set useradd to web-b.com
Set the shell script to B .com. sh.
3. nginx sever preparation
[Root @ web49 nginx] # egrep-v '#. * | ^ $'/etc/nginx/host/webhost. conf
Server {
Listen 8888;
# Bind a domain name
Server_name www.a.com www. B .com;
Access_log/var/log/nginx/chaohao. access. log main;
Error_log/var/log/nginx/chaohao. error. log;
Index. php index.shtml;
Set $ test_host www.chaohao.com;
Set $ Root_Path/home/www/html/$ test_host;
Root $ Root_Path/html;
Set $ sock_file www.chaohao.com-fcgi. sock;
If ($ host ~ * Www.a.com | www. B .com)
{
Set $ sock_file www.a.com-fcgi. sock;
}
Set $ sock_file unix:/tmp/$ sock_file;
Location ~ \. Php $ {
Include/etc/nginx/fastcgi_params;
Fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
Fastcgi_param Root_Path $ Root_Path;
Fastcgi_param Root_HTML $ document_root;
Fastcgi_index index. php;
Fastcgi_pass $ sock_file;
}
}
If the domain name and site are well designed, you can directly read the variables in $ host as the fastcgi_pass parameter.
Note:
If fastcgi_pass does not support variables, you must note that. This may be related to your nginx version.
The test showed that fastcgi_pass nginx 0.639 does not support variable usage. Later, 0.7.65 was used to support variable usage.