配置openldap使用SSL連接

火星人 @ 2014-03-04 , reply:0
←手機掃碼閱讀

配置openldap使用SSL連接

假設openldap伺服器已經配置好,可以正常工作。下面的步驟只是讓openldap使用ssl連接。
這篇文檔參考了http://www.openldap.org/pub/ksoper/OpenLDAP_TLS.html,那裡有更詳盡的介紹。
註:此配置在fc5下面通過。rhe系列會有不一樣的地方。

0 在開始之前,
0.1 建議備份/etc/openldap/slapd.conf, /etc/openldap/ldap.conf
0.2 安裝軟體包openssl, openssl-perl.後者是用來創建CA認證的一個perl腳本包。

1 創建證書(certificate)
這一步分為3個步驟,首先把CA建立起來,然後讓此CA簽發一個server的證書和一個client的證書。
需要特別注意的是創建證書時,輸入Common Name的時候一定要輸入目標機器的fully qualified name

1.1 創建CA
這裡關係到兩個目錄,/etc/pki/tls/misc是工作目錄,/etc/pki/CA是存放所有CA相關文件的目錄。
完成此步驟后,會在/etc/pki/CA目錄下生成一系列文件,其中最重要的是
/etc/pki/CA/cakey.pem   CA的私鑰文件
/etc/pki/CA/cacert.pem  CA的證書文件

tips:如果腳本檢測到/etc/pki/CA下面有文件存在,那麼script會安靜的退出,不會創建任何東西。
把/etc/pki/CA下的文件全部刪除,script就可以正常工作了

> cd /etc/pki/tls/misc
> ./CA.pl -newca
            
                ..........忽略部分信息........
                writing new private key to '../../CA/private/cakey.pem'
                Enter PEM pass phrase: <password>
                Verifying - Enter PEM pass phrase: <password>
                -----
                You are about to be asked to enter information that will be incorporated
                into your certificate request.
                What you are about to enter is what is called a Distinguished Name or a DN.
                There are quite a few fields but you can leave some blank
                For some fields there will be a default value,
                If you enter '.', the field will be left blank.
                -----
                Country Name (2 letter code) : <CN>
                State or Province Name (full name) :<shanghai>
                Locality Name (eg, city) :<shanghai>
                Organization Name (eg, company) :<foo>
                Organizational Unit Name (eg, section) []:<bar>
                Common Name (eg, your name or your server's hostname) []:<myca.foo.com> !!!!full qualified name!!!
                Email Address []: <someone@foo.com>
               
                Please enter the following 'extra' attributes
                to be sent with your certificate request
                A challenge password []:
                An optional company name []:
                Using configuration from /etc/pki/tls/openssl.cnf
                Enter pass phrase for ../../CA/private/cakey.pem:<rain>
                Check that the request matches the signature
                Signature ok
                ..........忽略部分信息........

1.2 創建server的證書
下面我們要創建ldap server的證書。分為兩步,第一步是生成一個創建證書的請求,第二步是讓CA為此請求籤發證書

> ./CA.pl -newreq-nodes
                Generating a 1024 bit RSA private key
                ............++++++
                .......++++++
                writing new private key to 'newkey.pem'
                -----
                You are about to be asked to enter information that will be incorporated
                into your certificate request.
                What you are about to enter is what is called a Distinguished Name or a DN.
                There are quite a few fields but you can leave some blank
                For some fields there will be a default value,
                If you enter '.', the field will be left blank.
                -----
                Country Name (2 letter code) :<CN>
                State or Province Name (full name) :<Shanghai>
                Locality Name (eg, city) :<Shanghai>
                Organization Name (eg, company) :<foo>
                Organizational Unit Name (eg, section) []:<bar>
                Common Name (eg, your name or your server's hostname) []:<ldapserver.foo.com> !!!!full qualified name!!!
                Email Address []:<someone@foo.com>
               
                Please enter the following 'extra' attributes
                to be sent with your certificate request
                A challenge password []:
                An optional company name []:
                Request is in newreq.pem, private key is in newkey.pem

> ./CA.pl -sign
                Using configuration from /etc/pki/tls/openssl.cnf
                Enter pass phrase for ../../CA/private/cakey.pem: <password>
                Check that the request matches the signature
                Signature ok
                Certificate Details:
                .....省略部分內容......
               
                Certificate is to be certified until Apr 16 22:37:14 2008 GMT (365 days)
                Sign the certificate? :y
               
               
                1 out of 1 certificate requests certified, commit? y
                Write out database with 1 new entries
                Data Base Updated
                Signed certificate is in newcert.pem

運行完兩個步驟后,你會發現當前目錄下創建了3個文件:
newreq.pem      創建證書請求文件,沒什麼用了
newcert.pem     CA簽發的證書
newkey.pem      證書對應的私鑰

首先我們重命名證書文件和私鑰文件
mv newcert.pem server.cert
mv newkey.pem server.key

然後給他們設置合適的許可權,特別是私鑰文件,一定要只有owner能讀。否則ssl安全體系形同虛設!
chmod 644 server.cert
chmod 600 server.key  (Nobody can read it except owner!!)

最後一步是把這兩個文件和CA的證書文件拷貝到openldap存放證書的目錄下,一般在/etc/openldap/cacerts
如果CA和ldap server不在同一個機器上,那麼用scp拷貝即可。這裡假設他們在同一台機器上

mv server.cert /etc/openldap/cacerts
mv serve.key /etc/openldap/cacerts
cp ../../CA/cacert.pem /etc/openldap/cacerts

1.3 創建client的證書
創建client的證書和上面創建server的證書類似。不過要注意的是
1)在輸入Common Name的時候一定要輸入clien的fully qualified name!!
2)證書文件和私鑰文件可以命名為client.cert, client.key,它們和cacert.pem也拷貝到client端的/etc/openldap/cacerts

