Often we create web applications with backend management, being web also, publicly expose anyone to get find the URL. Usually these systems are restricted, only a small group of users using it.
In scenarios where we have a limited number of users and requires authentication, you can use a certificate mechanism to provide greater security to the system, so only users who have the certificate in question have access to the machine.
Today we will see how to allow access to our app users who have a certificate that they have shipped previously while if they are not accessible in any way. This method can be combined also with the traditional username / password to provide greater security. We can even verify that the user name you are trying to use corresponds to the user certificate that was sent and does not attempt to authenticate with another.
SSL certificates Basics
The method we are going to see is based on SSL certificates. They are used to secure information between a client and the server and prevent eavesdropping because the information is encrypted. This is his role and makes although not signed by a certificate authority (CA) or official even though it is expired. Follow ensuring communications.
Web browsers recognize, by default, a number of certification authorities like Verisign or Thawte , but there are many more. You can see them all in your browser options. But what is really what makes a Certification Authority? Sign. Sign your SSL certificate ensuring that you belongs to you and your domain. When a client accesses your domain and download the SSL certificate, looking in their certificates of CA 's if any which signs. If found, accept your certificate and nothing special happens, but if you do not find the CA launches a notice indicating that it recognizes the authority who signs it. This does not mean that the certificate is not valid, all that happens is that he knows who signs it. This means, therefore, that you yourself can be your own certificate authority and sign your certificates, work perfectly and fulfill its mission of ensuring the client / server communications.
Commercially or public access systems in general, self-signed certificates are not recommended because the notice unrecognized certificate authority generate distrust among your users, but intranet environment or housing management panel is an ideal method.
The server may require, in addition, another certificate to the client, so that both ends authenticate communication. This is precisely what we do today in this article.
As we have explained, self-signed certificates are just as safe as those signed by a certificate authority. As in the example we are seeing are ensuring access to our application for a small group of users, there is no problem in using a certificate signed by ourselves and our users know that there is no problem. But this is not all, for this reason we can say that users install the public certificate from our CA, as do the official CA, and the browser will automatically begin to trust our certificates since, now has a certificate from a CA signing SSL certificates.
In summary, our trabjo consist of:
- Create our certificate authority and certificate.
- Create the SSL certificate for our web server signed by our CA.
- Create client certificates for our users.
- Enable SSL data reading from PHP.
SSL Web Server
Package will use openssl to generate the certificates. If you have not already installed on your server, it's time. Quickly explain how to create create SSL certificates to secure communications because it is the first necessary step to add client certificates, however it is not the main object of this article and there is a lot of documentation, googled a bit .
First we create the certificate and private key from our certifying authority:
- -keyout CAXplotaKey.pem -out CAXplotacert.pem openssl req-x509-newkey rsa: 2048-days 3650-keyout CAXplotaKey.pem-out CAXplotacert.pem
The most important of this command is the parameter days, we do not want that in one year certificate expires us of our own entity. I put 10 years. This command generates two files, the private key with which our future will sign certificates and certificate with the public key to install, if we do not get tips on your browser. This command will ask some data (company name, country ...) and, above all, a password. You will remember it every time you go to sign an SSL certificate, so do not forget. We have our CA created.
Now create the SSL certificate for your domain:
- genrsa openssl-des3-out claveprivada.pem 2048
- openssl req-new-key certificado.pem claveprivada.pem-out
The first command creates the private key of your certificate. I asked another password, this time for the private key. Also remember it.
The second command generates the certificate request on the previous private key. I asked for the password of the private key earlier.
At this point we have four files, the key and the certificate of your CA and the key and request for your SSL certificate. It only remains to sign the certificate with our CA and you can use it.
To sign must first generate a text file with some configuration parameters:
- basicConstraints = critical, CA: FALSE
- extendedKeyUsage = serverAuth
And signed the certificate.
- -CAcreateserial -sha1 -out certificado-servidor.pem openssl x509-CA CAXplotacert.pem-cakey-req-EXTFILE CAXplotaKey.pem configservidor.cnf - in certificado.pem-days 3650-sha1-out CAcreateserial-certificate-servidor.pem
We have an SSL certificate ready to use on our web server. In our case-servidor.pem certificate. We will configure Apache for use.
We will have to edit httpd.conf and add
- Ssl_module LoadModule modules / mod_ssl.so
- Listen 443
Chances are, if you've compiled your own Apache and have installed a precompiled package, you already have some ssl.conf. Activating this step have prepared. In my case, a CentOS5 , just include / etc / httpd / conf.d / ssl.conf.
Finally it should be noted in the virtual host you want to ensure that you use our new certificate. To do this we add a new virtual listen on port 443 and add the following lines:
- SSLEngine on
- SSLCertificateFile / path / to / certificate-servidor.pem
- SSLCertificateKeyFile / path / to / claveprivada.pem
If you now restart Apache and agree to your domain with https in your browser you will see the padlock appears indicating that the information is secure. You will also see a warning you that you do not trust the certifying authority. We will see later how to fix it.
Adding client certificates
Now that we have our secure web server with our self-signed certificate comes time to create certificates for our customers so that if someone tries to access your application without one of them is prohibited from passing.
First create a configuration file with the parameters that need.
- basicConstraints = critical, CA: FALSE
- extendedKeyUsage = clientAuth
This will give instructions to a client certificate when signing the certificate.
We create now, as we did before, the private key and certificate request.
- openssl des3-out genrsa-key-cliente.pem 2048
- openssl req-new-key key-cliente.pem-out certificate-client-req.pem
As before, the key generation will ask for you to enter a password then to make the certificate request. The data you requested this application, as before, the later read to check data or you deem appropriate, so it is important to pay attention.
Now signed the certificate with our CA:
- -extfile configcliente.cnf -CAcreateserial -sha1 -out certificado-cliente.pem openssl x509-CA-cakey CAXplotacert.pem CAXplotaKey.pem-req - in client certificate-req.pem-days 3650-EXTFILE configcliente.cnf-CAcreateserial-sha1-out certificate-cliente.pem
As you can see, the process is the same to generate the server certificate, but changed the content of the configuration file that indicates a client certificate, not server.
Okay, fine, but do not stay that it is the client that you must install the certificate? Yes, here we go now. The certificate you just generated it must install in your web browser, not the server, so we have to convert it to a format they can understand. For this we will:
- certificado-cliente.pem -inkey clave-cliente.pem -certfile CAXplotacert.pem -out cliente.p12 openssl pkcs12 - export - in cliente.pem-inkey certificate-key-cliente.pem-certfile CAXplotacert.pem-out cliente.p12
We asked for the password of the private key and certificate request one for us that will generate. It is important to end the certificate password and that is what you will send to your users and pretend that only they can use, so I put a password never hurts.
You have your certificate cliente.p12. You can try it yourself. Oh no, wait, we have not configured the web server to request a certificate or yes customer. Add your SSL setup Apache virtual host:
- SSLCACertificateFile / path / to / CAXplotacert.pem
- SSLVerifyClient required
And restart your web server. If you now try to access your domain watch him jump a window requesting a certificate that you have. From your browser options, find the SSL certificate section and add a new certificate. Choose your cliente.p12. I asked for the password you put to make to PK12. That's it. Access now and see how you receive the certificate certificiados window available and if you select it, it lets you access your application.
Sometimes it may be necessary to prohibit the passage with certain certificates, either because the user no longer works or works with you, either because there are chances that the certificate has been stolen, etc.. One option is, when creating the certificate, and if you know in advance that the user will need a few days (test account occasional user or any similar reason), generate a temporary (10 days, a month, etc. .), so that after this time the certificate expires and the user can not enter. The biggest problem you'll have it when you need to deny access to users with long-term certificates. To do this we must create a certificate revocation list.
In my case (CentOS5 and RHEL5) I had some configuration problems. Openssl should keep a list of the certificates it issues and their serial numbers yet as we generated our certificates do not. To fix this, manually create the list.
- touch / etc / pki / CA / index.txt
Now we must edit the configuration file to reflect some parameters Openssl. Default indicates a relative path to the directory where the certificates will, but it worked fine until I put absolute paths. We modified because the path to the directory and we indicate where the private key and certificate from our CA.
Edit / etc / pki / tls / openssl.cnf
- dir = / etc / pki / CA # Where everything is kept
- certificate = / path / to / CAXplotacert.pem # The CA certificate
- private_key = / path / to / CAXplotaKey.pem # The private key
Now we can revoke a certificate as simply as:
- openssl ca-revoke certificate-cliente.pem
From the list with the status of the certificates should create a revocation list that we use to tell the Web server certificates should not allow.
- openssl ca-gencrl-out recovados.crl
It is possible that this command will launch apareza crlnumber other related error. This is related to what I stated before and is simply that there is no serial number file. To fix this, simply create:
- > /etc/pki/CA/crlnumber echo "01"> / etc / pki / CA / crlnumber
And back to generate the revocation list. Whenever a certificate plaster must repeat this operation to have the new list.
You just need to tell Apache which certificates should not allow. We add to our virtual host configuration in the same place where the SSL certificate configured above, the following line:
- SSLCARevocationFile path / to / revocados.crl
That's it, we have served our SSL working, our application protected with client certificates and the option to revoke certificates.
Checking certificates with PHP
We want to go a little further. We want you, from our application, we can read the SSL client certificate and check who it is. You sure you can think of better things to do with this data . The first thing you have to do is to configure Apache to pass the certificate data. In the settings of your virtual host add:
- <Files ~ "\. (cgi|shtml|phtml|php?)$">
- SSLOptions + + ExportCertData StdEnvVars
- </ Files>
That's it. Now if you do a print_r ($ _SERVER) in the application where you installed your SSL client certificate from any data see something like:
- => / C= ES/ ST= Valencia/ L= Valencia/ O= Osusnet/ CN= blog.osusnet.com/ emailAddress= osusENosusnet.com [SSL_CLIENT_S_DN] => / C = ES / ST = Valencia / L = Valencia / O = Osusnet / CN = blog.osusnet.com / emailAddress = osusENosusnet.com
- => ES [SSL_CLIENT_S_DN_C] => EN
- => Valencia [SSL_CLIENT_S_DN_ST] => Valencia
- => Valencia [SSL_CLIENT_S_DN_L] => Valencia
- => Osusnet [SSL_CLIENT_S_DN_O] => Osusnet
- => blog.osusnet.com [SSL_CLIENT_S_DN_CN] => blog.osusnet.com
- => osusENosusnet.com [SSL_CLIENT_S_DN_Email] => osusENosusnet.com
You have all the information you need, is the data that is requested to create the certificate request. Generating these parameters appropriately can know who comes to your application from client certificate used.
That's all for today. In a very simple way we have added a little more security to a private access web application and a limited number of users. We also learned more about certificates and SSL and we have seen how to sign our own certificates, equally reliable than commercial. I hope you serve something .