Ir al contenido

Configurar Apache HTTPS Reverse-Proxy

Exponer OpenKM directamente desde Tomcat puede ser peligroso si necesita que se acceda a la aplicación desde Internet (por ejemplo https://issues.jboss.org/browse/JBAS-3861). Como resultado, podría infectarse con PerlBot. Además, el puerto 8080 puede estar bloqueado por un firewall. Por estas razones, es buena práctica exponer su instalación de OpenKM a través del puerto web estándar 80. En los siguientes pasos explicamos cómo configurar Apache para gestionar estas peticiones y reenviarlas al servidor de aplicaciones Tomcat usando el protocolo AJP13.

De la documentación de Apache: El protocolo AJP13 está orientado a paquetes. Presumiblemente se eligió un formato binario en vez del texto plano, más legible, por razones de rendimiento. El servidor web se comunica con el contenedor de servlets a través de conexiones TCP. Para reducir el costoso proceso de creación de sockets, el servidor web intentará mantener conexiones TCP persistentes con el contenedor de servlets, y reutilizar una conexión para varios ciclos de petición/respuesta.

Se puede acceder a su OpenKM desde dos zonas distintas: Internet y LAN. Esto significa que para acceder a este servidor necesita usar dos direcciones IP: IP externa (Internet) e IP interna (LAN).

La dirección IP interna (también conocida como “dirección IP local”) es la dirección asignada por su router de red local y suele empezar por 192.168.x.x. Estas direcciones IP solo las pueden ver otros equipos de su red local (LAN), no ningún equipo conectado en una red externa como Internet.

Para acceder a Internet o a un equipo de otra red, a su equipo se le suele asignar una dirección IP externa, que luego puede usarse para referirse al equipo de su red local.

En la imagen anterior, hay tres equipos en la red local a los que el router ha asignado su propia dirección IP interna. El ISP está conectado al router y le da una dirección IP externa que le permite comunicarse con Internet. En Internet todo el mundo ve su dirección IP externa, pero cualquier información que provenga del router se “convierte” de la dirección IP externa a la dirección IP interna.

Así que si quiere que su instalación de OpenKM sea accesible tanto desde la LAN como desde Internet, el truco consiste en configurar los equipos cliente para que resuelvan su IP interna (192.168.0.50) si están dentro de la LAN, o la IP externa si están en Internet. Para resolver la IP de Internet (67.166.214.148), su equipo usa el DNS público. Por tanto, necesita configurar un servidor DNS local dentro de la LAN o modificar el fichero hosts de cada cliente para que resuelva a la IP interna.

Lo primero es instalar el software de Apache necesario. En Debian/Ubuntu puede instalar Apache con un único comando:

Ventana de terminal
$ sudo apt-get install apache2

Edite el fichero llamado /etc/apache2/apache2.conf y configure un ServerName para evitar avisos en el proceso de arranque de Apache:

Ventana de terminal
$ vim /etc/apache2/apache2.conf
ServerRoot "/etc/apache2"
ServerName "your-domain.com"

Habilite el módulo proxy:

Ventana de terminal
$ sudo a2enmod proxy_ajp
$ sudo a2enmod proxy_wstunnel

Crear los certificados

Ventana de terminal
$ sudo mkdir /etc/apache2/ssl
$ sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem
$ sudo a2enmod ssl

Asegúrese de que el puerto 443 aparece en /etc/apache2/ports.conf:

Ventana de terminal
$ cat /etc/apache2/ports.conf | grep Listen

Cree el fichero de configuración /etc/apache2/sites-available/openkm.conf con este contenido:

Ventana de terminal
$ vim /etc/apache2/sites-available/openkm.conf
<VirtualHost *:443>
ServerName openkm.your-domain.com
RedirectMatch ^/$ /openkm
# WebSocket support - needs proxy-wstunnel
ProxyPass /openkm/webSocket wss://127.0.0.1:8080/openkm/webSocket
ProxyPassReverse /openkm/webSocket wss://127.0.0.1:8080/openkm/webSocket
ProxyPass /openkm ajp://127.0.0.1:8009/openkm
ProxyPassReverse /openkm https://openkm.your-domain.com/openkm
ErrorLog /var/log/apache2/openkm.your-domain.com-error.log
CustomLog /var/log/apache2/openkm.your-domain.com-access.log combined
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
</VirtualHost>

El ServerName del VirtualHost debe ser distinto del ServerName de la configuración principal de Apache. Habilite esta configuración de sitio:

Ventana de terminal
$ cd /etc/apache2/sites-available/
$ sudo a2ensite openkm.conf

Edite el fichero de configuración /etc/apache2/sites-available/openkm.conf y añada este contenido

Ventana de terminal
$ vim /etc/apache2/sites-available/openkm.conf
<VirtualHost *:80>
ServerName openkm.your-domain.com
Redirect permanent / https://openkm.your-domain.com/
</VirtualHost>

Reinicie Apache:

Ventana de terminal
$ sudo /etc/init.d/apache2 restart

Compruebe el acceso a su instalación de OpenKM en https://openkm.your-domain.com/.

Let’s Encrypt es una autoridad de certificación gratuita que proporciona certificados X.509 para cifrado Transport Layer Security (TLS) sin coste. Para poder solicitar e instalar los certificados necesita la utilidad certbot. Si usa Apache, también necesita el paquete certbot-apache:

Ventana de terminal
$ apt install certbot certbot-apache

Una vez instalado, ejecute la utilidad con estos parámetros:

Ventana de terminal
$ certbot --domain <your-domain-name> --email <your-sysadmin-email> --agree-tos --redirect --apache

Este certificado será válido durante 90 días, así que debe renovarlo antes de que expire. Es buena práctica crear una tarea cron para actualizarlo automáticamente:

Ventana de terminal
@monthly /usr/bin/certbot renew

Tenga también en cuenta que tanto el puerto 80 como el 443 deben ser accesibles desde Internet para validar el dominio y generar el certificado.

Use el gestor de aplicaciones yum para instalar Apache:

Ventana de terminal
$ sudo yum install httpd

Habilítelo al arrancar:

Ventana de terminal
$ sudo chkconfig httpd --level 2345 on

Crear el certificado

Ventana de terminal
$ sudo yum install mod_ssl openssl crypto-utils

Genere las claves privadas (para más información, visite Apache HTTP Secure Server Configuration).

Ventana de terminal
$ genkey your-domain.com

Durante el proceso se generarán dos ficheros en:

ReplaceSSLCertificateFile /etc/pki/tls/certs/your-domain.com.cert
SSLCertificateKeyFile /etc/pki/tls/private/your-domain.com.key

Ahora cree el fichero /etc/httpd/conf.d/openkm.conf con este contenido:

Ventana de terminal
$ vim /etc/httpd/conf.d/openkm.conf
<VirtualHost *:443>
ServerName openkm.your-domain.com
ProxyPass / ajp://localhost:8009/openkm/
ProxyPassReverse / http://your-domain.com/openkm/
ErrorLog /var/log/your-domain.com-error.log
CustomLog /var/log/your-domain.com-access.log combined
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/your-domain.com.cert
SSLCertificateKeyFile /etc/pki/tls/private/your-domain.com.key
</VirtualHost>

Por último, debe modificar los valores SSLCertificateFile y SSLCertificateKeyFile en el fichero /etc/httpd/conf.d/ssl.conf:

Ventana de terminal
$ vim /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/pki/tls/certs/your-domain.com.cert
SSLCertificateKeyFile /etc/pki/tls/private/your-domain.com.key

Reinicie Apache:

Ventana de terminal
$ sudo /etc/init.d/httpd restart

Compruebe el acceso a su instalación de OpenKM en https://openkm.your-domain.com/.

Error Permission denied: proxy: AJP: attempt to connect

Sección titulada «Error Permission denied: proxy: AJP: attempt to connect»

Si el log muestra un error como Permission denied: proxy: AJP: attempt to connect, resuélvalo ejecutando el siguiente comando:

Ventana de terminal
$ /usr/sbin/setsebool httpd_can_network_connect 1

Si funciona, haga la configuración permanente para que persista tras reinicios:

Ventana de terminal
$ /usr/sbin/setsebool -P httpd_can_network_connect 1

Si ve un error como:

Necesita habilitar estos módulos de Apache:

Ventana de terminal
$ sudo a2enmod rewrite
$ sudo a2enmod proxy_http
$ sudo a2enmod headers

Si ve errores como estos:

Ventana de terminal
[proxy_ajp:error] [pid 27579:tid 140057021224704] (70007)The timeout specified has expired: AH01030: ajp_ilink_receive() can't receive header
[proxy_ajp:error] [pid 27579:tid 140057021224704] [client xxx.xxx.xxx.xxx:60526] AH00992: ajp_read_header: ajp_ilink_receive failed
[proxy_ajp:error] [pid 27579:tid 140057021224704] (70007)The timeout specified has expired: [client xxx.xxx.xxx.xxx:60526] AH00878: read response failed from 127.0.0.1:8009 (127.0.0.1)

Es posible que Tomcat no esté aceptando conexiones AJP. Descomente estas líneas en $TOMCAT_HOME/conf/server.xml

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector protocol="AJP/1.3"
address="127.0.0.1"
port="8009"
redirectPort="8443"
secretRequired="false" />

El parámetro secretRequired es importante, y si no está presente debe añadirlo.

Más información en Apache Tomcat 8 Configuration Reference.