2 配置server
> service ldap stop # 首先停掉openldap server.

> vi /etc/openldap/slapd.conf
加入下面4行
TLSCACertificateFile /etc/openldap/cacerts/cacert.pem  # 配置CA證書的路徑
TLSCertificateFile /etc/openldap/cacerts/server.cert    # 配置server證書的路徑
TLSCertificateKeyFile /etc/openldap/cacerts/server.key  # 配置server私鑰的路徑

TLSVerifyClient never  
# 設置是否驗證client的身份,其值可以是never/allow/try/demand
# 配置什麼值取決於你的安全策略。僅僅就配置來說,
# 如果不需要認證client端的身份,那麼client只需要有CA的證書就可以了
# 如果需要認證client端的身份,那麼client 還 必須要有它自己的證書\
# 我們首先介紹"never"的情況下client的配置,然後介紹"demand"的情況下client的配置

ssl start_tls
# 如果client端使用TLS協議連接,那麼加上這一行。否則TLS連接會失敗
# 加上這一行后,both SSL and TLS can be supported by this ldap server.

3 配置client

3.1 首先我們假設ldap server不需要驗證client的身份
也就是在/etc/openldap/slapd.con里,TLSVerifyClient 設置為never。

>vi /etc/openldap/ldap.conf
需要加入或修改下面的內容

URI ldaps://ldapserver.foo.com  # 一定要和server的證書里輸入的full qualified name一樣

TLS_CACERT /etc/openldap/cacerts/cacert.pem # CA的證書
TLS_REQCERT demand # client總是要求認證server端

> service ldap restart
> ldapsearch -x
如果有正確的輸入,就表示配置成功了。

3.2 如果ldap server需要驗證client的身份
也就是在/etc/openldap/slapd.conf里,TLSVerifyClient設置為demand。這種情況下,client需要有自己的證書和私鑰。
配置clieng的證書和私鑰只能在用戶home目錄下的ldaprc文件里。

> vi ~/ldaprc
加入下面的內容

TLS_REQCERT demand
TLS_CERT /etc/openldap/cacerts/client.cert
TLS_KEY /etc/openldap/cacerts/client.key

注意此用戶對/etc/openldap/cacerts/client.key要有可讀的許可權!!

> service ldap restart
> ldapsearch -x
如果有正確的輸入,就表示配置成功了。

4 調試方法

4.1 在調試模式啟動slapd
> slapd -d127 -h "ldap:/// ldaps:///"
-d127是指定調試級別。slapd會在當前console啟動,所有的連接信息都會在屏幕上列印出來。

4.2 用openssl client連接ssl 伺服器

