Как заставить HTTP-транспорт Git (2.5+) предпочесть SPNEGO базовой аутентификации?

Вывод: я использую Git для Windows 2.5.1 для аутентификации на Git-сервере Kerbesized. Когда я использую URL-адрес в форме https://el2-gitlab.sa.c/kkm/GrammarTools.git, Git даже не пытается выполнить аутентификацию Negotiate и запрашивает имя пользователя и пароль. Обходной путь, чтобы заставить Git использовать SPNEGO, состоит в том, чтобы предоставить пустое имя пользователя и пароль в самом URL-адресе, как в https://:@el2-gitlab.sa.c/kkm/GrammarTools.git. В этом случае Git успешно аутентифицируется с помощью существующего билета Kerberos.

Могу ли я настроить Git для использования SPNEGO без изменения удаленного URL-адреса?

Подробнее. Я потратил довольно много времени, пытаясь решить проблему. Сначала я попытался задать пустое имя пользователя в .gitconfig, но безрезультатно:

[credential "https://el2-gitlab.sa.c"]
   username = ''

Я не раз сталкивался с вопросами по обратной проблеме, когда Git отказывался возвращаться к Basic после неудачной попытки Negotiate, но поведение подтверждено изменение в версии 2.3.1.

Ответ на запросы с пустым именем пользователя и паролем не помогает, вопреки некоторым предложениям, которые я мог найти на SO (но они могут быть до версии 2.3.1).

Наконец, подробный вывод libcurl (в сокращении) показывает, что Git действительно пытается выполнить обычную аутентификацию и полностью отказывается от Negotiate:

$ export GIT_CURL_VERBOSE=1
$ git clone https://el2-gitlab.sa.c/kkm/GrammarTools.git kerbtest
Cloning into 'kerbtest'...
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
<
* Connection #0 to host el2-gitlab.sa.c left intact
Username for 'https://el2-gitlab.sa.c':

Также может представлять интерес то, что клиент Git повторяет неаутентифицированный запрос на 401 во второй раз, прежде чем ответить билетом:

$ git clone https://:@el2-gitlab.sa.c/kkm/GrammarTools.git kerbtest
Cloning into 'kerbtest'...
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
* Connection #0 to host el2-gitlab.sa.c left intact
* Issue another request to this URL: 'https://:@el2-gitlab.sa.c/kkm/GrammarTools.git/info/refs?service=git-upload-pack'
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 401 Unauthorized
< Status: 401 Unauthorized
< Www-Authenticate: Basic realm=""
< Www-Authenticate: Negotiate
<
* Issue another request to this URL: 'https://:@el2-gitlab.sa.c/kkm/GrammarTools.git/info/refs?service=git-upload-pack'
* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults
> GET /kkm/GrammarTools.git/info/refs?service=git-upload-pack HTTP/1.1
Host: el2-gitlab.sa.c
Authorization: Negotiate YIIGtg[ .... trimmed ... ]
User-Agent: git/2.5.1.windows.1

< HTTP/1.1 200 OK

person kkm    schedule 25.09.2015    source источник
comment
Начиная с git 2.8+ (март 2016 г.), должно быть достаточно простого git config http.emptyAuth true. См. мой ответ ниже   -  person VonC    schedule 25.02.2016


Ответы (3)


git 2.8 (март 2016 г.) должен устранить эту проблему и принудительно указывать пустое имя пользователя и пароль во время HTTP-аутентификации:

См. commit 121061f (15 февраля 2016 г.) от Брайан М. carlson (bk2204).
(Объединено Junio ​​C Hamano -- gitster -- в commit 65ba75b, 24 февраля 2016 г.)

http: добавить возможность попробовать аутентификацию без имени пользователя

Выполнение аутентификации GSS-Negotiate с использованием Kerberos не требует указания имени пользователя или пароля, поскольку эта информация уже включена в сам билет.
Однако libcurl отказывается выполнять аутентификацию, если ему не были предоставлены имя пользователя и пароль.

