sábado, 6 de agosto de 2016

Configurando OpenLDAP com certificado SSL/TLS

Intodução

Se formos utilizar um serviço de diretórios como o OpenLDAP para fornecer autenticação, com certeza você irá querer fazer isso utilizando um protocolo criptografado. Sem a criptografia as informações irão passar como texto pela rede e é muito fácil captura-las sendo possível obter informação de usuários e algumas vezes até senhas.

Apenas como exemplo, suponha que você tenha um servidor LDAP fornecendo autenticação para seus servidores Linux.

Um servidor Linux que se autentica utilizando o servidor LDAP faz uma pesquisa no serviço de diretórios utilizando as credenciais de administrador pela porta ldap:/// que não fornece criptografia.

$ ldapsearch –D cn=manager,dc=example,dc=com –w secret –b dc=example,dc=com –s base -LLL

dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Dominio example.com
dc: example

No servidor LDAP utilize o comando tcpdump na porta 386 com a opção –X para mostrar o cabeçalho e os dados do pacote em Hexadecimal e ASCII

[root@ldap01 ~]# tcpdump –nvvv –i eth0 port 389 –X

10:53:20.498082 IP (tos 0x0, ttl 64, id 35989, offset 0, flags [DF], proto TCP (6), length 100)
192.168.206.101.41992 > 192.168.206.200.ldap: Flags [P.], cksum 0xa5c4 (correct), seq 1:49, ack 1, win 229, options [nop,nop,TS val 5200896 ecr 5236832], length 48
0x0000: 4500 0064 8c95 4000 4006 8f7f c0a8 ce65 E..d..@.@......e
0x0010: c0a8 cec8 a408 0185 1fce d094 8014 31dd ..............1.
0x0020: 8018 00e5 a5c4 0000 0101 080a 004f 5c00 .............O\.
0x0030: 004f e860 302e 0201 0160 2902 0103 041c .O.`0....`).....
0x0040: 636e 3d6d 616e 6167 6572 2c64 633d 6578 cn=manager,dc=ex
0x0050: 616d 706c 652c 6463 3d63 6f6d 8006 7365 ample,dc=com..se
0x0060: 6372 6574 cret

Veja que o usuário cn=manager,dc=example,dc=com com a senha secret aparece claramente na saída do comando tcpdump. Você pode rodar esse comando no servidor cliente ou em um servidor firewall intermediário na rede e ainda assim verá esse tipo de informação trafegando na sua rede sem segurança alguma.

Acho que não preciso me prolongar mais sobre o assunto, certo ? = )

Pois bem. Neste post iremos ver como configurar o nosso servidor OpenLDAP com a base de dados em OLC (cn=config) para operar com protocolo ldaps:/// fornecendo criptografia com SSL/TLS. O Sistema Operacional utilizado é o CentOS 7, mas pode ser facilmente replicado para o RedHat 7 ou outras distribuições.

Para saber como subir um servidor OpenLDAP com a base cn=config consulte o post Servidor OpenLDAP (cn=config) no CentOS 7

Criando um Certificado


Antes de configurar o servidor precisamos de um certificado SSL. Neste post iremos utilizar um certificado Self-Signed (auto-assinado). Para criar o certificado Self-Sign no CentOS 7 siga o procedimento abaixo a partir do servidor LDAP:

Primeiro geramos a chave do certificado

# cd /etc/pki/tls/certs/

# make server.key
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > server.key
Generating RSA private key, 2048 bit long modulus
..................................+++
..........................................+++
e is 65537 (0x10001)
Enter pass phrase: secret
Verifying - Enter pass phrase: secret

Removemos a senha da chave gerada acima

# openssl rsa -in server.key -out server.key
Enter pass phrase for server.key:
writing RSA key

Geramos o arquivo .csr (Certificate Sign Request) com a chave gerada acima

# make server.csr
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key server.key -out server.csr
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) [XX]:BR
State or Province Name (full name) []:Sao Paulo
Locality Name (eg, city) [Default City]:Sao Paulo
Organization Name (eg, company) [Default Company Ltd]:HOME
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ldap01.example.com
Email Address []:rafaelrb@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Por último assinamos o certificado gerado por um período de 10 anos

# openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650
Signature ok
subject=/C=BR/ST=Sao Paulo/L=Sao Paulo/O=HOME/CN=ldap01.example.com/emailAddress=rafaelrb@gmail.com
Getting Private key

Agora que temos o certificado copiamos os arquivos para o diretório de certificados do OpenLDAP

# cp /etc/pki/tls/certs/server.key \
/etc/pki/tls/certs/server.crt \
/etc/pki/tls/certs/server.csr \
/etc/pki/tls/certs/ca-bundle.crt /etc/openldap/certs/

Ajustamos as permissões para o usuário ldap e grupo ldap

# chown -R ldap.ldap /etc/openldap/certs/

Configurando o certificado no OpenLDAP

Agora que temos os arquivos do certificado podemos configurar o servidor OpenLDAP para utilizá-los. Criamos então o arquivo mod_ssl.ldif com o seguinte conteúdo:

dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca-bundle.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/server.key

Usamos então o comando ldapmodify para adicionar as configurações de certificado na base cn=config do nosso servidor LDAP

[root@ldap01 ~]# ldapmodify -Y EXTERNAL -H ldapi:/// -f mod_ssl.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

Editamos o parâmetro SLAPD_URLS no arquivo /etc/sysconfig/slapd para habilitar o protocolo ldaps:///

# OpenLDAP server configuration
# see 'man slapd' for additional information

# Where the server will run (-h option)
# - ldapi:/// is required for on-the-fly configuration using client tools
# (use SASL with EXTERNAL mechanism for authentication)
# - default: ldapi:/// ldap:///
# - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:///
SLAPD_URLS="ldapi:/// ldap://ldap01/ ldaps://ldap01/"

# Any custom options
#SLAPD_OPTIONS=""

# Keytab location for GSSAPI Kerberos authentication
#KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"

Reiniciamos o serviço slapd para carregar as configurações de SSL

# systemctl restart slapd.service

Agora podemos verificar se o serviço SSL está no ar com o comando netstat

# netstat -lpn | grep 636 tcp 0 0 192.168.206.200:636 0.0.0.0:* OUÇA 2627/slapd

A porta 636 é do protocolo LDAPS. Na saída do comando acima podemos ver que o serviço está no ar. Podemos verificar se o certificado foi carregado corretamente utilizando o comando openssl

