Qtunnel 加密数据库主从复制通道
Qtunnel 加密数据库主从复制通道
链接见:
https://github.com/getqujing/qtunnel https://github.com/arstercz/qtunnel
背景
在异地机房的环境下, MySQL 数据同步复制基于 tcp 的明文传输, slave 接收到的 sql 语句可以很容易的被监听到, 对于敏感数据, 这种简单的异地复制是很危险的方式. 当然机房之间如果已经打通或有 vpn 互相通信就可以忽略该文的介绍. 另外也可以通过 MySQL 内置的 tls/ssl 方式实现复制, 不过该方式对应用的访问性能可能造成影响, 也容易影响线上的数据库架构, 详见 https://dev.mysql.com/doc/refman/5.6/en/ssl-connections.html
qtunnel 介绍
qtunnel 是一款用于加密 client 和 server 之间链路通信的工具, 类似的工具有 Stunnel 和 stud . qtunnel 默认使用 rc4 加密算法来加密数据, rc4 是一种类似 DES 的对称加密算法, 它以字节流的方式加密明文中的每一个字节, 解密也是依次对对密文中的每个字节进行解密, 该算法比较简单, 运行速度快, 另外因为 rc4 的密钥长度可变(1-256字节), 所以可以很好的抵御暴力搜索密钥的攻击, 详见 https://en.wikipedia.org/wiki/RC4
另外 Stunnel 和 stud 工具都是基于 ssl/tls 环境配置的工具, 增加了认证配置稍显复杂, qtunnel 则不需要这些, 可以比较轻量且快速的加解密 client 到 server 端之间的数据.
完整的访问如下所示, slave 以明文方式通信,经过 qtunnel client 加密后发送到 qtunnel server, server 端再进行解密, 传到 master; master 的响应也以此方式完成.
+---------+ +----------------+ qtunnel 加解密 +----------------+ +--------+
| slave | ---> | qtunnel client | ------------------> | qtunnel server | ---> | master |
+---------+ +----------------+ +----------------+ +--------+
Note: 笔者在原工具的基础上重新 fork 该工程, 增加了配置选项, 可以支持多连接运行, 同时支持了以 daemon 模式运行程序.
qtunnel 使用
qtunnel 常用选项包括:
Usage of qtunnel:
-backend="127.0.0.1:6400": host:port of the backend
-clientmode=false: if running at client mode
-conf="": read connection setup from config file
-crypto="rc4": encryption method
-daemon=false: running in daemon mode
-listen=":9001": host:port qtunnel listen on
-logto="stdout": stdout or syslog
-secret="secret": password used to encrypt the data
listen 等同下面的 faddr 选项, 为本地监听地址, 指定 conf 选项后, 其它的加密算法的选项可以忽略.
- 在明文环境中, 使用 tcpdump 来监听 MySQL 端口, 可以很方便的看到 sql 语句以及相关的事务语句信息, 如下:
# tcpdump -s 0 -l -w - port 23301 | strings
SYSTEM
BEGIN
SYSTEMuser_test
insert into user_msg(type, app_id, user_id, title, content, create_time, update_time, expire_time) values(3, null, 39871, '
', '
2015-11-05 14:12:14
iPhone 6 (xxxxxxx)
- iOS
', now(), now(), '2015-11-15 14:12:14')
SYSTEM
BEGIN
SYSTEMtest
可以看到在公网环境中, 明文传输方式是很危险的.
- 下面来看看 qtunnel 的配置, 我们在一台机器中配置 qtunnel 的 server 模式, 如下:
# cat /etc/conn.con
[server1]
faddr = 10.0.21.5:23301
baddr = 10.0.21.7:3301
cryptoMethod = rc4
secret = 3301_test%Iad # rc4 密钥
clientmode = false
[server2]
faddr = 10.0.21.5:23302
baddr = 10.0.21.7:3302
cryptoMethod = rc4
secret = 3302_test$sOc
clientmode = false
qtunnel 以转发的方式在本地启动一个监听端口, 转发到后端的数据库主机, 该方式类似传统的 rinetd 工具; 启动 qtunnel:
qtunnel -conf=/etc/conn.conf -daemon -logto=syslog
[root@cz1 ~]# netstat -tunlp|grep qtun
tcp 0 0 10.0.21.5:23301 0.0.0.0:* LISTEN 9504/qtunnel
tcp 0 0 10.0.21.5:23302 0.0.0.0:* LISTEN 9504/qtunnel
- 在另一台机器配置 qtunnel 的 client 模式:
因为 rc4 是对称加密, 所以 client 端的密钥需要和 server 端保持一致.
[client1]
faddr = 10.0.21.3:30031
baddr = 10.0.21.5:23301
cryptoMethod = rc4
secret = 3301_test%Iad
clientmode = true
[client2]
faddr = 10.0.21.3:30032
baddr = 10.0.21.5:23302
cryptoMethod = rc4
secret = 3302_test$sOc
clientmode = true
启动 qtunnel
# qtunnel -conf=/etc/conn.conf -daemon -logto=syslog
[root@cz3 test]# netstat -tunlp|grep qtunnel
tcp 0 0 10.0.21.3:30031 0.0.0.0:* LISTEN 1519/qtunnel
tcp 0 0 10.0.21.3:30032 0.0.0.0:* LISTEN 1519/qtunnel
重新修改内网 slave 指向, slave 指到 qtunnel client 端:
# stop slave
# CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=62778, MASTER_HOST='10.0.21.3', MASTER_PORT=30031, MASTER_CONNECT_RETRY=10;
# start slave
- 再看看qtunnel server 端加密后的 tcpdump 监听:
# tcpdump -s 0 -l -w - port 23301 | strings
#}?P
[~/e
+WlA
TS@F^
?k*L
m=R~
^o}
{C\1
rsYU
ax&A
u4|.
iN0K
Omv[
u~n
m=R~
m=R~
]e ,
Out~
QQu@a
#r6)
*n2"
总结说明 qtunnel 采用 rc4 加密, 在算法强度和速度方面是很好的选择, 不会引起 slave 太大的延迟, 对管理员或开发而言数据都是透明的, 只是在两端传输的过程中增加了加解密处理. 核心的业务(比如用户和充值)在做异地架构的时候可以考虑该方式增强数据的安全性.