配置laravel的nginx站点

server{}配置

server{
        #端口配置
        listen 80;
        #域名配置
        server_name laravel.cc;

        index index.php index.html index.htm;
        #站点配置到public
        root /data/wwwroot/laravel.cc/public;
      #日志记录
        access_log /data/logs/nginx.laravel.cc.log access;
        error_log /data/logs/nginx.laravel.cc.error debug;
     #静态文件配置
        location ~ .*.(jpg|jpeg|gif|png|bmp|css|js|swf|txt|ttf|woff|ico)$ {
                expires 7d;
                break;
        }

        location / {
         #重点区
                try_files $uri $uri/ /index.php?$query_string;
                index index.php index.html index.htm;
        }
        #静态文件配置
        location /logs {
                autoindex on;
                autoindex_exact_size off;
                autoindex_localtime on;
                break;
        }
        #处理php配置
        location ~ ".php$" {
                include fastcgi_params;
                fastcgi_index index.php;
                #在nginx.conf配置server_mango
                fastcgi_pass server_mango;
        }
}

http下的server_mango配置
  

http {
    include       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"';

    log_format access '$remote_addr [$time_local] "$http_host" "$request" "$status $body_bytes_sent" "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;
    server_tokens       off;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip on;
    gzip_min_length  5k;
    gzip_buffers     4 16k;
    #gzip_http_version 1.0;
    gzip_comp_level 3;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    #重点区与server{}中的处理php应用到的
    upstream server_mango {
        server 127.0.0.1:9000;
    }
    #加载vhost下的.conf后缀所有文件
    include /usr/local/nginx/conf/vhost/*.conf;
}

Nginx版本无缝升级

/usr/local/nginx/sbin/nginx -V     #查看版本
nginx version: nginx/1.4.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-ld-opt='-ljemalloc' #注意这里的编译项
cd lnmp/src
wget http://nginx.org/download/nginx-1.4.4.tar.gz
tar xzf nginx-1.4.4.tar.gz
cd nginx-1.4.4
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-ld-opt='-ljemalloc'
make    //注意只make  不要make install
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx$(date +%m%d)    #备份nginx原文件
cp objs/nginx /usr/local/nginx/sbin/nginx     #复制编译make后的文件覆盖nginx原文件
/usr/local/nginx/sbin/nginx -t     #检测nginx文件配置
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`    #把nginx.pid改成nginx.pid.oldbin跟着启动新的nginx
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`   #退出旧的nignx

Nginx下wordpress 固定链接更改后404问题解决

安装好wordpress后默认文章固定链接后缀是 ?p=xx之类的,这样的链接虽然挺简洁,但对SEO不利。

在后台自定义固定链接后,打开网站除首页外,其他页面都是404。这是由于没有设置好Nginx对wordpress的rewrite规则,google了一些解决办法,说的都是要在Nginx的配置文件写入

server{

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

}

但是写上以上代码仍然不起作用。于是google到Nginx官网上对于wordpress的rewrite规则说明,照着例子改了自己的Nginx配置,参考如下

upstream php {
        server unix:/tmp/php-cgi.socket;
        server 127.0.0.1:9000;
}

server {
    listen 80;
    server_name www.zhenglinbo.com zhenglinbo.com;

    root /var/www/blog;
    index index.html index.htm index.php;

    location / {

      try_files $uri $uri/ /index.php?$args;

    }

    location ~ .php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

    location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }

    error_page 404 /error/index.html;
        location = /40x.html {
    }   

}

成功!使用自定义的文章固定链接为 /post-%post_id%.html 。

附Nginx官网对wordpress的rewrite规则说明:https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/

NGINX,APACHE开启文件目录浏览功能

我们都知道在apache下可以配置访问web服务器的某个路径时,自动显示其目录下面的文件列表的,其实Nginx一点也不比apache弱,它当然也可以实现这个功能,而且还非常容易和简单;主要用到autoindex 这个参数来开启,其配置如下:

复制代码代码如下:

location / {
root /data/www/file                     //指定实际目录绝对路径;
autoindex on;                            //开启目录浏览功能;
autoindex_exact_size off;            //关闭详细文件大小统计,让文件大小显示MB,GB单位,默认为b;
autoindex_localtime on;              //开启以服务器本地时区显示文件修改日期!
}

如上配置后,用IE访问该服务器的根目录,就会显示出 /data/www/file目录下的所有文件列表,Nginx目录浏览效果图:

未分类

为了备忘,最后将apache下的配置方法也记录一下!实现效果和上面一样!

复制代码代码如下:

Alias / ”/data/www/file”
< Directory  ”/data/www/file” >
Options Indexes                                               //开启目录列表索引模式
Order allow,deny
IndexOptions  NameWidth = 25   Charset = UTF -8     //设定文件名显示长度,文字字符编码
Allow from all
</ Directory >

Docker配置Hexo+Git+Nginx

未分类

功能需求

像我这种Tototototo Young的码字儿的总喜欢追求逼格,原来用博客园onenote可以直接导入,后来就想迁移到自己云主机上

为了保证服务器环境的干净(强迫症晚期),将整套环境封装进docker中

如果想要8003直接绑定到域名上,见另一篇Docker配置Nginx反向代理

解决方案

  • Hexo+Github的构建博客资料网上有很多,不赘述,不使用这种方法

  • Hexo+Git+Nginx+云主机上构建服务器资料也不少,如果想要配置过程的邮件私聊我

  • Hexo+Git+Nginx+云主机+Docker,今天使用这种方法构建,镜像还没有push到Docker源,有需要的私聊~

实现思路

Hexo是基于Nodejs的一个框架,将markdown文件解析生成html静态文件

通过Git将本地的html文件拉取到云主机上,存入nginx站点目录供解析

Docker容器需要开放两个端口,80用于nginx解析,22端口给git推送博客页面,宿主机监听8003和8004端口

镜像以Centos为基础镜像,拉取NodeJS,使用yum安装Nginx,Git,OpenSSH
但由于需要配置ssh的公钥私钥,则在实例化镜像后再进入容器配置ssh

主机环境

  • 宿主机环境
    centos Linux release 7.3.1611 (Core)
    docker version 17.06.1-ce, build 874a737
    node v8.4.0
    npm 5.3.0

  • 容器环境
    centos Linux release 7.4.1708 (Core)
    nginx version: nginx/1.12.1
    git version 1.8.3.1

  • 容器目录
    git库: /root/blogs.git
    nginx: /etc/nginx/conf.d/default.conf
    blog文件: /usr/share/nginx/html
    ssh私钥: /root/.ssh/authorized_keys

前期准备

  • 宿主机已有nodejs环境并可运行,根目录在/usr/local/node

  • 宿主机安装docker

  • 电脑端安装git

构建Dockerfile

拉取Centos镜像

$ sudo docker pull centos

编辑Dockerfile文件

FROM centos:latest # 基于centos
COPY . /usr/local/node # 将node环境复制
RUN 
        yum install -y wget &&  # 安装wget
        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup &&  # 备份yum源
        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo &&  # 更换yum源为阿里源
        yum clean all &&  # yum缓存
        yum makecache && 
        rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm &&  # 获取nginx的yum源
        yum install -y nginx &&  # 安装nginx
        yum install -y git &&  # 安装git
        yum install -y vim &&  # 安装vim
        git init --bare ~/blogs.git &&  # 创建git库
        echo "git --work-tree=/usr/share/nginx/html --git-dir=/root/blogs.git checkout -f" >~/blogs.git/hooks/post-receive &&  # 创建git勾子用于拉取hexo推送的信息
        chmod a+x ~/blogs.git/hooks/post-receive &&  # 给勾子执行权限
        yum install -y openssh openssh-server openssh-clients &&  # 安装ssh服务
        ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key &&  # 生成服务端钥匙
        ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && 
        ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
EXPOSE 22 # 暴露22端口用于ssh连接,git拉取页面
EXPOSE 80 # 暴露80端口用于nginx服务
CMD ["nginx","-g","daemon off;"] # nginx服务命令,必须使用daemon守护进程

Docker容器后台运行,就必须有一个前台进程,如果CMD仅执行nginx,那么nginx执行完后台启动后,会立即自杀,docker容器状态会变为exited

docker容器必须有一个常驻的前台进程,所以使用daemon,使pid=1的进程不是/bin/bash而退出

构建镜像与容器

构建镜像

$ docker build -t hexoblogs . // 构建新镜像,注意不要少了最后的点
Successfully built 70eaeb40d97b
Successfully tagged hughdong/hexoblogs:latest

实例化容器并映射到宿主机端口,后台运行容器

$ sudo docker run --name dhblogs -p 8003:80 -p 8004:22 -d hexoblogs:latest

查看容器情况,当看到Status是UP且能看到Ports端口情况时为正常

$ sudo docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                        NAMES
c58e2a73f117        hexoblogs:latest         "nginx -g 'daemon ..."   12 minutes ago      Up 12 minutes       0.0.0.0:8004->22/tcp, 0.0.0.0:8003->80/tcp   dhblogs

测试镜像

浏览器输入http://...:8003/是否显示nginx测试页

未分类

配置ssh

获取本地ssh公钥,电脑端打开git bash

$ ssh-keygen

一路回车下去,然后打开C:UsersUsername.sshid_rsa.pub,复制内容,username是自己的电脑账户名

从宿主机进入Docker容器

$ sudo docker exec -it dhblogs /bin/bash

进入容器后执行以下步骤

# echo "*******************************" > ~/.ssh/authorized_keys // 复制的公钥,替换掉命令的******
# chmod 600 ~/.ssh/authorized_keys // 赋予权限
# chmod 700 ~/.ssh
# /usr/sbin/sshd // 启动ssh服务

本地测试ssh并互换秘钥

本地git bash执行

$ ssh root@***.***.***.*** -p 8004 // 前面是宿主机ip后面是端口

首次执行ssh时需要输入yes连接,之后hexo才能正常推送

未分类

如果报错ERROR

ERROR // 如果多次更换docker,同配置ssh连接时需要删除客户机的known_hosts
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HASCHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

C:Usershughd.sshknown_hosts 删除该主机对应的旧信息即可

本地配置ssh配置文件

打开C:Usershughd.ssh,如果没有config文件则创建新的

Host是云主机ip地址,Port是容器映射到宿主机的端口8004

Host ***.***.***.***
Port ***

本地配置hexo

nodejs和npm安装过程略

$ npm install -g hexo-cli
$ npm install hexo-deployer-git --save 
$ npm install hexo-server
$ hexo init f:/6.Code/GitBlogs // 初始化hexo
$ npm install

配置本地hexo的_config.yml

# Site
title: Hugh
subtitle: Mad web developers
description:
author: HughDong
language: zh-CN
timezone: Asia/Shanghai
# Deployment
deploy:
  type: git
  repo: root@***.***.***.***:/root/blogs.git
  branch: master

生成并推送博客,看到回显服务器端files文件更新则成功

$ hexo clean && hexo g -d
[master 29390bd] Site updated: 2017-10-13 11:03:15 9 files changed, 23 insertions(+), 23 deletions(-)
Branch master set up to track remote branch master from root@***.***.***.***:/root/blogs.git.
To ***.***.***.***:/root/blogs.git   aa45a3e..29390bd  HEAD -> master
INFO  Deploy done: git

nginx+lamp负载均衡实验

实验实现目的如下

  • 客户端通过外网地址访问 nginx 的 外网地址(假设的) 172.18.5.117

  • nginx 通过轮询的负载均衡设置分别调度到 apache服务器 192.168.5.109 和 192.168.5.111

  • php-fpm 服务器 192.168.5.113 上传 discuz源码文件到目录下, 用nfs共享此目录, 提供两个 apache 服务器挂载到站点根目录下,实现访问的资源一致性

  • apache响应站点目录下的静态文件, 动态文件使用fastcgi 交给php server 响应, php需要查询插入在与 mariadb服务交互

  • 整体实现 客户端访问 172.18.5.117 能够实现,轮询,正常发帖看帖

实验拓扑图如下

未分类

实验过程如下

编译安装httpd

在192.168.5.109 和 192.168.5.111 主机上编译安装httpd.

  • 主机操作系统: centos6.9_x86_64

  • httpd版本: httpd-2.4.47

  • apr版本: apr-1.5.2

  • aprutil版本: apr-util-1.5.4

  • 依赖软件包: gcc make expat-devel pcre-devel openssl-devel

操作步骤如下

# 下载源码包后放在 /usr/local/src
cd /usr/local/src
tar xf /usr/local/src/httpd-2.4.47.tar.gz
tar xf /usr/local/src/apr-1.5.2.tar.gz
tar xf /usr/local/src/apr-util-1.5.4.tar.gz
cp -r apr-1.5.2 httpd-2.4.47/srclib/apr
cp -r apr-util-1.5.4 httpd-2.4.47/srclib/apr-util
cd httpd-2.4.47
./configure 
--prefix=/usr/local/httpd 
--sysconfdir=/etc/httpd 
--enable-so --enable-ssl 
--enable-rewrite 
--with-zlib 
--with-pcre 
--with-included-apr 
--enable-deflate 
--enable-modules=most 
--enable-mpms-shared=all 
--with-mpm=prefork
make && make install
echo 'export PATH=/usr/local/httpd/bin:$PATH' > /etc/profile.d/httpd.sh

注意事项:

  • httpd2.2 不支持 fastcgi 所以在centos6 上要编译安装

  • centos6 中的默认apr版本过低 httpd-2.4版本需要 apr-1.4以上版本

  • 这里采用的编译是将apr和apr-util的源码复制到 httpd-2.4.47/srclib 中并去掉版本号, 这样编译比较方便,不用apr和apr-util一个一个编译, 但在httpd编译选项中要加上 –with-included-apr 的选项,

  • 编译完成后,推荐导出头文件,库文件,man帮助,和PATH变量. 和制作启动脚本,复制rpm安装的脚本就行,这里没有做这些步骤

配置httpd虚拟主机

注释中心主机
--------------
#DocumentRoot "/usr/local/httpd/htdocs"
----------------
启用包含虚拟机配置文件
Include /etc/httpd/extra/httpd-vhosts.conf   # 启用虚拟机配置
mkdir /web/forum -p                          # 创建站点根目录
echo "test" > /web/forum/index.html          # 创建测试文件
vim /etc/httpd/extra/httpd-vhosts.conf       
# 编辑虚拟机配置文件如下所示
<VirtualHost *:80>
    DocumentRoot "/web/forum"
    <Directory "/web/forum">
        Options none
        DirectoryIndex index.php index.html
        Require all granted             # 注意此项,要启用不然 403
    </Directory>
</VirtualHost>
# 导入PATH 变量后启动httpd 这里就不贴命令了
apachectl      # 启动后测试访问页面

编译安装php+xcache

192.168.5.113 上编译安装php+xcache

  • 操作系统版本 centos6.9

  • php版本: php-5.6.31

  • xcache版本: xcache-3.2.0

  • 依赖软件:gcc make libxml2-devel bzip2-devel libmcrypt-devel autoconf

第一步安装php:

cd /usr/local/src
tar xf php-5.6.31.tar.bz2
cd php-5.6.31
./configure 
--prefix=/usr/local/php 
--with-mysql=mysqlnd    # 注意以下三台如果mysql在本机上要使用mysqlnd
--with-mysqli=mysqlnd 
--with-pdo-mysql=mysqlnd 
--with-openssl 
--enable-mbstring       #支持多字节字符串即中文
--with-freetype-dir   
--with-jpeg-dir 
--with-png-dir 
--with-zlib 
--with-libxml-dir=/usr 
--enable-xml 
--enable-sockets 
--enable-fpm       # 启用fpm模式
--with-mcrypt 
--with-config-file-path=/etc/ 
--with-config-file-scan-dir=/etc/php.d 
--with-bz2
make && make install

第二步: php配置

cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
cp /usr/local/src/php-5.6.31/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
cp /usr/local/src/php-5.6.31/php.ini-production /etc/php.ini
chmod +x /etc/init.d/php-fpm
chkconfig --add php-fpm

第三步: 编译安装xcache

cd /usr/local/src
tar xf xcache-3.2.0.tar.gz
cd xcache-3.2.0
/usr/local/php/bin/phpize   # xcache没有configure脚本, 这条命令php提供 依赖 autoconf 软件包
./configure  --enable-xcache --with-php-config=/usr/local/php/bin/php-config
make && make install

注意事项

  • xcache 编译完成后会输出xcache.so的目录,请复制出此目录,(每次编译是目录并不是都一样)

  • xcache 源码经过企业多方测试性能稳定,不过版本太老,貌似不支持 php7版本

未分类

第四步: 配置php支持xcache模块

mkdir /etc/php.d
cp /usr/local/src/xcache-3.2.0/xcache.ini /etc/php.d/
# 找出xcache.so模块的路径
xcache_so_path=`find /usr/local/php/lib/php/extensions/ -name "xcache.so"`
# 替换配置文件extension = < xcache.so的路径 >
sed -i  '/^extension = xcache.so/cextension = '"${xcache_so_path}"'' /etc/php.d/xcache.ini

配置httpd, 并测试httpd连接php

在 192.168.5.111 和 192.168.5.109 上的虚拟主机上配置

# 更改虚拟机配置文件,让以php结尾的文件,通过fastcgi 交给php服务器处理,虚拟机配置文件如下
LoadModule proxy_module modules/mod_proxy.so            # 开启代理模块
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so  # 开启支持fcgi的反向代理
<VirtualHost *:80>
    DocumentRoot "/web/forum"
    ServerName forum.zxs.com
    <Directory "/web/forum">
        DirectoryIndex index.html  index.php
        Require all granted
    </Directory>
    ProxyRequests Off                                    # 关闭正向代理
    ProxyPassMatch ^(.*.php)$ fcgi://192.168.5.113:9000/web/forum/$1   # fastcgi连接php
</VirtualHost>
# 完成后重启httpd
/usr/local/httpd/bin/apachectl stop
/usr/local/httpd/bin/apachectl

在php 192.168.5.113主机上修改如下配置: php配置监听本机端口, 并允许 192.168.5.111和 192.168.5.109 ,需要修改以下参数

vim /usr/local/php/etc/php-fpm.conf         # 编辑fpm.conf 的配置文件
listen 192.168.5.113:9000                   # 增加监听本机网卡地址 默认只监听 127.0.0.1
listen.allowed_clients = 192.168.5.109,192.168.5.111 # 允许web服务器通过fastcgi 的9000端口进来
service php-fpm restart                     # 重启php-fpm

测试连接状态

在php的主机 192.168.5.113上执行如下操作(创建一个index.php的文件)

mkdir /web/forum
vim /web/forum/index.php       
# 添加如下内容
<?php
    phpinfo();
?>

注意: php文件的路径要根 fastcgi上的路径相匹配, 例如: httpd的proxy规则是 192.168.5.113:9000/web/forum/$1 , 那就要创建在 /web/forum目录下, 可以改成别的但必须保持一致.

测试效果如下, 成功后浏览器搜索 xcache 加速器是否已经启用

未分类

通用二进制安装mariadb

mkdir /mydata
useradd -r mysql
cd /usr/local/src
tar xf mariadb-5.5.57-linux-x86_64.tar.gz -C /usr/local/
ln -s /usr/local/mariadb-5.5.57-linux-x86_64.tar.gz /usr/local/mysql
cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql --datadir=/mydata
cp support-files/my-huge.cnf /etc/my.cnf
sed -i '/^[mysqld]/adatadir=/mysqdata' /etc/my.cnf
sed -i '/^[mysqld]/alog-error=/var/log/mysqld.log' /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
service mysqld start
echo 'export PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysqld.sh
. /etc/profile.d/mysqld.sh
mysql_secure_installation            # 安全初始化,嫌麻烦可以暂时不做

接下来我们需要安装discuz论坛系统, 在这之前先来测试下php是否能连接上mysql

# 首先连接上mysql
mysql> CREATE DATABASE forum;
mysql> GRANT ALL ON forum.* TO 'zxs'@'192.168.5.113' IDENTIFIED BY '123456';
# 创建数据库和授权完成后切换到php服务器测试是否能远程mysql服务器,没安装客户端的安装下mysql客户端
mysql -uzxs -h192.168.5.115 -p123456  
# 测试手动可以链接后在测试mysql是否可以连接, 需要编辑index.php文件添加如下代码
vim /web/forum/index.php
<?php
$mysqli=new mysqli("192.168.5.115","zxs","123456");
if(mysqli_connect_errno()){
echo "connect to database failure!";
$mysqli=null;
exit;
}
echo "connect to database success!";
$mysqli->close();
phpinfo();
?>

未分类

下载解压discuz源码到php 192.168.5.113 服务器上,并通过nfs共享出了来

unzip Discuz_X3.2_SC_UTF8.zip
rm -rf forum                # 删除原来的目录,之前做测试用的 
cp upload/ /web/forum -r    # 复制源码下 upload 目录并重命名为 forum
yum install rpcbind nfs-utils   # nfs服务依赖的包
service rpcbind start           # 启动rpcbind
chkconfig rpcbind on            
chkconfig nfs on
groupadd -g 800 apache   # 这里创建uid=800的用户和组,用于nfs共享是映射的用户,避免权限问题
useradd -g apache -u 800 -s /sbin/nologin apache   
chown -R apache.apache /web/forum  #将站点目录该为apache所有
vim /etc/exports
/web 192.168.5.109(rw,all_squash,anonuid=800,anongid=800)  #nfs配置所有用户映射为apache
/web 192.168.5.111(rw,all_squash,anonuid=800,anongid=800) 
service nfs start

httpd服务器上 192.168.5.109和192.168.5.111 上挂载php共享出来的nfs 并且写入/etc/fstab中

# 先安装nfs-utils 不然挂载不上
yum install nfs-utils -y
vim /etc/fstab
192.168.5.113:/web      /web                    nfs     defaults        0 0
mount -a

浏览器访问 192.168.5.109 和 192.168.5.111 进入discuz 向导

未分类

安装步骤到第二步可能会报如下错误, php进程可能无法写入以下文件

未分类

查看php以 nobody身份允许 ,改为apache 身份允许就能访问站点目录了

# 修改下php以apache的身份允许,这样就可以写了
vim /usr/local/php/etc/php-fpm.conf  # 修改php-fpm的配置文件
user = apache
group = apache

编译安装nginx,做负载均衡

wget http://nginx.org/download/nginx-1.13.6.tar.gz
tar xf nginx-1.13.6.tar.gz
cd nginx-1.13.6/
mkdir /var/tmp/nginx
useradd -r nginx
./configure 
--prefix=/usr/local/nginx 
--conf-path=/etc/nginx/nginx.conf 
--user=nginx 
--group=nginx 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--pid-path=/var/run/nginx/nginx.pid 
--lock-path=/var/lock/nginx.lock 
--with-http_ssl_module 
--with-http_stub_status_module 
--with-http_gzip_static_module 
--with-http_flv_module 
--with-http_mp4_module 
--http-client-body-temp-path=/var/tmp/nginx/client 
--http-proxy-temp-path=/var/tmp/nginx/proxy 
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi 
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
make && make install
ln -sv /usr/local/nginx/sbin/nginx  /usr/sbin/nginx
nginx
# 启动后测试nginx是否能访问

简单设置nginx设置使用轮询负载均衡, nginx (修改的部分)配置如下:

...
  #keepalive_timeout  0;
keepalive_timeout  65;
#gzip  on;
upstream backend {
    server 192.168.5.111;
    server 192.168.5.109;
}
server {
    listen       80;
    #charset koi8-r;
    #access_log  logs/host.access.log  main;
    location  / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
    }
...

测试是否能访问:

修改php服务器上的discuz的主页文件最前面, 让其能识别前端apache服务器是那个发来的请求, 好测试负载均衡轮询是否成功

vim /web/forum/forum.php       # 修改 php服务器站点目录下的 
<?php
echo 'apache服务器地址:'. $_SERVER['SERVER_ADDR']."<br/>"; 
?>   #该代码用于输出前端访问php的apache 服务器地址 用户测试调度是否成功

修改后访问测试页面如下所示

未分类

多台图片服务器下 nginx 自动匹配图片

需求:有图片服务器,A、B、C、D,由于某种原因,读取图片时,不知道图片在哪台机器上。所以用 nginx 来判断图片在哪台机器上。

upstream test.com {
    server t2.com:80;
    server t3.com:80;
    server t4.com:80;
}
server {
    listen       80;
    server_name  test.com;
    root /var/www/test.com;
    access_log  logs/test.log  main;

    location / {
        try_files $uri @proxy;
    }
    location @proxy {
        proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
        proxy_pass http://test.com;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

参考资料

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

Nginx 安装 Lua 支持

Nginx 支持 Lua 需要安装 lua-nginx-module 模块,一般常用有 2 种方法:

  • 编译 Nginx 的时候带上 lua-nginx-module 模块一起编译

  • 使用 OpenResty: Nginx + 一些模块,默认启用了 Lua 支持

OpenResty is just an enhanced version of Nginx by means of addon modules anyway. You can take advantage of all the exisitng goodies in the Nginx world.

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

OpenResty

OpenResty 的安装很方便,Mac 里使用 brew 安装,对于一些常见的 Linux 发行版本,OpenResty® 提供 官方预编译包,CentOS 使用 yum,Ubuntu 使用 apt-get,具体请参考 https://openresty.org/cn/installation.html,以下以 Mac 和 CentOS 7 中安装 OpenResty 为例。

Mac 使用 OpenResty

  • 终端执行 brew install homebrew/nginx/openresty 把 OpenResty 安装到 /usr/local/Cellar/openresty

  • 终端执行 openresty -V 可以从输出信息中发现 Nginx 的配置文件为 /usr/local/etc/openresty/nginx.conf

  • 启动 Nginx,2 种启动方式都可以

    • sudo openresty (openresty 其实就是 nginx 的软连接)

    • sudo nginx (把 /usr/local/Cellar/openresty/1.11.2.5/nginx/sbin 添加到 PATH 里,注意不同版本时的路径不同)

    • 查看是否启动了 nginx: ps -ef | grep nginx

  • 测试是否支持 Lua

1、/usr/local/etc/openresty/nginx.conf 中添加

location /lua {
    default_type 'text/html';
    content_by_lua 'ngx.say("hello world");';
}

2、nginx -t 测试配置没问题,然后 nginx -s reload 重新加载配置 (nginx -s stop 关闭 Nginx)

3、curl http://localhost/lua 输出 hello world 则说明 Nginx 支持 Lua

CentOS 7 使用 OpenResty

  • 终端执行下面 3 条命令把 OpenResty 安装到 /usr/local/openresty
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openresty
  • Nginx 的配置文件位于 /usr/local/openresty/nginx/conf/nginx.conf (openresty -V 中没有指定)

  • 启动 Nginx,2 种启动方式都可以

    • sudo openresty

    • sudo nginx

    • 查看是否启动了 nginx: ps -ef | grep nginx

  • 测试是否支持 Lua: 参考上面的方法

编译 Nginx + Lua

编译 Nginx 需要先准备好下面的这些工具,如果不确定是否已安装,可以在编译的时候根据出现的错误提示再进行安装

  • yum install -y gcc g++ gcc-c++

  • yum -y install zlib zlib-devel openssl openssl–devel pcre pcre-devel

Nginx 支持 Lua 需要依赖 LuaJIT-2.0.4.tar.gz,ngx_devel_kit,lua-nginx-module,下面介绍具体的编译过程 (都下载到 /root 目录)

1、下载安装 LuaJIT-2.0.4.tar.gz

wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar xzvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make install PREFIX=/usr/local/luajit
# 添加环境变量
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0

2、下载解压 ngx_devel_kit

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
tar -xzvf v0.3.0.tar.gz

3、下载解压 lua-nginx-module

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz
tar -xzvf v0.10.8.tar.gz

4、下载安装 nginx-1.10.3.tar.gz

wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -xzvf nginx-1.10.3.tar.gz
cd nginx-1.10.3
# 注意ngx_devel_kit和lua-nginx-module 以实际解压路径为准
./configure --add-module=/root/ngx_devel_kit-0.3.0 --add-module=/root/lua-nginx-module-0.10.8
make -j2
make install

5、支持 Nginx 被安装到了 /usr/local/nginx,配置文件为 /usr/local/nginx/conf/nginx.conf

6、验证

  • 将 nginx 做成命令: ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

  • /usr/local/nginx/conf/nginx.conf 中添加 Lua 测试代码

location /lua {
    default_type 'text/html';
    content_by_lua 'ngx.say("hello world");';
}
  • 启动 Nginx: sudo nginx

  • curl http://localhost/lua 输出 hello world 则说明 Nginx 支持 Lua

Nginx 验证 Token

为了提高效率,常把 Nginx 作为静态文件服务器,把视频文件,JS,CSS 等放到 Nginx 上。例如我们要开发一个视频网站,免费视频不需要访问权限验证,收费视频就需要对用户的权限进行验证,验证通过了才能够继续访问,Nginx 可以借助 Lua 来实现访问验证,用户信息使用 token 表示

  • 计算 token: md5(appId+appKey)

  • 请求的链接从应用服务器上动态获取,请求参数带上 appId 和 token: http://localhost/private/tih.mp4?appId=app_1&token=1409dc951714a8226032e0b0fb60bdb0

  • Nginx 接收到请求的时候,根据 appId 找到 appKey,然后 token2 = ngx.md5(appId+appKey),token2 和请求中的 token 比较,如果相等则验证通过放行访问,否则禁止访问

Nginx 简单的验证代码如下:

location ~ /private/.+.mp4$ {
    root html;
    access_by_lua '
        -- 应用的 ID 和 key,和应用服务器上的一致
        local appIdKeys = {["app_1"] = "key_1", ["app_2"] = "key_2"};
        local args   = ngx.req.get_uri_args();
        local appId  = args["appId"];
        local appKey = appIdKeys[appId];
        local token1 = args["token"]; -- 参数中 token
        local token2 = ngx.md5(appId .. appKey); -- 用应用的 ID 找到对应的 key,然后根据算法计算 token
        -- 如果参数中的 token 和计算得到的 token 不相等,则说明访问非法,禁止访问,否则放行访问
        if token1 ~= token2 then
            ngx.exit(ngx.HTTP_FORBIDDEN);
        end
    ';
}

Nginx 和应用服务器上同时存储 appId 和 appKey,这样就能根据参数中的 appId 查找到对应的 appKey。至于使用 Lua 的变量存储,或者使用数据库,还是文件,根据具体的情况而定(Nginx 中 Lua 能够访问数据、Redis 等)。

上面的验证规则比较简单,如果其他人得到了 token,就可以无限制的访问了,为了增强安全性,可以使用更多的参数生成 token,例如用户 id,限制 URL 期限的时间戳等。

Nginx 默认没有安装 Lua 模块,需要自己安装,可参考 http://qtdebug.com/mac-nginx-lua

nginx+nginx_lua实现WAF防护功能

nginx_lua

nginx_lua模块是nginx的第三方模块,它可以将lua语言嵌入到nginx配置中,从而极大的扩展了nginx的能力,nginx以高并发而知名,而lua作为嵌入式语言轻便,两者的结合可以做到在nginx层就实现编程,而这里我们加入waf的lua过滤编程来实现waf。

安装

需要的程序包:

  • nginx

  • nginx_devel_kit(拓展nginx服务器核心功能的模块)

  • lua-nginx-module(nginx_lua模块)

  • nginx_lua_waf(waf策略 web应用防火墙)

  • LuaJIT(c实现的lua解释器)

LuaJIT

下载网站:

~]# wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
~]# tar xf LuaJIT-2.0.5.tar.gz
~]# cd LuaJIT-2.0.5
~]# make -j 2 && make install

lib和include是直接放在/usr/local/lib和/usr/local/include

设置环境变量(nginx编译时需要)

~]# ~]# vim /etc/profile.d/LuaJIT.conf
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.0
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
~]# . /etc/profile.d/LuaJIT.conf

nginx_devel_kit

第三方模块,我们可以到nginx wiki是查找:www.nginx.com/resources/wiki/modules/index.html

~]# git clone https://github.com/simpl/ngx_devel_kit

lua-nginx-module

~]# git clone https://github.com/openresty/lua-nginx-module

nginx

编译nginx_devel_kit和lua-nginx-module进nginx

~]# wget http://nginx.org/download/nginx-1.12.1.tar.gz
~]# tar xf nginx-1.12.1.tar.gz
~]# cd nginx-1.12.1
~]# yum install -y openssl-devel pcre-devel
~]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=../ngx_devel_kit --add-module=../lua-nginx-module --user=nginx --group=nginx

nginx_lua_waf

~]# wget -c https://github.com/loveshell/ngx_lua_waf/archive/master.zip
~]# mkdir -p /usr/local/nginx/conf/waf
~]# unzip master.zip 
~]# cd ngx_lua_waf-master
~]# cp -rf * /usr/local/nginx/conf/waf/
~]# mkdir -p /usr/local/nginx/logs/hack
~]# chown -R nginx /usr/local/nginx/logs/hack

nginx_lua_waf的用途

  • 防止sql注入,本地包含,部分溢出,fuzzing测试,xss,SSRF等web攻击

  • 防止svn/备份之类文件泄漏

  • 防止ApacheBench之类压力测试工具的攻击

  • 屏蔽常见的扫描黑客工具,扫描器

  • 屏蔽异常的网络请求

  • 屏蔽图片附件类目录php执行权限

  • 防止webshell上传

nginx_lua_waf的使用

nginx安装路径假设为:/usr/local/nginx/conf/
在nginx.conf的http段添加

lua_need_request_body on;
      lua_package_path "/usr/local/nginx/conf/waf/?.lua";
      lua_shared_dict limit 10m;
      init_by_lua_file  /usr/local/nginx/conf/waf/init.lua; 
      access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;

配置config.lua里的waf规则目录(一般在waf/conf/目录下)

RulePath = "/usr/local/nginx/conf/waf/wafconf/"

config.lua 配置说明

RulePath = "/usr/local/nginx/conf/waf/wafconf/"
      --规则存放目录
      attacklog = "off"
      --是否开启攻击信息记录,需要配置logdir
      logdir = "/usr/local/nginx/logs/hack/"
      --log存储目录,该目录需要用户自己新建,切需要nginx用户的可写权限
      UrlDeny="on"
      --是否拦截url访问
      Redirect="on"
      --是否拦截后重定向
      CookieMatch = "on"
      --是否拦截cookie攻击
      postMatch = "on" 
      --是否拦截post攻击
      whiteModule = "on" 
      --是否开启URL白名单
      black_fileExt={"php","jsp"}
      --填写不允许上传文件后缀类型
      ipWhitelist={"127.0.0.1"}
      --ip白名单,多个ip用逗号分隔
      ipBlocklist={"1.0.0.1"}
      --ip黑名单,多个ip用逗号分隔
      CCDeny="on"
      --是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)
      CCrate = "100/60"
      --设置cc攻击频率,单位为秒.
      --默认1分钟同一个IP只能请求同一个地址100次
      html=[[Please go away~~]]
      --警告内容,可在中括号内自定义
      备注:不要乱动双引号,区分大小写

waf.conf 自定义过滤规则

  • args里面的规则get参数进行过滤的

  • url是只在get请求url过滤的规则

  • post是只在post请求过滤的规则

  • whitelist是白名单,里面的url匹配到不做过滤

  • user-agent是对user-agent的过滤规则

注意:默认开启了get和post过滤,需要开启cookie过滤的,编辑waf.lua取消部分–注释即可

WAF测试

未分类

看下日志:

hack]# tail -f localhost_2017-09-16_sec.log 
10.211.55.2 [2017-09-16 14:01:40] "GET localhost/?id=select%20*%20from%20mysql;" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0" "select.+(from|limit)"
10.211.55.2 [2017-09-16 14:05:51] "GET localhost/?id=union%20select%20*%20from%20mysql;" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0" "select.+(from|limit)"

从日志中我们可以看见我么测试的url的args请求触发了那条规则。

从config.lua中我们还可以看见cc防护,测试下:

~]# cat /usr/local/nginx/conf/waf/config.lua
...
CCDeny="on"     #开启cc防护
CCrate="5/60"   #降低触发阀值便于测试
...
~]# nginx -s reload

测试结果,当我在1分钟频繁请求超过5次,返回404错误,最后结果返回的是503错误,当我们停止访问,过一会就可以恢复访问,经过测试这个防护是针对请求ip的,证明cc防护还是可以达到一定的效果的。

未分类

这是nginx+lua的一种扩展,而nginx的另一个分支openresty将nginx与lua做了很多扩展,有空一定需要好好研究下。