Добавьте параметр http.emptyAuth, который предоставляет libcurl пустое имя пользователя и пароль, чтобы он все равно пытался выполнить аутентификацию.

В git config документации будет указано:

http.emptyAuth:

Попытка аутентификации без поиска имени пользователя или пароля.
Это можно использовать для попытки аутентификации GSS-Negotiate без указания имени пользователя в URL-адресе, поскольку libcurl обычно требует имя пользователя для аутентификации.


Git 2.10.2 (октябрь 2016 г.) улучшит это.

См. commit 5275c30 (4 октября 2016 г.) от Дэвид Тернер (csusbdt).
(объединено Хунио C Хамано -- gitster -- в commit c6400bf, 17 октября 2016 г.)

http: http.emptyauth должен разрешать пустые (не только NULL) имена пользователей

При использовании проверки подлинности Kerberos с более новыми версиями libcurl CURLOPT_USERPWD должно быть установлено значение, даже если это пустое значение. Это значение никогда не отправляется на сервер.
Предыдущие версии libcurl не требовали установки этой переменной.
Одним из способов, которым некоторые пользователи выражают пустое имя пользователя/пароль, является http://:@gitserver.example.com, для поддержки которого и был разработан http.emptyauth.< br> Еще один эквивалентный URL – http://@gitserver.example.com.
Последний ведет к имени пользователя нулевой длины, а не к имени пользователя NULL, но CURLOPT_USERPWD все равно необходимо установить (если установлено http.emptyauth) .
Сделайте это.


Git 2.13 (второй квартал 2017 г.) уменьшит двустороннюю аутентификацию по HTTP, если сервер поддерживает только один метод аутентификации.

См. коммит 40a18fc (25 февраля 2017 г.) и коммит 840398f (22 февраля 2017 г.), автор Джефф Кинг (peff).
Помощь: Йоханнес Шинделин (dscho).
(Объединено
Юнио С. Хамано -- gitster -- в commit 92718f5, 10 марта 2017 г.)

http: добавить режим "auto" для http.emptyauth

Эта переменная (http.emptyauth) должна быть указана, чтобы некоторые типы неосновной аутентификации работали, но в идеале она должна работать из коробки для всех.

Тем не менее, просто установив для него значение "1" по умолчанию, вы получите дополнительную обратную связь в тех случаях, когда это бесполезно. В итоге мы отправляем поддельные пустые учетные данные, которые сервер отклоняет.

«Автоматический» режим должен заставить его работать «из коробки», не требуя дополнительных циклов для людей, использующих серверы только для Basic.

person VonC    schedule 25.02.2016
comment
Изменение этого на выбранный статус ответа (к счастью, мой ответ 2015 года устарел!) - person kkm; 09.02.2018

Это не проблема Git, а проблема curl. Вы страдаете от известной ошибки № 10. Реализация curl намного ниже реализации libserf, используемой в Subversion.

Что касается выбора аутентификации: Git запрашивает ANY_AUTH с libcurl и должен выбрать самый надежный доступный механизм. Если это не так (с простым curl), вы нашли ошибку. Сообщите об этом curlна GitHub.

