Category Archives: Nginx

Nginx日志增长过快详细分析

前言:

         Nginx日志里面Mobileweb_access.log增长特别大,一天上百兆,将近100W的访问记录,按照我们目前的规模,热点用户才500个左右,就算人人用手机app访问,怎么可能会有这么大的url访问量?以前只是安装使用nginx,还没有抽出时间仔细研究,这回需要彻底的去分析nginx日志了。

1,日志分类

主要2种,一种是错误日志,一种是访问日志,这些配置都在/usr/local/nginx/conf/nginx.conf里面,默认都是打开的,自己也可以选择关闭。

1.1,访问日志

访问日志主要记录每一个访问nginx的请求,格式可以自己定义,在nginx.conf文件里面,通过访问日志,你可以看到每一个请求的详细信息,对于访问日志的格式,主要是配置文件中的log_format来限制的。

1.1.1 log_format日志格式

$request_time:整个请求的总时间。

$time_iso8601:访问的时间与时区,比如18/Jul/2012:17:00:01 +0800,时间信息最后的”+0800″表示服务器所处时区位于UTC之后的8小时。

$upstream_response_time:请求过程中,upstream的响应时间。

$request_method:客户端请求的动作,通常为GET或POST。

$request_uri:是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。

$args:这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah;

$query_string:与$args相同。

$proxy_add_x_forwarded_for:变量包含客户端请求头中的”X-Forwarded-For”,与$remote_addr用逗号分开,如果没有”X-Forwarded-For” 请求头,则$proxy_add_x_forwarded_for等于$remote_addr。

$upstream_addr:upstream的地址,即真正提供服务的主机地址。

$status:记录请求返回的http状态码,比如成功是200。

$http_user_agent:客户端浏览器信息

$http_range

$sent_http_content_length:发送内容的长度

$body_bytes_sent:发送给客户端的文件主体内容的大小,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量。

$http_referer:记录从哪个页面链接访问过来的。

$host:请求主机头字段,否则为服务器名称。

$http_x_forwarded_for:客户端的真实ip,通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

$http_user_agent:客户端浏览器信息

$body_bytes_sent:发送给客户端的文件主体内容的大小,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量。

$ssl_protocol:SSL协议版本,比如TLSv1。

$ssl_cipher:交换数据中的算法,比如RC4-SHA。

生产环境上的范例:

log_format  main  ‘$proxy_add_x_forwarded_for  $remote_user [$time_local] “$request” ‘

                      ‘$status $body_bytes_sent “$http_referer” ‘

                      ‘”$http_user_agent” “$http_x_forwarded_for” ‘

                      ‘upsteam: $upstream_addr’;

    access_log  logs/access.log  main;

    log_not_found off;

1.1.2,访问日志路径

access_log  logs/access.log  main;

Nginx支持为每个location指定强大的日志记录。同样的连接可以在同一时间输出到不止一个的日志中。如果想关闭日志,可以如下:

access_log off;

能够使用access_log指令的字段包括:http、server、location。

PSNginx进程设置的用户和组必须对日志路径有创建文件的权限,否则,会报错。

1.2,错误日志

错误日志主要记录客户端访问Nginx出错时的日志,格式不支持自定义。通过错误日志,你可以得到系统某个服务或server的性能瓶颈等。因此,将日志好好利用,你可以得到很多有价值的信息。错误日志由指令error_log来指定,具体格式如下:

error_log path(存放路径) level(日志等级)

        path含义同access_log,level表示日志等级,具体如下:

        [ debug | info | notice | warn | error | crit ]

    从左至右,日志详细程度逐级递减,即debug最详细,crit最少,举例说明如下:

        error_log  logs/mobileweb_error.log error;

    需要注意的是:error_log off并不能关闭错误日志,而是会将错误日志记录到一个文件名为off的文件中。正确的关闭错误日志记录功能的方法如下:

        error_log /dev/null;

    上面表示将存储日志的路径设置为“垃圾桶”。

2,为每一个工程定义特定的日志

