Dovecot Не удалось инициализировать dict: dict redis: Неверный IP - PullRequest
0 голосов
/ 24 февраля 2020

Я использую Dovecot v2.3.9.3. Глядя на голубятню docs , я вижу, что спецификация для Redis следующая:

redis:param=value:param2=value2:...

Здесь один из параметров host: Redis server host (default: 127.0.0.1).

In мою конфигурацию я указал uri = redis:host=redis:port=6379:

23 февраля 20:48:32 auth: Fatal: dict /etc/dovecot/dovecot-dict-auth.conf.ext: не удалось инициализировать dict: dict redis: неверный IP: redis

redis имя хоста на моем сервере разрешается без проблем с IP:

# getent hosts redis
192.168.48.2      redis  redis

Есть ли способ использовать hostname ( может быть какая-то скрытая настройка, которая разрешает разрешение), или они просто прямо не реализовали поддержку для этого? : /

1 Ответ

0 голосов
/ 24 февраля 2020

TL; DR

Dovecot redis dict Драйвер принимает недокументированный параметр path , в котором можно указать сокет unix. Затем вы можете создать прокси для имени хоста redis, обслуживающего порт tcp 6379 через unix сокет /run/redis.soc:

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, поэтому мое понимание было ограничено.

Код , который покрывает мою ошибку (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 , которая зависит от 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 == '\0' && 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 != '\0')
        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;
}

Поэтому параметр host в драйвере dovecot redis dict не может быть чем-то еще, кроме IP-адреса ¯_ (ツ) _ / ¯

...