person Michael-O    schedule 25.09.2015
comment
Спасибо. Знаете ли вы обходной путь, который заставит Git передать пустое имя пользователя и пароль в libcurl, помимо изменения URL-адреса? Кроме того, я не могу понять второй абзац. Если это известная ошибка, то зачем мне сообщать о ней? И как я могу попробовать то же самое с обычным curl? - person kkm; 25.09.2015
comment
Попробуйте сначала клонировать из https://:@el2-gitlab.sa.c/kkm/GrammarTools.git. Второй абзац о смешении авторизаций. То же самое в curl: $ curl --negotiate https://:@el2-gitlab.sa.c/kkm/GrammarTools.git или похоже на конфигурацию Git: $ curl --any-auth https://:@el2-gitlab.sa.c/kkm/GrammarTools.git. - person Michael-O; 25.09.2015
comment
Я понимаю. когда я делаю $ curl -s -v --negotiate https://el2-gitlab.sa.c/kkm/GrammarTools.git/info/refs?service=git-upload-pack, curl не пытается выполнить аутентификацию, как в ошибке 10. Однако, когда я указываю любое имя пользователя, включая пустое, с помощью переключателя -u '', curl просто зависает, ничего не печатая. Это не похоже на то, о чем сообщалось на sourceforge.net/p/curl/bugs/440 -- как вы думаете, это все та же ошибка? - person kkm; 25.09.2015
comment
Вы либо должны передать : в URL-адресе, либо в качестве параметра, такого как -u :, но не -u ''. - person Michael-O; 25.09.2015
comment
Ага, -u : сделал свое дело! К сожалению, git config --global credential.https://el2-gitlab.sa.c.username ':' этого не сделал :( Можете ли вы придумать какой-нибудь способ заставить git передать curl поддельное имя пользователя, но без изменения удаленного URL-адреса? - person kkm; 25.09.2015
comment
Только что обнаружил, что размещение предложения host с поддельным именем пользователя и паролем в .netrc (или, скорее, _netrc в этом порте Windows) заставляет git пытаться использовать Kerberos! Это сделает это за нас. Спасибо за подсказки! - person kkm; 25.09.2015
comment
@kkm Да, это эквивалентно, но некрасиво. Поскольку это было полезно, вы можете принять и/или проголосовать за этот ответ. - person Michael-O; 26.09.2015
comment
Справедливости ради по отношению к сообществу, написанный ответ не отвечает на вопрос. Вопрос заключался в следующем: могу ли я настроить Git для использования SPNEGO без изменения удаленного URL-адреса? и я считаю, что принятый ответ должен отвечать на него. Не могли бы вы дополнить свой ответ фактическим ответом: какой бы уродливой, на ваш взгляд, установка _netrc действительно не достигла того, чего хотел ОП. Я с радостью приму его с этой модификацией. (И если вам интересно, зачем мне это нужно, Git-сервер GitLab показывает URL-адрес без части @:, и мне важно, чтобы пользователи могли копировать/вставлять URL-адрес без изменений). - person kkm; 29.09.2015
comment
@kkm Я понимаю, имейте в виду, что я изобразил проблему в завитке. Вы можете поднять это снова с помощью curl и исправить эту известную проблему. - person Michael-O; 29.09.2015

ВНИМАНИЕ: раньше это был выбранный ответ, но теперь он устарел с версии git v2.8. Перейдите к ответу VonC, который теперь отмечен зеленым флажком.

Все, что ниже этой строки, является историческим и устаревшим. Не делайте этого.


Поскольку большая часть относится к @Michael-O в обсуждении его ответа на этот вопрос, я считаю, что последний простой решение проблемы должно быть опубликовано в интересах сообщества SO.

Обходной путь к известной ошибке в libcurl, о которой упоминал Майкл, заключается в создании файла ~/.netrc (исходный libcurl) или ~/_netrc (порт Git для Windows 2.5+, основанный на MSys2). Файл должен содержать пустое имя пользователя и пароль для узла сервера Git с поддержкой Kerberos. Поскольку совпадение узлов является точным, включите как короткие, так и полные DNS-имена, а также возможные псевдонимы, если таковые имеются, например:

machine gitlab.acme.com username '' password ''
machine gitlab          username '' password ''

Если все верно, строка, которую вы видите в исходных журналах вопросов

* Couldn't find host el2-gitlab.sa.c in the _netrc file; using defaults

больше не следует печатать, и следует использовать аутентификацию согласования с использованием билета Kerberos пользователя.

person kkm    schedule 09.11.2015