LINUX.ORG.RU
ФорумAdmin

sshd, PermitOpen, unix-socket

 , ,


0

1

Насколько я вижу в man sshd_config, форваринг unix-сокетов разрешается опцией AllowStreamLocalForwarding и больше никаких настроек там не причастно. По факту же, если в конфиге указана опция PermitOpen и в ней стоит что-то кроме any, форвардинг unix-сокетов всегда отвергается с надписью типа такой:

Received request to connect to path /path/to/socket, but the request was denied.

Собственно, посмотрев в исходник, всё так и есть: для unix-сокетов там точно так же вызывается проверка белого списка, только вот способов внести в этот белый список unix-сокет (кроме общего для всех any) я что-то не вижу. Ну и с маном это поведение кардинально расходится (кроме того что синтаксис PermitOpen рассчитан только на TCP).

Проверял на 7.9 (дефолтный в freebsd12) и 8.4 (дефолтный в debian11).

Это я что-то напутал или всё так и есть и уже за много вышедших версий никто даже не заметил проблемы?

---------------------------------------------------

Места в исходниках (8.4 но думаю там мало что менялось):

1) serverloop.c: server_request_direct_streamlocal()

        if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
            auth_opts->permit_port_forwarding_flag &&
            !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) {
                c = channel_connect_to_path(ssh, target,
                    "direct-streamlocal@openssh.com", "direct-streamlocal");
        } else {
                logit("refused streamlocal port forward: "
                    "originator %s port %d, target %s",
                    originator, originator_port, target);
        }
тут всё ок, проверяются глобальные разрешения на unix-socket forwarding

2) channels.c: channel_connect_to_path()

        permit = pset->all_permitted;
        if (!permit) {
                for (i = 0; i < pset->num_permitted_user; i++) {
                        perm = &pset->permitted_user[i];
                        if (open_match(perm, path, PORT_STREAMLOCAL)) {
                                permit = 1;
                                break;
                        }
                }
        }
это функция специально для unix-сокетов, так что общего кода с tcp тут нет, а вот проверка белого списка выше процитирована (она одинаковая с проверкой в channel_connect_to_port() для tcp
static int
open_match(struct permission *allowed_open, const char *requestedhost,
    int requestedport)
{
        if (allowed_open->host_to_connect == NULL)
                return 0;
        if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT &&
            allowed_open->port_to_connect != requestedport)
                return 0;
        if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 &&
            strcmp(allowed_open->host_to_connect, requestedhost) != 0)
                return 0;
        return 1;
}

★★★★★

Последнее исправление: firkax (всего исправлений: 5)