Redis RU330课程 Redis Security 第3周学习笔记

Week Overview and Introduction to TLS

TLS用来保证网络通讯安全,在Redis 6中引进,实现3点:

  • Privacy
  • Identity
  • Integrity

Redis Horror Story #3

packet sniffing:拦截未加密的网络数据

upshot:结果

很好的对比例子。
先安装tcpdump:

$ sudo yum install -y tcpdump
hset user:1:secret gender m birthday 20200101
tcpdump port 6379

https://danielmiessler.com/study/tcpdump/

最佳实践:

  • 使用TLS加密传输中的敏感数据
  • 将Redis Server和应用部署在私有网络中

TLS Theory

Encryption

gpg - GNU Privacy Guard

OpenSSL Command Line Utilities

加密算法称为cipher。

encryption key类似于口令,但比口令更长更难记。cipher使用encryption key加密数据。

对称加密指加解密使用同一个key。非对称加密指加解密使用不同的key。

gpg命令包含在以下包中:

$ yum search gnupg2
============================================================== N/S matched: gnupg2 ===============================================================
gnupg2.x86_64 : Utility for secure communication and data storage

来看一个对称加密的例子,此处使用的算法是AES256:

$ hexdump -c input.txt
0000000   H   e   l   l   o       W   o   r   l   d   !  \n
000000d

# 以下命令会要求输入两次加密口令
$ gpg --symmetric --cipher-algo AES256 --output output.txt input.txt
gpg: directory `/home/vagrant/.gnupg' created
gpg: new configuration file `/home/vagrant/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/vagrant/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/vagrant/.gnupg/pubring.gpg' created

