Postgres 安全 LDAP 身份验证问题

问题描述 投票:0回答:2

我似乎无法让我的 CNPG postgres 数据库通过安全方式连接到 LDAP;我已经使用用户

user01
和密码
password01
设置了一个 bitnami openldap 容器,并且可以通过 ldapsearch 绑定到它:

❯ ldapsearch    -H ldap://openldap-test.example.org  -D "cn=user01,ou=users,dc=example,dc=org" -w 'password01'  -b 'dc=example,dc=org'
❯ ldapsearch    -H ldaps://openldap-test.example.org -D "cn=user01,ou=users,dc=example,dc=org" -w 'password01'  -b 'dc=example,dc=org'
❯ ldapsearch -Z -H ldap://openldap-test.example.org  -D "cn=user01,ou=users,dc=example,dc=org" -w 'password01'  -b 'dc=example,dc=org'

所有返回结果均符合预期 - 即 ldap、ldaps 和 STARTTLS 均正常运行。

在我的 Postgres 数据库中,我尝试将 CNPN 值设置为

postgresql:
  ldap:
    scheme: ldap[s]
    server: openldap-test.example.org
    tls: false
    port: [389|636]
    bindAsAuth:
      prefix: 'cn='
      suffix: ',ou=users,dc=example,dc=org'

取决于:

clear-text: port=389, scheme=ldap, tls=false
ldaps:      port=636, scheme=ldaps, tls=false
starttls:   port=389, scheme=ldap, tls=true

这会导致

pg_hba.conf
被填充为这样:

host all all 0.0.0.0/0 ldap ldapserver=openldap-test.example.org ldapport=389 ldapscheme=ldap ldapprefix="cn=" ldapsuffix=",ou=users,dc=example,dc=org"
host all all 0.0.0.0/0 ldap ldapserver=openldap-test.example.org ldapport=636 ldapscheme=ldaps ldapprefix="cn=" ldapsuffix=",ou=users,dc=example,dc=org"
host all all 0.0.0.0/0 ldap ldapserver=openldap-test.example.org ldapport=389 ldapscheme=ldap ldaptls=1 ldapprefix="cn=" ldapsuffix=",ou=users,dc=example,dc=org"

分别。

登录方式:

PGPASSWORD=password01 psql -h postgres-database -U user01 -d mydb

仅适用于明文(端口 389,无 STARTTLS)。当尝试使用其他两种方法时,我收到此错误:

psql:错误:连接到“postgres-database”服务器,端口 5432 失败:致命:用户“user01”的 LDAP 身份验证失败

带有 TLS 的 postgres 容器的输出

{"level":"info","ts":1663799766.7574096,"logger":"postgres","msg":"record","logging_pod":"usdf-butler-ldap-1","record":{"log_time":"2022-09-21 22:36:06.757 UTC","user_name":"user01","database_name":"lsstdb1","process_id":"37730","connection_from":"192.168.252.244:54054","session_id":"632b91d6.9362","session_line_num":"1","command_tag":"authentication","session_start_time":"2022-09-21 22:36:06 UTC","virtual_transaction_id":"3/63120","transaction_id":"0","error_severity":"LOG","sql_state_code":"00000","message":"LDAP login failed for user \"cn=user01,ou=users,dc=example,dc=org\" on server \"openldap-test.example.org\": Can't contact LDAP server","detail":"LDAP diagnostics: (unknown error code)","backend_type":"client backend","query_id":"0"}}
{"level":"info","ts":1663799766.7574224,"logger":"postgres","msg":"record","logging_pod":"usdf-butler-ldap-1","record":{"log_time":"2022-09-21 22:36:06.757 UTC","user_name":"user01","database_name":"lsstdb1","process_id":"37730","connection_from":"192.168.252.244:54054","session_id":"632b91d6.9362","session_line_num":"2","command_tag":"authentication","session_start_time":"2022-09-21 22:36:06 UTC","virtual_transaction_id":"3/63120","transaction_id":"0","error_severity":"FATAL","sql_state_code":"28000","message":"LDAP authentication failed for user \"user01\"","detail":"Connection matched pg_hba.conf line 14: \"host all all 0.0.0.0/0 ldap ldapserver=openldap-test.example.org ldapport=636 ldapscheme=ldaps ldapprefix=\"cn=\" ldapsuffix=\",ou=users,dc=example,dc=org\"\"","backend_type":"client backend","query_id":"0"}}

