由于HTTP明文传输的特性,中间设备可以随意监听、篡改网页内容。运营商和路由器也偶尔会拿HTTP网页挂广告。所以上HTTPS势在必行。
这个站一直托管在阿里云的虚拟主机,基本上免维护。之前也尝试过用VPS自己搭了一个博客站,但是由于水平太菜没过多久就被黑,挂广告了。结果查了半天也没找到在哪挂的。索性全删了,只能放弃。那次应该是某个黑阔大佬的爬虫自动挂的,毕竟一个没有访问量的试验站,专门去挂广告也没什么价值。不过还是让我感受了一把什么叫做力量。从那之后一直心有余悸,只好继续用虚拟主机,惹不起只好躲。
不过HTTPS现在越来越流行,基本要成为标配。HTTP也处处受限,再继续用就越来越落后了。加上最近要用HTTPS做些事情, 所以先拿这个博客站练练手。
决定上HTTPS之后,首先就是要选个服务器。独立IP的VPS,国内的还是太贵。手上有几个日常上网用的美国VPS(日常上网用VPS?身处这片神奇的土地,大家都懂的),这几年用下来,还比较稳定。所以选择其中一个延迟较低的来部署。硬件配置:单核、512M RAM、10G SSD。拿来安装LNMP(Linux、Nginx、MySql、PHP。WordPress的运行环境),然后跑我这个基本没什么访问量的博客站,还是绰绰有余的。
软件方面,操作系统 Ubuntu 18.04 server 64位。 HTTPS证书使用Let’s Encrypt的RSA 2048,这家的证书免费,并且兼容性也很好,目前基本上是个人站的首选。证书有效期三个月,可以配置 Let’s Encrypt的自动续签工具,到期自动续签。 Nginx、MySql、PHP都是直接用apt install的,另外为了方便维护MySql数据库,还安装了PhpMyAdmin,这些基础软件的安装配置方法,可参考相应的官网文档和其他博客文章,在此不再赘诉。
经过上次那次被黑,所以这次需要特别注意安全相关的配置。主要做了以下几方面:
- apt update、apt upgrade 升级系统软件、打系统补丁
- mysql_secure_installation命令配置mysqld,root使用强密码。并且在
/etc/mysql/mysql.conf.d/mysqld.cnf中配置bind-address = 127.0.0.1使mysqld只监听本地IP请求,拒绝外部IP访问。 - PhpMyAdmin和phpinfo这些维护工具,通过Nginx location配置只能本机IP访问。通过本机代理访问时可正常打开,但是非代理访问会被拒绝。
Nginx 站点配置文件 /etc/nginx/sites-available/default :
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name gk969.com; # managed by Certbot
location / {
# Let wordpress process all request by index.php
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
# phpinfo.php
location = /phpinfo.php {
allow 127.0.0.1;
allow 172.96.216.88;
deny all;
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
# phpmyadmin
location ~ .*phpmyadmin.* {
allow 127.0.0.1;
allow 172.96.216.88;
deny all;
location ~ \.php$ {
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/gk969.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/gk969.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# Transform all http request to https request
server {
listen 80 ;
listen [::]:80 ;
server_name gk969.com;
return 301 https://$server_name$request_uri;
}
这样配置过后,可以从阿里云虚拟主机导出网站根目录文件夹和数据库备份,网站文件放入/var/www/html目录下,修改修改 wp-config.php中数据库位置为localhost,用户名密码修改为MySQL中用于wordpress数据库所属的用户名和密码。然后chown修改网站文件所有者为nginx worker用户www-data。PhpMyAdmin配置root用户和密码后即可使用,数据库备份可通过PhpMyAdmin 导入,也可以使用mysql命令 source /path/xxx.sql导入。数据库过程中可能会有阿里云数据库备份与MySQL格式不兼容,根据提示直接编辑修改备份文件中出错的部分重新导入即可。
最后把网站域名指向服务器IP。至此网站已完成搬家,可通过HTTPS访问。但是为了安全,还要考虑备份。毕竟系统漏洞,软件漏洞总是不可避免,目前的配置也不能保证100%安全无虞。备份方案必须假设网站服务甚至root权限都会被攻破,此时要保证网站文件备份和数据库备份不被破坏,至少可以尽快恢复网站到被黑之前的状态。所以备份操作最好是以系统服务方式开机启动并且定期备份,备份文件不能存放到本机。
备份文件的格式传统上一般采用定期压缩文件,但是这种方式难以对比网站文件和数据库的修改内容。因此最好使用版本管理工具Git定期提交,然后push到远程Git仓库。这样可以对比每次修改内容,如果被攻击之后网站文件和数据库被修改,也能被很快查找出来并恢复到修改前的状态。不过远程Git仓库必须能够设置禁止git push -f之类的强制push,这样才能保证远程Git仓库的记录不被恶意清除。gitlab可以设置私有仓库并且默认禁止强制push,所以此网站采用gitlab托管文件备份和数据库备份。mysqldump导出数据库备份时可通过–extended-insert=FALSE,让数据表的每行数据使用独立的insert语句。这样每行数据的增删改均可以被Git方便地按行记录。虽然这样导出的数据库备份文件较大,但是目前网站数据量不大,所以还能接受。
下面是备份脚本,脚本路径添加到/etc/rc.local即可开机启动。
#!/bin/bash
function cp_push(){
mkdir conf
cd conf
cp /etc/nginx/nginx.conf _etc_nginx_nginx.conf
cp /etc/nginx/sites-available/default _etc_nginx_sites-available_default
cp /etc/php/7.2/fpm/php.ini _etc_php_7.2_fpm_php.ini
cp /etc/mysql/mysql.conf.d/mysqld.cnf _etc_mysql_mysql.conf.d_mysqld.cnf
cd ..
rsync -av /var/www/html/ _var_www_html/ --delete
mysql -e "use gk969;show tables;" | tail -n +2 | while read table
do
mysqldump gk969 $table -qc --extended-insert=FALSE --skip-comments > db/$table.sql
done
git add -A
git commit -m "auto"
git push
}
while true
do
cp_push >/dev/null 2>&1
sleep 1d
done