如何配置 System.DirectoryServices.Protocols.LdapConnection 以连接容器化的LDAP服务器?

huangapple go评论80阅读模式
英文:

How do I configure System.DirectoryServices.Protocols.LdapConnection for a containerized LDAP server?

问题

我已经按照这个指南在容器中设置了一个OpenLDAP服务器。当我以以下方式运行不使用TLS/SSL的容器时:

sudo docker run \
    --name openldap-server \
    --rm \
    --publish 389:389 \
    --hostname my.ldap.server.org \
    --env LDAP_ORGANISATION="My LDAP organization" \
    --env LDAP_DOMAIN="my.ldap.server.org" \
    --env LDAP_BASE_DN="dc=my,dc=ldap,dc=server,dc=org" \
    --env LDAP_ADMIN_PASSWORD="test" \
    --volume /data/slapd/database:/var/lib/ldap \
    --volume /data/slapd/config:/etc/ldap/slapd.d \
    --env LDAP_TLS=false \
    --detach osixia/openldap:latest

然后,在我的C# 7.0代码中,我可以像下面这样连接到测试用户:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 389))
{
    AuthType = AuthType.Basic
};
ldapConnection.SessionOptions.ProtocolVersion = 3;

string username = "uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org", password = "test";
ldapConnection.Bind(new NetworkCredential(username, password));

但是,当我启用TLS/SSL重新启动OpenLDAP容器时,如下所示:

sudo docker run \
    --name openldap-server \
    --rm \
    --publish 636:636 \
    --hostname my.ldap.server.org \
    --env LDAP_ORGANISATION="My LDAP organization" \
    --env LDAP_DOMAIN="my.ldap.server.org" \
    --env LDAP_BASE_DN="dc=my,dc=ldap,dc=server,dc=org" \
    --env LDAP_ADMIN_PASSWORD="test" \
    --volume /data/slapd/database:/var/lib/ldap \
    --volume /data/slapd/config:/etc/ldap/slapd.d \
    --volume /data/certificates:/container/service/slapd/assets/certs \
    --env LDAP_TLS_CRT_FILENAME=server.crt \
    --env LDAP_TLS_KEY_FILENAME=server.key \
    --env LDAP_TLS_CA_CRT_FILENAME=ca.crt \
    --detach osixia/openldap:latest

那么我不知道如何在C#代码中添加所有必需的证书到LdapConnection。我已经做到了这一步:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 636))
{
    AuthType = AuthType.Basic
    // AuthType = AuthType.Negotiate
};
ldapConnection.SessionOptions.SecureSocketLayer = true;

// var serverCrt = File.ReadAllText("<my certificate directory>/server.crt");
// var serverKey = File.ReadAllText($"<my certificate directory>/server.key");
// var serverCertificate = X509Certificate2.CreateFromPem(serverCrt, serverKey);
// var serverCertificate = X509Certificate.CreateFromCertFile("<my certificate directory>/server.crt");
// var caCertificate = new X509Certificate("<my certificate directory>/ca.crt");

// connection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((connection, serverCertificate ) => true);
// connection.SessionOptions.VerifyServerCertificate = delegate { return true; };

ldapConnection.SessionOptions.ProtocolVersion = 3;

ldapConnection.Bind(new NetworkCredential("uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org", "test"));

当OpenLDAP服务器期望同时具有服务器和CA证书(我认为)时,如何配置代码以使用TLS/SSL连接?我认为解决方法不是在我的主机上安装证书,因为代码将在容器中运行,证书将在运行时挂载。

也许我在生成证书时出现了问题。服务器证书的“Common Name”(CN)是“my.ldap.server.org”,而CA的CN是托管OpenLDAP容器的机器的用户名(但容器内的用户名不同)。

英文:

I've followed this guide to setup an OpenLDAP server in a container. When I run the container with TLS/SSL set to false, as follows:

sudo docker run \
	--name openldap-server \
	--rm \
	--publish 389:389 \
	--hostname my.ldap.server.org \
	--env LDAP_ORGANISATION=&quot;My LDAP organization&quot; \
	--env LDAP_DOMAIN=&quot;my.ldap.server.org&quot; \
	--env LDAP_BASE_DN=&quot;dc=my,dc=ldap,dc=server,dc=org&quot; \
	--env LDAP_ADMIN_PASSWORD=&quot;test&quot; \
	--volume /data/slapd/database:/var/lib/ldap \
	--volume /data/slapd/config:/etc/ldap/slapd.d \
	--env LDAP_TLS=false \
	--detach osixia/openldap:latest

