Anterior Siguiente Inicio

Servidor Web con virtualhosts, https, y restricción por ip

    Lo usamos para hacer nuestras pruebas de webs que hacemos, y para mostrar de forma sencilla datos de interés, como la lista de ip's de la página anterior, un administrador de impresión via web, o un wiki con apuntes diversos. Para facilitar las cosas optamos por usar virtualhosts, de modo que tengamos dominios impresoras.local.gadelek.com, ips.local.gadelek.com, tienda.local.gadelek.com, etc.
Configurar virtualhosts en apache2 es muy sencillo. Simplemente tenemos que poner el fichero de nuestro virtualhost dentro de /etc/apache2/sites-avaliable y añadir las ip's y puertos que servirán hosts virtuales en nuestro fichero de configuración de apache. En este caso /etc/apache2/apache2.conf

NameVirtualHost *:80
NameVirtualHost *:443

Este es el contenido habitual de un virtualhost en el que restringimos el acceso a un directorio:

#/etc/apache2/sites-avaliable/tienda

<VirtualHost *:80>

        ServerAdmin webmaster@gadelek.com
        ServerName tienda.local.gadelek.com
        DocumentRoot /var/www/tienda/
        ErrorLog /var/log/apache2/tienda/error.log
        CustomLog /var/log/apache2/tienda/access.log common

        <Directory /var/www/tienda/cosas>
        AuthType Basic
        AuthName "Restricted Files"
        AuthUserFile /etc/apache2/passwd
        Require user usuario1 usuario2 usuario3
        </Directory>
</VirtualHost>

Podemos especificar tantos directorios como queramos. También podemos poner varios virtualhosts dentro del mismo fichero; por ejemplo para que www.gadelek.com y gadelek.com apunten a la misma página.
Para restringir acceso a directorios tenemos que crear un fichero de contraseñas. Esto lo hacemos con el programa htpasswd:

htpasswd -c /etc/apache2/passwd usuario1

Posteriormente podemos añadir usuarios:

htpasswd /etc/apache2/passwd pepe

Tras todo esto, nos aseguramos que en el comienzo del virtualhost correspondinete a "default" se especifique el puerto y no se especifique el ServerName:

<VirtualHost *:80>

Luego ejecutamos:

a2ensite tienda
/etc/init.d/apache2 reload
Si por el contrario necesitamos varios certificados, crearemos nuestra propia entidad de certificación, rellenando los datos que nos pide la ejecución de este comando.
Nos creará un directorio demoCA que contendrá la clave privada de nuestra entidad, necesaria para firmar peticiones de certificados.

Ahora creamos un certificado:
Cuando nos pida "Common Name", debemos introducir el nombre del dominio para el que se usará este certificado. Es decir, tiene que coincidir con el campo ServerName del virtualhost.
Y lo firmamos con nuestra autoridad certificadora:
Llegados a este punto tendremos dos ficheros newreq.pem y newcert.pem. El fichero newreq.pem contiene la clave privada y el certificado sin firmar. El fichero newcert.pem contiene los datos del certificado, y el certificado en sí firmado por la autoridad certificadora que creamos al principio.
    Hay múltiples posibilidades para almacenar los certificados, desde eliminar datos innecesarios y unir los dos ficheros, hasta dejarlos tal cual por separado. Generalmente los programas que usan SSL permiten configurar los certificados en ficheros separados o todo en el mismo.

Copiamos newreq.pem a /etc/ssl/private/clave.key y newcert.pem a /etc/ssl/certs/cert.pem. Asimismo nos será util tener a mano el certificado de nuestra entidad certificadora. Para ello copiamos ./demoCA/cacert.pem a /etc/ssl/certs/ca.pem

Configuración de apache2

Dado que el soporte actual se hace mediante ssl, existe una limitación a la hora de crear virtualhosts en https. El chequeo de certificado se hace antes de comprobar el host virtual. Por lo tanto solo podemos usar un certificado para todos nuestros virtualhosts. Ello dará lugar a que algunos navegadores avisen de que el certificado de nuestra página no se corresponde con su dirección, como en el caso de yahoo. (El certificado de mail.yahoo.com está expedido para login.yahoo.com). La solución es que cada virtualhost https use un puerto distinto. De este modo para https://host1.com:443 (puerto por defecto) se usará un certificado, pero para https://host2.com:10443 se usará otro certificado, y el navegador se comportará correctamente.
Actualización: Se puede usar el mismo certificado para varios sitios web de modo que todo el tráfico pase por el puerto 443. Aquí la manera de hacerlo.
    Ahora bien, los usuarios son reacios a recordar dirección+puerto, así que podemos usar redirects de apache, de modo que http://host2.com sea redirigido a https://host2.com:10443. Esto es tan fácil como añadir una línea como esta en el virtualhost de host2.com:

Redirect / https://host2.com:10443

Obviamente debemos añadir los puertos necesarios en /etc/apache2/ports.conf

Listen 443
Listen 10443

Y crear unos virtualhosts similares a éste: (observar las diferencias entre ambos)

<VirtualHost *:443>
        ServerAdmin webmaster@host1.com
        ServerName host1.com
        DocumentRoot /var/www/host1.com
SSLEngine On
SSLCertificateFile /etc/ssl/certs/host1.com.pem
SSLCertificateKeyFile /etc/ssl/private/host1.com.key
SSLCACertificateFile /etc/ssl/certs/ca.pem
</VirtualHost>

<VirtualHost *:10443>
        ServerAdmin webmaster@host2.com
        ServerName host2.com
        DocumentRoot /var/www/host1.com
SSLEngine On
SSLCertificateFile /etc/ssl/certs/host2.com.pem
SSLCertificateKeyFile /etc/ssl/private/host2.com.key
SSLCACertificateFile /etc/ssl/certs/ca.pem
</VirtualHost>

En este momento tenemos todo configurado, pero apache nos pedirá la clave de los certificados cada vez que lo iniciemos. Para evitar esto, podemos eliminar la clave de dicho certificado.

    openssl rsa -in cert.key -out certnopass.key

Eso si, debemos ajustar bien los permisos del fichero para que nadie sin autorización pueda acceder a nuestro certificado.

Podemos, si nuestra entidad certificadora nos lo permite, usar el mismo certificado para varios sitios web, de modo que el certificado que usarán tanto navegador como servidor será el mismo para todos los virtualhost. Evidentemente si tenemos varios clientes y cada uno con su propio dominio esto es un engorro, pero si tenemos control sobre los dominios que servimos, ésta puede ser una solución.
CaCert permite de forma gratuíta emitir certificados para sitios seguros. Simplemente debemos enviar una solicitud de certificado para varios dominios (todos en la misma solicitud). Este script nos facilitará la tarea.
Para más información, visitar esta página.
Simplemente creamos una directiva <Directory> en la cual especificamos las ip's que permitimos:

<Directory /var/www/mipagina/>

Order allow,deny
Allow from 127.0.0.1
Allow from 192.168.1.2
Allow from 192.168.0.0/255.255.255.0
Allow from 123.456.789
</Directory>
Para que apache no nos genere índices de los directorios, de forma que nadie pueda ver el contenido de los mismos, debemos añadir la siguiente opción en el virtualhost afectado:
Option   -indexes

Anterior Siguiente Inicio