location ~* ^/mobileWeb/.*$ {

           client_max_body_size 5m;

           include deny.conf;

           proxy_pass http://mobilewebbackend;

           include proxy.conf;

           error_log  logs/mobileweb_error.log error;

           access_log  logs/mobileweb_access.log  main;

           include gzip.conf;

}

这样,就会在日志路径/usr/local/nginx/logs/下面生成mobileWeb工程的专门日志mobileweb_error.log 以及mobileweb_access.log 日志,如果想查询mobileWeb工程的访问记录,就可以单独去查看这2个日志。

3,开始分析

根据来源ip进行分组统计分析,看看哪个ip的访问量最多

[root@wgq_idc_web_1_21 tmp]# cat mobileweb_access.log |grep “14/Oct/2014” |awk ‘{print $1}’|sort -nr |uniq -c |sort -nr |more

705980 1xx.xx.xx.185,

190273 6x.1×4.1xx.35,

14900 1xx.xxx.xx.xx3,

14670 1xx.xxx.x3.8x,

结果发现,这几个ip都是我们公司广场公用的wifi出口ip地址,属于安全地址,不是私人的IP地址,很大程度上排除了从外部恶意攻击我们网站的可能性。接下来就需要重点分析,为什么会有这么多的URL记录。

仔细排查来源为1xx.xx.xx.185的日志记录,发现有很多$http_user_agent为空的记录,大概90%的记录都是如此,看记录如下:

1xx.xx.xx.185, 10.2xx.xx1.xx0 – [10/Oct/2014:10:52:11 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “1xx.xx.xx.185″upsteam: 110.xx7.1.22:7100

猜测是否不是手机app访问的记录?只有自己停掉wifi,用手机的4G网络,去登录我们的移动app应用,操作完,点击了几下赞,访问了一些页面,操作时间2分钟,然后使用自己的移动4Gip地址“2xx.10x.5.129”去检索下nginx下的mobileweb的记录,4台nginx记录,每一台40个左右url访问,4台就是160个记录,下面是一台的记录

[root@wgq_idc_web_1_22 logs]# more mobileweb_access.log |grep “2xx.10x.5.129”

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:01 +0800] “POST /mobileWeb/userMobileCenter/queryUserNameAndIconByIds.htm? HTTP/1.1” 200 20 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:37 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:42 +0800] “POST /mobileWeb/square/query.htm? HTTP/1.1” 200 9485 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:42 +0800] “POST /mobileWeb/square/query.htm? HTTP/1.1” 200 9485 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:49 +0800] “POST /mobileWeb/square/clickSupport.htm? HTTP/1.1” 200 46 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:51 +0800] “POST /mobileWeb/square/clickSupport.htm? HTTP/1.1” 200 46 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:54 +0800] “POST /mobileWeb/square/clickSupport.htm? HTTP/1.1” 200 46 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:55 +0800] “POST /mobileWeb/square/query.htm? HTTP/1.1” 200 4831 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:54:57 +0800] “POST /mobileWeb/userMobileCenter/queryUserNameAndIconByIds.htm? HTTP/1.1” 200 20 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:03 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:04 +0800] “POST /mobileWeb/version/queryVersion.htm? HTTP/1.1” 200 160 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:06 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:06 +0800] “POST /mobileWeb/mobile/loadCart.htm? HTTP/1.1” 200 940 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:07 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:07 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:07 +0800] “POST /mobileWeb/userMobileCenter/findAllinterfaceVersion.htm? HTTP/1.1” 200 411 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:13 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:56 +0800] “POST /mobileWeb/userMobileCenter/queryUserNameAndIconByIds.htm? HTTP/1.1” 200 20 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:57 +0800] “POST /mobileWeb/userMobileCenter/findAllinterfaceVersion.htm? HTTP/1.1” 200 411 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:58 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:58 +0800] “POST /mobileWeb/version/queryVersion.htm? HTTP/1.1” 200 160 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:55:59 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:00 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:06 +0800] “POST /mobileWeb/userMobileCenter/findAllinterfaceVersion.htm? HTTP/1.1” 200 411 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:07 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:07 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:08 +0800] “POST /mobileWeb/version/queryVersion.htm? HTTP/1.1” 200 160 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:08 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:08 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:16 +0800] “POST /mobileWeb/userMobileCenter/queryUserNameAndIconByIds.htm? HTTP/1.1” 200 20 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:19 +0800] “POST /mobileWeb/userMobileCenter/findAllinterfaceVersion.htm? HTTP/1.1” 200 411 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:21 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:21 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:23 +0800] “POST /mobileWeb/userMobileCenter/queryUserNameAndIconByIds.htm? HTTP/1.1” 200 20 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:23 +0800] “POST /mobileWeb/userMobileCenter/findAllinterfaceVersion.htm? HTTP/1.1” 200 411 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:24 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:24 +0800] “POST /mobileWeb/userMobileCenter/queryAdvertisement.htm? HTTP/1.1” 200 5175 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:24 +0800] “POST /mobileWeb/version/queryVersion.htm? HTTP/1.1” 200 160 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:25 +0800] “POST /mobileWeb/userMobileCenter/unReadNumsMobile.htm? HTTP/1.1” 200 239 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:56:25 +0800] “POST /mobileWeb/mobile/getCartItemNum.htm? HTTP/1.1” 200 114 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:14:57:37 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:00:37 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:02:07 +0800] “POST /mobileWeb/userMobileCenter/messageListMobile.htm? HTTP/1.1” 200 106 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:02:08 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:02:37 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:05:07 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:05:08 +0800] “POST /mobileWeb/push/query.htm? HTTP/1.1” 200 97 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:05:37 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.21:7100

