Bug 39440

Summary: MS DNS RFC 2845 violation (samba and windows compatibility)
Product: Sisyphus Reporter: Evgeny Sinelnikov <sin>
Component: bindAssignee: Stanislav Levin <slev>
Status: NEW --- QA Contact: qa-sisyphus
Severity: major    
Priority: P4 CC: aen, george, glebfm, ldv, placeholder, rider, sem, slev
Version: unstable   
Hardware: all   
OS: Linux   
Attachments:
Description Flags
MS DNS RFC 2845 violation
none
Лог ошибки tsig none

Description Evgeny Sinelnikov 2020-12-15 06:12:17 MSK
При попытке обновления записей через Kerberos с помощью nsupdate возникает проблема некорректной обработки ответа на клиентской стороне. Проблема проявлется следующим образом:

# cat /var/log/named/req
server dc.domain.alt
update add dc.domain.alt. 900 A 10.64.128.2
show
send

# nsupdate -g /var/log/named/req   
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:      0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
dc.domain.alt.          900     IN      A       10.64.128.2

; TSIG error with server: tsig verify failure

То есть, несмотря на успешный результат, nsupdate возвращает ошибку. Проблема стабильно воспроизводится против Samba.

В коде nsupdate имеется соответствующий участок кода:

#if 0
               if (usegsstsig && answer->rcode == dns_rcode_noerror) {
                       /*
                        * For MS DNS that violates RFC 2845, section 4.2
                        */
                       break;
               }
#endif

Предлагаю его раскомментировать. Ничего сильно крамольного не наблюдаю.
Comment 1 Evgeny Sinelnikov 2020-12-15 06:22:35 MSK
Created attachment 9082 [details]
MS DNS RFC 2845 violation

Патч включающий доп. обработку ошибки, в случае успешного выполнения через GSSAPI.
Comment 2 Evgeny Sinelnikov 2020-12-15 06:32:40 MSK
В сизиф отправлена таска:
#263464 BUILDING #1 [locked] [test-only] sisyphus bind.git=9.11.25-alt3

Данное исправление хотелось бы также бекпортировать в p9. Сейчас там bind-utils-9.11.22, в то время как в сизифе уже bind-utils-9.11.25. Как лучше поступить? Планировалось ли это обноевление в p9?
Comment 3 Evgeny Sinelnikov 2020-12-15 06:41:39 MSK
Данная проблема у меня воспроизвелась как известная, блуждающая бага:
- https://lists.samba.org/archive/samba/2018-November/219362.html
- https://access.redhat.com/solutions/4437901
- https://lists.samba.org/archive/samba/2019-August/225179.html

которую решают всякими костылями вида:
# cat /usr/local/samba/etc/smb.conf
> dns update command = /usr/sbin/samba_dnsupdate --use-samba-tool

________

Кроме того, обнаружена похожая проблема другой природы:
DNS update using BIND9_DLZ fail using MIT KRB5 with "Request is a replay"
https://bugzilla.samba.org/show_bug.cgi?id=13066

Там решение выглядит так:

# echo 'KRB5RCACHETYPE="none"' >> /etc/sysconfig/bind
# systemctl restart bind

Но уже тема для bind-control.
Comment 4 Stanislav Levin 2020-12-15 12:28:26 MSK
Спасибо за репорт.

Очевидно, что нарушать RFC - это плохо.
Не знаю почему ISC не смогла повлиять на этот MS DNS(что это?).
Менять в этом случае дефолтное поведение категорически нет, так как на это могут быть завязаны пользователи.

Как вариант, предлагаю добавить кастомную опцию, чтобы быть совместимыми с этим DNS сервером, естественно, через апстрим.

Еще одно обсуждение:
https://bugzilla.redhat.com/show_bug.cgi?id=1394320

Маловлияющий фактор, но просто обратите внимание, что никто не сделал этого в других дистрибутивах, почему?

