Redis 7.0.X 在Windows下编译支持TLS连接,遇坑埋坑


前言

Redis在版本6以及以后,基于安全的需要,就开始支持TLS连接了。基于Windows版本的维护,在网上以前有两个库,一个是微软维护的,维护到3.x之后就变成archive了,见后边的参考链接。另一个库也只维护到5.x。还没有一个windows版本维护到6及以上的版本。

如果仔细推敲其原因,可能还是在windows平台上用的不多吧。简单的非TLS的在windows上跑跑也不差不多了。

那到底有没有可能编译出一份支持TLS的windows版本呢?回想起很久以前使用msys+mingw来编译PostgreSQL的经历,感觉隐约可行。只是可能一样会遇到一些坑。

环境准备

1、从https://www.msys2.org 下载一份,默认安装到本机。经是基础环境。

2、从msys64的msys2_shell.cmd进入,也就是说,进入的是msys2的shell,而不是mingw64的shell。后者经过实践证明,不适用于Redis的编译。(这是第一个大坑)

在 MSYS2 中,你可以使用 pacman 包管理器来安装软件包。但是,你可能不会找到名为 libssl-devopenssl-dev 的包,因为这些通常是在 Debian 或 Ubuntu 系统中的包名。在 MSYS2 或其他使用 Pacman 的系统中,你可能需要安装 opensslopenssl-devel

你可以使用以下命令来安装:

pacman -S openssl
pacman -S openssl-devel

请注意,这些包可能已经被包含在你的系统中,或者可能有不同的名称。如果你无法找到正确的包,你可能需要搜索它们:

pacman -Ss openssl

这将显示所有与 openssl 相关的包,你可以从中找到你需要的包。msys64下边, 如果通过pacman 安装libssl-dev和openssl-dev

pacman的相关帮助。
$ pacman --help
usage:  pacman  [...]
operations:
    pacman {-h --help}
    pacman {-V --version}
    pacman {-D --database}  
    pacman {-F --files}    [options] [file(s)]
    pacman {-Q --query}    [options] [package(s)]
    pacman {-R --remove}   [options] 
    pacman {-S --sync}     [options] [package(s)]
    pacman {-T --deptest}  [options] [package(s)]
    pacman {-U --upgrade}  [options] 

use 'pacman {-h --help}' with an operation for available options

基于上边这些,做一些更新:

pacman -Syu
pacman -Sy gcc make pkg-config
pacman -S openssl-devel

实作与分析:

下载源码:https://github.com/redis/redis/archive/refs/tags/7.0.12.tar.gz

解压到/c/3rdparty/redis

make distclean
cd deps
make PREFIX=/c/tools/redis BUILD_TLS=yes hdr_histogram  hiredis linenoise  lua

cd ../
make PREFIX=/c/tools/redis install  BUILD_TLS=yes

会发现编译不过(第二大坑)

解决这个坑的方法是:(参考链接里头也有相关介绍)

找到文件:msys64\usr\include\dlfcn.h

line: 49 ~ 61,修改如下:(即把第4961行注释掉)
// #if __GNU_VISIBLE
typedef struct Dl_info Dl_info;

struct Dl_info
{

   char        dli_fname[PATH_MAX];  /* Filename of defining object */
   void       *dli_fbase;            /* Load address of that object */
   const char *dli_sname;            /* Name of nearest lower symbol */
   void       *dli_saddr;            /* Exact value of nearest symbol */
};

extern int dladdr (const void *addr, Dl_info *info);
// #endif

这样就能顺利编译完成。最后打包:

最后安装到/c/tools/redis

打包时,要加入这三个文件:
2023-07-15  12:50 AM         2,982,622 msys-2.0.dll
2023-06-01  07:17 AM         4,523,484 msys-crypto-3.dll
2023-06-01  07:17 AM           610,496 msys-ssl-3.dll
它们来自目录:C:\tools\msys64\usr\bin
还有两个配置文件,来自源文件目录。
最后的结构如下:

c:\tools\redis\bin>dir
 Volume in drive C is OSDisk
 Volume Serial Number is 6E46-ACF4

 Directory of c:\tools\redis\bin

2023-07-30  07:00 PM    
          .
2023-07-30  07:00 PM    
          ..
2023-07-30  12:06 PM               101 dump.rdb
2023-07-15  12:50 AM         2,982,622 msys-2.0.dll
2023-06-01  07:17 AM         4,523,484 msys-crypto-3.dll
2023-06-01  07:17 AM           610,496 msys-ssl-3.dll
2023-07-30  04:19 PM           997,529 redis-benchmark.exe
2023-07-30  04:19 PM         7,883,673 redis-check-aof
2023-07-30  04:19 PM         7,883,673 redis-check-rdb
2023-07-30  04:19 PM         1,155,751 redis-cli.exe
2023-07-30  04:19 PM         7,883,673 redis-sentinel
2023-07-30  04:19 PM         7,883,673 redis-server.exe
2023-07-10  07:39 PM           106,545 redis.conf
2023-07-10  07:39 PM            14,005 sentinel.conf

