Nginx配置图片防盗链

为了防止其他站点直接从我们网站引用图片等链接,消耗了我们服务器资源和网络流量,我们一般会对图片等资源做一些限制,比如打水印,防盗链设置等,本文主要结合Nginx来讲解如何设置图片防盗链。

我们所说的防盗链功能是都是基于 HTTP 协议支持的 Referer 机制,通过 referer 跟踪来源,对来源进行识别和判断。 利用这个策略,我们基本可以防止其他站点直接链接我们站上的图片。 举个例子,如果a.com网站的页面调用了我站的图片:https://www.helloweba.net/p.jpg,我们通过Nginx来判断它的来源域,不属于www.helloweba.net过来的图片都返回403,即禁止访问。

打开对应站点的conf配置文件,有关Nginx站点配置文件可以参考: https://www.helloweba.net/server/504.html ,主要配置代码如下:

location ~*.(gif|jpg|jpeg|png|bmp|swf)$ { 
    valid_referers none blocked www.helloweba.net m.helloweba.net; 
    if ($invalid_referer) { 
        return 403; 
        #rewrite ^/ http://www.baidu.com/error.jpg; 
    } 
} 

以上代码解释如下:

1、location中指定要防篡改的文件类型,多个后缀用“|”符号分开。

2、valid_referers指定资源访问是通过以下几种方式为合法,即白名单,允许文件链出的域名白名单。

none:直接通过url访问,无referer值的情况

blocked:referer值被防火墙修改

servername:指定资源在合法的域名白名单中可以被引用,支持*通配符,多个域名使用空格符分开

3、if判断如果用户请求的资源不符合上述配置,那么rewrite重定向到你想指定的url上,也可以配置403权限错误。

以上设置差不多就可以起到防盗链作用了,但是,这样并不是彻底地实现真正意义上的防盗链!

我们应该注意设置:

location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
            valid_referers m.helloweba.net www.helloweba.net;
            if ($invalid_referer) {
                #rewrite ^/ http://www.baidu.com/a.html; 
                return 403;
            }
        }

expires 30d;属于配置文件中location作用域中原有的图片缓存时间配置,这里我们把两个location合并在一起。

接着,我们去掉none blocked两个关键词,目的是直接在浏览器地址栏中输入对应的图片地址也会被拒绝访问。

如果匹配到不属于设定的referer来源域,则返回403,或者重置到一个url地址上去,这样可以避免右键另存为的方式下载图片。

当然,话又说回来,如果人家真想获得你的图片还是有办法的,比如各种伪造referer来源等方法。

还有一种情况,如果我们站点使用CDN,那么在nginx上的防盗链配置似乎不起作用了,别担心,找CDN厂商,他们有一整套资源防盗链方法,大多在CDN管理平台直接设置即可,比如阿里云CDN,其原理也是判断referer。

使用OpenSSL给Nginx添加访问密码

1、创建用户名为sam

sh -c “echo -n ‘sam:’ >> /etc/nginx/.htpasswd”

2、创建用户密码

sh -c “openssl passwd -apr1 >> /etc/nginx/.htpasswd”

3、添加到nginx配置

location / {

try_files $uri $uri/ =404;

#下列两行为新增
**auth_basic “Restricted Content”;

auth_basic_user_file /etc/nginx/.htpasswd;**

}

nginx使用secure_link模块防盗链

secure_link模块介绍

ngx_http_secure_link_module是nginx内置的一个防盗链模块
使用这个模块,可以有效的防止文件被其他网站盗用.
有效防止服务器流量流失.

secure_link模块如何启用

编译时加入以下参数(0.7.18后版本可用)

--with-http_secure_link_module

nginx设置secure_link

location  / {
    secure_link $arg_md5,$arg_expires;  #设置两个变量 
    secure_link_md5 "key$remote_addr$arg_expires";   #设置md5,当作口令 

    if ($secure_link = "") {
        return 403;
    }

    if ($secure_link = "0") {
        return 410;
    }
}

网站生成口令设置[php为例]

$secret = 'key';   // key,自定义秘钥 
$ipip=$_SERVER["REMOTE_ADDR"]; 
$expires = time()+300; //这里是300妙内访问有效 

$md5 = base64_encode(md5($secret . $ipip . $expires, true)); // MD5生成 
$md5 = strtr($md5, '+/', '-_'); // + and / 替换掉 
$md5 = str_replace('=', '', $md5); // 替换= 