2xx.10x.5.129, 10.2xx.xx1.xx0 – [16/Oct/2014:15:11:44 +0800] “POST /mobileWeb/square/queryCounts.htm? HTTP/1.1” 200 82 “-” “-” “2xx.10x.5.129″upsteam: 110.xx7.1.22:7100

[root@wgq_idc_web_1_22 logs]#

看到了我的访问url记录,其中$http_user_agent几乎都是为”-”空记录,奇怪,我也是用手机访问的,询问andriod开发人员,他说有些低版本的手机在记录$http_user_agent后退回去会报错返回空界面,所以后来就不记录$http_user_agent信息了。

原来如此,而且看到这么多url全是我访问过的,移动mobileweb后台开发人员说,移动app一个页面里面有许多url需要加载,所以你访问1个页面就会加载N个link连接去取各种数据值。分析道这里,已经差不多明了:就是一个登录用户访问页面,会加载N(N>10)个link连接url,这些url都被记录在nginx访问日志里面,短短2分钟内,我访问了一些页面,就有160个左右的记录,照这么算下来,一个小时就是5000个左右的记录,一天平均25分钟分钟,500个用户个就是SELECT 5000*25/60*500=1041667,差不多100W左右了,通常来说nginx日志的量比较大是正常的。

           其中,半夜1点到6点左右,这个公司广场wifi的ip地址还会不停的访问mobileweb,经过分析是由于登录了移动app应用,但是睡觉了没有退出应用,手机也没有关系,所以导致移动app依然不停的在访问mobile应用(因为1分钟左右会刷新一次去获取访问当前登录用户的站内互动消息)。

      从此可以看出nginx的访问日志记录了用户的所有访问行为记录,而且详细到每一个页面里内嵌的url记录,如果用适当的工具仔细分析nginx日志,就会大概摸清楚用户的访问习惯,这些数据对于市场部门、产品部门来说,是非常有价值的。

申請 Let’s Encrypt 免費憑證讓網站支援 HTTP2

Letsencrypt

寫這篇最主要推廣讓網站都支援 HTTPS 加密連線及 HTTP2 協定,對於網站為什麼要支援 HTTP2,可以直接參考 ihower 寫的說明文章,最近在玩 Facebook, Line, Telegram Bot 時,填寫 Webhook URL,都強制要填寫 https:// 開頭,所以更不能忽略 HTTPS 了。,去年底寫了一篇 Let’s Encrypt 開放申請免費 SSL 憑證 推廣 Let’s Encrypt 的貢獻,讓買不起憑證,又想玩看看 HTTP2 的開發者可以用很簡單的方式來安裝及自動更新憑證,而 gslin 大為了推廣 HTTPS 也做了一個網站教學,文章寫得相當清楚,支援 Apache 及 Nginx 設定。

