C# Как подключиться к серверу LDAP (AD DC) с помощью SSL или TLS из Linux Ubuntu 22.04C#

Место общения программистов C#
Ответить
Anonymous
 C# Как подключиться к серверу LDAP (AD DC) с помощью SSL или TLS из Linux Ubuntu 22.04

Сообщение Anonymous »

Я запускаю приложение C# .NET 6 в контейнере Linux Ubuntu 22.04. Мне нужно, чтобы приложение подключалось к контроллеру домена Active Directory для аутентификации пользователей приложения. Я могу заставить работать незащищенные соединения LDAP с контроллером домена, но получаю исключения для любых попыток соединений LDAP SSL или TLS. Сообщения об исключениях довольно расплывчаты, поэтому я застрял в дальнейших исследованиях. Мне нужно использовать безопасные подключения к LDAP, чтобы приложение не отправляло учетные данные пользователей в открытом виде.
Мой контейнер Linux не подключен к домену Active Directory.Я использую пакеты nuget System.DirectoryServices версии 7.0.1 и System.DirectoryServices.Protocols версии 7.0.1. Согласно запросу на извлечение № 52904, была добавлена ​​поддержка TLS, но мне неясно, каковы предварительные требования и какие сценарии поддерживаются.
Должен ли я использовать другой тип AuthType или мне не хватает предварительного пакета? Будем очень признательны за любую помощь.
Тестирование
Я тестировал, используя приведенный ниже код. (Где username — это sAMAccountName, а userDN — это отличительное имя). Я думал, что использую неправильные параметры подключения, поэтому этот код циклически переключает различные варианты.

Код: Выделить всё

internal class LdapConnectionTest
{

enum EncryptionOption
{
None = 0,
SSL = 1,
TLS = 2
}

public static void StartTest(
string ldapServer,
string userName,
string userDN,
string password)
{

foreach (AuthType authType in new AuthType[] {
AuthType.Anonymous,
AuthType.Basic,
AuthType.Negotiate,
AuthType.Ntlm })
{

foreach (EncryptionOption encryptionOption in new EncryptionOption[] {
EncryptionOption.None,
EncryptionOption.SSL,
EncryptionOption.TLS})
{

foreach (int protocolVersion in new int[] {2,3})
{

foreach (ReferralChasingOptions referralChasingOption in new ReferralChasingOptions[] {
ReferralChasingOptions.None,
ReferralChasingOptions.All})
{

foreach (bool skipVerifyCertificate in new bool[] { false, true })
{

int port = 389; //TLS is also on port 389

if (encryptionOption == EncryptionOption.SSL)
{
port = 636;
}

if (encryptionOption == EncryptionOption.TLS && protocolVersion == 2) continue; //TLS not supported in LDAP v2

Console.WriteLine();
Console.WriteLine($"##### Attempt with  AuthType: {authType}  Encryption: {encryptionOption}  Port: {port}  Protocol Version: {protocolVersion}  ReferalChasing: {referralChasingOption}  Skip Verify Cert: {skipVerifyCertificate}");

try
{

LdapDirectoryIdentifier id = new(ldapServer, port);

LdapConnection connection = new(id)
{
AuthType = authType
};

connection.SessionOptions.ReferralChasing = referralChasingOption;

if (encryptionOption == EncryptionOption.SSL)
{
connection.SessionOptions.SecureSocketLayer = true;

if (skipVerifyCertificate)
{
connection.SessionOptions.VerifyServerCertificate = (con, cer) => true; //this is insecure
}
}

connection.SessionOptions.ProtocolVersion = protocolVersion;

NetworkCredential credential = new(authType == AuthType.Basic ? userDN : userName, password);

if (encryptionOption == EncryptionOption.TLS)
{
if (skipVerifyCertificate)
{
connection.SessionOptions.VerifyServerCertificate = (con, cer) => true;  //this is insecure
}
connection.SessionOptions.StartTransportLayerSecurity(null);
}

if (authType == AuthType.Anonymous)
{
connection.Bind();
}
else
{
connection.Bind(credential);
}

Console.WriteLine($"Successfull connection  Protocol Version: {connection.SessionOptions.ProtocolVersion}  Secure: {connection.SessionOptions.SecureSocketLayer}");

connection.Dispose();

}
catch (Exception? ex)
{
while (ex != null)
{
Console.WriteLine($"Exception {ex.GetType().ToString()}  {ex.Message}");
Console.WriteLine(ex.StackTrace);

//exit on wrong credential in order to not lock out account
if (ex.Message.Contains("credential", StringComparison.InvariantCultureIgnoreCase)) return;

ex = ex.InnerException;

if (ex != null)
{
Console.WriteLine("Inner Exception:");
}
}
}
}
}
}
}
}
}

}