$url = "http://domain.com/test.zip?md5=$md5&expires=$expires";  //安全下载链接demo设置 

$arr = array("url"=>$url, "expires"=>date("Y-m-d H:i:s", $expires), "md5"=>$md5);

echo json_encode($arr); //json格式输出

如何查看Nginx的运行状态:nginx_status

如何查看Nginx的运行状态信息?很简单,只要你在编译安装Nginx时添加了ngx_http_stub_status_module模块(一般都有的),然后
在配置文件里添加如下配置(高亮部分):

server {
listen 80;
server_name xxx;
…
location /status
{
stub_status on;
access_log off;
error_log off;
}
…
}

从浏览器中打开:http://www.yourdomain.com/status 可以看到类似以下的内容:

Active connections: 410
server accepts handled requests
30871298 30871298 105864919
Reading: 4 Writing: 8 Waiting: 398

active connections– 对后端发起的活动连接数
server accepts handled requests– nginx 总共处理了 30871298 个连接, 成功创建 30871298 次握手,总共处理了 105864919个请求
reading– nginx 读取到客户端的Header信息数
writing– nginx 返回给客户端的Header信息数
waiting– 开启 keep-alive 的情况下,这个值等于 active – (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接
如果reading或writing的值很高,说明正在处理的数据量很大,可能是因为后端的php程序处理慢,拖了后腿,而一般来说,PHP之后以慢,是因为MYSQL,另一个原因很可能就是IO慢,或者客户端的网络慢(这种情况在国内常见些).因为CPU配置低的情况少见.

nginx 出现413 Request Entity Too Large问题的解决方法

nginx 出现413 Request Entity Too Large问题的解决方法

使用php上传图片(大小1.9M),出现 nginx: 413 Request Entity Too Large 错误。

根据经验是服务器限制了上传文件的大小,但php默认的文件上传是2M,应该不会出现问题。

打开php.ini,把 upload_max_filesize 和 post_max_size 修改为20M,然后重启。

再次上传,问题依旧,可以排除php方面的问题。

原来nginx默认上传文件的大小是1M,可nginx的设置中修改。

解决方法如下:

  1. 打开nginx配置文件 nginx.conf, 路径一般是:/etc/nginx/nginx.conf。

  2. 在http{}段中加入 client_max_body_size 20m; 20m为允许最大上传的大小。

  3. 保存后重启nginx,问题解决。

https双向验证-nginx实例

简介

一般的web服务器都是https单向认证,双向认证大部分用于企业对接,信任对方身份。比如该网站的接口不是所有人都可以访问,只允许一个或者部分持有证书的人访问。就需要双向认证

环境准备

ubuntu 16.4
nginx或者OpenResty, 本文用的OpenResty 版本为:openresty-1.11.2.1

创建目录

  1. 修改/etc/ssl/openssl.cnf配置文件(如果不知道openssl配置文件可以查找一下,后者使用locate openssl.cnf命令)
  2. 找到[CA_default]标签
  3. 修改dir对应的工作目录,我的目录为 /home/用户名/ca
  4. cd 到工作目录

生成CA证书

openssl genrsa -aes256 -out private/ca.pem 1024
openssl rsa -in private/ca.pem -out private/ca.key
openssl req -new -key private/ca.pem -out private/ca.csr
openssl x509 -req -days 365 -sha1 -signkey private/ca.pem -in private/ca.csr -out certs/ca.cer

生成服务端证书

用根证书签发server端证书

openssl genrsa -aes256 -out private/server.pem 1024
openssl rsa -in private/server.pem -out private/server.key
openssl req -new -key private/server.pem -out private/server.csr
openssl x509 -req -days 365 -sha1 -CA certs/ca.cer -CAkey private/ca.pem -CAserial ca.srl -in private/server.csr -out certs/server.cer

生成客户端证书

openssl genrsa -aes256 -out private/client.pem 1024
openssl rsa -in private/client.pem -out private/client.key
openssl req -new -key private/client.pem -out private/client.csr
openssl x509 -req -days 365 -sha1 -CA certs/ca.cer -CAkey private/ca.pem -CAserial ca.srl -in private/client.csr -out certs/client.cer

导出证书

openssl pkcs12 -export -clcerts -inkey private/client.pem -in certs/client.cer -out certs/client.p12
openssl pkcs12 -export -clcerts -inkey private/server.pem -in certs/server.cer -out certs/server.p12

安装证书

  1. 安装CA证书,在谷歌浏览器中点击设置->高级选项->证书管理->授权中心,点击导入,然后选择生成的ca.cer证书文件。
  2. 安装客户端证书,在谷歌浏览器中点击设置->高级选项->证书管理->您的证书 点击导入,选择生成的client.p12证书文件

未分类

未分类

需要注意的地方

在生成客户端证书的时候在填写CN的时候不要和生成CA证书和服务端证书一样。测试好多次如果subj和CA,server一样的话浏览器一直是400错误。

配置nginx启动

server {
        listen       443 ssl;
        server_name  www.soaer.com;
        ssl on;
        ssl_certificate      /home/sunny/ca/certs/server.cer;
        ssl_certificate_key  /home/sunny/ca/private/server.key;
        ssl_client_certificate /home/sunny/ca/certs/ca.cer;
        ssl_verify_client on;
        ssl_prefer_server_ciphers on;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;

        location / {
            root   html;
            index  index.html index.htm;
        }
}

测试

浏览器中输入https://www.soaer.com, 如图所示,需要你选择发送给服务端的证书,此时选择client.p12证书文件

未分类

结果(成功)

未分类

使用zabbix监控nginx和php-fpm性能

一、系统环境

1.1 软件及其版本

未分类

1.2 软件安装路径

zabbix安装在/usr/local/zabbix路径下,其相关配置文件及二进制执行程序都放置其中。
nginx安装在/usr/local/nginx下,其相关配置文件及二进制执行程序都放置其中。
php安装在/usr/local/php下,其相关配置文件及二进制执行程序都放置其中。
继续后面的操作前,请确认nginx和php-fpm的服务端口都处于监听状态。

二、配置nginx的status

2.1 确认nginx的status已编译到程序包中

使用nginx -V可以查看nginx是否将模块·http_stub_status_module`编译进包中:

[root@monitor-server2 zabbix_agentd.conf.d]# nginx -V
nginx version: nginx/1.10.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.10.3 
--with-http_ssl_module 
--with-http_stub_status_module --with-pcre   
#出现with-http_stub_status_module说明已装载status模块

2.2 启用nginx的status模块

  • 修改nginx.conf文件

一般在默认主机中增加如下location即可:

location /nginx_status {
  stub_status on;
  access_log off;
  allow 127.0.0.1;
  allow 192.168.249.0/24;
  deny all;
  • 查看nginx status

nginx配置文件修改完成以后,使用nginx -t测试配置文件是否有明显逻辑及语法错误,没有问题则重载配置文件。

nginx -t
nginx -s reload

然后使用浏览器或者curl指令查看nginx status:

[root@monitor-server2 zabbix_agentd.conf.d]# curl localhost/nginx_status
Active connections: 2 
server accepts handled requests
 1585 1585 7785 
Reading: 0 Writing: 1 Waiting: 1 

2.3 nginx status数值的含义说明

未分类

三、配置php-fpm的status

php-fpm自带的有用于查询其工作状态的页面,需要进行如下 两步,以启用这一功能。

3.1 启用php-fpm status页面

修改php-fpm.conf文件,去掉status页面的注释,并可以根据需要将其改名。操作如下:

vim /usr/local/php/etc/php-fpm.conf
pm.status_path = /php_fpm-status      
 #去掉了前面的;注释符,并更名为php_fpm-status

3.2 查看php-fpm的status

修改完php-fpm.conf后,使用service php-fpm reload重新加载配置文件,然后在浏览器或者使用curl指令查看php-fpm的status。操作如下:

[root@monitor-server2 zabbix_agentd.conf.d]# curl localhost/php_fpm-status
pool:                 www
process manager:      dynamic
start time:           01/May/2017:15:14:23 +0800
start since:          29536
accepted conn:        5947
listen queue:         0
max listen queue:     3
listen queue len:     128
idle processes:       2
active processes:     1
total processes:      3
max active processes: 3
max children reached: 0
slow requests:        0

php-fpm的status可以查看汇总信息和详细信息,详细信息比汇总信息要多出每一个php-fpm进程的相关信息,同时支持多种格式输出,如xml、html和json,默认情况下分别使用如果指令即可:

Examples for summary status page:
http://example.com/status
http://example.com/status?json
http://example.com/status?html
http://example.com/status?xml
Example for detailed status page:
http://example.com/status?full
http://example.com/status?json&full
http://example.com/status?html&full
http://example.com/status?xml&full

使用何种格式查看status决定了后续使用zabbix进行监控获取status数值的方式。本文以上述curl localhost/php_fpm-status的输出为例。

3.3 php-fpm status的含义

未分类

四、编写status数据提取脚本

在适当的位置,一般是/usr/local/zabbix/bin里准备脚本用于提取status里每个字段的数值。

4.1 nginx的status数值提取脚本

此脚本为/usr/local/zabbix/bin/nginx_status.sh,其内容如下:

#!/bin/bash
#check nginx status
ip=127.0.0.1
function ping() {                              #用于检测nginx进程是否存在
    /sbin/pidof nginx | wc -l
}

function active() {                 #用于提取status中的active数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '1p' | awk '{print $NF}'
}

function accepts() {            #用于提取status中的accepts数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $1}'
}

function handled() {          #用于提取status中的handled数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $2}'
}

function requests() {        #用于提取status中的request数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '3p' | awk '{print $3}'
}

function reading() {        #用于提取status中的reading数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $2}'
}

function writing() {        #用于提取status中的writing数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $4}'
}

function waiting() {     #用于提取status中的waiting数值
    /usr/bin/curl http://$ip/nginx_status 2>/dev/null | sed -n '4p' | awk '{print $6}'
}

$1                           #通过第一个位置参数的值来调用相应的函数  

4.2 php-fpm status数值提取脚本

php-fpm status数值提取脚本为/usr/local/zabbix/bin/php_fpm_status.sh,内容如下:

#!/bin/bash
#check php-fpm status
case $1 in
    ping)                           #检测php-fpm进程是否存在
    /sbin/pidof php-fpm | wc -l
    ;;
    start_since)             #提取status中的start since数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==4{print $3}'
    ;;
    conn)                     #提取status中的accepted conn数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==5{print $3}'
    ;;
    listen_queue)         #提取status中的listen queue数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==6{print $3}'
    ;;
     max_listen_queue)  #提取status中的max listen queue数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==7{print $4}'
    ;;
    listen_queue_len)    #提取status中的listen queue len
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==8{print $4}'
    ;;
    idle_processes)      #提取status中的idle processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==9{print $3}'
    ;;
    active_processes)   #提取status中的active processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==10{print $3}'
    ;;
     total_processes)    #提取status中的total processess数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==11{print $3}'
    ;;
    max_active_processes)     #提取status中的max active processes数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==12{print $4}'
    ;;
     max_children_reached)    #提取status中的max children reached数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==13{print $4}'
    ;;
    slow_requests)   #提取status中的slow requests数值
    /usr/bin/curl localhost/php_fpm-status 2>/dev/null  | awk 'NR==14{print $3}'  
    ;;
    *)
    echo "Usage: $0 {conn|listen_queue|max_listen_queue|listen_queue_len|idle_processes|active_processess|total_processes|max_active_processes|max_children_reached|slow_requests}"
    exit 1
    ;;
esac

五、创建zabbix_agentd的子配置文件

在/usr/local/zabbix/etc/zabbix_agentd.d/中创建关联nginx status和php-fpm status的子配置文件,创建一个,或者在已有的某配置文件中增加也可以,我这里分别为它们创建配置文件,文件名可自定义,只要确保此文件夹全部内容在zabbix_agentd.conf中包含(include)了。

5.1 userparameter_nginx.conf

[root@monitor-server2 zabbix_agentd.conf.d]# cat userparameter_nginx.conf 
#/usr/local/zabbix/bin/nginx_status.sh
UserParameter=nginx.status[*],/usr/local/zabbix/bin/nginx_status.sh $1  
 #这种写法比较简洁,参考zabbix 3.2.4中自带的的userparameter_examples.conf
UserParameter=nginx.version,/usr/local/nginx/sbin/nginx -v     
#让zabbix-agentd获取nginx的版本信息 ,一切shell指令都推荐使用绝对路径 

5.2 userparameter_php-fpm.conf

[root@monitor-server2 zabbix_agentd.conf.d]# cat userparameter_php-fpm.conf 
#/usr/local/zabbix/bin/php_fpm_status.sh
UserParameter=php-fpm.status[*],/usr/local/zabbix/bin/php_fpm_status.sh $1
UserParameter=php-fpm.version,/usr/local/php/sbin/php-fpm -v | awk 'NR==1{print $0}'   
#获取php-fpm版本信息

5.3 确认子配置文件被zabbix_agentd配置文件包含

确认在/usr/local/zabbix/etc/zabbix_agentd.conf中包含:Include=/usr/local/zabbix/etc/zabbix_agentd.conf.d/且没有被注释。

六、重启zabbix_agentd服务

service zabbix_agentd restart 让zabbix_agentd加载新的配置文件。

七、测试zabbix_get能否取到数据

在zabbix server上使用如下指令测试能否获取到nginx和php-fpm status数值。

[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[ping]'      
1
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[active]'
6
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'nginx.status[requests]'  
1841
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'php-fpm.status[ping]' 
1
[root@monitor-server2 zabbix_agentd.conf.d]# zabbix_get -s 127.0.0.1 -k 'php-fpm.status[conn]'
1247

注意:

  • zabbix_get指令在zabbix server上运行。
  • userparameter_*.conf文件位于zabbix_agentd端。
  • nginx_status.sh和php_fpm_status.sh位于zabbix_agentd端。
  • zabbix-get后-s指定的ip为zabbix-agentd的监听ip。

八、zabbix server上配置相应的模板

这里的模板包含对nginx status和php-fpm status要监控的item、trigger、Graphs等一系列内容。对于在zabbix server上新增要监控的内容,最好的办法就是从模板开始,然后按照顺序依次配置相应内容,无需去网上找现成的模板导入,对于系统的监控按需配置是最好的。下面是相应的操作过程。

8.1 添加nginx status监控模板

未分类

新建nginx status模板

未分类

定义nginx status模板

未分类

新建nginxApplication

未分类

定义nginx status items,这里我使用的是被动临控

未分类

增加nginx status状态码映射

未分类

nginx trigger定义

未分类

定义nginx监控视图

8.2 添加php-fpm status监控模板

php-fpm status的模板添加步骤和上述方法一样,此处不在赘述。

8.3 选择相应的主机或主机组关联上相应的模板

未分类

给主机或主机组关联模板

九、实际监控效果展示

查看监控效果可以通过查看Monitoring—->Latest data,过滤出相应的主机及应用名进行查看,最新收集的各item的监控结果,凡是监控到数据的item会显示数据,出现灰色的表示没有监控到数据,需要排查原因。如下所示:

未分类

nginx的监控数据

也可以通过定义的Graphs查看监控效果:

未分类

nginx statur监控视图

十、小结

zabbix中要实现对用户自定义的item的监控,大致过程如下:

  • 启用相应软件的性能统计功能
  • 编写性能统计数据提取脚本
  • 配置自定义的userparameter conf文件
  • 重启zabbix_agentd服务
  • zabbix server web上添加相应的模板
  • 给主机或主机组调用模板

Nginx 启用 Brotli 压缩

Brotli 是 Google 开发的一种压缩格式,它通过内置分析大量网页得出的字典,实现了更高的压缩比率,同时几乎不影响压缩 / 解压速度。

本站通过 ngx_brotli 模块来让 Nginx 支持 Brotli 压缩方式。本文介绍其配置方式。

安装模块

若要启用 ngx_brotli 模块,需要在编译 Nginx 时,加入相应模块:

# get source

git clone https://github.com/google/ngx_brotli.git

cd ngx_brotli

git submodule update --init

cd ..

# configure

./configure ... --add-module=../ngx_brotli

配置文件

安装完成 ngx_brotli 模块后,你就可以在配置文件里启用它了:

# 配置段: http, server, location

# 开启 ngx_brotli 压缩

brotli on;

# 指定压缩数据的最小长度,只有大于或等于最小长度才会对其压缩。这里指定 20 字节

brotli_min_length 20;

# Brotli 请求缓冲区的数量和大小

brotli_buffers 16 10k;

# Brotli 使用的窗口值。默认值为 512k

brotli_window 512k;

# 压缩水平可以是 0 到 11,默认值是 6。太高的压缩水平对性能提升并没有太大好处,因为这需要更多的 CPU 时间

brotli_comp_level 6;

# 指定允许进行压缩的回复类型

brotli_types text/html text/xml text/plain application/json text/css image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl application/javascript image/x-icon image/jpeg image/gif image/png;

# 是否允许查找预处理好的、以 .br 结尾的压缩文件。可选值为 on、off、always

brotli_static always;

未分类

Nginx+SSL+Tomcat+CDN部署总结

之前在度娘搜索资料,无意间看到一些个人站点的博客都用了https协议,在浏览器地址栏中被标记为绿色的“安全”,前些天特地给自己负责的小项目升级成https协议,其优点这里不再赘述,小伙伴们可以自行百度,今天把整合部署分享在这里,希望小伙伴们少走弯路~

效果如下:

未分类

软件版本如下:

未分类

一、生成SSL证书

首先我们创建一个用来存放letsencrypt生成证书项目的路径并进入:

cd /usr/local/letsencrypt

接下来我们克隆letsencrypt项目:

git clone https://github.com/letsencrypt/letsencrypt

开始生成SSL证书:

./letsencrypt-auto certonly --standalone --email [email protected] -d www.test1.com -d www.test2.com --agree-tos

这里一定注意:

(1). 域名绑定在国内DNS服务器无法生成,需要先将DNS服务器切换到DNS服务商,例如ClouldFlare、Godaddy、Dnsever后才能正常生成!
(2). web服务需要处于关闭状态,注意关闭nginx和80端口的占用!(不间断服务方式生成可以自行百度)
(3). -d 代表domain 可以同时生成多个域名对应证书,生成后我们可以在默认目录中看到:

/etc/letsencrypt/live/www.test.com/
cert.pem(用户证书) 
chain.pem(中间证书) 
fullchain.pem(证书链) 
privkey.pem(证书私钥)

最后我们生成Perfect Forward Security(PFS)键值,具体作用可以自行百度:

mkdir /etc/ssl/private/ -p
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

二、Nginx配置SSL证书及Tomcat代理

    #Tomcat 8080端口
    upstream tomcat_8080{
        server    127.0.0.1:8080  weight=1;
    }

    #将所有http协议内容重定向到https协议
    server {
        listen 80;
        server_name www.test.com;
        rewrite ^ https://$server_name$request_uri? permanent;
    }

    #https协议
    server {
        listen 443;
        server_name www.test.com;

        # letsencrypt生成的文件
        ssl on;
        ssl_certificate /etc/letsencrypt/live/www.test.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/www.test.com/privkey.pem;

        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets on;

        ssl_dhparam /etc/ssl/private/dhparam.pem;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        # 一般推荐使用的ssl_ciphers值: https://wiki.mozilla.org/Security/Server_Side_TLS
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
        ssl_prefer_server_ciphers on;

        # 代理tomcat
        location / {   
            proxy_set_header    Host                $http_host;             
            proxy_set_header    X-Real-IP           $remote_addr;     
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;     
            proxy_set_header    Cookie              $http_cookie;
            proxy_pass          http://tomcat_8080;
            #proxy_redirect     default;
        }

        access_log /home/wwwlogs/www.test.com_access.log;
        error_log  /home/wwwlogs/www.test.com_error.log;
    }

三、Tomcat的SSL配置

1、Connector节点将redirectPort=”8443″修改为 redirectPort=”443″ proxyPort=”443″最终为:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443" proxyPort="443" />

2、找到Engine节点,在最后一个Host标签后加入:

<Host name="www.test.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
    <Valve className="org.apache.catalina.valves.RemoteIpValve"
        remoteIpHeader="x-forwarded-for"
        remoteIpProxiesHeader="x-forwarded-by"
        protocolHeader="x-forwarded-proto"/>
    <Context docBase="/www/java/projectName" path="" crossContext="true" debug="3" privileged="true"  reloadable="false" deubt="true" />
</Host>

四、CloudFlare CDN设置(这里很重要)

我们将域名解析到自己服务器后,点击Crypto选项卡,将SSL状态修改为Full(strict)模式,在这种模式下会使用你服务器中的ssl证书,否则会导致页面无限301跳转,导致chrome提示重定向次数过多,请求失败!

php nginx 实时输出

PHP 里开启实时输出方法是ob_implicit_flush(),
但它大部分情况下都不管用,

因为php.ini配置里output_buffering输出缓冲大部分是On开启的,
还有zlib.output_compression也经常会被开启,

除了 PHP 这一层,还有 Nginx 的缓冲设置proxy_buffering,和压缩gzip也大都是开启的。
为了一两个页面的需求,修改整个服务器的网站配置,恐怕没有人会做这种选择。

这里推荐一下简单的方法:

set_time_limit(0);
ob_end_clean();
ob_implicit_flush();

header('X-Accel-Buffering: no'); // 关键是加了这一行。

echo '现在是:'.date('H:i:s').'<br>';
sleep(5);
echo '五秒后:'.date('H:i:s');