[12] LNMP架构
12.1 LNMP架构介绍
Linux 7.0+Nginx 1.1+Mysql 5.6+php 5.6
LNMP特性
LAMP不同的是,提供web服务的是Nginx
php是作为一个独立服务存在的,这个服务叫做php-fpm
- Nginx直接处理静态请求,动态请求会转发给php-fpm
12.2 Mysql安装
将下载好的免编译二进制包放在/usr/local/src下
点此下载Mysql5.6.35源码包
点此下载Mysql5.6.35二进制包
- 解压免编译二进制包
[root@localhost src]# tar -zxvf mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz
[root@localhost src]# mv mysql-5.6.35-linux-glibc2.5-x86_64 /usr/local/mysql
- 创建mysql用户,并创建存储路径
[root@localhost mysql]# useradd -s /sbin/nologin -M mysql
[root@localhost mysql]# mkdir -p /data/mysql
- 初始化数据库
[root@localhost mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql
- 拷贝模板配置文件和启动脚本
[root@localhost mysql]# cp support-files/my-default.cnf /etc/my.cnf
[root@localhost mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@localhost mysql]# vim /etc/init.d/mysqld
定义/etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/data/mysql
[root@localhost mysql]# /etc/init.d/mysqld start
[root@localhost mysql]# chkconfig --add mysqld
[root@localhost mysql]# chkconfig mysqld on
12.3 PHP安装
LAMP安装PHP方法有差别,需要开启php-fpm服务,php作为单独的服务
1.解压源码包
[root@localhost ~ ]# cd /usr/local/src/
[root@localhost src]# tar zxvf php-5.6.30.tar.gz
添加php用户
[root@localhost src]# useradd -s /sbin/nologin -M php-fpm
2.编译安装php5.6.30
首次安装php需要安装以下包:
yum install -y libxml2-devl openssl-devel bzip2-devel libjpeg-devel freetype-devel epel-release libmcrypt-devel libpng-devel
[root@localhost src]# cd php-5.6.30/
[root@localhost src]# yum install -y libxml2-devel openssl-devel bzip2-devel libjpeg-devel freetype-devel epel-release libmcrypt-devel libpng-devel
[root@localhost php-5.6.30]# ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl --with-openssl
[root@localhost php-5.6.30]# make && make install
3.查看php加载的模块和PHP信息等信息
[root@localhost php-5.6.30]# cd /usr/local/php-fpm/
查看php加载的模块
[root@localhost php-fpm]# sbin/php-fpm -m
查看php相关信息
[root@localhost php-fpm]# sbin/php-fpm -i
测试配置文件语法
[root@localhost php-fpm]# sbin/php-fpm -t
4.配置php服务
拷贝配置文件
[root@localhost php-fpm]# cp /usr/local/src/php-5.6.30/php.ini-production /usr/local/php-fpm/etc/php.ini
[root@localhost php-fpm]# vim /usr/local/php-fpm/etc/php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
拷贝启动脚本
[root@localhost php-fpm]# cp /usr/local/src/php-5.6.30/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
更改启动脚本权限
[root@localhost php-fpm]# chmod 755 /etc/init.d/php-fpm
添加服务和开机启动
[root@localhost php-fpm]# chkconfig --add php-fpm
[root@localhost php-fpm]# chkconfig php-fpm on
5.检测配置文件是否有误
[root@localhost php-fpm]# /usr/local/php-fpm/sbin/php-fpm -t
[09-Aug-2017 23:46:51] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
6.启动php
[root@localhost php-fpm]# service php-fpm start
Starting php-fpm done
[root@localhost php-fpm]# ps aux |grep php
12.4 Nginx介绍
- Nginx应用场景
web服务、反向代理、负载均衡
- Nginx 著名分支
淘宝基于Nginx开发的Tengine,使用上和Nginx一致,服务名,配置文件名都一样,和Nginx的最大区别在于Tenging增加了一些定制化模块,在安全限速方面表现突出,另外它支持对js,css合并
Nginx核心+lua相关的组件和模块组成了一个支持lua的高性能web容器openresty
- 扩展
12.5 Nginx安装
1.下载源码包
[root@localhost src]# wget http://nginx.org/download/nginx-1.12.1.tar.gz
[root@localhost src]# tar zxvf nginx-1.12.1.tar.gz
[root@localhost src]# cd nginx-1.12.1/
2.编译源码包
此处为最基础的编译,没有编译ssl等模块
[root@localhost nginx-1.12.1]# ./configure --prefix=/usr/local/nginx
[root@localhost nginx-1.12.1]# make && make install
3.查看配置文件是否有误
[root@localhost nginx-1.12.1]# cd /usr/local/nginx/
查看配置文件配置文件是否有误
[root@localhost nginx]# sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
4.创建启动脚本
[root@localhost nginx]# vim /etc/init.d/nginx
脚本内容为
#!/bin/bash
# chkconfig: - 30 21
# description: http service.
# Source Function Library
. /etc/init.d/functions
# Nginx Settings
NGINX_SBIN="/usr/local/nginx/sbin/nginx"
NGINX_CONF="/usr/local/nginx/conf/nginx.conf"
NGINX_PID="/usr/local/nginx/logs/nginx.pid"
RETVAL=0
prog="Nginx"
start()
{
echo -n $"Starting $prog: "
mkdir -p /dev/shm/nginx_temp
daemon $NGINX_SBIN -c $NGINX_CONF
RETVAL=$?
echo
return $RETVAL
}
stop()
{
echo -n $"Stopping $prog: "
killproc -p $NGINX_PID $NGINX_SBIN -TERM
rm -rf /dev/shm/nginx_temp
RETVAL=$?
echo
return $RETVAL
}
reload()
{
echo -n $"Reloading $prog: "
killproc -p $NGINX_PID $NGINX_SBIN -HUP
RETVAL=$?
echo
return $RETVAL
}
restart()
{
stop
start
}
configtest()
{
$NGINX_SBIN -c $NGINX_CONF -t
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
restart
;;
configtest)
configtest
;;
*)
echo $"Usage: $0 {start|stop|reload|restart|configtest}"
RETVAL=1
esac
exit $RETVAL
更改启动脚本权限
[root@localhost nginx]# chmod 755 /etc/init.d/nginx
添加开机启动
[root@localhost nginx]# chkconfig --add nginx
[root@localhost nginx]# chkconfig nginx on
5.新增配置文件
配置文件配置详解
[root@localhost nginx]# cd conf/
[root@localhost conf]# mv nginx.conf nginx.conf.bak
[root@localhost conf]# vim nginx.conf
配置文件内容
user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 6000;
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 3526;
server_names_hash_max_size 4096;
log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
' $host "$request_uri" $status'
' "$http_referer" "$http_user_agent"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 8 4k;
request_pool_size 4k;
output_buffers 4 32k;
postpone_output 1460;
client_max_body_size 10m;
client_body_buffer_size 256k;
client_body_temp_path /usr/local/nginx/client_body_temp;
proxy_temp_path /usr/local/nginx/proxy_temp;
fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
fastcgi_intercept_errors on;
tcp_nodelay on;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_comp_level 5;
gzip_http_version 1.1;
gzip_types text/plain application/x-javascript text/css text/htm
application/xml;
server
{
listen 80;
server_name localhost;
index index.html index.htm index.php;
root /usr/local/nginx/html;
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
}
}
}
上面配置文件server类似于apache中的虚拟主机,每一个server对应一个虚拟主机。
检查配置文件是否有误
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
6.启动Nginx服务
[root@localhost ~]# /etc/init.d/nginx start
Starting nginx (via systemctl): [ 确定 ]
[root@localhost ~]# ps aux |grep nginx
root 1062 1.2 0.0 20484 624 ? Ss 10:49 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody 1063 17.2 0.1 25012 3508 ? S 10:49 0:03 nginx: worker process
nobody 1064 18.8 0.1 25012 3248 ? S 10:49 0:03 nginx: worker process
root 1071 0.0 0.0 112664 972 pts/2 S+ 10:50 0:00 grep --color=auto nginx
root 128059 0.0 0.2 151528 5360 pts/0 S+ 09:40 0:00 vim nginx.conf
当服务已经启动后,更改配置文件可以选择重新加载
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
reload和重启nginx区别:
当配置文件有误时,reload不会生效错误的配置文件,以前的服务正常运但是重启服务,会加载错误的配置文件会导致服务不可用。
7.测试Nginx页面
[root@localhost ~]# curl 192.168.1.11
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
测试解析php
[root@localhost nginx]# vim html/index.php
<?php
echo phpinfo();
[root@localhost ~]# curl 127.0.0.1/index.php
12.6 Nginx设置默认虚拟主机
设置虚拟主机除了有以上在nginx.conf中添加server字段外,还有一种方式,那就是在nginx.conf指定虚拟主机目录
- 修改nginx.conf配置文件
删除之前的server字段定义的主机信息,添加一行如下信息:
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
include vhost/*.conf;
- 创建虚拟主机配置存放路径
由于上面nginx.conf中定义的虚拟主机配置路径为nginx/conf/vhost/,所以我们要创建相应的目录
[root@localhost ~]# mkdir /usr/local/nginx/conf/vhost
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/temence.com
server
{
listen 80 default_server;
server_name aaa.com;
index index.html index.htm index.php;
root /data/www/nginx.page/;
}
- 创建虚拟主机登陆页
[root@localhost ~]# mkdir -p /data/www/nginx.page
[root@localhost ~]# vim /data/www/nginx.page/index.php
<?php
echo phpinfo();
?>
- 验证虚拟主机
[root@localhost ~]# curl -x192.168.1.11:80 temence.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 07:31:50 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sat, 12 Aug 2017 01:19:29 GMT
Connection: keep-alive
ETag: "598e57a1-264"
Accept-Ranges: bytes
TIPS
设置默认虚拟主机有两种方式:
1. 在虚拟主机配置文件中,将需要设为默认主机的虚拟主机配置文件设为0或者a开头的文件名。这样每次访问默认虚拟主机配置文件就会第一个访问该配置文件
2. 在虚拟主机配置文件listen 80后面加default_server; ,该字段就是将该虚拟主机设为默认虚拟主机
12.7 Nginx用户认证
- 创建测试主机test.com
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/test.com
添加虚拟主机页面
[root@localhost ~]# mkdir /data/www/test.com
[root@localhost ~]# echo "test.com" > /data/www/test.com/index.html
1.针对全站做用户认证
server
{
listen 80;
server_name test.com;
index index.html index.htm index.php;
root /data/www/test.com;
location /
{
auth_basic "Auth";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
}
2.针对某个目录做用户认证
server
{
listen 80;
server_name test.com;
index index.html index.htm index.php;
root /data/www/test.com;
location admin/
{
auth_basic "Auth";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
}
3.针对某个文件做用户认证
server
{
listen 80;
server_name test.com;
index index.html index.htm index.php;
root /data/www/test.com;
location ~ admin.php
{
auth_basic "Auth";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
}
- 使用htpasswd生成密码
如果设备上未安装apache,则需要yum安装httpd才能使用htpasswd。
[root@localhost ~]# htpasswd -c /usr/local/nginx/conf/htpasswd temence
首次使用htpassws需要使用-c参数创建密码存放文件,下次再创建密码就不需-c参数。
- 检查配置文件重新加载服务
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
- 验证用户验证是否生效
[root@localhost vhost]# curl -x 192.168.1.11:80 test.com -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 12:16:33 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Auth"
[root@localhost vhost]# curl -u temence:000000 -x 192.168.1.11:80 test.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 12:16:55 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Sat, 12 Aug 2017 08:20:39 GMT
Connection: keep-alive
ETag: "598eba57-9"
Accept-Ranges: bytes
12.8Nginx域名重定向
- 更改虚拟主机配置文件nginx/conf/test.com.conf
server
{
listen 80;
server_name test.com test1.com test2.com;
index index.html index.htm index.php;
root /data/www/test.com;
if ($host != 'test.com' ) {
rewrite ^/(.*)$ http://test.com/$1 permanent;
}
}
server_name后面支持多个域名,apache server_name不支该多个域名。
permanent为永久重定向,状态码为301,如果写redirect则为302
- 测试域名跳转
[root@localhost vhost]# curl -x 192.168.1.11:80 test.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 13:15:04 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Sat, 12 Aug 2017 08:20:39 GMT
Connection: keep-alive
ETag: "598eba57-9"
Accept-Ranges: bytes
[root@localhost vhost]# curl -x 192.168.1.11:80 test2.com -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 13:15:09 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://test.com/
12.9 Nginx访问日志
vim /usr/local/nginx/conf/nginx.conf //搜索log_format
- 常用日志字段
字段 | 释义 |
---|---|
remote_addr | 客户端IP(公网IP) |
$http_x_forwarded_for | 代理服务器的IP |
$time_local | 服务器本地时间 |
$host | 访问主机名(域名) |
$request_uri | 访问的url地址 |
$status | 状态码 |
$http_referer | referer |
$http_user_agent | user_agent |
- 日志配置
主配置文件nginx.conf里定义日志格式,然后虚拟配置文件中引用定义的日志格式:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
log_format tes.com.logformat'$remote_addr$http_x_forwarded_for [$time_local]'' $host "$request_uri" $status'' "$http_referer" "$http_user_agent"';
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/test.com.conf
access_log /tmp/test.com.log test.com.logformat
其中虚拟配置文件中定义的日志格式要为主配置文件中定义的日志格式名称,这里指定的日志格式为test.com.logformat
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
- 验证日志是否记录
[root@localhost ~]# curl -x 192.168.1.11:80 test.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 13:52:20 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Sat, 12 Aug 2017 08:20:39 GMT
Connection: keep-alive
ETag: "598eba57-9"
Accept-Ranges: bytes
[root@localhost ~]# curl -x 192.168.1.11:80 test2.com -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.1
Date: Sat, 12 Aug 2017 13:52:28 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://test.com/
[root@localhost ~]# cat /tmp/test.com.log
192.168.1.11 - [12/Aug/2017:21:52:20 +0800] test.com "/" 200 "-" "curl/7.29.0"
192.168.1.11 - [12/Aug/2017:21:52:28 +0800] test2.com "/" 301 "-" "curl/7.29.0"
12.10 Nginx日志切割
nginx并没有自带的日志切割工具,需要借助系统的切割工具或者自定义shell脚本
- 自定义shell脚本
#! /bin/bash
## 假设nginx的日志存放路径为/tmp/
d=`date -d "-1 day" +%Y%m%d` #切割日志时获取前一天的时间
logdir="/tmp"
nginx_pid="/usr/local/nginx/logs/nginx.pid"
cd $logdir
for log in `ls *.log`
do
mv $log $log-$d
done
/bin/kill -HUP `cat $nginx_pid`
- 添加任务计划
0 0 * * * /bin/bash /usr/local/sbin/nginx_log_rotate.sh
[root@localhost ~]# sh -x /usr/local/nginx/conf/nginx_log_rotate.sh
12.11 静态文件不记录日志和过期时间
- 虚拟主机配置文件添加配置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 7d;
access_log off;
}
location ~ .*\.(js|css)$
{
expires 12h;
access_log off;
}
- 检查和加载配置文件
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
12.12 nginx防盗链
- 修改虚拟主机配置
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/test.com.conf
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$
{
expires 7d;
valid_referers none blocked server_names *.test.com ;
if ($invalid_referer) {
return 403;
}
access_log off;
}
location后面定义了匹配以gif等结尾的文件
expires 定义过期时间
valid_referers none blocked server_names 定义白名单
if ($invalid_referer) {return 403;} 如果不匹配白名单中的referer则拒绝访问
~*
- 验证防盗链
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# curl -e"http://www.baidu.com/1.txt" -x192.168.1.11:80 test.com/1.gif -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 14:46:57 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
[root@localhost ~]# curl -x192.168.1.11:80 test.com/1.gif -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 14:47:25 GMT
Content-Type: image/gif
Content-Length: 0
Last-Modified: Mon, 14 Aug 2017 14:47:23 GMT
Connection: keep-alive
ETag: "5991b7fb-0"
Expires: Mon, 21 Aug 2017 14:47:25 GMT
Cache-Control: max-age=604800
Accept-Ranges: bytes
12.13 Nginx访问控制
站点目录下一些文件不希望别人访问,可以使用用户认证去控制访问,但不能完全做到拒绝访问。此时,我们就需要使用Nginx访问控制。
- 配置目录访问控制
需求:访问/admin/目录的请求,只允许某几个IP访问
location /admin/
{
allow 192.168.1.11;
allow 127.0.0.1;
deny all;
}
Nginx和apache匹配有所不同,Nginx先匹配,当匹配到条件时,后面再匹配到该条件则忽略。apache则是以最后一次匹配规则为准
- 验证目录访问控制
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# curl -x127.0.0.1:80 test.com/admin -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:16:04 GMT
Content-Type: text/html
Content-Length: 185
Location: http://test.com/admin/
Connection: keep-alive
[root@localhost ~]# curl -x192.168.1.11:80 test.com/admin -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:16:19 GMT
Content-Type: text/html
Content-Length: 185
Location: http://test.com/admin/
Connection: keep-alive
[root@localhost ~]# curl -x192.168.79.128:80 test.com/admin/ -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:15:31 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
- 配置匹配正则访问控制
1. 匹配正则,禁止upload和image目录下PHP文件访问解析
location ~ .*(upload|image)/.*\.php$
{
deny all;
}
2. 根据user_agent限制
if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato')
{
return 403;
}
deny all和return 403效果一样
- 验证匹配正则访问控制
1.
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# mkdir /data/www/test.com/upload
[root@localhost ~]# echo "test.com/upload/1.php" /data/www/test.com/upload/1.php
test.com/upload/1.php /data/www/test.com/upload/1.php
[root@localhost ~]# echo "test.com/upload/1.txt" /data/www/test.com/upload/1.txt
[root@localhost ~]# echo "test.com/upload/1.php" /data/www/test.com/upload/1.php
test.com/upload/1.php /data/www/test.com/upload/1.php
[root@localhost ~]# echo "test.com/upload/1.txt" /data/www/test.com/upload/1.txt
test.com/upload/1.txt /data/www/test.com/upload/1.txt
[root@localhost ~]# curl -x192.168.1.11:80 test.com/upload/1.txt -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:35:21 GMT
Content-Type: text/plain
Content-Length: 0
Last-Modified: Mon, 14 Aug 2017 15:35:08 GMT
Connection: keep-alive
ETag: "5991c32c-0"
Accept-Ranges: bytes
[root@localhost ~]# curl -x192.168.1.11:80 test.com/upload/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:35:27 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
-----------------------------------------
2.
[root@localhost ~]# curl -A "Tomato" -x192.168.1.11:80 test.com -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:37:35 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
[root@localhost ~]# curl -A "test_user_agent" -x192.168.1.11:80 test.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 14 Aug 2017 15:38:06 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Sat, 12 Aug 2017 08:20:39 GMT
Connection: keep-alive
ETag: "598eba57-9"
Accept-Ranges: bytes
12.14 Nginx解析php相关配置
- 修改配置文件
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /data/wwwroot/test.com$fastcgi_script_name;
}
fastcgi_pass 指定Nginx的sock文件路径,可以查看/usr/local/php-fpm/etc/php-fpm.conf中定义的sock文件路径。sock指定错误,会显示502的错误。这里也可以指定ip和端口的形式监听,主要看/usr/local/php-fpm/etc/php-fpm.conf中定义的事sock还是IP/端口。
另外一种502的错误为sock文件权限定义不够,在/usr/local/php-fpm/etc/php-fpm.conf中有一个字段listen.mod = 666,这是定义上面sock文件的权限,因为nginx在调用sock文件时是以nobody用户运行,所以需要可读可写的权限,否则同样会出现502错误。
报错时记得查看nginx错误日志:/usr/local/nginx/logs/nginx_error.log 在nginx主配置文件中定义
12.15 Nginx代理
- 理解正反向代理
正向代理与反向代理
(1).正向代理的概念
正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。
结论就是,正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
(2).反向代理的概念
举例:
例用户访问 http://www.test.com/readme,但www.test.com上并不存在readme页面,他是偷偷从另外一台服务器上取回来,然后作为自己的内容返回用户,但用户并不知情。这里所提到的 www.test.com 这个域名对应的服务器就设置了反向代理功能。
结论就是,反向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。
(3).两者区别
从用途上来讲:
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。
从安全性来讲:
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
- 配置代理
server
{
listen 80;
server_name Nginx主机域名;
location /
{
proxy_pass http://121.201.9.155/(需要代理的服务器域名);
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
12.16 Nginx负载均衡
代理一台服务器为代理,当代理多带服务器时可以理解为负载均衡
负载均衡实现流程
使用dig解析域名ip
[root@localhost ~]# yum install bind-utils
[root@localhost ~]# dig qq.com
- 配置负载均衡配置文件
upstream qq_com ##upstream模块的名字,可以自定
{
ip_hash;
server 61.135.157.156:80; #需要代理的远端web服务器域名
server 125.39.240.113:80; #需要代理的远端web服务器域名
}
server
{
listen 80;
server_name Nginx主机域名;
location /
{
proxy_pass http://qq(这里指定upstream模块的名字);
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
12.17 SSl原理
- 浏览器发送一个https的请求给服务器;
- 服务器要有一套数字证书,可以自己制作也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥;
- 服务器会把公钥传输给客户端;
- 客户端(浏览器)收到公钥后,会验证其是否合法有效,无效会有警告提醒,有效则会生成一串随机数,并用收到的公钥加密;
- 客户端把加密后的随机字符串传输给服务器;
- 服务器收到加密随机字符串后,先用私钥解密(公钥加密,私钥解密),获取到这一串随机数后,再用这串随机字符串加密传输的数据(该加密为对称加密,所谓对称加密,就是将数据和私钥也就是这个随机字符串通过某种算法混合在一起,这样除非知道私钥,否则无法获取数据内容);
- 服务器把加密后的数据传输给客户端;
- 客户端收到数据后,再用自己的私钥也就是那个随机字符串解密;
12.18 生产ssl密钥对
- 借用openssl工具生成密钥对
[root@localhost ~]# yum install -y openssl
[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# openssl genrsa -des3 -out test.key 2048
这一步必须指定test私钥的密码,可以用下面一条命令转换私钥取消密码
[root@localhost conf]# openssl rsa -in test.key -out test.com.key
in指定需要转换的密钥,out指定转换后的密钥
[root@localhost conf]# rm -fr test.key
删除之前旧的密钥
[root@localhost conf]# openssl req -new -key test.com.key -out test.com.csr
生成证书请求文件,需要拿这个文件和私钥一起生产公钥文件。请求文件中包含国家地区、公司名称等相关信息。
[root@localhost conf]# openssl x509 -req -days 365 -in test.com.csr -signkey test.com.key -out test.com.crt
输入私钥和请求文件,生成crt的公钥。
12.19 Nginx配置SSL
- 新建ssl的虚拟主机配置文件
[root@localhost conf]# vim /usr/local/nginx/conf/vhost/ssl.conf
添加以下内容
server
{
listen 443;
server_name testssl.com;
index index.html index.php;
root /data/www/testssl.com;
ssl on;
ssl_certificate test.com.crt;
ssl_certificate_key test.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
[root@localhost conf]# mkdir /data/www/testssl.com
[root@localhost conf]# echo "this is ssl" > /data/www/testssl.com/index.html
- 检查配置文件,重新加载nginx服务
[root@localhost conf]# /usr/local/nginx/sbin/nginx -t
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
此时出现一个报错信息,无法识别ssl配置,因为在编译nginx时未指定ssl模块。需要重新编译nginx
[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.12.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
configure arguments: --prefix=/usr/local/nginx
[root@localhost ~]# cd /usr/local/src/nginx-1.12.1/
[root@localhost nginx-1.12.1]# ./configure --help|grep ssl
[root@localhost nginx-1.12.1]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module
[root@localhost nginx-1.12.1]# make && make install
重新编译nginx,添加对ssl模块支持
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
[root@localhost ~]# /etc/init.d/nginx restart
[root@localhost ~]# netstat -lntp
再次插卡配置是否有误,然后重启nginx服务,并查看443端口是否打开
[root@localhost ~]# iptables -F
清除防火墙规则
- 验证ssl
浏览器输入url:https://192.168.1.11
12.20 php-fpm的pool
使用ps aux查看pool相关进程时,右侧会显示php fpm 的pool。一个pool里可以加载多个站点,但是有一个问题,当一个pool中php进程耗尽时,会影响到pool中的其他网站502错误。此时我们就需要将每个站点加载的pool单独隔离开,在/usr/local/php-fpm/etc/php-fpm.conf
- 修改php-fpm配置文件
在[global]部分增加
include = etc/php-fpm.d/*.conf
[root@localhost ~]# mkdir /usr/local/php-fpm/etc/php-fpm.d/
[root@localhost ~]# cd /usr/local/php-fpm/etc/php-fpm.d/
[root@localhost php-fpm.d]# vim www.conf
[www]
listen = /tmp/www.sock
listen.mode=666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
[root@localhost php-fpm.d]# vim test.com.conf
[test.com]
listen = /tmp/test.com.sock
listen.mode=666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
其中监听的sock需要根据实际sock位置来定义目录
- 检查配置文件是否有误
[root@localhost php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[root@localhost php-fpm.d]# /etc/init.d/php-fpm restart
12.21 php-fpm慢执行日志
- 配置慢执行日志
[root@localhost php-fpm.d]# vim /usr/local/php-fpm/etc/php-fpm.d/test.com.conf
添加如下内容:
request_slowlog_timeout = 2
slowlog = /usr/local/php-fpm/var/log/www-slow.log
- 检查配置文件是否有误
[root@localhost php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm –t
[root@localhost php-fpm.d]# /etc/init.d/php-fpm restart
[root@localhost php-fpm.d]# cat /usr/local/php-fpm/var/log/www-slow.log
12.22 open_basedir
将用户访问文件的活动范围限制在指定的区域,通常是其家目录的路径,也
可用符号”.”来代表当前目录。注意用open_basedir指定的限制实际上是前缀,而不是目录名。
举例来说: 若”open_basedir = /dir/user”, 那么目录 “/dir/user” 和 “/dir/user1”都是
可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。例如设置成:
“open_basedir = /dir/user/”
当PHP定义多个站点配置文件时,需要在每个站点配置文件中分别添加
- 配置php-fpm配置文件,添加限制目录
[root@localhost php-fpm.d]# vim /usr/local/php-fpm/etc/php-fpm.d/test.com.conf
php_admin_value[open_basedir]=/data/wwwr/test.com:/tmp/
- 测试配置文件
[root@localhost php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[root@localhost php-fpm.d]# /etc/init.d/php-fpm restart
12.23 php-fpm进程管理
- php-fpm配置文件
配置文件主要有以下几点涉及到php-fpm进程
pm = dynamic //动态进程管理,也可以是static
pm.max_children = 50 //最大子进程数,ps aux可以查看
pm.start_servers = 20 //启动服务时会启动的进程数
pm.min_spare_servers = 5 //定义在空闲时段,子进程数的最少数量,如果达到这个数值时,php-fpm服务会自动派生新的子进程。
pm.max_spare_servers = 35 //定义在空闲时段,子进程数的最大值,如果高于这个数值就开始清理空闲的子进程。
pm.max_requests = 500 //定义一个子进程最多处理的请求数,也就是说在一个php-fpm的子进程最多可以处理这么多请求,当达到这个数值时,它会自动退出。