Redis6.0新特性-TLS测试

本文详细介绍了如何在CentOS 7.3环境下为Redis 6.2.7编译时启用TLS支持,包括安装OpenSSL、生成测试证书、配置启动参数以及连接与验证过程。重点展示了TLS模式下客户端和服务端的交互与限制。

背景

传输层安全性协议(英语:Transport Layer Security,缩写作TLS),及其前身安全套接层(Secure Sockets Layer,缩写作SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。Redis6支持TLS,并且支持SSL。

1.目录设置

redis源码解压目录

/app/cachecloud/redis

测试环境:CENTOS7.3
redis版本:6.2.7

2.编译redis

要测试TLS,要在编译时选择编译TLS,跳转到redis源码解压目录,执行

make BUILD_TLS=yes

编译过程中出现如下错误:

ssl.c:45:25: 致命错误:openssl/ssl.h:没有那个文件或目录
 #include <openssl/ssl.h>

这时要中断编译,先安装openssl

yum install openssl-devel

安装好 open-ssl后再次执行make BUILD_TLS=yes命令即可编译成功

3.生成测试证书

在源码目录执行生成证书脚本

[root@redis-7-109 ~]# cd /app/cachecloud/redis
[root@redis-7-109 redis]# ./utils/gen-test-certs.sh
Generating RSA private key, 4096 bit long modulus
……

生成后在tests/tls目录下可以看到生成的证书文件

[root@redis-7-109 tls]# ls -l /app/cachecloud/redis/tests/tls/
总用量 44
-rw-r--r--. 1 root root 1879 711 11:30 ca.crt
-rw-r--r--. 1 root root 3243 711 11:30 ca.key
-rw-r--r--. 1 root root   17 711 11:30 ca.txt
-rw-r--r--. 1 root root 1456 711 11:30 client.crt
-rw-r--r--. 1 root root 1675 711 11:30 client.key
-rw-r--r--. 1 root root  163 711 11:30 openssl.cnf
-rw-r--r--. 1 root root 1399 711 11:30 redis.crt
-rw-r--r--. 1 root root  424 711 11:34 redis.dh
-rw-r--r--. 1 root root 1679 711 11:30 redis.key
-rw-r--r--. 1 root root 1456 711 11:30 server.crt
-rw-r--r--. 1 root root 1679 711 11:30 server.key

4.启动和连接

使用tls模式启动redis服务,如下命令

[root@redis-7-109 tls]# cd /app/cachecloud/redis
[root@redis-7-109 redis]# ./src/redis-server --tls-port 6379 --port 0 \
>     --tls-cert-file ./tests/tls/redis.crt \
>     --tls-key-file ./tests/tls/redis.key \
>     --tls-ca-cert-file ./tests/tls/ca.crt

--tls-port 6379指定了tls端口为6379,--port 0 禁用非tls的端口。

连接tls模式redis服务,连接后可以正常执行命令

[root@redis-7-109 ~]# cd /app/cachecloud/redis
[root@redis-7-109 redis]# ./src/redis-cli --tls \
>     --cert ./tests/tls/redis.crt \
>     --key ./tests/tls/redis.key \
>     --cacert ./tests/tls/ca.crt
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"

如果不使用tls模式直接连接tls模式的redis服务,虽然也可以正常连接,但是无法执行命令。

#客户端表现
[root@redis-7-109 ~]# redis-cli -p 6379
127.0.0.1:6379> get hello
Error: Connection reset by peer

#服务端表现
[root@redis-7-109 redis]# ./src/redis-server --tls-port 6379 --port 0 \
>     --tls-cert-file ./tests/tls/redis.crt \
>     --tls-key-file ./tests/tls/redis.key \
>     --tls-ca-cert-file ./tests/tls/ca.crt
9591:C 11 Jul 2022 11:51:18.598 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
9591:C 11 Jul 2022 11:51:18.598 # Redis version=6.2.7, bits=64, commit=00000000, modified=0, pid=9591, just started
……省略……
9591:M 11 Jul 2022 11:51:18.612 * Ready to accept connections
9591:M 11 Jul 2022 11:51:43.594 # Error accepting a client connection: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol (conn: fd=8)
9591:M 11 Jul 2022 11:51:50.771 # Error accepting a client connection: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol (conn: fd=8)
9591:M 11 Jul 2022 14:02:37.069 # Error accepting a client connection: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol (conn: fd=8)

参考:
https://redis.io/docs/manual/security/encryption/

<think>好的,我现在需要仔细分析用户提供的Docker命令是否存在问题。用户的问题是关于运行Redis容器时,使用多个redis-server指令是否会导致问题。首先,我应该回忆Docker运行容器时的命令结构。 用户给出的命令是: docker run -d \ --name redis6 \ -e REDIS_PASSWORD=【密码】 \ -p 6379:6379 \ -v /shizhun/redis/data:/data \ -v /shizhun/redis/conf:/usr/local/etc/redis \ redis:6.0 \ redis-server --requirepass ${REDIS_PASSWORD} \ redis-server /usr/local/etc/redis/redis.conf \ # 配置 redis-server --appendonly yes # 开启持久化 首先,注意到在Docker的run命令中,最后的部分是容器的启动命令。如果用户多次使用redis-server,这会导致问题,因为每次执行redis-server都会启动一个新的Redis实例,而Docker容器默认只会执行最后一条命令,或者如果有多条命令的话,可能只会执行第一条,后面的会被忽略,除非使用正确的shell语法来连接命令。 但是,用户在这里连续写了三个redis-server命令,这显然不正确。正确的做法应该是将所有配置参数合并到一条redis-server命令中。例如,同时指定配置文件、密码和持久化选项。 另外,用户使用了环境变量REDIS_PASSWORD,并在命令中通过${REDIS_PASSWORD}引用。需要确认在Docker命令中,环境变量是否能够正确传递。使用-e选项设置环境变量是正确的,但在命令中直接使用${REDIS_PASSWORD}可能存在问题,因为在容器启动时,是否能够正确解析这个变量?或者是否需要通过shell来传递变量?可能需要使用sh -c来执行命令,或者在配置文件中预先设置密码。 再者,用户挂载了配置文件目录到/usr/local/etc/redis,但Redis默认的配置文件路径是/usr/local/etc/redis/redis.conf吗?不同版本的Redis可能有不同的默认路径,需要确认这一点。例如,官方Redis镜像的配置文件可能位于/etc/redis/redis.conf,用户挂载的路径是否正确? 还有,用户试图同时通过命令行参数和配置文件来设置选项,这时候需要了解Redis的配置加载顺序。如果同时使用配置文件和命令行参数,命令行参数会覆盖配置文件中的设置。但在这个命令中,用户可能重复指定了某些参数,导致冲突或者忽略。 另外,关于持久化,用户使用了--appendonly yes,这是正确的,但需要确保配置文件中也未禁用这个选项,否则可能会有冲突。不过,如果命令行参数指定了,应该会覆盖配置文件中的设置。 总结用户命令中的问题: 1. 多次调用redis-server命令,导致只有最后一个可能生效,或者容器启动失败。 2. 环境变量${REDIS_PASSWORD}是否正确解析,是否需要使用shell脚本来传递变量。 3. 配置文件路径是否正确,挂载的卷是否有效。 4. 是否应该将所有的配置参数合并到一条redis-server命令中,并正确指定配置文件和选项。 接下来,我需要验证这些点。例如,正确的启动命令应该是一个redis-server命令,后面跟着配置文件和参数。例如: redis-server /path/to/redis.conf --requirepass ${REDIS_PASSWORD} --appendonly yes 但需要注意,如果配置文件中已经设置了requirepass和appendonly,可能不需要在命令行中再次指定。或者如果需要在命令行中覆盖配置文件的设置,可以这样做。 另外,环境变量在Docker命令中的使用是否正确?当在命令中使用${REDIS_PASSWORD}时,Docker会在容器内部解析这个变量,前提是该变量已经被正确设置。用户使用了-e选项,所以变量应该存在。但需要注意,在命令行参数中使用变量是否需要通过shell来展开。例如,如果命令是直接执行的,而不是通过shell,可能变量不会被替换。这时候可能需要使用sh -c "..."来包裹命令,以便变量被正确替换。 例如: redis-server --requirepass $REDIS_PASSWORD ... 如果Docker直接执行这个命令,而不是通过shell,那么$REDIS_PASSWORD可能不会被替换。这时候需要使用: sh -c "redis-server --requirepass $REDIS_PASSWORD ..." 但用户是否在命令中正确使用了引号和shell?可能需要调整命令的结构。 此外,用户挂载了配置文件目录到/usr/local/etc/redis,假设redis.conf在这个目录下,那么在命令中应该指定配置文件路径为/usr/local/etc/redis/redis.conf。这个路径是否正确取决于Redis镜像中的默认配置路径。比如,官方Redis镜像的配置文件可能存放在/etc/redis/redis.conf,因此用户挂载的路径可能不正确,导致配置文件无法被加载。需要确认镜像中的配置文件路径。 例如,如果用户挂载到/usr/local/etc/redis,而Redis默认在/etc/redis/redis.conf,则需要在启动命令中明确指定配置文件路径,如:redis-server /usr/local/etc/redis/redis.conf。 另外,用户是否在宿主机上正确放置了redis.conf文件?如果挂载的是一个空目录,可能会导致容器内的配置文件被覆盖为空,从而引发错误。 最后,用户命令中的反斜杠和注释是否导致语法错误?在命令行中,反斜杠用于换行,但注释符#可能会导致后面的内容被忽略。例如,在最后两行: redis-server /usr/local/etc/redis/redis.conf\ # 配置 redis-server --appendonly yes # 开启持久化 这里的反斜杠后有一个空格和注释,可能会导致换行失效,命令被错误地分割。正确的换行应该是在反斜杠后直接换行,不能有空格或注释。因此,用户可能在命令中错误地使用了注释,导致命令被截断,从而出现语法错误。 综上所述,用户命令存在多个问题,需要逐一修正,包括:合并多个redis-server命令为一个,正确指定配置文件和参数,确保环境变量替换,修正挂载路径,以及删除命令中的注释以避免语法错误。</think>以下是对您提供的Docker命令的分析和修正方案: --- ### 一、原命令问题分析 ```bash docker run -d \ --name redis6 \ -e REDIS_PASSWORD=【密码】 \ -p 6379:6379 \ -v /shizhun/redis/data:/data \ -v /shizhun/redis/conf:/usr/local/etc/redis \ redis:6.0 \ redis-server --requirepass ${REDIS_PASSWORD} \ # 问题1 redis-server /usr/local/etc/redis/redis.conf \ # 问题2 redis-server --appendonly yes # 问题3 ``` #### 主要问题: 1. **重复启动Redis服务**:连续调用3次`redis-server`命令,Docker容器只会执行第一条命令,后续命令无效 2. **变量解析失败**:`${REDIS_PASSWORD}`在命令中未通过Shell解析,直接传递会变成字面量`${REDIS_PASSWORD}` 3. **语法错误**:行尾注释`#`破坏了命令连续性,导致参数截断 --- ### 二、修正后的命令 ```bash docker run -d \ --name redis6 \ -e REDIS_PASSWORD=yourpassword \ -p 6379:6379 \ -v /shizhun/redis/data:/data \ -v /shizhun/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \ redis:6.0 \ redis-server /usr/local/etc/redis/redis.conf \ --requirepass "${REDIS_PASSWORD}" \ --appendonly yes ``` #### 修正说明: 1. **合并配置参数**:将密码、持久化等参数统一附加到`redis-server`主命令后 2. **配置文件挂载**:明确挂载单个配置文件(非目录),避免路径混淆 3. **变量传递**:通过双引号确保环境变量解析`"${REDIS_PASSWORD}"` 4. **注释清理**:移除行内注释,确保命令完整性 --- ### 三、关键配置验证 #### 1. 配置文件要求 确保宿主机文件存在: ```bash ls /shizhun/redis/conf/redis.conf # 确认配置文件已准备 ``` #### 2. 配置项检查 在`redis.conf`中需关闭以下配置(避免与命令行参数冲突): ```conf # requirepass foobared # 注释掉原有密码设置 appendonly no # 由命令行参数覆盖 ``` --- ### 四、完整生产级建议 #### 1. 推荐Docker Compose部署 ```yaml version: '3' services: redis: image: redis:6.0 container_name: redis6 environment: - REDIS_PASSWORD=yourpassword ports: - "6379:6379" volumes: - /shizhun/redis/data:/data - /shizhun/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf command: - redis-server - /usr/local/etc/redis/redis.conf - --requirepass $${REDIS_PASSWORD} - --appendonly yes ``` #### 2. 安全增强措施 ```bash # 限制容器资源 --memory 1g --cpus 1 # 启用TLS加密(需配置证书) --tls-port 6379 --port 0 \ --tls-cert-file /path/to/redis.crt \ --tls-key-file /path/to/redis.key ``` --- ### 五、常见问题排查 1. **密码验证失败**:检查`docker logs redis6`查看是否成功加载`requirepass` 2. **持久化未生效**:确认宿主机`/shizhun/redis/data`目录有写入权限 3. **配置未加载**:使用`docker exec -it redis6 cat /usr/local/etc/redis/redis.conf`验证文件内容 --- 通过以上修正方案,可确保Redis容器正确加载配置文件、启用密码验证和持久化功能。生产环境建议配合监控和备份策略使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值