YOLO813

http添加ssl证书和https网站日志实时可视化

    先插入一个与本文无关的前言,在我的认知里,mysql数据库中,类似这种双百分号like %var% 语句应该是使用不了索引的,只有var%这种模糊搜索才可以使用索引,但是在实际测试中,我发现like双百分号也是可以用索引的,例如

SELECT name FROM table WHERE `name` LIKE "%aaaaaaa%" LIMIT 20

    当然,这个是有前提的,就是你查询的这个字段名和where限定条件中的字段名是一致的(上例中是name),假如将搜索字段名换成下例中的other_name或者*或者是name,other_name,那么索引就会失效,即使有other_name的索引:

SELECT other_name FROM table WHERE `name` LIKE "%aaaaaaa%" LIMIT 20

 

    先来讲下web网站如何利用nginx包装ssl,升级成https网站。
    在正文开始之前,我需要先解决一个问题,因为之前为了学习,一直采用的是源码编译nginx,没有采用yum安装(yum会将所有模块都给你安装上),这就导致nginx缺少SSL加密模块http_ssl_module,所以需要重新配置、编译,具体的流程参考之前的Nginx构建高可用集群

    1.我选择的证书提供商是Let’s Encrypt,首先利用python安装certbot,操作如下:

yum install -y python3 && pip install certbot

    安装后,运行certbot --help可以查看用法。

    2.解析域名,在域名提供商那里将域名进行dns解析至你服务器的公网IP,一般来讲TTL设置为最低600,几分钟就生效了。

    3.开始获取证书,certbot 默认使用http方式对域名所有权进行验证,该操作需要使用云服务器的80端口,查看80端口是否被占用

lsof -i:80

将其关闭掉,请注意,如果是国内的阿里或腾讯云服务器,还需要在安全组配置80端口放行。

killall httpd # Apache
killall nginx # nginx

standalone,运行独立的Web服务器进行身份验证;-d,DOMAINS,以逗号分隔的域列表,以获取证书;certonly,获取或续订证书,以上摘录至帮助文档:

certbot certonly --standalone -d example.com -d www.example.com

按部就班的yes or no就可以了,接下来查看证书安装情况及到期时间,可以看到到期日期及Certificate Path和Private Key Path(这两个路径后面有用),不记得也没关系,使用find命令多查几次就熟了:

certbot certificates

    4.配置nginx的虚拟主机,我还是开放了http服务的,只不过将其全部重定向至https了,注意下ssl_certificate和ssl_certificate_key这里填写刚刚获取到的证书和秘钥位置。

server {
    listen       80;
    server_name  www.example.com example.com;
    rewrite ^(.*) https://$host$1 permanent;
}
# HTTPS server
server {
   listen       443 ssl;
   server_name  www.example.com example.com;
   ssl_certificate      /etc/letsencrypt/live/example.com/fullchain.pem;
   ssl_certificate_key  /etc/letsencrypt/live/example.com/privkey.pem;
   ssl_protocols       TLSv1.3;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;
   ssl_session_tickets off;
   ssl_ciphers  HIGH:!******MD5;
   ssl_prefer_server_ciphers  on;
}

我是编译的nginx,检查一下,配置文件是否有问题,然后启动nginx。

打开https服务(或者打开SSL默认监听端口号443),

firewall-cmd --permanent --add-service=https
firewall-cmd --reload

这时候,打开你自己的网站,应该是可以看到锁的存在了,如果网站还是无法打开,照例,请先检查云服务器的安全组

    5.证书自动续期,免费的ssl证书90天过期,我们还得搞个自动续期才好。

使用crontab -e或者直接编辑/etc/crontab文件随你,如下

# renew the ssl certificates
00 00 */2 * * root /usr/local/python38/bin/certbot renew; systemctl restart nginx.service

使用which certbot可以查看刚刚安装的certbot绝对路径,为什么我的服务器nginx是源码编译,但是带了个nginx.service呢?因为我也仿照大佬们写了个nginx服务脚本,虽然我是菜鸟,但也有一颗变强的心啊

vim /usr/lib/systemd/system/nginx.service
[Unit]
# 20210310 zhangxiaofei
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
# Nginx will fail to start if nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload # 重启已生效

这样,就可以直接使用systemctl来管理nginx了,而不用像之前要进入一大堆的路径来启动nginx,扯远了,以上就是ssl证书申请的一些步骤了。

 

    接下来就是写一下关于https网站利用goaccess进行实时可视化。其实之前的文章利用GoAccess实现nginx日志可视化也介绍过,但是只针对于http类型的网站,自己在对https的nginx日志进行实时可视化还是发现有些坑要踩,故备注下来,以下内容有跳跃,请尽量参考官网一起查看。

    1.源码编译安装,相较上一篇文章介绍的enable-geoip这次选择的是mmdb,因为需要在htttps网站上实现实时可视化,所以增加了with-openssl模块,