# openssl s_client -connect 192.168.206.200:636
CONNECTED(00000003)
depth=0 C = BR, ST = Sao Paulo, L = Sao Paulo, O = HOME, CN = ldap01.example.com, emailAddress = rafaelrb@gmail.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = BR, ST = Sao Paulo, L = Sao Paulo, O = HOME, CN = ldap01.example.com, emailAddress = rafaelrb@gmail.com
verify return:1
---
Certificate chain
0 s:/C=BR/ST=Sao Paulo/L=Sao Paulo/O=HOME/CN=ldap01.example.com/emailAddress=rafaelrb@gmail.com
i:/C=BR/ST=Sao Paulo/L=Sao Paulo/O=HOME/CN=ldap01.example.com/emailAddress=rafaelrb@gmail.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDhjCCAm4CCQDXGQGvI9owSjANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
QlIxEjAQBgNVBAgMCVNhbyBQYXVsbzESMBAGA1UEBwwJU2FvIFBhdWxvMQ0wCwYD
VQQKDARIT01FMRswGQYDVQQDDBJsZGFwMDEuZXhhbXBsZS5jb20xITAfBgkqhkiG
9w0BCQEWEnJhZmFlbHJiQGdtYWlsLmNvbTAeFw0xNjA4MDYxNTIzMDlaFw0yNjA4
MDQxNTIzMDlaMIGEMQswCQYDVQQGEwJCUjESMBAGA1UECAwJU2FvIFBhdWxvMRIw
EAYDVQQHDAlTYW8gUGF1bG8xDTALBgNVBAoMBEhPTUUxGzAZBgNVBAMMEmxkYXAw
MS5leGFtcGxlLmNvbTEhMB8GCSqGSIb3DQEJARYScmFmYWVscmJAZ21haWwuY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA72pIzy0J6Ns3Vj8zwn65
Zew8HlnZS3VBdEwGf2cNXZ1mkcjGSqbBSkI6rCRHhMmi0lwAheezbB1GUuY2i4rQ
pbSVN+6+PfJJyqfaFuiXQy9TGtEhkqVI6398Jrfp3ZX1uHbX6ng4lBAqg0IYMrE9
ygp1xJc7dU2ZLWND6akPUQ5N+LMreI/jOaV1zOvJv61GXrX3IHbJ2hibAQanhDqO
5E4ZVuOWYSDGrm6BbeeTalFF4j4p5rNqGeQrIj2xLDV0hIa1NJjOJDZyNE5ohb1h
8vfPWhsbzHDNuN80S1V/CzeIt2oOqtPSB63WtWy8Gbpwc0ctYNu4RTDbZuiBhh/o
0QIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA4xBg0YdgQ5epznyCG2uEELrgxuJUK
QOMH+EDdY0o3ez6KjauW+obqpWj2UsgRv5n0+xUy7cRUs0GNg2TapkJXKBwOQj94
UO/GsOX8PVReiS7KUio+r/oDGhyea2+TVTZpT3umJJWQ15KabSDtcjtHRyhkEOsl
vz1v8yfucLDa+cGmssWTK84vQQ/MwBKnb+nYLKB6JSE0GIXJENVe+bu2iUQlOdr1
2Kt3kkYTkJFvlRGLaDUpG2zZx5qyx+0CTEvhZafn/LMPoLt0fOYW8xfWTfuxljL9
4dFJbw7O2fv+L5yGOZtAdjgQreKd9GG4h0MJkxgm/38pXmQ8MR8PxeNB
-----END CERTIFICATE-----
subject=/C=BR/ST=Sao Paulo/L=Sao Paulo/O=HOME/CN=ldap01.example.com/emailAddress=rafaelrb@gmail.com
issuer=/C=BR/ST=Sao Paulo/L=Sao Paulo/O=HOME/CN=ldap01.example.com/emailAddress=rafaelrb@gmail.com
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 1396 bytes and written 373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 0A437CC31B5082B02CBAC425D673446E70CA57F1EEEE189241D46B5BAD527689
Session-ID-ctx:
Master-Key: F117AD5975460891775B9CE9B787E6C7C541ABF759652E1C964644AA461D62FCDA2CF9C4E2CDC07F06AD4955D88015C3
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1470498253
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---

Configurando Servidores Clientes

Agora precisamos configurar o servidor cliente Linux para utilizar o serviço de diretórios com ldaps. No servidor cliente Linux CentOS 7 utilize o seguinte comando:

# authconfig --enableldaptls --update
getsebool: SELinux is disabled

Edite o arquivo /etc/nslcd.conf com o seguinte conteúdo:

uid nslcd
gid ldap
uri ldaps://192.168.206.200/
base dc=example,dc=com
tls_reqcert allow

Reinicie o serviço nslcd para carregar as alterações:

# systemctl restart nslcd.service

Edite o arquivo /etc/openldap/ldap.conf com o seguinte conteúdo:

BASE dc=example,dc=com
URI ldaps://192.168.206.200/
TLS_CACERTDIR /etc/openldap/cacerts
SASL_NOCANON on
TLS_REQCERT allow

Agora você pode se logar no servidor cliente normalmente. A comunicação entre cliente e servidor LDAP está acontecendo de forma criptografada através do protocolo LDAPS. Experimente fazer consultas no servidor cliente com o comando ldapsearch e monitore no servidor LDAP a porta 636 com o comando tcpdump –X e veja que toda a informação do pacote está criptografada.

Referências:

https://www.server-world.info/en/note?os=CentOS_7&p=openldap&f=4
https://www.server-world.info/en/note?os=CentOS_7&p=ssl

Até a próxima!

- Rafael Baena
Postar um comentário