【Redis数据库开启SSL加密】【填坑指南】附带服务器配置和python连接测试代码
本教程转为小白提供设置Redis安全访问,自签名证书进行安全访问你的Redis数据库,轻松实现安全访问和保护数据库不被非法入侵。
本文原创,转载请注明出处,谢谢~~
【宝塔配置Redis的容器——Docker】
用宝塔的话用应用商店直接安装:
傻瓜式下一步获得密码访问图一张:
修改redis.conf文件,它来配置服务器的参数:
首先将前面几个基础的配置找到:
bind 0.0.0.0
protected-mode no
port 0
tls-port 6379
其它不用改,然后到文件最后添加:
# 以下为新增的TLS加密配置
# 服务器证书文件路径(替换为实际路径,若与redis.conf同目录可直接写文件名)
tls-cert-file /etc/redis/certs/redis.crt
# 服务器私钥文件路径
tls-key-file /etc/redis/certs/redis.key
# 信任的CA证书(自签名证书使用自身证书)
tls-ca-cert-file /etc/redis/certs/redis.crt# 允许的TLS协议版本(仅保留高安全性版本)
tls-protocols "TLSv1.2 TLSv1.3"
# 加密套件(选择高强度算法)
tls-ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# 可选:强制客户端验证(根据需求开启)
#tls-auth-clients no
如果你懒得找,你可以复制我的,肯定没错:
bind 0.0.0.0
protected-mode no
port 0
tls-port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
list-compress-depth 0
set-max-intset-entries 512
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
# 以下为新增的TLS加密配置
# 服务器证书文件路径(替换为实际路径,若与redis.conf同目录可直接写文件名)
tls-cert-file /etc/redis/certs/redis.crt
# 服务器私钥文件路径
tls-key-file /etc/redis/certs/redis.key
# 信任的CA证书(自签名证书使用自身证书)
tls-ca-cert-file /etc/redis/certs/redis.crt# 允许的TLS协议版本(仅保留高安全性版本)
tls-protocols "TLSv1.2 TLSv1.3"
# 加密套件(选择高强度算法)
tls-ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# 可选:强制客户端验证(根据需求开启)
#tls-auth-clients no
保存后就可以尝试重启docker了。不过你别忘了,你还没有把证书文件放入,所以还要进行SSL证书的生成和上传。
【生成SSL 自签名证书】工具很多,Python代码也可以生成。
如果不适用python代码生成,那么可能需要下载‘openssl’或者‘cryptography’的安装包。我懒得找和下载,我已经有python环境了,所以就直接用python来自己生成。
第一步:建立项目文件夹
去D盘或者空路径建立文件夹,举个栗子哈:D:\TempFile\tls_cert_file, 在D盘TempFile目录下面建立tls_cert_file文件夹。
第二步:创建python的虚拟环境
通过看图,可以光速完成环境和组件的下载和搭建。可能我配置了国内的镜像会快一点,你如果没有配置,可能需要配置一下pip的镜像。
如果你又不知道怎么找,那么我也为你准备了小白套餐:直接复制命令使用:(windows下,因为用linux的肯定不是小白了。)
python.exe -m venv venv
.\venv\Scripts\Activate.ps1
pip install pyopenssl -i https://mirrors.cloud.tencent.com/pypi/simple
pip install cryptography -i https://mirrors.cloud.tencent.com/pypi/simple
然后新建一个py代码文件:generate_ssl.py (代码内的信息根据自己的情况修改)
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography import x509
from cryptography.x509.oid import NameOID
import datetime
import osdef generate_ssl_files():# 生成4096位RSA私钥private_key = rsa.generate_private_key(public_exponent=65537,key_size=4096,)# 保存私钥到文件(PEM格式)with open("redis.key", "wb") as f:f.write(private_key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.PKCS8,encryption_algorithm=serialization.NoEncryption() # 不加密私钥# 如果需要加密私钥,替换为以下行(需设置密码):# encryption_algorithm=serialization.BestAvailableEncryption(b"your_password")))os.chmod("redis.key", 0o600) # 限制访问权限# 生成证书签名请求(CSR)csr_builder = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Beijing"),x509.NameAttribute(NameOID.LOCALITY_NAME, "Beijing"),x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Example Company"),x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "IT Department"),x509.NameAttribute(NameOID.COMMON_NAME, "localhost"),]))# 添加扩展信息csr_builder = csr_builder.add_extension(x509.SubjectAlternativeName([x509.DNSName("localhost"),x509.DNSName("127.0.0.1"),]),critical=False,)# 签名CSRcsr = csr_builder.sign(private_key, hashes.SHA512())# 保存CSR到文件with open("redis.csr", "wb") as f:f.write(csr.public_bytes(serialization.Encoding.PEM))# 生成自签名证书cert_builder = x509.CertificateBuilder().subject_name(x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Beijing"),x509.NameAttribute(NameOID.LOCALITY_NAME, "Beijing"),x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Example Company"),x509.NameAttribute(NameOID.COMMON_NAME, "localhost"),])).issuer_name(x509.Name([ # 自签名,颁发者与主体相同x509.NameAttribute(NameOID.COMMON_NAME, "localhost"),])).public_key(private_key.public_key()).serial_number(x509.random_serial_number() # 随机序列号).not_valid_before(datetime.datetime.now(datetime.timezone.utc) # 生效时间(UTC)).not_valid_after(datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365) # 有效期1年)# 添加证书扩展cert_builder = cert_builder.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True,).add_extension(x509.KeyUsage(digital_signature=True,key_encipherment=True,content_commitment=False,data_encipherment=False,key_agreement=False,key_cert_sign=False,crl_sign=False,encipher_only=False,decipher_only=False), critical=True,).add_extension(x509.ExtendedKeyUsage([x509.OID_SERVER_AUTH, # 服务器认证x509.OID_CLIENT_AUTH # 客户端认证]), critical=True,).add_extension(x509.SubjectAlternativeName([x509.DNSName("localhost"),x509.DNSName("127.0.0.1"),]), critical=False,)# 自签名证书certificate = cert_builder.sign(private_key, hashes.SHA512())# 保存证书到文件with open("redis.crt", "wb") as f:f.write(certificate.public_bytes(serialization.Encoding.PEM))print("成功生成4096位RSA密钥及证书(使用cryptography库):")print("私钥:redis.key")print("证书签名请求:redis.csr")print("自签名证书:redis.crt")if __name__ == "__main__":generate_ssl_files()
在虚拟环境中运行(请注意修改代码中的域名信息):
py generate_ssl.py成功生成4096位RSA密钥及证书:
私钥:redis.key
证书签名请求:redis.csr
自签名证书:redis.crt
将它们丢到服务器中手动创建的文件夹 certs中,并且修改一下权限。所有人可以访问但是不能修改。或者根据自己的需求调整权限。但是读取权限必须保证docker能够读取到。
【第三步】将证书和密钥上传到服务器,然后重启docker
【第四步】检查docker日志,
完成配置。
【测试是否可以正确访问,以及用代码如何访问Redis数据库服务器】
【在虚拟环境中,配置运行组件:redis】
用命令:pip install --upgrade redis 安装或者用 pip install --upgrade redis -i https://mirrors.cloud.tencent.com/pypi/simple
[编写python访问代码】
我测试了很多次,因为自己重头开始配置,中间遇到了很多神仙坑,花了几个小时爆肝才搞通,当然,【豆包】小姐功不可没。只是她的一点遗漏让我辛苦了很久。哎,说多了都是泪,作为我的读者,我就帮你们省下一点时间,让你更好地进行吧。
创建代码文件: test_redis_ssl_with_auth.py
import redis
import osdef test_redis_ssl_connection(host='你的ip或者域名', #自行修改port=26739, #自行修改cert_path='redis.crt', #这个证书文件的真实地址,我这里测试就放在同一目录下了。key_path='redis.key', #这个证书文件的真实地址,我这里测试就放在同一目录下了。server_password=None # 服务器密码
):"""测试通过SSL连接Redis服务器(简化版,不涉及私钥密码)"""try:# 检查证书和密钥文件if not os.path.exists(cert_path):raise FileNotFoundError(f"证书文件不存在: {cert_path}")if not os.path.exists(key_path):raise FileNotFoundError(f"私钥文件不存在: {key_path}")# 配置连接参数(移除ssl_keyfile_password)print("尝试连接Redis服务器(SSL + 密码认证)")r = redis.Redis(host=host,port=port,password=server_password, # 服务器密码ssl=True,ssl_certfile=cert_path,ssl_keyfile=key_path,ssl_cert_reqs='none', decode_responses=True)# 测试连接if r.ping():print("SSL连接成功!Redis服务器响应正常(已通过密码认证)")# 执行测试操作test_key = "ssl_test_key"test_value = "ssl_test_value"r.set(test_key, test_value)print(f"已设置键值: {test_key} = {test_value}")retrieved_value = r.get(test_key)print(f"获取到键值: {test_key} = {retrieved_value}")r.delete(test_key)print(f"已删除测试键: {test_key}")else:print("连接失败,服务器无响应")except redis.ConnectionError as e:print(f" {str(e)}")except redis.AuthenticationError as e:print(f"认证错误: 密码错误或未提供密码 - {str(e)}")except Exception as e:print(f"发生错误: {str(e)}")if __name__ == "__main__":test_redis_ssl_connection(host="你的ip或者域名", #记得修改port=26739,#记得修改server_password="czCikrrafkstXLsc" # Redis服务器密码)
保存好代码,然后运行:
(venv) PS D:\TempFile\tls_cert_file> py ./test_redis_ssl_with_auth.py
尝试连接Redis服务器(SSL + 密码认证)
SSL连接成功!Redis服务器响应正常(已通过密码认证)
已设置键值: ssl_test_key = ssl_test_value
获取到键值: ssl_test_key = ssl_test_value
已删除测试键: ssl_test_key
【结束语】
完成了这一步,基本上Redis就可以开放使用了。因为设置了访问密码,别人想访问也不容易。因为用了加密SSL,所以想通过中间拦截攻击也不容易获取你的密码了。这样比较安全了。但是由于是自签名证书,相对来说比较没有安全保障,哈哈,但是它免费啊~~
为了保证安全性,我的代码特地使用了4096位的加密,还是比较可靠的。
希望能够得到你的一个免费赞哦~~
最好就关注我拉~哈哈
本文章原创,转载请注明出处。