./configure --enable-utf8 --enable-geoip=mmdb --with-openssl --prefix=/usr/local/goaccess

我先解释下我为什么要使用mmdb(也是官网现在的推荐)而不使用legacy,第一,GeoIP2数据库更强,第二,它可以将IP定位到城市,可能之前稍微使用过goaccess的用户都知道,使用legacy确实很方便,只需要安装一个Geoip的库即可,但是它只能将IP锁定到洲、国家级别,感觉很鸡肋,但是GeoIP2数据库则完全不一样了。我们将其进行编译安装之后,可能有的用户很快发现不管怎么配置,输出报告中都没有地理位置的出现。

    2.想要进行定位,必须要使用MaxMind的GeoIP,在goaccess官网手册中,下拉到GEOLOCATION OPTIONS一行,做了GeoIP Legacy和GeoIP2的解释,大致内容就是需要去MaxMind网站下载城市数据库,我将下载链接放在了下方参考中,进入网站,注册,邮箱激活,登录进去,大概是这么个画面

前往下载,我选择的是城市数据库

下载完成之后,上传至服务器的目录,我上传的是自己新建的GeoIP目录,

/usr/local/share/GeoIP
>>GeoLite2-City_20210316.tar

对这个文件解压之后是一个目录,进入里面,大概是以下几个文件,其中mmdb后缀文件就是我们接下来需要的:

COPYRIGHT.txt  GeoLite2-City.mmdb  LICENSE.txt  README.txt
#当前我所在目录为
pwd
/usr/local/share/GeoIP/GeoLite2-City_20210316

    3.事先声明下,此时我的goaccess配置文件已经做了简单修改,主要是将日期格式注释去掉了(分别是13行,36行,65行),关于这些参数具体是什么含义,也可以参考之前的那篇goaccess文章

time-format %H:%M:%S
date-format %d/%b/%Y
#log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"
log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u" ~h

    4.输出实时可视化且带有IP解析的中文报告,以下的代码应为一行,为了看的方便我将其进行了拆分:

LANG="zh_CN.UTF-8" bash -c '
/usr/local/goaccess/bin/goaccess -d
/usr/local/nginx/logs/access.log -o
/usr/local/nginx/html/report/index.html --real-time-html --daemonize
--ssl-cert=/etc/letsencrypt/live/example.com/fullchain.pem
--ssl-key=/etc/letsencrypt/live/example.com/privkey.pem
--html-report-title="zhangxiaofei"
--geoip-database=/usr/local/share/GeoIP/GeoLite2-City_20210316/GeoLite2-City.mmdb'

    解释如下,因为我想获得中文报告,但是Linux系统语言为英文,我又不想将其语言修改成中文,所以LANG="zh_CN.UTF-8" bash -c '..'就解决了输出报告为中文而且不用修改系统语言的问题,注意引号;-d表示在HTML或JSON输出上启用IP解析器(反解析),输出到index.html中,--real-time-html --daemonize 应该不用解释了吧,--ssl-cert和--ssl-key就是指定自己ssl证书所在的文件路径,--html-report-title指定标题,--geoip-database,用于指定我们刚刚下载的GeoIP2城市数据库,可以看到正是我们需要的GeoLite2-City.mmdb文件,进入到报告里面,可以看到访问的IP所在城市也被解析出来了

    这些参数信息其实也都可以写入到goaccess的配置文件,但是我也就运行一次(因为后续都是实时更新),就懒得去修改配置文件了。

    另外,我已经通过htpasswd做了一个用户名验证,所以可以安心的放在公网上进行浏览,但是因为我也是初步了解nginx和htpasswd,所以就犯了一个低级错误,以下是正确的的写法,一开始我将auth_basic写到了server下,所以所有的用户访问网站都变成了需要登录,还好及时发现,将其放到了location里面

location /report {
  auth_basic "xiaofei";
  auth_basic_user_file /usr/local/nginx/pwd/htpasswd;
  alias /usr/local/nginx/html/report/;
}

    这里面还有些需要注意,如果你没有指定端口,则goaccess默认运行在7890端口上,安全组和防火墙都需要放行此端口,否则输出的报告无法实时更新数据。

 

参考:

#MaxMind
https://dev.maxmind.com/geoip/geoip2/geolite2/
https://goaccess.io/download