..并开始:

{"level":"info","ts":1663799655.9419446,"logger":"postgres","msg":"record","logging_pod":"usdf-butler-ldap-1","record":{"log_time":"2022-09-21 22:34:15.941 UTC","user_name":"user01","database_name":"lsstdb1","process_id":"37528","connection_from":"192.168.252.244:36380","session_id":"632b9167.9298","session_line_num":"1","command_tag":"authentication","session_start_time":"2022-09-21 22:34:15 UTC","virtual_transaction_id":"3/62785","transaction_id":"0","error_severity":"LOG","sql_state_code":"00000","message":"could not start LDAP TLS session: Connect error","detail":"LDAP diagnostics: (unknown error code)","backend_type":"client backend","query_id":"0"}}
{"level":"info","ts":1663799655.9419892,"logger":"postgres","msg":"record","logging_pod":"usdf-butler-ldap-1","record":{"log_time":"2022-09-21 22:34:15.941 UTC","user_name":"user01","database_name":"lsstdb1","process_id":"37528","connection_from":"192.168.252.244:36380","session_id":"632b9167.9298","session_line_num":"2","command_tag":"authentication","session_start_time":"2022-09-21 22:34:15 UTC","virtual_transaction_id":"3/62785","transaction_id":"0","error_severity":"FATAL","sql_state_code":"28000","message":"LDAP authentication failed for user \"user01\"","detail":"Connection matched pg_hba.conf line 14: \"host all all 0.0.0.0/0 ldap ldapserver=openldap-test.example.org ldapport=389 ldapscheme=ldap ldaptls=1 ldapprefix=\"cn=\" ldapsuffix=\",ou=users,dc=example,dc=org\"\"","backend_type":"client backend","query_id":"0"}}

来自 openldap 的日志:

632b9167.376217e9 0x7f784ae33700 conn=1005 fd=14 ACCEPT from IP=172.24.4.42:25550 (IP=0.0.0.0:389)
632b9167.376345a0 0x7f784a632700 conn=1005 op=0 EXT oid=1.3.6.1.4.1.1466.20037
632b9167.376425eb 0x7f784a632700 conn=1005 op=0 STARTTLS
632b9167.3765614e 0x7f784a632700 conn=1005 op=0 RESULT oid= err=0 qtime=0.000012 etime=0.000153 text=
632b9167.3792906f 0x7f784a632700 conn=1005 fd=14 TLS established tls_ssf=256 ssf=256 tls_proto=TLSv1.3 tls_cipher=TLS_AES_256_GCM_SHA384
632b9167.379e8703 0x7f784ae33700 conn=1005 fd=14 closed (connection lost)
632b9167.37ef19fe 0x7f784a632700 conn=1006 fd=14 ACCEPT from IP=172.24.4.42:58264 (IP=0.0.0.0:389)
632b9167.37efd555 0x7f784ae33700 conn=1006 op=0 EXT oid=1.3.6.1.4.1.1466.20037
632b9167.37f01047 0x7f784ae33700 conn=1006 op=0 STARTTLS
632b9167.37f09797 0x7f784ae33700 conn=1006 op=0 RESULT oid= err=0 qtime=0.000006 etime=0.000055 text=
632b9167.381a6e2a 0x7f784ae33700 conn=1006 fd=14 TLS established tls_ssf=256 ssf=256 tls_proto=TLSv1.3 tls_cipher=TLS_AES_256_GCM_SHA384
632b9167.382591e3 0x7f784a632700 conn=1006 fd=14 closed (connection lost)
632b91d6.2c73ec6d 0x7f784ae33700 conn=1007 fd=14 ACCEPT from IP=172.24.4.42:27509 (IP=0.0.0.0:636)
632b91d6.2c9ede29 0x7f784ae33700 conn=1007 fd=14 TLS established tls_ssf=256 ssf=256 tls_proto=TLSv1.3 tls_cipher=TLS_AES_256_GCM_SHA384
632b91d6.2ca8d57f 0x7f784a632700 conn=1007 fd=14 closed (connection lost)
632b91d6.2cf610c8 0x7f784ae33700 conn=1008 fd=14 ACCEPT from IP=172.24.4.42:40216 (IP=0.0.0.0:636)
632b91d6.2d1b084d 0x7f784ae33700 conn=1008 fd=14 TLS established tls_ssf=256 ssf=256 tls_proto=TLSv1.3 tls_cipher=TLS_AES_256_GCM_SHA384
632b91d6.2d24bdaa 0x7f784a632700 conn=1008 fd=14 closed (connection lost)