拿一个真实的环境初步尝试:

c:\tools>cf ssh aaaaaaa -L 1381:clusteaaaaaaaaaaaaaaawxxxxxxxxxxxxx:1381 -T -N

c:\tools\redis\bin>redis-cli -c -p 1381 -a jRxxxxxxxxxxxxxxxnhWy --tls --no-auth-warning
Could not connect to Redis at 127.0.0.1:1381SSL_connect failedNo error
not connectedquit

会一直报这个错:SSL_connect failedNo error
这是遇到的第三个坑。

用它作为普通的Redis client使用还是可以的。

实际上,主要是因为用的是Windows自带的shell (DOS)窗口运行上述命令。这样是不行的。必须还得使用msys2_shell.cmd来启动它的shell再执行上述命令。

Redis TLS连接测试

参考文档: https://zhuanlan.zhihu.com/p/145972315

也可以直接参照文档:https://redis.io/docs/management/security/encryption/

https://cloud.tencent.com/developer/article/1839188

启动msys2_shell.cmd,然后:

1. 运行./utils/gen-test-certs.sh生成根CA证书和服务器证书。
2. 运行./runtest --tls或./runtest-cluster --tls,以TLS模式运行Redis和Redis集群测试。

手动运行:

2. 启动Server.
./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
启动是成功的:
4970:C 30 Jul 2023 19:16:49.821 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4970:C 30 Jul 2023 19:16:49.821 # Redis version=7.0.12, bits=64, commit=00000000, modified=0, pid=4970, just started
4970:C 30 Jul 2023 19:16:49.821 # Configuration loaded
4970:M 30 Jul 2023 19:16:49.841 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
4970:M 30 Jul 2023 19:16:49.841 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
4970:M 30 Jul 2023 19:16:49.841 # Current maximum open files is 3200. maxclients has been reduced to 3168 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
4970:M 30 Jul 2023 19:16:49.841 * monotonic clock: POSIX clock_gettime
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 7.0.12 (00000000/064 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'
` _.-'|     Port: 6379
 |    `
-._   `._    /     _.-'    |     PID: 4970
  `
-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `
-._`-._        _.-'_.-'    |           https://redis.io
  `
-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'
    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `
-._    `-.__.-'    _.-'
          `
-._        _.-'
              `-.__.-'


4970:M 30 Jul 2023 19:16:49.868 # Server initialized
4970:M 30 Jul 2023 19:16:49.870 * Ready to accept connections
4970:M 30 Jul 2023 19:18:03.523 # Error accepting a client connection: error:0A00010B:SSL routines::wrong version number (conn: fd=8)
4970:M 30 Jul 2023 19:18:18.781 # Error accepting a client connection: error:0A00010B:SSL routines::wrong version number


使用redis-cli连接到此Redis服务器:
./src/redis-cli –tls --cert ./tests/tls/redis.crt --key ./tests/tls/redis.key \
--cacert ./tests/tls/ca.crt

MSYS /c/tools/3rdpart/redis/redis-7.0.12

再试一下:
./src/redis-cli --tls \
    --cert ./tests/tls/redis.crt \
    --key ./tests/tls/redis.key \
    --cacert ./tests/tls/ca.crt
127.0.0.1:6379>    

--  这下终于成功了 --

当然也可以使用额外的参数:-tls-ciphers 来指定允许的TLS协议。
$ ./src/redis-cli --tls --cert ./tests/tls/redis.crt --key ./tests/tls/redis.key \
--cacert ./tests/tls/ca.crt --tls-ciphers TLSv1.2:TLSv1.1:TLSv1.0:SSLV3:SSLv2
(ssl2/ssl3/tls1.0/tls1.1/tls1.2)

小结:

使用msys2的shell cmd,更新必要的库,是可以完成Redis带TLS的完整编译的,并且最终也能使用。这些用于平时的Windows上的开发测试环境,还是可以的,尤其是需要支持TLS的情况下。

不过,有一个依赖关系,打包时,最好将这三个文件一起打包。

msys-2.0.dll
msys-crypto-3.dll
msys-ssl-3.dll

另外,还需要一个https://www.msys2.org  上下载安装的最小msys2运行时,在那个运行时环境里头才能正常运行Redis with TLS。

相关参考资料:

使用 Redis 源码编译发布 Windows 版 Redis For Windows 发行包: https://mp.weixin.qq.com/s/V-wGPkyhuNHkfB3wCflXdQ

编译实战 | 手摸手教你在Windows环境下运行Redis6.x

https://www.msys2.org  从这里下载一个msys2

MS提供的低版本Redis for Windows: https://github.com/microsoftarchive/redis/tags

https://github.com/tporadowski/redis/tags

https://github.com/redis/go-redis

https://github.com/redis/redis

https://github.com/sewenew/redis-plus-plus

openssl 1.11,  3.0源码下载


请使用浏览器的分享功能分享到微信等