安裝方式

如果主機是使用 Amazone EC2,可以直接用 AWS Certificate Manager,用 AWS 的好處就是只要透過後台介面搭配 ELB 就可以直接設定好 HTTPS 對應到 EC2 主機,壞處就是直接被綁死,將來如果不要使用 AWS,要轉移機器會相當痛苦。所以本篇會紀錄如何用 Nginx 搭配 Let’s Encrypt。為了方便部署機器,我們選用 dehydrated 來設定 Let’s Encrypt,好處就是不用安裝 Python 套件,官方網站提供的安裝方式需要安裝 Python 相關環境。透過 wget 將 dehydrated 安裝到 /etc/dehydrated/ 底下

01
02
03
$ mkdir -p /etc/dehydrated/
$ wget https://raw.githubusercontent.com/lukas2511/dehydrated/master/dehydrated -O /etc/dehydrated/dehydrated
$ chmod 755 /etc/dehydrated/dehydrated

建立設定檔

建立 dehydrated config 設定檔

01
02
$ echo "WELLKNOWN=/var/www/dehydrated" > /etc/dehydrated/config
$ mkdir -p /var/www/dehydrated

Nginx 設定,先在 80 port 的 Server section 內寫入底下設定:

01
02
03
location /.well-known/acme-challenge/ {
  alias /var/www/dehydrated/;
}

可以先丟個檔案到 /var/www/dehydrated/ 確定網站可以正常讀取檔案,接著透過 dehydrated 指令產生 SSL 設定檔

01
$ /etc/dehydrated/dehydrated -c -d fbbot.wu-boy.com

執行上述指令會看到底下結果

01
02
03
04
05
06
07
08
09
10
11
12
13
# INFO: Using main config file /etc/dehydrated/config
Processing fbbot.wu-boy.com
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for fbbot.wu-boy.com...
 + Responding to challenge for fbbot.wu-boy.com...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!

最後在設定一次 nginx

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
  # don't forget to tell on which port this server listens
  listen 80;
  # listen on the www host
  server_name fbbot.wu-boy.com;
  # and redirect to the non-www host (declared below)
  return 301 https://fbbot.wu-boy.com$request_uri;
}
server {
  listen 0.0.0.0:443 ssl http2;
  server_name fbbot.wu-boy.com;
  location /.well-known/acme-challenge/ {
    alias /var/www/dehydrated/;
  }
  ssl_certificate /etc/dehydrated/certs/fbbot.wu-boy.com//fullchain.pem;
  ssl_certificate_key /etc/dehydrated/certs/fbbot.wu-boy.com/privkey.pem;
  location / {
    proxy_pass http://localhost:8081;
  }
}

上面是將 80 port 自動轉到 https,如果下次要重新 renew 的時候才不會又要打開 80 port 一次。

加入 Cron 設定

每天半夜可以自動 renew 一次,請參考 https://letsencrypt.tw/ 最後章節

01
0 0 * * * root sleep $(expr $(printf "\%d" "0x$(hostname | md5sum | cut -c 1-8)") \% 86400); ( /etc/dehydrated/dehydrated -c -d fbbot.wu-boy.com; /usr/sbin/service nginx reload ) > /tmp/dehydrated-fbbot.wu-boy.com.log 2>&1

後記

除了這方法之外,也可以使用 Certbot 來自動更新憑證,但是這方式就是要安裝 Python 環境,不過也不是很難就是了,可以直接參考這篇『NGINX 使用 Let’s Encrypt 免費 SSL 憑證設定 HTTPS 安全加密網頁教學』。結論就是你可以在網路上找到超多種方法來申請 Let’s Encrypt 憑證,就找到自己覺得不錯的方法即可,而我是認為不用安裝 Python 環境的方式最適合部署了。

 

refer by https://blog.wu-boy.com/2016/10/website-support-http2-using-letsencrypt/