配置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 []: <
[email protected]>
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 []:<
[email protected]>
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/
[email protected] verify return:1
depth=0 /C=CN/ST=Shanga/L=shanghai/O=dean/OU=home/CN=fedora.dean.com/
[email protected] 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
《解決方案》
太過企業化了....一般人不懂:)
《解決方案》
《解決方案》