换上了用Let's Encrypt Closed Beta自己签发的证书

先上图。两个小时的成果。
letsencrypt

在10月31的时候就收到了letsencrypt发的 Let’s Encrypt Closed Beta Invite‏ 说我的tms.im和www.tms.im已经加入内测白名单。可惜这封邮件被“智能”的丢进了垃圾邮件文件夹。导致我今天才看到。于是来折腾一下。

在开始之前先严重吐槽下,可能是由于内测或者该计划刚开始还不完善的原因。这个东西特别特别特别不亲民。我搞了两个多小时才签了一个证书出来。突然发现只签了tms.im没签www.tms.im。于是又用了40分钟的时间重新签了这两个。外加这货的有效期只有三个月,也就是说三个月以后我要重新签。在现在年付的付费证书已经这么便宜的情况下。到底letsencrypt有没有竞争力。

下面正文。

由于现在还是内测。官方在邮件里提供了一个内测用的API路径。

To use Let’s Encrypt’s official client to obtain your real
certificates, you will need to provide the production API URL on the
command line:

https://acme-v01.api.letsencrypt.org/directory

还提供了软件

git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt
./letsencrypt-auto --agree-dev-preview --server
https://acme-v01.api.letsencrypt.org/directory auth

但是装好软件以后运行./letsencrypt-auto报错。

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-Wa1Lwq/ConfigArgParse

去官方论坛https://community.letsencrypt.org/看了一下说只支持python2.7,不支持2.6。 好吧我centos6.7默认是2.6的python。也懒得搞成2.7了,于是另开了一台centos7的服务器来签发。

执行./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth -d tms.im -d www.tms.im

   报错The program nginx (process ID 7176) is already listening on TCP port 
    80. This will prevent us from binding to that port. Please stop the  
    nginx program temporarily and then try again.      

提醒我80端口被占用。验证个域名所有权还要关80端口额。还好只是个个人博客。如果我是生产用的域名和服务器怎么办。总不能停机去搞域名验证吧。

暂时停了80的nginx。终于进到了下一步。然后又开始报错

Failed authorization procedure. tms.im (dvsni): unauthorized :: The client lacks sufficient authorization :: Correct zName not found for TLS SNI challenge

只好切换用手动模式:后面加一个
-a manual

手动模式告诉我需要自己开一个 SimpleHTTPServer 来搞验证,并且给了我一堆指令。我以为它会自动开呢。用netstat看了一下,果然没有自动开。好吧我只好手动调用python开一个SimpleHTTPServer 。然后按照每次验证它给的路径和文件名和文件内容创建对应的验证文件。

当我以为这样就可以通过验证的时候,letsencrypt告诉我还是tooyoung

:: The client lacks sufficient authorization :: Invalid response from http://tms.im/.well-known/acme-challenge/g2eyBgAf3Z-NpzBAzTrvxopLxJ1PH1I8lt7sqiA01sQ [103.242.111.8]

什么。不是已经开好SimpleHTTPServer 了么。我的SimpleHTTPServer 里也有access log啊。我在浏览器打开也可以访问啊。再仔细一看IP是103.242.111.8。这,我不是改了DNS指向验证用的这台服务器了么,为什么非要去以前的服务器验证。

可能是远程API那边DNS更新比较慢吧。可是我用nslookup看了一下主要的几个DNS服务器都更新过了啊。鬼知道他们用的什么DNS,或者是就是有机制让你不能改IP验证?谁知道呢。只好在以前的服务器上也开了个SimpleHTTPServer,放入同样的验证文件。再进行验证。

这下终于生成成功了。最新的证书和私钥都在/etc/letsencrypt/live/$domain里面。内测阶段只能签三个月的证书。

/etc/letsencrypt/keys里面存的是所有的包括之前和最新的证书。

最好把整个/etc/letsencrypt目录都备份一下,里面是包括邮箱和token之类的东西。以后renew的时候用的。

折腾了两个多小时签发出第一张免费证书。letsencrypt还有很长的路要走啊。

本站启用nginx的HTTP/2新特性

今天新配服务器,到nginx官网下载源码,瞬间看到

2015-09-22 nginx-1.9.5 mainline version has been released, featuring experimental HTTP/2 module.

Nginx终于原生支持HTTP/2了。早就听闻HTTP/2的一大堆优秀的新特性。马上开启尝尝鲜。

根据官网的说明,在编译的时候configure时加入–with-http_v2_module即可编译带ngx_http_v2_module的nginx

The ngx_http_v2_module module (1.9.5) provides support for HTTP/2 and
supersedes the ngx_http_spdy_module module.

This module is not built by default, it should be enabled with the
–with-http_v2_module configuration parameter.

编译成功后在conf文件里把listen 443 ssl改为 listen 443 ssl http2即可开启http2支持

server {
    listen 443 ssl http2;
}

开启完毕,马上验证一下

开启前:

开启前

开启后

开启后

速度提升将近一倍,头部压缩、压缩HTTP头等特性表现的很明显,初始化连接和ssl的损耗都已经降到最低。看来HTTP/2的优化还是很给力的,期待更多的网站支持HTTP/2

参考阅读:
Module ngx_http_v2_module
View the HTTP/SPDY/HTTP2 Protocol in Google Chrome

跨IDC数据备份

为了数据安全性。除了做了主从和多机互备份以外,在异地容灾和数据备份方面也不容忽视。
这里是实现跨IDC数据备份的一种思路。分为文件备份和数据库备份两部分。文件备份可以保证用户上传的文件,图片和网站的代码不会丢失。而数据库备份则是数据保护的重中之重。
之所以采用跨IDC进行数据备份也是考虑到数据的安全性和同IDC的网络崩溃和主机崩溃的可能性。

