Entonces, esta es la situación. Parece que necesitamos tener un puerto TCP abierto 5432 para el mundo, donde un cliente tiene acceso a su base de datos PostgreSQL.
Por razones obvias, no podemos decir simplemente "no", solo como último recurso.
¿Cuáles son los mayores problemas? ¿Cómo puedo defender nuestra infraestructura?
De todos modos: ¿por qué no debería abrirse al mundo? Creo que quizás sea más seguro que un servidor FTP sin mantenimiento de 20 años.
PS VPN no está bien. Tal vez algún cifrado (si puedo darle una URL de conexión JDBC que funcione ).
security
postgresql
internet
Josip Rodin
fuente
fuente
Respuestas:
Requerir SSL, mantener SELinux activado, monitorear los registros y usar una versión actual de PostgreSQL .
Lado del servidor
Requerir SSL
En
postgresql.conf
conjuntossl=on
y asegúrese de tener su archivo de claves y su archivo de certificados instalados adecuadamente (vea los documentos y los comentarios enpostgresql.conf
).Es posible que deba comprar un certificado de una CA si desea que los clientes confíen en él sin una configuración especial en el cliente.
En
pg_hba.conf
uso algo como:... posiblemente con "todos" para usuario y / o base de datos, y posiblemente con un filtro de dirección IP de origen más amplio.
Limite a los usuarios que pueden iniciar sesión, denegar el inicio de sesión de superusuario remoto
No permita "todos" para los usuarios si es posible; no desea permitir inicios de sesión de superusuario de forma remota si puede evitar la necesidad de hacerlo.
Limitar los derechos de los usuarios.
Restrinja los derechos de los usuarios que pueden iniciar sesión. No les dé derechos
CREATEDB
niCREATEUSER
derechos.REVOKE
elCONNECT
derecho desdePUBLIC
todas sus bases de datos, luego devuélvalas solo a los usuarios / roles que deberían poder acceder a esa base de datos. (Agrupe a los usuarios en roles y otorgue derechos a los roles, en lugar de directamente a los usuarios individuales).Asegúrese de que los usuarios con acceso remoto solo puedan conectarse a las bases de datos que necesitan, y solo tengan derechos sobre los esquemas, tablas y columnas que realmente necesitan. Esta es una buena práctica para los usuarios locales también, es solo una seguridad sensata.
Configuración del cliente
En PgJDBC, pase el parámetro
ssl=true
:... e instale el certificado del servidor en el almacén de confianza del cliente, o use un certificado de servidor en el que confíe una de las CA en el almacén de confianza incorporado de Java si no desea que el usuario tenga que instalar el certificado.
Acción en curso
Ahora asegúrese de mantener PostgreSQL actualizado . PostgreSQL solo ha tenido un par de agujeros de seguridad previos a la autenticación, pero eso es más que cero, así que manténgase actualizado. De todos modos, deberías tener correcciones de errores.
Agregue un firewall al frente si hay grandes bloques de red / regiones de los que sabe que nunca necesita acceder.
Registro de conexiones y desconexiones (ver
postgresql.conf
). Registro de consultas si es práctico. Ejecute un sistema de detección de intrusos o fail2ban o similar al frente si es práctico. Para fail2ban con postgres, hay un procedimiento práctico aquíMonitorear los archivos de registro.
Bonus paranoia
Pasos adicionales para pensar ...
Requerir certificados de cliente
Si lo desea, también puede utilizar
pg_hba.conf
para exigir que el cliente presente un certificado de cliente X.509 en el que confíe el servidor. No necesita usar la misma CA que el certificado del servidor, puede hacerlo con una CA homebrew openssl. Un usuario JDBC necesita importar el certificado del cliente en su Java Keystorekeytool
y posiblemente configurar algunas propiedades del sistema JSSE para apuntar Java a su almacén de claves, por lo que no es totalmente transparente.Poner en cuarentena la instancia
Si desea ser realmente paranoico, ejecute la instancia para el cliente en un contenedor / VM separado, o al menos bajo una cuenta de usuario diferente, con solo las bases de datos que requieren.
De esa forma, si comprometen la instancia de PostgreSQL, no avanzarán más.
Use SELinux
No debería tener que decir esto, pero ...
Ejecute una máquina con soporte SELinux como RHEL 6 o 7, y no apague SELinux ni lo configure en modo permisivo . Manténgalo en modo obligatorio.
Use un puerto no predeterminado
La seguridad solo por oscuridad es estupidez. La seguridad que usa un poco de oscuridad una vez que haya hecho las cosas sensibles probablemente no le hará daño.
Ejecute Pg en un puerto no predeterminado para hacer la vida un poco más difícil para los atacantes automáticos.
Pon un proxy al frente
También puede ejecutar PgBouncer o PgPool-II frente a PostgreSQL, actuando como un grupo de conexiones y proxy. De esa manera, puede dejar que el proxy maneje SSL, no el host de la base de datos real. El proxy puede estar en una máquina virtual o máquina separada.
El uso de servidores proxy de agrupación de conexiones es generalmente una buena idea con PostgreSQL de todos modos, a menos que la aplicación cliente ya tenga un grupo integrado. La mayoría de los servidores de aplicaciones Java, Rails, etc. tienen agrupación integrada. Incluso entonces, un proxy de agrupación del lado del servidor es, en el peor de los casos, inofensivo.
fuente
Una extensión simple al impresionante plan de acción de Craigs:
Tal vez el usuario está utilizando solo un conjunto relativamente pequeño de proveedores de red (por ejemplo, su proveedor de red móvil mientras se mueve, su red de cable desde el hogar y el lugar de trabajo de IP saliente del trabajo).
La mayoría de los proveedores de red tienen muchas IP, pero no muchas subredes. Por lo tanto, puede proporcionar un filtro de iptables, que limita el acceso postgresql a los segmentos de red que utiliza su cliente. Esto redujo en gran medida las posibilidades de ataque de las fuentes de problemas de la red seleccionadas al azar.
Un escenario de soporte simple:
tcpdump -i eth0 -p tcp port 5432
orden, de dónde viene.whois 1.2.3.4
puede obtener la dirección IP utilizada por esta ip. Por ejemplo, puede ser1.2.3.0/24
.iptables -A INPUT -s 1.2.3.0/24 -p tcp --dport 5432 -j ACCEPT
(o algo similar) permite las conexiones tcp con su nueva subred.Hay un muy buen script perl llamado
uif
que puede proporcionar conjuntos de reglas de iptables declarables permanentes e intuitivos. (Google para "uif iptables").fuente
Aquí hay una configuración bastante sencilla de Fail2ban para PostgreSQL basada en el CÓMO vinculado anteriormente, pero ajustada para funcionar realmente con paquetes de Ubuntu, detectar otra condición de error y omitir varios mensajes de depuración para hacerlo más rápido:
/etc/fail2ban/filter.d/local-postgresql.conf
:/etc/fail2ban/jail.d/local-postgresql.conf
:fuente
Fail2ban es una herramienta poderosa, pero no confíe en que un filtro funcionará como está. Pruebe los filtros con la herramienta failregex y recuerde escapar de las comillas (es decir, "admin" sería \ "admin \"). Como ejemplo, probar la siguiente línea failregex del filtro desde mi /etc/log/postgresql/postgresql-9.3-main.log no funcionó para mí.
Lo anterior me dio
Tuve que actualizar el failregex para que coincida con el formato de registro.
Esto me dio un resultado positivo.
La prueba fail2ban-regex también se puede implementar en archivos de registro completos.
Lo anterior me dio el siguiente resultado positivo con el failregex actualizado.
fuente