Все тестовые сценарии работают, когда я запускаю тестовый код с рабочей станции Windows. Когда я пробую это в Ubuntu 22.04, небезопасные соединения работают, но я получаю следующие исключения для безопасных соединений (сводка результатов приведенного выше кода). Я ожидал, что хотя бы один из вариантов безопасного соединения сработает.

Код: Выделить всё

##### Attempt with  AuthType: Basic  Encryption: None  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Successfull connection  Protocol Version: 3  Secure: False

##### Attempt with  AuthType: Basic  Encryption: SSL  Port: 636  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  The LDAP server is unavailable.
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential newCredential)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 110

##### Attempt with  AuthType: Basic  Encryption: TLS  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  The connection cannot be established.
at System.DirectoryServices.Protocols.LdapSessionOptions.StartTransportLayerSecurity(DirectoryControlCollection controls)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 101

##### Attempt with  AuthType: Negotiate  Encryption: None  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  The feature is not supported.
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential newCredential)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 110

##### Attempt with  AuthType: Negotiate  Encryption: SSL  Port: 636  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  The feature is not supported.
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential newCredential)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 110

##### Attempt with  AuthType: Negotiate  Encryption: TLS  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  The connection cannot be established.
at System.DirectoryServices.Protocols.LdapSessionOptions.StartTransportLayerSecurity(DirectoryControlCollection controls)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 101

##### Attempt with  AuthType: Ntlm  Encryption: None  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  An unknown authentication error occurred.
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential newCredential)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 110

##### Attempt with  AuthType: Ntlm  Encryption: SSL  Port: 636  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert: False
Exception System.DirectoryServices.Protocols.LdapException  An unknown authentication error occurred.
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.Protocols.LdapConnection.Bind(NetworkCredential newCredential)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 110

##### Attempt with  AuthType: Ntlm  Encryption: TLS  Port: 389  Protocol Version: 3  ReferalChasing: None  Skip Verify Cert:  False
Exception System.DirectoryServices.Protocols.LdapException  The connection cannot be established.
at System.DirectoryServices.Protocols.LdapSessionOptions.StartTransportLayerSecurity(DirectoryControlCollection controls)
at MyTestApp.Ldap.LdapConnectionTest.StartTest(String ldapServer, String userName, String userDN, String password) in /src/MyTestApp/MyTestApp/Ldap/LdapConnectionTest.cs:line 101

Среда
Я установил корневой сертификат AD с помощью update-ca-certificates. Мой файл ldap.conf указывает на файл crt, в котором установлены все мои центры сертификации.

Код: Выделить всё

# cat ldap.conf
#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

# TLS certificates (needed for GnuTLS)
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt
Другие сведения о моем окружении:

Код: Выделить всё

# dotnet --info
.NET SDK (reflecting any global.json):
Version:   6.0.122
Commit:    dc5a76ad5c

Runtime Environment:
OS Name:     ubuntu
OS Version:  22.04
OS Platform: Linux
RID:         ubuntu.22.04-x64
Base Path:   /usr/lib/dotnet/sdk/6.0.122/

global.json file:
Not found

Host:
Version:      6.0.22
Architecture: x64
Commit:       4bb6dc195c

.NET SDKs installed:
6.0.122 [/usr/lib/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.22 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.22 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]

Download .NET:
https://aka.ms/dotnet-download

Learn about .NET Runtimes and SDKs:
https://aka.ms/dotnet/runtimes-sdk-info
#
Я установил в свой контейнер следующие пакеты:

Код: Выделить всё

FROM ubuntu:22.04

#update software package lists
RUN apt-get update && \
apt update && \
#install .NET ASP Core runtime
apt-get install -y aspnetcore-runtime-6.0 && \
#install LDAP library + symlink from old version that .NET wants https://github.com/dotnet/runtime/issues/69456
apt-get install -y libldap-2.5-0 && \
ln -s /usr/lib/x86_64-linux-gnu/libldap-2.5.so.0 /usr/lib/x86_64-linux-gnu/libldap-2.4.so.2 && \
#install ca certificates (required for ssl)
apt-get install -y ca-certificates && \
#tidyup
apt clean && \
apt-get clean
Я использую обходной путь символической ссылки, описанный в #69456, для жестко запрограммированной ссылки на libldap-2.4.so.2, которая недоступна в Ubuntu 22 апреля.
Я успешно запустил ldapsearch, чтобы установить ldaps:// соединение с контроллером домена из моего контейнера Linux.

Подробнее здесь: https://stackoverflow.com/questions/771 ... nux-ubuntu
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»