文件备份

文件数量和大小决定了需要做到文件同步备份必须采用增量备份的方式。传统的方法是使用 inotify + rsync 来进行同步备份。
这里采用Sersync 来进行服务器间文件同步。

配置 Slave 上的 WWW 同步

Slave上安装rsync
然后配置文件写明,其中rsync.pass里面写入密码

log file = /var/log/rsyncd.log 
pidfile = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock  
secrets file = /etc/rsyncd/rsync.pass
[tongbu]
path = /home/wwwroot/
comment = tongbu
uid = root
gid = root
port=873
use chroot = no
read only = no
list = no
max connections = 200
timeout = 600 
auth users = tms
hosts allow = 主机的IP

最后启动Rsync的 rsync –daemon

启动 Master 上的 Sersync 做数据同步

主机上配置sersync

 <sersync>
	<localpath watch="/home/wwwroot">
	    <remote ip="远程IP" name="tongbu"/>
	</localpath>

其他配置略

第一次启动加上 -r 参数做首次同步,之后就不要再加  -r 参数了
./sersync2 -n 2 -d -r -o confxml.xml

文件备份到此结束。

数据库备份

数据库备份这里采用主从的方式,而这里的slave纯粹做备份使用。无业务访问他。
前期准备工作步骤如下:
1、修改备份服务器上my.cnf中的server-id

2、登录主服务器创建同步账号GRANT REPLICATION SLAVE ON . TO ‘slave’@‘Slave服务器IP’ IDENTIFIED BY ‘password’;

备份主服务器步骤:
1、FLUSH TABLES WITH READ LOCK;

2、cp -ar /var/lib/mysql /home/DATA/tmp

3、show master status;并且记录file和position

4、UNLOCK TABLES;

复制主服务器的/home/DATA/tmp到从服务器并且替换mysql的var目录

登录从服务器的mysql

CHANGE MASTER TO
 
    ->     MASTER_HOST='master_host_name',
 
    ->     MASTER_USER='replication_user_name',
 
    ->     MASTER_PASSWORD='replication_password',
 
    ->     MASTER_LOG_FILE='前面让你记录下的 master 状态显示的 logfile 名字',
 
    ->     MASTER_LOG_POS=前面记录下的 postion;

START SLAVE;

show slave status \G

这样Master —> Slave 就运行起来了。数据库备份结束。

为了进一步的安全考虑,采用crontab每隔一天做一次全量备份,在备份服务器进行。脚本如下

#!/bin/bash
DBName=数据库名
DBUser=备份用户
DBPasswd=备份用户的密码
BackupPath=/root/Dropbox/   #保存到同步目录

LogFile=/root/db.log
DBPath=/var/lib/mysql/ #备份的数据库目录
BackupMethod=mysqldump
#BackupMethod=mysqlhotcopy
#BackupMethod=tar

NewFile="$BackupPath"db$(date +%y%m%d).tgz
DumpFile="$BackupPath"db$(date +%y%m%d)
OldFile="$BackupPath"db$(date +%y%m%d --date='5 days ago').tgz  #自动删除5天前的备份
echo "-------------------------------------------" >> $LogFile
echo $(date +"%y-%m-%d %H:%M:%S") >> $LogFile
echo "--------------------------" >> $LogFile
#Delete Old File
if [ -f $OldFile ]
then
        rm -f $OldFile >> $LogFile 2>&1
        echo "[$OldFile]Delete Old File Success!" >> $LogFile
else
        echo "[$OldFile]No Old Backup File!" >> $LogFile
fi
if [ -f $NewFile ]
then
        echo "[$NewFile]The Backup File is exists,Can't Backup!" >> $LogFile
else
        case $BackupMethod in
        mysqldump)
                if [ -z $DBPasswd ]
                then
                        mysqldump -u $DBUser --opt $DBName > $DumpFile
                else
                        mysqldump -u $DBUser -p$DBPasswd --opt $DBName > $DumpFile
                fi
                tar czvf $NewFile $DumpFile >> $LogFile 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                rm -rf $DumpFile
                ;;
        mysqlhotcopy)
                rm -rf $DumpFile
                mkdir $DumpFile
                if [ -z $DBPasswd ]
                then
                        mysqlhotcopy -u $DBUser $DBName $DumpFile >> $LogFile 2>&1
                else
                        mysqlhotcopy -u $DBUser -p $DBPasswd $DBName $DumpFile >>$LogFile 2>&1
                fi
                tar czvf $NewFile $DumpFile >> $LogFile 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                rm -rf $DumpFile
                ;;
        *)
                service mysql stop >/dev/null 2>&1
                tar czvf $NewFile $DBPath$DBName >> $LogFile 2>&1
                service mysql start >/dev/null 2>&1
                echo "[$NewFile]Backup Success!" >> $LogFile
                ;;
        esac
fi
echo "-------------------------------------------" >> $LogFile

同时采用dropbox实时上传网盘。保证每日的数据库在云端存有一份备份。

MYSQL主从复制大深坑

今天在配置proxy需要一主多从,配置主库的时候使用了binlog_ignore_db和binlog_do_db参数,结果发现主库的所有的update操作都不写binlog了。导致从库根本不改变。做很多操作可是show master status;里的position一直没有变过。所以从库也不会跟上操作。查阅好多资料无果。突然看到replicate-ignore-db和replicate-do-db这两个参数在从库上使用。于是试了一下。果然是因为主库的binlog_ignore_db和binlog_do_db参数的原因。虽然不知道是为什么。不过这个坑还真是爬了一上午。以后忽略复制在slave上使用replicate-ignore-db和replicate-do-db不要在主库用binlog参数了。