$ hexdump -c output.txt
0000000 214  \r 004  \t 003 002 224   T 333   u 322 346   g   } 347 322
0000010   K 001 313   S 026 336 303   R 022   Y   , 373   l 361   6   ]
0000020   0   3   A 312   d 005 266 243 266 274   V 016 232 376 372 320
0000030 321   \ 316 314 372   & 332 216 214 004   n   ( 370 261 016   9
0000040 353 340 316 200   '   c   [   1 226 307   H   _   D   [ 235   :
0000050  \r 222 267 334   8 304   ? 031 231   N 221 020
000005c

$ gpg --decrypt output.txt
gpg: keyring `/home/vagrant/.gnupg/secring.gpg' created
gpg: AES256 encrypted data
gpg: encrypted with 1 passphrase
Hello World!

对称加密的问题是如何分享加密key。因此就出现了非对称加密。

非对称加密使用了公钥和私钥。公钥用来加密,可以公开发布;私钥用来解密,需要妥善保存。你可以使用对方的公钥加密,然后对方使用其私钥即可解密。

$ openssl genrsa -out key.pem 2048
Generating RSA private key, 2048 bit long modulus
..........................................+++
...............+++
e is 65537 (0x10001)

# key.pem中包含了公钥
$ head -n 15 key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwBuUFk0iHrZ6ErPKey6CuoiLbNB+O+SfJMzCGiB/jZS7cRYN
vO1lSwsAkaDslu6Voi2V5z3/V4spwwO6tI02FX//zpYxK/y9N7IFUjzfxjkRJ/dj
aeXhjx5o4UKb9nBLFN+0NGzqU7gbm33MH/K9wW9yBY75cU0E8XnEmKefEXH5/sRE
VMmQOBh6GMorOkJMKDxZzUa0lWW3FWq+Vzpd7woZF2vvYTPRH/gFGviX48YTz0pg
YtR+8VMTVASnqr4Ff5OVy67dTP5JBPa4omV6+fNDPfUZSML8VyP3i8QeX0lFVUnB
iiYuIjOE/ox42MEddPZqJbiDNjRpIm9awsKCdwIDAQABAoIBABFZrEtDViSN+IJ9
6Hitn7L3KBiA0BXatSDeuV0guERyPWeeRUld63sWmEuOzC9phuwpz9Mdv1UJxZDO
YmtyIYNZlyHyYKiHYBOKqX5e7xr5Bnqklj73OyLw7SoDGRDt3WoaNi1R9OvwwdWO
TARKqSaySQsFebPo79xbUg0zfmNVzrV5KqQu7cIo8ie7HEG0cwyRQOzbhVx/FD4u
zGU8jfwkKbJidH2nO85KGxLy8Wt9jyaGv6ukX94Sll4nuHuQvynrcSCLxtsGxFyo
aJAM1ZV6smyVenpmktpBDhm5YQBUMU73EdiOdQ/1qNgWTu0i1jgTmnMhzmqsJt/B
O54F3kkCgYEA8oA1YUMcMR4Gz6ClRTqKY8wPwcsfS9UcA3CnW4n9nXZKODCUVM7y
2KOUXW1x7HaOwSN906d9PFMu2TNKLtlluKzF6c2YL19hL0KG8Y/weR8ipVwT2Ip/
QN5urL8EApwvUcfRzZCHJqpmhcJEXhz8SG4kyJOHpwugjqB2dI2faSMCgYEAys08

# 提取公钥
$ openssl rsa -in key.pem -out key.pub -pubout
writing RSA key

$ cat key.pub
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwBuUFk0iHrZ6ErPKey6C
uoiLbNB+O+SfJMzCGiB/jZS7cRYNvO1lSwsAkaDslu6Voi2V5z3/V4spwwO6tI02
FX//zpYxK/y9N7IFUjzfxjkRJ/djaeXhjx5o4UKb9nBLFN+0NGzqU7gbm33MH/K9
wW9yBY75cU0E8XnEmKefEXH5/sREVMmQOBh6GMorOkJMKDxZzUa0lWW3FWq+Vzpd
7woZF2vvYTPRH/gFGviX48YTz0pgYtR+8VMTVASnqr4Ff5OVy67dTP5JBPa4omV6
+fNDPfUZSML8VyP3i8QeX0lFVUnBiiYuIjOE/ox42MEddPZqJbiDNjRpIm9awsKC
dwIDAQAB
-----END PUBLIC KEY-----

# 加密
$ openssl rsautl -in input.txt -out output.txt -pubin -inkey key.pub -encrypt

$ hexdump -c output.txt
0000000 202   : 215 332 026   [ 001   x 204   q 217   % 023 331 264 003
0000010   y 304 326 250   X 330 225   m 216   | 316 364   z 022   } 017
0000020   3   <   Z   . 247 302   d 337   R 255 210   o 317   { 005 267
0000030   < 277   l   > 314   +   B   A   S   y   Y 316 355   $   e   C
0000040   ` 205 375  \n 325 032 366 017 340 361   9 202   8   j 330 235
0000050   " 201   @ 355   ,   P   S 363 032   X   Z 260 303 237 324   #
0000060 202 342 323   S   U   R 216 263     375 331   D   < 246 232 233
0000070   M   P  \a   *   I 335 006 251   ! 221 222   ; 333 337 374 352
0000080 276  \t   t 032   =   v   E 334   ! 240 344 341 211   D 212   }
0000090 033   .   " 201 350 320 346   Q   o  \0 354 017 322 253 310 247
00000a0 255 244 344 031 260 234 336 177 222 325 271 203   i   a 203 330
00000b0 002 275 247   &   4 337  \f 016 271 207   L   j 001       s  \v
00000c0   - 036  \a   . 201 345   ] 377 023   z 270   k   } 037 242   /
00000d0 207 264   3 311 235 240 240 237   o 320 325 327 002 001 323   m
00000e0 306   r 337   f 242   n 233 267   8   _   L 216   w 357 214 363
00000f0 021 222 311   | 342 363  \a 216   W 215 255   { 256   O   #   e
0000100

# 解密
$ openssl rsautl -in output.txt -inkey key.pem -decrypt
Hello World!

从性能看,非对称加密消耗更多资源。因此当数据量大时,应使用对称加密。

TLS结合了两者的优点,通过非对称加密来交换用于加密的key;后续使用此key对数据实现对称加密。

来看一个客户端和银行交互的过程:

  1. 客户端连接到银行网站
  2. 银行发回其公钥
  3. 生成随机数,用银行公钥加密,然后发给银行作为shared secret
  4. 客户端和银行使用此shared secret生成加密key
  5. 后续就可以用此加密key来加密数据了。

Authentication

  • Digital Certificates (Wikipedia)
  • Certificate Authority (Wikipedia)
  • Man-in-the-middle Attack (Wikipedia)

如果你收到一个公钥,你如何确认此公钥就属于他声称的那个人?这就是认证所解决的问题。否则如果此公钥属于攻击者,后续所有的数据都将被他看到。

TLS使用以下方法来解决:

  • asymmetric-key ciphers
  • certificate
  • certificate authorities
  • digital signature

lilliput:小人国

第三方机构提供的身份证明,如护照。信任护照实际就是信任发护照的国家和政府。

回到TLS,数字证书(类似护照)提供了公钥的属主,数字证书是由CA(certificate authorities,类似政府)签发的。数字签名则类似于水印,全息照相(hologram),虹膜等。

连接任意网站,在浏览器上方点击带锁的图标,可以看到证书的信息。

与网站的信任建立在以下前提:

  • 证书与你连接的网站域名匹配
  • 证书由可信的第三方机构签发

Integrity, Cipher Suites and TLS Versioning

Integrity, Cipher Suites and TLS Versioning

再回顾之前TLS实现的3点:

  • Privacy,通过加密
  • Identity,通过加密,数字证书和CA
  • Integrity

Integrity是通过MAC(message authentication code)实现的,类似于校验和。也就是可以确认数据未篡改,同时数据是由所声称的人发出的。

因此,TLS中使用了多种加密算法:

  • asymmetric-key cipher
  • digital signature algorithm
  • symmetric-key cipher
  • message authentication code

这些算法由多种实现方式,在建立TLS连接前,这些算法也需要双方达成一致,我们称之为cipher suite。

例如,注意SSL-Session部分的Cipher:

$ openssl rsautl -in output.txt -inkey key.pem -decrypt
Hello World!
$ openssl s_client -connect wikipedia.org:443
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Wikimedia Foundation, Inc.", CN = *.wikipedia.org
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIIRzCCBy+gAwIBAgIQD+Jq/rlFfSfP2Z7uT19HXDANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
...
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3832 bytes and written 415 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
    Session-ID: 64BE3B2710AF90DCD5E87A638952592DF4480D2D90C112DDDC326F58015E73F2
    Session-ID-ctx:
    Master-Key: 329268140E362C3064208CA2F55EF15102CB8676F675394335167846AFEB49815B71A9136D3E683D1F207265EBB1A8DA
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 86400 (seconds)
    TLS session ticket:
    0000 - 7a 54 6d 55 39 5f 36 50-46 59 55 4c 75 68 30 34   zTmU9_6PFYULuh04
    0010 - 47 f1 9d c5 c4 d2 5d 21-bf 72 94 d0 c4 c2 7f b8   G.....]!.r......
    0020 - bc 51 c7 36 7e 74 5e 7a-9e e4 9e fb d6 2a 2e 4e   .Q.6~t^z.....*.N
    0030 - ab 0c 3f fb 8e d8 6c 0c-d7 9f 64 e9 c5 4c 0c 77   ..?...l...d..L.w
    0040 - 1f 27 4c dc 30 ec ff c3-79 9e 79 1b d4 98 5a 89   .'L.0...y.y...Z.
    0050 - cf ee fc 9d 52 2d ba 5f-30 9e 4b 09 c2 8e 99 43   ....R-._0.K....C
    0060 - 92 c6 a8 d5 20 f4 a0 3c-3c a4 07 5b 43 a8 e5 13   .... ..<<..[C...
    0070 - f3 b5 e7 ae 6f 2c 1d 68-d0 04 61 37 6d de 2d 88   ....o,.h..a7m.-.
    0080 - 70 16 54 07 b8 a7 79 b3-bd d7 47 6e 11 8c 92 9a   p.T...y...Gn....
    0090 - 2d 43 54 51 a3 77 90 e5-59 51 6c 66 c8 23 f4 a0   -CTQ.w..YQlf.#..
    00a0 - 19 01 42 61 7b 35 31 73-2c 30 ec 9d b3 6f d3 f0   ..Ba{51s,0...o..
    00b0 - f1 77 47 4c ea 48 43 78-f9 74 6c fa 8d b4 8e 17   .wGL.HCx.tl.....

    Start Time: 1612175132
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

TLS版本是另一个需要协商的部分。目前最常用的是TLS 1.2。TLS 1.3是最新的版本。

TLS in Redis

Encrypting Connections

此实验需要先生成支持openssl的redis-server build:

sudo yum install openssl-devel
sudo yum install jemalloc-devel
wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
scl enable devtoolset-9 -- sudo make MALLOC=libc BUILD_TLS=yes install

之所以需要sudo,是因为最终的可执行程序安装在了系统目录下:

$ which redis-server
/usr/local/bin/redis-server

TLS需要3个文件:

  1. Server 证书
  2. 发证CA的证书(通常来自于公司内部CA)
  3. Server的私钥

大概就是以下这些步骤了,但我没有按照这个做:

# 创建私钥: ca.key
openssl genrsa -out ca.key 4096

# 用私钥生成发证CA的证书: ca.crt
openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -subj '/O=Redislabs/CN=Redis Prod CA' -out ca.crt

# 用发证CA的证书创建Server证书: redis.crt
openssl genrsa -out redis.key 2048

openssl req -new -sha256 -nodes -sha256 -key redis.key -subj '/O=Redislabs/CN=Production Redis' \
	| openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAserial ./ca.txt -CAcreateserial -days 365 -out redis.crt

$ sudo mkdir /usr/local/share/ca-certificates
$ sudo cp ca.crt /usr/local/share/ca-certificates

$ sudo mkdir /etc/ssl/private
$ sudo cp ca.key /etc/ssl/private
$ sudo cp redis.key /etc/ssl/private
$ sudo cp redis.crt /etc/ssl

实际是按这个来做的,TLS Support in Redis 6 at redis.io,非常简单。

测试:

$ redis-cli
127.0.0.1:6379> ping
Error: Connection reset by peer

$ ./src/redis-cli --tls \
>     --cert ./tests/tls/redis.crt \
>     --key ./tests/tls/redis.key \
>     --cacert ./tests/tls/ca.crt
127.0.0.1:6379> ping
PONG

TLS 1.3, Mutual Authentication and Advanced TLS Configuration

除了客户端与Redis Server,Redis集群和复制各节点间通讯也需要加密。

tls-replication yes
tls-cluster yes

TLS 1.3是最新的TLS标准,性能更好,支持更多的cipher suite。

tls-protocols "TLSv1.3"

Security Tip #4: Security Maintenance and Advanced Hardening

Security Maintenance and Advanced Hardening

  • 账户管理:需定期检查账户和权限,删除不需要的账户和权限。方法是ACL LIST和redis.conf文件。
  • 口令管理:口令过期,复杂度等。ACL和AUTH命令
  • 软件维护:客户端和服务器软件都必须保持最新。检查https://redis.io/downloadhttps://redis.io/clients
  • 修改Redis端口:默认是6379。可以修改redis.conf中的tls-port

Wrap Up and a Redis Security Checklist

Redis Production Security Checklist

Architecture

Standalone and Cluster Mode
1 . Ensure Redis is always deployed inside a trusted network.
2 . Ensure protected mode is on unless ACLs or AUTH is enabled.
3 . Ensure the Redis Log file is configured.
4 . Ensure Redis is run as a non-privileged user.
5 . Ensure Redis files are given a non-privileged group
6 . Ensure Redis logs, files and configurations are not readable or writable by others on the operating system.
7 . Ensure the Redis Log file is rotated.
8 . Ensure Redis configuration files are not accessible by others, such as 740 permissions.
9 . Ensure you leverage the latest Redis client and server version.
10. Consider IP restrictions through the network or operating system to ensure only trusted IPs can connect to Redis.
11. Consider using client side encryption to encrypt sensitive data.
12. Consider if TLS is right for your use case.
13. Consider changing the default Redis port
14. Consider backing up RDB and AOF files to a remote external location.
15. Ensure you select the right persistence method for your use case.
16. Consider sending Redis log files to syslog.

Cluster Mode Only

  1. Ensure that an odd number of at least 3 nodes are deployed in the cluster
  2. Ensure any reboot schedules do not reboot enough nodes at the same time to lose quorum.
Account Management

Standalone and Cluster Mode
1 . Ensure AUTH or ACLs are enabled.
2 . Ensure all users have a strong password.
3 . Ensure the default user is disabled, unless required for backwards compatibility.
4 . Ensure the @dangerous command category is excluded from all users and dangerous commands are given on a case by case basis.
5 . Ensure that an external ACL file is used to configure ACLs.
6 . Ensure that users configured in an external ACL file or the redis.conf file store passwords in hashed format.
7 . Ensure that the requirepass is only set if backwards compatibility is required.
8 . Consider if all ACL users are configured to least privilege.
9 . Consider renaming commands to disable them entirely

Cluster Mode Only

  1. Ensure that masteruser is used for authentication to masters.
  2. Ensure that sentinel auth-user is used if you are using sentinel.
Transport layer Security

Standalone & Cluster Mode
1 . Ensure non-TLS ports are disabled.
2 . Ensure strong cipher suites are used with Redis.
3 . Ensure appropriate modern TLS protocols are used.
4 . Ensure client authentication is used.
5 . Ensure server ciphers are prefered.
6 . Ensure TLS is configured for replication
7 . Ensure key files are given 400 permissions.
8 . Ensure key files are owned by the Redis user.

Cluster Mode Only

  1. Ensure TLS is enabled on the cluster bus
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值