Then, in my C# 7.0 code, I'm able to connect just fine as my test user, as follows:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 389))
{
    AuthType = AuthType.Basic
};
ldapConnection.SessionOptions.ProtocolVersion = 3;

string username = &quot;uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org&quot;, password = &quot;test&quot;;
ldapConnection.Bind(new NetworkCredential(username, password));

But when I restart the OpenLDAP container with TLS/SSL enabled, as such:

sudo docker run \
	--name openldap-server \
	--rm \
	--publish 636:636 \
	--hostname my.ldap.server.org \
	--env LDAP_ORGANISATION=&quot;My LDAP organization&quot; \
	--env LDAP_DOMAIN=&quot;my.ldap.server.org&quot; \
	--env LDAP_BASE_DN=&quot;dc=my,dc=ldap,dc=server,dc=org&quot; \
	--env LDAP_ADMIN_PASSWORD=&quot;test&quot; \
	--volume /data/slapd/database:/var/lib/ldap \
	--volume /data/slapd/config:/etc/ldap/slapd.d \
	--volume /data/certificates:/container/service/slapd/assets/certs \
	--env LDAP_TLS_CRT_FILENAME=server.crt \
	--env LDAP_TLS_KEY_FILENAME=server.key \
	--env LDAP_TLS_CA_CRT_FILENAME=ca.crt \
	--detach osixia/openldap:latest

Then I don't know how to add all the required certificates to the LdapConnection in the C# code. I've gotten this far:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 636))
{
    AuthType = AuthType.Basic
    // AuthType = AuthType.Negotiate
};
ldapConnection.SessionOptions.SecureSocketLayer = true;

// var serverCrt = File.ReadAllText(&quot;&lt;my certificate directory&gt;/server.crt&quot;);
// var serverKey = File.ReadAllText($&quot;&lt;my certificate directory&gt;/server.key&quot;);
// var serverCertificate = X509Certificate2.CreateFromPem(serverCrt, serverKey);
// var serverCertificate = X509Certificate.CreateFromCertFile(&quot;&lt;my certificate directory&gt;/server.crt&quot;);
// var caCertificate = new X509Certificate(&quot;&lt;my certificate directory&gt;/ca.crt&quot;);

// connection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((connection, serverCertificate ) =&gt; true);
// connection.SessionOptions.VerifyServerCertificate = delegate { return true; };

ldapConnection.SessionOptions.ProtocolVersion = 3;

ldapConnection.Bind(new NetworkCredential(&quot;uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org&quot;, &quot;test&quot;));

How do I configure the code to connect with TLS/SSL when the OpenLDAP server expects both a server & a CA certificate (I think)? I don't think the solution is to install the certificates on my host machine because the code will run in a container and the certificates will be mounted at runtime.

Perpaps I made a mistake while generating the certificates. The Common Name (CN) of the Server certificate is my.ldap.server.org, and the CN of the CA is the username of the machine that hosts the OpenLDAP Container (but the username within the container is different).

答案1

得分: 0

我发现我需要在 docker run 命令中设置一个额外的环境变量,即 --env LDAP_TLS_VERIFY_CLIENT=never

然后,使用以下代码可以正常工作:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 636))
{
    AuthType = AuthType.Basic
};
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.VerifyServerCertificate = delegate { return true; };
ldapConnection.SessionOptions.ProtocolVersion = 3;

ldapConnection.Bind(new NetworkCredential("uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org", "test"));
英文:

I turns out that I had to set an additional environment variable in the docker run command, namely --env LDAP_TLS_VERIFY_CLIENT=never

It then worked with this code:

var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier(serverIp, 636))
{
    AuthType = AuthType.Basic
};
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.VerifyServerCertificate = delegate { return true; };    
ldapConnection.SessionOptions.ProtocolVersion = 3;

ldapConnection.Bind(new NetworkCredential(&quot;uid=test,ou=person,dc=my,dc=ldap,dc=server,dc=org&quot;, &quot;test&quot;));

huangapple
  • 本文由 发表于 2023年6月5日 22:20:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76407388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定