В действительности нигде не предъявлено четких доказательств, что происходит на самом деле(gdb).
Comment 5 Evgeny Sinelnikov 2020-12-15 15:11:37 MSK
(Ответ для Stanislav Levin на комментарий #4)
...
> Маловлияющий фактор, но просто обратите внимание, что никто не сделал этого
> в других дистрибутивах, почему?

Из этого факта, самого по себе, ещё ничего не следует. Совершенно не стоит предполагать, что причина только в потенциальной несовместимости.

> В действительности нигде не предъявлено четких доказательств, что происходит
> на самом деле(gdb).

Причём тут gdb, как он тут поможет?

Тут всё очевидно:
https://tools.ietf.org/html/rfc2845


   4.2. TSIG on Answers

   When a server has generated a response to a signed request, it signs
   the response using the same algorithm and key.  The server MUST not
   generate a signed response to an unsigned request.  The digest
   components are:

      Request MAC
      DNS Message (response)
      TSIG Variables (response)

Смысл в том, что успешность операции передаётся в переменных. А как быть если в ответе на запрос уже был - status: NOERROR? Каким должен быть, по умолчанию ответ в переменной TSIG RDATA Error, если переменную не вернули? Если обязательно ошибка, то верна традиционная ISC Bind интерпретация RFC 2845. Но я этого не вижу явно их текста RFC.

Честно говоря, я не вижу ни одной технической причины, исходя из анализа протокола и деталей обработки ответа, которая бы не позволяла включить этот патч.

Суть в следующем:
- протокол требует в переменных TSIG явный ответ в виде переменной ERROR;
- при этом в ответе и так присутствует Error: No error (0);
- но, как следует, из коментария - это не по RFC 2845 в чьей-то интерпретации.


Frame 24: 197 bytes on wire (1576 bits), 197 bytes captured (1576 bits) on interface lo, id 0
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol Version 4, Src: 10.64.128.2, Dst: 10.64.128.2
Transmission Control Protocol, Src Port: 53, Dst Port: 33903, Seq: 1, Ack: 144, Len: 143
Domain Name System (response)
    Length: 141
    Transaction ID: 0x20fb
    Flags: 0xa880 Dynamic update response, No error
        1... .... .... .... = Response: Message is a response
        .010 1... .... .... = Opcode: Dynamic update (5)
        .... .0.. .... .... = Authoritative: Server is not an authority for domain
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...0 .... .... = Recursion desired: Don't do query recursively
        .... .... 1... .... = Recursion available: Server can do recursive queries
        .... .... .0.. .... = Z: reserved (0)
        .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
        .... .... ...0 .... = Non-authenticated data: Unacceptable
        .... .... .... 0000 = Reply code: No error (0)
    Zones: 1
    Prerequisites: 0
    Updates: 1
    Additional RRs: 1
    Zone
        domain.alt: type SOA, class IN
            Name: domain.alt
            [Name Length: 10]
            [Label Count: 2]
            Type: SOA (Start Of a zone of Authority) (6)
            Class: IN (0x0001)
    Updates
        dc.domain.alt: type A, class IN, addr 10.64.128.2
            Name: dc.domain.alt
            Type: A (Host Address) (1)
            Class: IN (0x0001)
            Time to live: 900 (15 minutes)
            Data length: 4
            Address: 10.64.128.2
    Additional records
        1370890395.sig-dc.domain.alt: type TSIG, class ANY
            Name: 1370890395.sig-dc.domain.alt
            Type: TSIG (Transaction Signature) (250)
            Class: ANY (0x00ff)
            Time to live: 0 (0 seconds)
            Data length: 54
            Algorithm Name: gss-tsig
            Time Signed: Dec 15, 2020 15:36:22.000000000 +04
            Fudge: 300
            MAC Size: 28
            MAC
                [Expert Info (Warning/Undecoded): No dissector for algorithm:gss-tsig]
                    [No dissector for algorithm:gss-tsig]
                    [Severity level: Warning]
                    [Group: Undecoded]
            Original Id: 8443
            Error: No error (0)
            Other Len: 0
    [Request In: 19]
    [Time: 0.282538714 seconds]
Comment 6 Stanislav Levin 2020-12-15 15:28:37 MSK
Попробую воспроизвести локально, после этого, если потребуется, попробую поговорить с апстримом.
Comment 7 Evgeny Sinelnikov 2020-12-15 15:59:21 MSK
Created attachment 9084 [details]
Лог ошибки tsig

Судя по выводу tshark, проблема может быть в самой обработке пакета.
Comment 8 Evgeny Sinelnikov 2020-12-16 06:08:45 MSK
В коде nsupdate.c имеется такой кусок:

        case ISC_R_SUCCESS:
                /*
                 * XXXSRA Waaay too much fun here.  There's no good
                 * reason why we need a TSIG here (the people who put
                 * it into the spec admitted at the time that it was
                 * not a security issue), and Windows clients don't
                 * seem to work if named complies with the spec and
                 * includes the gratuitous TSIG.  So we're in the
                 * bizarre situation of having to choose between
                 * complying with a useless requirement in the spec
                 * and interoperating.  This is nuts.  If we can
                 * confirm this behavior, we should ask the WG to
                 * consider removing the requirement for the
                 * gratuitous TSIG here.  For the moment, we ignore
                 * the TSIG -- this too is a spec violation, but it's
                 * the least insane thing to do.
                 */
#if 0
                /*
                 * Verify the signature.
                 */
                rcvmsg->state = DNS_SECTION_ANY;
                dns_message_setquerytsig(rcvmsg, NULL);
                result = dns_message_settsigkey(rcvmsg, tsigkey);
                check_result(result, "dns_message_settsigkey");
                result = dns_message_checksig(rcvmsg, NULL);
                ddebug("tsig verification: %s", dns_result_totext(result));
                check_result(result, "dns_message_checksig");
#endif /* 0 */

                send_update(&tmpzonename, &master_servers[master_inuse]);
                setzoneclass(dns_rdataclass_none);
                break;


Если его раскомментировать, то вывод выглядит так:

[root@dc nsupdate]# ./nsupdate -g /var/log/named/req 
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:      0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
dc.domain.alt.          900     IN      A       10.64.128.2

dns_message_checksig: did not expect a TSIG or SIG(0)

[root@dc nsupdate]# echo $?
1

Если раскомментировать оба патча, то поведение аналогично.

Ну, то есть вот о чём идёт речь из RFC 2845 4.2. TSIG on Answers:
"The server MUST not generate a signed response to an unsigned request."

Правда кто тут ещё чему не соответствует уже становиться не очевидно:
"So we're in the bizarre situation of having to choose between complying with a useless requirement in the spec and interoperating."

___________________

Таким образом расклад такой:
- коллективный автор nsupdate считает, что samba и другие windows-подобные сервера не соотвествуют некому стандарту (я пока не до конца понял в чем точно);
- по факту мы имеем лишний TSIG-пакет, который как бы не имеет смысла в случае GSSAPI ("did not expect a TSIG or SIG(0)");
- пакет этот игнорируется;
- но, по завершению функции dns_request_getresponse(), при вызове функции dns_tsig_verify(), на такой вот проверке:

        /*
         * If this is a response, there should be a TSIG in the query with the
         * the exception if this is a TKEY request (see RFC 3645, Section 2.2).
         */
        response = is_response(msg);
        if (response && msg->querytsig == NULL) {
                if (msg->tkey != 1) {
                        return (DNS_R_EXPECTEDTSIG);
                }
        }

- Ну, и далее всё отваливается:
; TSIG error with server: tsig verify failure

Ну, оно и логично как бы. Пакет-то пропущен. Как-то на багу похоже.

Плюс имеется опция -o в эту тему, но с ней тоже ничего не работает:

GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode is switched on with the -g flag. A non-standards-compliant variant of GSS-TSIG used by Windows 2000 can be switched on with the -o flag.
Comment 9 AEN 2021-06-07 00:20:33 MSK
Что с этой багой?
Comment 10 Stanislav Levin 2021-06-07 13:45:52 MSK
Работы не проводились