Dovecot 无法初始化 dict:dict redis:无效 IP
Dovecot Failed to init dict: dict redis: Invalid IP
我正在使用 Dovecot v2.3.9.3
。通过查看鸽舍 docs,我看到 Redis
的规格如下:
redis:param=value:param2=value2:...
这里参数之一是host: Redis server host (default: 127.0.0.1)
.
在我的配置中我指定了 uri = redis:host=redis:port=6379
:
Feb 23 20:48:32 auth: Fatal: dict /etc/dovecot/dovecot-dict-auth.conf.ext: Failed to init dict: dict redis: Invalid IP: redis
redis
我服务器上的主机名毫无问题地解析为 IP:
# getent hosts redis
192.168.48.2 redis redis
有没有办法使用 hostname
(也许是一些启用分辨率的隐藏设置),或者他们只是直截了当地没有实现对此的支持? :/
TL;DR
Dovecot redis dict
驱动程序接受未记录的参数 path,您可以在其中指定 unix 套接字。然后,您可以通过 unix 套接字 /run/redis.soc
:
创建一个服务于 tcp 端口 6379
的主机名 redis
的代理
socat unix-listen:/run/redis.soc,reuseaddr,fork,perm=0644,user=dovecot tcp:redis:6379 &
Dovecot 配置变为:
# Dictionary URI
uri = redis:path=/run/redis.soc
以下是我对问题的分析。我不会在 C
中编写代码,所以我的理解是有限的。
Code 涵盖了我的错误 (Invalid IP: redis
) 如下:
} else if (str_begins(*args, "host=")) {
if (net_addr2ip(*args+5, &ip) < 0) {
*error_r = t_strdup_printf("Invalid IP: %s",
*args+5);
ret = -1;
}
}
它依赖于net_addr2ip function which depends on the net_addr2ip_inet4_fast。这两个功能似乎都不做,它们的名字暗示了什么(它们不会将 addr
转换为 ip
):
static bool net_addr2ip_inet4_fast(const char *addr, struct ip_addr *ip)
{
uint8_t *saddr = (void *)&ip->u.ip4.s_addr;
unsigned int i, num;
if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
if (*addr == '[=13=]' && num <= 0xffffffff) {
/* single-number IPv4 address */
ip->u.ip4.s_addr = htonl(num);
ip->family = AF_INET;
return TRUE;
}
/* try to parse as a.b.c.d */
i = 0;
for (;;) {
if (num >= 256)
return FALSE;
saddr[i] = num;
if (i == 3)
break;
i++;
if (*addr != '.')
return FALSE;
addr++;
if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
}
if (*addr != '[=13=]')
return FALSE;
ip->family = AF_INET;
return TRUE;
}
int net_addr2ip(const char *addr, struct ip_addr *ip)
{
int ret;
if (net_addr2ip_inet4_fast(addr, ip))
return 0;
if (strchr(addr, ':') != NULL) {
/* IPv6 */
T_BEGIN {
if (addr[0] == '[') {
/* allow [ipv6 addr] */
size_t len = strlen(addr);
if (addr[len-1] == ']')
addr = t_strndup(addr+1, len-2);
}
ret = inet_pton(AF_INET6, addr, &ip->u.ip6);
} T_END;
if (ret == 0)
return -1;
ip->family = AF_INET6;
} else {
/* IPv4 */
if (inet_aton(addr, &ip->u.ip4) == 0)
return -1;
ip->family = AF_INET;
}
return 0;
}
因此 dovecot 的 redis dict
驱动程序中的 host
参数只能是 IP 地址 ¯_(ツ)_/¯
我正在使用 Dovecot v2.3.9.3
。通过查看鸽舍 docs,我看到 Redis
的规格如下:
redis:param=value:param2=value2:...
这里参数之一是host: Redis server host (default: 127.0.0.1)
.
在我的配置中我指定了 uri = redis:host=redis:port=6379
:
Feb 23 20:48:32 auth: Fatal: dict /etc/dovecot/dovecot-dict-auth.conf.ext: Failed to init dict: dict redis: Invalid IP: redis
redis
我服务器上的主机名毫无问题地解析为 IP:
# getent hosts redis
192.168.48.2 redis redis
有没有办法使用 hostname
(也许是一些启用分辨率的隐藏设置),或者他们只是直截了当地没有实现对此的支持? :/
TL;DR
Dovecot redis dict
驱动程序接受未记录的参数 path,您可以在其中指定 unix 套接字。然后,您可以通过 unix 套接字 /run/redis.soc
:
6379
的主机名 redis
的代理
socat unix-listen:/run/redis.soc,reuseaddr,fork,perm=0644,user=dovecot tcp:redis:6379 &
Dovecot 配置变为:
# Dictionary URI
uri = redis:path=/run/redis.soc
以下是我对问题的分析。我不会在 C
中编写代码,所以我的理解是有限的。
Code 涵盖了我的错误 (Invalid IP: redis
) 如下:
} else if (str_begins(*args, "host=")) {
if (net_addr2ip(*args+5, &ip) < 0) {
*error_r = t_strdup_printf("Invalid IP: %s",
*args+5);
ret = -1;
}
}
它依赖于net_addr2ip function which depends on the net_addr2ip_inet4_fast。这两个功能似乎都不做,它们的名字暗示了什么(它们不会将 addr
转换为 ip
):
static bool net_addr2ip_inet4_fast(const char *addr, struct ip_addr *ip)
{
uint8_t *saddr = (void *)&ip->u.ip4.s_addr;
unsigned int i, num;
if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
if (*addr == '[=13=]' && num <= 0xffffffff) {
/* single-number IPv4 address */
ip->u.ip4.s_addr = htonl(num);
ip->family = AF_INET;
return TRUE;
}
/* try to parse as a.b.c.d */
i = 0;
for (;;) {
if (num >= 256)
return FALSE;
saddr[i] = num;
if (i == 3)
break;
i++;
if (*addr != '.')
return FALSE;
addr++;
if (str_parse_uint(addr, &num, &addr) < 0)
return FALSE;
}
if (*addr != '[=13=]')
return FALSE;
ip->family = AF_INET;
return TRUE;
}
int net_addr2ip(const char *addr, struct ip_addr *ip)
{
int ret;
if (net_addr2ip_inet4_fast(addr, ip))
return 0;
if (strchr(addr, ':') != NULL) {
/* IPv6 */
T_BEGIN {
if (addr[0] == '[') {
/* allow [ipv6 addr] */
size_t len = strlen(addr);
if (addr[len-1] == ']')
addr = t_strndup(addr+1, len-2);
}
ret = inet_pton(AF_INET6, addr, &ip->u.ip6);
} T_END;
if (ret == 0)
return -1;
ip->family = AF_INET6;
} else {
/* IPv4 */
if (inet_aton(addr, &ip->u.ip4) == 0)
return -1;
ip->family = AF_INET;
}
return 0;
}
因此 dovecot 的 redis dict
驱动程序中的 host
参数只能是 IP 地址 ¯_(ツ)_/¯