有趣的是,postgres 的每次登录尝试都会尝试查询 ldap 两次;每个显然都成功完成了 TLS 握手,然后立即关闭。甚至没有尝试任何绑定。两者都在 postgres 中报告

sql_state_code
28000

认为这可能是一个证书问题,来自我运行的 postgres 容器:

$ openssl s_client -showcerts -verify 5 -connect openldap-test.examp:636  < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/)    {a++}; out="cert"a".pem"; print >out}'
$ for cert in *.pem; do openssl verify -show_chain $cert ; done
C = US, ST = **redacted**, O = **redacted**, CN = openldap-test.example.org
error 20 at 0 depth lookup: unable to get local issuer certificate
error cert1.pem: verification failed
cert2.pem: OK
Chain:
depth=0: C = US, ST = MI, L = Ann Arbor, O = Internet2, OU = InCommon, CN = InCommon RSA Server CA (untrusted)
depth=1: C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
cert3.pem: OK
Chain:
depth=0: C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority (untrusted)
depth=1: C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
cert4.pem: OK
Chain:
depth=0: C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services

关于为什么 postgres 断开连接并且甚至不尝试绑定有什么想法吗?

postgresql authentication ssl ldap starttls
2个回答
0
投票

我认为您遇到了证书验证问题。 postgres 服务器不信任 LDAP 服务器提供的证书。有多种方法可以解决这个问题。

正确方法:安装正确的CA证书

  1. 将适当的 CA 证书(签署您的 ldap 服务器证书的证书)放置在 postgres 服务器上的某处(例如,

    /etc/ssl/certs/my-ca-certificate.crt
    )。

  2. 将 libldap 配置为信任该 CA 签名的证书。将以下内容添加到

    /etc/ldap/ldap.conf
    (如果文件不存在则创建该文件):

    TLS_CACERT /etc/ssl/certs/my-ca-certificate.crt
    

错误方式:禁用证书验证

  1. 将以下内容添加到

    /etc/ldap/ldap.conf

    TLS_REQCERT never
    

如果您无法写入

/etc/ldap/ldap.conf
,您可以将配置放在不同的文件中,并将
LDAPCONF
环境变量设置为指向该文件。

如果您有兴趣,我已经设置了一个简单的 docker-compose 堆栈来测试它;你可以在这里找到它。


0
投票

@yee379 @larsks

你曾经让它工作过吗?我们遇到了同样的问题,我不知道我们做错了什么。我什至创建了一个自定义 CNPG 镜像,并将我们的根 CA 融入其中。但它仍然拒绝工作。我们找到的唯一解决方案是通过以下方式禁用证书检查:

  env:
    - name: LDAPTLS_REQCERT
      value: never

我意识到这是一个安全风险,也是解决此问题的错误方法,但我对如何让它以其他方式工作感到愤怒。

© www.soinside.com 2019 - 2024. All rights reserved.