【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 os
def 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,
)
# 签名CSR
csr = 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 os
def 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位的加密,还是比较可靠的。
希望能够得到你的一个免费赞哦~~
最好就关注我拉~哈哈
本文章原创,转载请注明出处。