4.2.1 對於不需要client驗證的情況
> openssl s_client -connect ldapserver.foo.com:636 -showcerts -state -CAfile /etc/openldap/cacerts/cacert.pem
        file /etc/openldap/cacerts/cacert.pem
        CONNECTED(00000003)
        SSL_connect:before/connect initialization
        SSL_connect:SSLv2/v3 write client hello A
        SSL_connect:SSLv3 read server hello A
        depth=1 /C=CN/ST=shanghai/O=dean/OU=mobile/CN=fedora.dean.com/emailAddress=ss@ss.com
        verify return:1
        depth=0 /C=CN/ST=Shanga/L=shanghai/O=dean/OU=home/CN=fedora.dean.com/emailAddress=sdf@ss.com
        verify return:1
        SSL_connect:SSLv3 read server certificate A
        SSL_connect:SSLv3 read server done A
        SSL_connect:SSLv3 write client key exchange A
        SSL_connect:SSLv3 write change cipher spec A

        .......省略了部分內容.......

        Compression: NONE
        Expansion: NONE
        SSL-Session:
            Protocol  : TLSv1
            Cipher    : AES256-SHA
            Session-ID: 03FDE102050C7828C39E03D7A3F526E6E9D256115A0ADF7793538B616C5548ED
            Session-ID-ctx:
            Master-Key: 07A62B4E5060BF4542E49DC33C2C6D6F10FF266F48856A780187C759A3007CF2F18ECAB49DBA8915394D52179AC8FE9B
            Key-Arg   : None
            Krb5 Principal: None
            Start Time: 1198247985
            Timeout   : 300 (sec)
            Verify return code: 0 (ok)
        ---
用"CTRL-C" 退出

4.2.2 對於需要clien驗證的情況
> openssl s_client -connect ldapserver.foo.com:636 -showcerts -state \
    -CAfile /etc/openldap/cacerts/cacert.pem
    -cert /etc/openldap/cacerts/client.cert
    -key /etc/openldap/cacerts/client.key

[ 本帖最後由 lifr 於 2008-1-2 17:15 編輯 ]
《解決方案》

好資料,我喜歡!
《解決方案》

我用client驗證
openssl s_client -connect ldap.abc.net:636 -showcerts -state -CAfile /etc/openldap/cacerts/cacert.pem
已經通過了。

CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
..................................
............................................
---
No client certificate CA names sent
---
SSL handshake has read 1758 bytes and written 340 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: CEBC00B0C41C4F59CC789484A963A4AFFA167ED1B6FC5F925B52128AB27BFE06
    Session-ID-ctx:
    Master-Key: E5975BF8EBB6C9DD7BBA81F86760E9BCF78A4F100DA09408CED1507A5603C13F278E53B238398D5A88600EB449FBB055
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1198745896
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---




但是我用ldap作用系統用戶驗證死活過不去。
客戶端openvpn配置如下
/etc/openldap/ldap.conf配置如下:
#DEREF          never
URI ldaps://ldap.abc.net
BASE dc=abc,dc=net
TLS_CACERT /etc/openldap/cacerts/cacert.pem
#TLS_CACERTDIR /etc/openldap/cacerts
TLS_REQCERT demand
~                                                                                                                                             

openldap server端的log如下:

Dec 27 17:05:10 localhost slapd: daemon: read active on 14
Dec 27 17:05:10 localhost slapd: connection_get(14)
Dec 27 17:05:10 localhost slapd: connection_get(14): got connid=11
Dec 27 17:05:10 localhost slapd: connection_read(14): checking for input on id=11
Dec 27 17:05:10 localhost slapd: ber_get_next on fd 14 failed errno=11 (Resource temporarily unavailable)
Dec 27 17:05:10 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:10 localhost slapd: daemon: activity on:
Dec 27 17:05:10 localhost slapd:  
Dec 27 17:05:10 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: do_extended
Dec 27 17:05:10 localhost slapd: do_extended: oid=1.3.6.1.4.1.1466.20037
Dec 27 17:05:10 localhost slapd: conn=11 op=0 STARTTLS
Dec 27 17:05:10 localhost slapd: send_ldap_extended: err=1 oid= len=0
Dec 27 17:05:10 localhost slapd: send_ldap_response: msgid=1 tag=120 err=1
Dec 27 17:05:10 localhost slapd: conn=11 op=0 RESULT oid= err=1 text=TLS already started
Dec 27 17:05:10 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:10 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:10 localhost slapd: daemon: activity on:
Dec 27 17:05:10 localhost slapd:  14r
Dec 27 17:05:10 localhost slapd:  
Dec 27 17:05:11 localhost slapd: daemon: read active on 14
Dec 27 17:05:11 localhost slapd: connection_get(14)
Dec 27 17:05:11 localhost slapd: connection_get(14): got connid=11
Dec 27 17:05:11 localhost slapd: connection_read(14): checking for input on id=11
Dec 27 17:05:11 localhost slapd: ber_get_next on fd 14 failed errno=0 (Success)
Dec 27 17:05:11 localhost slapd: connection_read(14): input error=-2 id=11, closing.
Dec 27 17:05:11 localhost slapd: connection_closing: readying conn=11 sd=14 for close
Dec 27 17:05:11 localhost slapd: do_unbind
Dec 27 17:05:11 localhost slapd: connection_close: deferring conn=11 sd=14
Dec 27 17:05:11 localhost slapd: conn=11 op=1 UNBIND
Dec 27 17:05:11 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: connection_resched: attempting closing conn=11 sd=14
Dec 27 17:05:11 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: connection_close: conn=11 sd=14
Dec 27 17:05:11 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:11 localhost slapd: daemon: removing 14
Dec 27 17:05:11 localhost slapd: daemon: activity on:
Dec 27 17:05:11 localhost slapd: conn=11 fd=14 closed
Dec 27 17:05:11 localhost slapd:  
Dec 27 17:05:11 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:11 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:26 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:26 localhost slapd: daemon: activity on:
Dec 27 17:05:26 localhost slapd:  
Dec 27 17:05:26 localhost slapd: daemon: listen=10, new connection on 14
Dec 27 17:05:26 localhost slapd: daemon: added 14r
Dec 27 17:05:26 localhost slapd: conn=12 fd=14 ACCEPT from IP=172.16.0.4:59320 (IP=0.0.0.0:636)
Dec 27 17:05:26 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:26 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:26 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:26 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:26 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:26 localhost slapd: daemon: activity on:
Dec 27 17:05:26 localhost slapd:  14r
Dec 27 17:05:26 localhost slapd:  
Dec 27 17:05:26 localhost slapd: daemon: read active on 14
Dec 27 17:05:26 localhost slapd: connection_get(14)
Dec 27 17:05:26 localhost slapd: connection_get(14): got connid=12
Dec 27 17:05:27 localhost slapd: connection_read(14): checking for input on id=12
Dec 27 17:05:27 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:27 localhost slapd: daemon: activity on:
Dec 27 17:05:27 localhost slapd:  14r
Dec 27 17:05:27 localhost slapd:  
Dec 27 17:05:27 localhost slapd: daemon: read active on 14
Dec 27 17:05:27 localhost slapd: connection_get(14)
Dec 27 17:05:27 localhost slapd: connection_get(14): got connid=12
Dec 27 17:05:27 localhost slapd: connection_read(14): checking for input on id=12
Dec 27 17:05:27 localhost slapd: connection_read(14): unable to get TLS client DN, error=49 id=12
Dec 27 17:05:27 localhost slapd: conn=12 fd=14 TLS established tls_ssf=256 ssf=256
Dec 27 17:05:27 localhost slapd: daemon: select: listen=7 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=8 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=9 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: select: listen=10 active_threads=0 tvp=NULL
Dec 27 17:05:27 localhost slapd: daemon: activity on 1 descriptor
Dec 27 17:05:27 localhost slapd: daemon: activity on:
《解決方案》

沒人知道?
《解決方案》

支持下.......:wink:
《解決方案》

unable to get TLS client DN, error=49
似乎不能獲取客戶端的身份信息。

TLS_REQCERT demand 應該是在服務端配置的,在slapd.conf中
如果設置為 demand , 客戶端必須指定證書和私鑰。

[ 本帖最後由 forxy 於 2008-1-3 00:02 編輯 ]
《解決方案》

回復 #3 pwtitle 的帖子

use command "ldapsearch" to debug

ldapsearch -d 127 -x
《解決方案》

太過企業化了....一般人不懂:)
《解決方案》

《解決方案》





[火星人 via ] 配置openldap使用SSL連接已經有334次圍觀

http://www.coctec.com/docs/service/show-post-14019.html