# rm-rf.es | Administración de sistemas

Blog de un SysAdmin Unix, Gnu/Linux, Windows y lo que haga falta.

Port knocking en Debian con knockd

El golpeo de puertos (del inglés port knocking) es un mecanismo para abrir puertos externamente en un firewall mediante una secuencia preestablecida de intentos de conexión a puertos que se encuentran cerrados. Una vez que el firewall recibe una secuencia de conexión correcta, sus reglas son modificadas para permitir al host que realizó los intentos conectarse a un puerto específico.

El propósito principal del golpeo de puertos es prevenir un escanéo de puertos por parte de un atacante que busca posibles servicios vulnerables. Como los mismos solo se abren ante un golpeo de puertos correcto. Normalmente los puertos donde se brindan los servicios se muestran aparentemente cerrados.

Wikipedia

Port knocking

Una vez que sabemos qué es el Port knocking y sus utilidades, vamos a ver el modo de instalarlo y utilizarlo, tanto en modo servidor como cliente. Para ello podemos hacer uso de varias herramientas, una de ellas es knockd, que incluye tanto el demonio (Servidor) como el cliente así que será lo que instalemos en ambas partes.

Los paquetes precompilados y código fuente se pueden descargar desde el sitio de knockd, para Debian y derivados podemos instalarlo directamente desde los repositorios:

$ sudo apt-get install knockd

Una vez instalado, la configuración básica, requiere por un lado habilitar el servicio (que no arrancarlo), para ello debemos modificar la variable START_KNOCKD de 0 a 1 en el fichero /etc/default/knockd. Veréis que al instalar os ha indicado lo siguiente:

  * knockd disabled: not starting. To enable it edit /etc/default/knockd

Ese fichero tiene dos variables, una la comentada y la otra en la que especificamos la interfaz de red en la que escuchará knockd y cualquier otro parámetro que queramos pasar al demonio:

################################################
#
# knockd's default file, for generic sys config
#
################################################

# control if we start knockd at init or not
# 1 = start
# anything else = don't start
#
# PLEASE EDIT /etc/knockd.conf BEFORE ENABLING
START_KNOCKD=1

# command line options
KNOCKD_OPTS="-i eth1"

Y el otro fichero de configuración es en el que especificamos las opciones de logging y las secuencias que queramos configurar para abrir y cerrar puertos, es el fichero /etc/knockd.conf. Vemos que por defecto estamos mandando los logs a syslog y que hay dos secuencias, una para abrir el puerto 22 (SSH) para una IP y otra para cerrarla. La primera con la secuencia de puertos TCP 7000,8000 y 9000 y la segunda a la inversa:

 
[options]
	UseSyslog

[openSSH]
	sequence    = 7000,8000,9000
	seq_timeout = 5
	command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn

[closeSSH]
	sequence    = 9000,8000,7000
	seq_timeout = 5
	command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
	tcpflags    = syn

Esta es la configuración por defecto, si quisiéramos probarla podemos arrancar el demonio (/etc/init.d/knockd start) o ejecutarlo manualmente ampliando el debug y ver directamente en STDOUT el funcionamiento. Voy a probarlo en local contra la interfaz “lo” y añadiendole verbose:

# knockd -i lo -v
listening on lo...

En el lado del cliente utilizaremos el comando “knock”, es tan sencillo como pasarle la IP seguida de los puertos y el protocolo (si es tcp no hace falta ponerlo). Para nuestro caso anterior, si quisieramos abrir el puerto 22 para nuestra IP haríamos lo siguiente:

$ knock localhost 7000 8000 9000

Y una vez ejecutado veremos en el log o en STDOUT si lo hemos ejecutado a mano:

127.0.0.1: openSSH: Stage 1
127.0.0.1: openSSH: Stage 2
127.0.0.1: openSSH: Stage 3
127.0.0.1: openSSH: OPEN SESAME
openSSH: running command: /sbin/iptables -A INPUT -s 127.0.0.1 -p tcp --dport 22 -j ACCEPT

Y para cerrarlo:

$ knock localhost 9000 8000 7000

Y el log:

127.0.0.1: closeSSH: Stage 1
127.0.0.1: closeSSH: Stage 2
127.0.0.1: closeSSH: Stage 3
127.0.0.1: closeSSH: OPEN SESAME
closeSSH: running command: /sbin/iptables -D INPUT -s 127.0.0.1 -p tcp --dport 22 -j ACCEPT

A partir de aquí conviene investigar ya que las posibilidades son infinitas, jugando con las secuencias de puertos, flags tcp (syn, ack…), timeouts de secuencias, comandos a ejecutar, etc. Os recomiendo esta entrada de Kriptopolis donde profundizan más en sus posibilidades.

Desactivar Java en Firefox y Chrome

Los que tengáis instalada la última versión de Java (Java 7 Update 10) deberíais desactivarla y/o desinstalarla ya mismo. Todavía no está claro si la vulnerabilidad (links al final de la entrada) afecta a la versión 6, pero ante la duda, lo mejor es desactivar los plugins de los navegadores como vamos a ver a continuación.

Google Chrome

Para desactivar el plugin de Java en Google Chrome escribiremos en la barra de direcciones lo siguiente:

chrome://plugins/

Buscamos el plugin de Java y pinchamos en Disable. Cuando hayamos actualizado y se haya solucionado la vulnerabilidad podremos activarlo desde el mismo sitio pinchando en Enable.

Firefox

En Firefox también es muy sencillo, pinchamos en el menú de herramientas (Tools) y después en Add-ons. Una vez que se haya abierto el gestor de add-ons seleccionamos el panel de plugins. Seleccionamos el plugin de Java y pinchamos en el botón Disable.

Si os interesa profundizar en el fallo de seguridad, tenéis un buen artículo de S21sec en el que lo explican. También podéis buscar en google por el código de vulnerabilidad CVE-2013-0422.

Securizar el acceso a wp-admin de WordPress

Seguridad Unix TCP WrappersSiguiendo un poquito con la temática WordPress hoy quería tratar el tema de la securización del acceso a la zona de administración. Tiene lógica que al tratarse de la puerta de entrada a toda la gestión de nuestro sitio queramos tenerla lo más securizada posible.

Por defecto, la entrada a la zona de administración (ejemplo.com/wp-admin/) tiene un sistema de autenticación interno de WordPress que funciona contra la base de datos. El administrador, por defecto accede con el usuario “admin”, si dejamos este valor por defecto, el atacante ya tiene el punto de partida para intentar acceder. Por este motivo se recomienda:

  • Establecer una clave lo suficientemente compleja para el usuario administrador.
  • Cambiar el nombre del usuario administrador de “admin” a uno personalizado. Para ello podemos usar el plugin WP-Optimize, que además nos sirve para otras cosas como mantener optimizada y limpia la base de datos. Si no queremos instalar el plugin, bastará con crear un nuevo usuario con rol de administrador y posteriormente borrar el original “admin”. Ojo, con esta última opción no borréis los artículos de “admin”, sino asociarlos al nuevo usuario. También se podría cambiar directamente en la base de datos, desde la shell de MySQL o phpMyAdmin.

Una vez que nuestro usuario administrador está securizado, lo mejor es proceder a añadir una segunda capa de autenticación para la ruta wp-admin, de modo que lo primero que se encuentre el atacante sea la barrera de autenticación básica de Apache, y en el hipotético caso de que la sobrepasara tuviera que enfrentarse también a la de WordPress.

Lo que hacemos entonces es crear, vía el fichero .htaccess dentro de la carpeta “wp-admin” una capa de autenticación. Creamos el fichero con el siguiente contenido:

AuthName "Acceso restringido"
AuthUserFile /home/foo/bar/.htpasswd
AuthType basic
require user miusuario

Nota importante: El fichero .htpasswd, que contendrá los usuarios y passwords con acceso autorizado, debe ubicarse fuera de la ruta pública del sitio web. Podemos añadir los usuarios al mismo desde línea de comandos con el comando htpasswd:

# htpasswd -cb /home/foo/bar/.htpasswd  miusuario mipassword

En este ejemplo, nos generaría el fichero .htpasswd siguiente:

# cat .htpasswd
miusuario:ktRS/8rW/AFm3as3l0/Y

Si no disponéis de un equipo Unix con el comando htpasswd, podéis usar cualquiera de las webs que permiten generar este fichero a través de asistentes.

Con estos dos ficheros ya tenemos una nueva capa de autenticación para acceder a la administración de WordPress. En el caso de que utilicemos las funcionalidades Ajax de la administración de WordPress se recomienda añadir también lo siguiente al fichero .htaccess del directorio “wp-admin”:

<Files admin-ajax.php>
    Order allow,deny
    Allow from all
    Satisfy any 
</Files>

Y finalmente, si tras realizar estos cambios recibimos un error 404 al acceder a la administración o un bucle “Too many redirects error”, añadimos la siguiente línea al fichero .htaccess principal del sitio (ojo, al principal, no al de wp-admin):

ErrorDocument 401 default

Existen otras opciones, como modificar el nombre del directorio “wp-admin” para dificultar aún más su exposición a ataques, no obstante con lo comentado en esta entrada debería ser suficiente para tener seguro nuestro acceso a la administración.

Importar / exportar contextos y booleanos personalizados de SELinux

El comando semanage es una herramienta que nos permite configurar las políticas de SELinux (Security-Enhanced Linux), está disponible dentro del paquete policycoreutils-python:

# yum info policycoreutils-python
Installed Packages
Name        : policycoreutils-python
Arch        : i686
Version     : 2.0.83
Release     : 19.24.el6
Size        : 910 k
Repo        : installed
From repo   : base
Summary     : SELinux policy core python utilities
URL         : http://www.selinuxproject.org
License     : GPLv2+
Description : The policycoreutils-python package contains the management tools use to manage an SELinux
            : environment.

En el caso de instalaciones masivas en las que queramos clonar las configuraciones, contextos, booleanos de SELinux, logins, etc de una máquina base, o si simplemente queremos tener una copia de seguridad de todas nuestras configuraciones de una máquina, el parámetro “-o” de semanage nos servirá.

       -o, --output
              Output current customizations as semanage commands

Volcamos entonces la configuración personalizada de SELinux a un fichero:

# semanage -o /root/selinux.configuration

Una vez finalizado vemos que efectivamente el fichero contiene nuestra configuración de booleeanos, contextos, login, etc:

# cat selinux.configuration
boolean -D
boolean -1 allow_ftpd_anon_write
boolean -1 rsync_export_all_ro
boolean -1 samba_export_all_rw
login -D
login -a -s guest_u -r 's0' __default__
user -D
port -D
interface -D
node -D
fcontext -D
fcontext -a -f 'all files' -t public_content_rw_t '/ftp(/.*)?'
fcontext -a -f 'all files' -t samba_share_t '/samba-shares(/.*)?'
fcontext -a -f 'all files' -t httpd_sys_content_t '/www(/.*)?'

Nota: los comandos que veis con -D eliminan las personalizaciones locales en la máquina antes de añadir las especificadas en el volcado.

El paso inverso, importar es igual pero con el parámetro “-i” y especificando el fichero del cual extraer las configuraciones. Como habéis podido ver el fichero son los comandos de semanage en orden de ejecución.

# semanage -i /root/selinux.configuration

El procedimiento para exportar e importar las configuraciones de SELinux entre máquinas sería el siguiente:

# semanage -o /root/selinux.configuration
# scp /root/selinux.configuration server-destino:/root
# ssh server-destino
# semanage -i /root/selinux.configuration

IPTABLES, FTP y Passive Mode

Cuando conectamos a un servidor FTP, tenemos la opción de elegir dos modos de conexión:

  • Modo activo: el cliente establece una conexión al servidor FTP a través del puerto TCP 21, una vez establecida se crea un canal de datos entre el puerto TCP 20 del servidor y un puerto aleatorio superior al 1024 en el cliente.
  • Modo pasivo: el cliente también establece la conexión al servidor FTP a través del puerto TCP 21. Una vez establecida la conexión el servidor abre un puerto aleatorio (> 1024) al que se conectará el cliente.

Me tomo la libertad de adjuntar estos dos esquemas de la Wikipedia, que lo explican de forma más gráfica y amplia:

FTP modo activo
FTP modo pasivo

 

Entrando al tema de la entrada, si quisiéramos configurar IPTABLES para permitir conexiones FTP con modo pasivo, no es tan sencillo como hacerlo para el modo activo. El modo activo únicamente necesita tener abiertos los puertos TCP 20 para datos y 21 para establecer la conexión:

# iptables -I INPUT 3 -p tcp --dport 21 -j ACCEPT
# iptables -I INPUT 4 -m state --state RELATED,ESTABLISHED -p tcp --dport 20 -j ACCEPT

Con estas dos reglas permitimos el acceso para cualquier tipo de conexión al puerto 21 y posteriormente las conexiones ya establecidas o relacionadas con destino el puerto 20 (datos FTP). Pero, ¿qué pasa con el modo pasivo? no conocemos cual es el puerto de datos. Está claro que el puerto 21 tcp sí que tendrá que estar abierto como en el modo activo:

# iptables -I INPUT 3 -p tcp --dport 21 -j ACCEPT

Con esta configuración podremos conectar al FTP, pero llegado el momento de transferir datos o incluso listar los ficheros del FTP recibiremos un timeout:

Status:	Connected
Status:	Retrieving directory listing...
Command:	PWD
Response:	257 "/"
Command:	TYPE I
Response:	200 Switching to Binary mode.
Command:	PASV
Response:	227 Entering Passive Mode (192,168,1,129,54,45).
Command:	LIST
Error:	Connection timed out
Error:	Failed to retrieve directory listing

Los servidores FTP normalmente permiten establecer un rango de puertos aleatorios a ser usados con el modo pasivo. Lo que tenemos que hacer es aceptar ese rango en iptables para conexiones ya establecidas y relacionadas, no es necesario aceptarlo para nuevas conexiones ya que el FTP nunca se va a conectar a ese puerto sin pasar antes por el 21. Si hubieramos configurado el rango 10000-10500 tcp en el servidor FTP añadiríamos esta regla:

# iptables -I INPUT 3 -m state --state ESTABLISHED,RELATED -p tcp --dport 10000:10500 -j ACCEPT

Pero esto no es todo, todavía necesitamos cargar un par de módulos de IPTABLES que sirven para seguir las conexiones FTP y llevar un control sobre ellas. Los módulos son nf_conntrack_ftp e ip_nat_ftp. El primer es necesario siempre y el segundo cuando se trabaja con NAT. En RHEL, CentOS y derivados los módulos se pueden cargar en el fichero /etc/sysconf/iptables-config:

# Load additional iptables modules (nat helpers)
#   Default: -none-
# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES="nf_conntrack_ftp ip_nat_ftp"

Una vez cargados, reiniciamos iptables para cargar los módulos y verificamos que han sido cargados con el comando lsmod:

# lsmod | grep ip
nf_conntrack_ipv4       7694  4 nf_nat
nf_defrag_ipv4          1039  1 nf_conntrack_ipv4
iptable_filter          2173  1 
ip_tables               9567  1 iptable_filter
ipt_REJECT              1931  2 
ip6t_REJECT             3987  2 
nf_conntrack_ipv6       7207  2 
nf_defrag_ipv6          9873  1 nf_conntrack_ipv6
nf_conntrack           65524  6 nf_nat_ftp,nf_nat,nf_conntrack_ftp,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
ip6table_filter         2245  1 
ip6_tables             10867  1 ip6table_filter
ipv6                  264641  34 ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6,cnic

Y ya tendremos nuestro firewall configurado para permitir FTP en modo pasivo.

Cómo enviar alertas AVC de SELinux por email (setroubleshoot-server)

Nadie nos impide hacer troubleshooting/debug de SELinux a través del log de audit (/var/log/audit/audit.log), el problema es que en dicho log la información se vuelca en bruto y puede ser complejo analizarla si nuestros conocimientos de SELinux no son avanzados o si no tenemos buena vista. Para evitar esto existe un paquete que nos solucionará este problema, setroubleshoot-server.

# yum info setroubleshoot-server

Available Packages
Name        : setroubleshoot-server
Arch        : i686
Version     : 3.0.47
Release     : 3.el6_3
Size        : 1.3 M
Repo        : updates
Summary     : SELinux troubleshoot server
URL         : https://fedorahosted.org/setroubleshoot
License     : GPLv2+
Description : Provides tools to help diagnose SELinux problems. When AVC messages
            : are generated an alert can be generated that will give information
            : about the problem and help track its resolution. Alerts can be configured
            : to user preference. The same tools can be run on existing log files.

Básicamente, setroubleshoot-server es una herramienta que diagnostica los problemas de SELinux a partir de las alertas AVC generadas en el log de audit y las parsea para volcar información legible en /var/log/messages que posteriormente, a través de un identificador único podemos consultar con sealert, ejemplo:

Contenido de /var/log/messages:

setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index.html. For complete SELinux messages. run sealert -l 66719ae7-cd7f-474e-a7c5-b70e0739ab91

Ejecución de sealert:

# sealert -l 66719ae7-cd7f-474e-a7c5-b70e0739ab91
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index2.html.

*****  Plugin restorecon (99.5 confidence) suggests  *************************

If you want to fix the label. 
/var/www/html/index2.html default label should be httpd_sys_content_t.
Then you can run restorecon.
Do
# /sbin/restorecon -v /var/www/html/index2.html

*****  Plugin catchall (1.49 confidence) suggests  ***************************

If you believe that httpd should be allowed getattr access on the index2.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

Additional Information:
Source Context                unconfined_u:system_r:httpd_t:s0
Target Context                system_u:object_r:admin_home_t:s0
Target Objects                /var/www/html/index2.html [ file ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          
Host                          lab1
....
....
....
....

Bien, la idea de esta entrada es enviar estas alertas por correo electrónico, de modo que si somos realmente paranoicos podamos estar al tanto de todas las alertas de tipo AVC que tenemos en un sistema. Para ello existe una sección [email] en el fichero de configuración de setroubleshoot: /etc/setroubleshoot/setroubleshoot.conf:

[email]
# recipients_filepath: Path name of file with email recipients. One address
# per line, optionally followed by enable flag. Comment character is #.
recipients_filepath = /var/lib/setroubleshoot/email_alert_recipients

# smtp_port: The SMTP server port
smtp_port = 25

# smtp_host: The SMTP server address
smtp_host = localhost

# from_address: The From: email header
from_address = SELinux_Troubleshoot

# subject: The Subject: email header
subject = SELinux AVC Alert

Simplemente indicamos los parámetros del servidor SMTP que queramos usar y posteriormente, una en cada línea las direcciones de correo electrónico a las que enviar las alertas en el fichero /var/lib/setroubleshoot/email_alert_recipients.

Una vez configurado todo e instalado setroubleshoot-server reiniciamos auditd para releer los cambios:

# /etc/init.d/auditd restart
Stopping auditd:                                           [  OK  ]
Starting auditd:                                           [  OK  ]

También tenemos que reiniciar (o iniciar) messagebus ya que sino recibiremos estos mensajes en el log messages:

Dec  4 09:44:54 lab1 sedispatch: Connection Error (Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory): AVC Will be dropped
Dec  4 09:44:54 lab1 sedispatch: Connection Error (Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory): AVC Will be dropped
# /etc/init.d/messagebus restart
Stopping system message bus:                               [FAILED]
Starting system message bus:                               [  OK  ]

Si forzamos entonces una alerta de SELinux recibiremos un correo con toda la información, ejemplo:

Received: from [127.0.0.1] (localhost [IPv6:::1])
	by lab1.localdomain (Postfix) with ESMTP id BBAA148D9
	for ; Tue,  4 Dec 2012 10:04:13 +0100 (CET)
Content-Type: multipart/alternative; boundary="===============0185241993=="
MIME-Version: 1.0
Subject: [SELinux AVC Alert] SELinux is preventing /usr/sbin/httpd from
	getattr access on the file /var/www/html/index2.html.
From: SELinux_Troubleshoot@lab1.localdomain
To: root@lab1.localdomain
Date: Tue, 04 Dec 2012 09:04:12 -0000
Message-Id: 

--===============0185241993==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index2.html.

*****  Plugin restorecon (99.5 confidence) suggests  *************************

If you want to fix the label. 
/var/www/html/index2.html default label should be httpd_sys_content_t.
Then you can run restorecon.
Do
# /sbin/restorecon -v /var/www/html/index2.html

*****  Plugin catchall (1.49 confidence) suggests  ***************************

If you believe that httpd should be allowed getattr access on the index2.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

Additional Information:
Source Context                unconfined_u:system_r:httpd_t:s0
Target Context                system_u:object_r:admin_home_t:s0
Target Objects                /var/www/html/index2.html [ file ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          
Host                          lab1
Source RPM Packages           
Target RPM Packages           
Policy RPM                    
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     lab1
Platform                      Linux lab1 2.6.32-220.el6.i686 #1 SMP Tue Dec 6
                              16:15:40 GMT 2011 i686 i686
Alert Count                   11
First Seen                    Tue Dec  4 09:49:49 2012
Last Seen                     Tue Dec  4 10:03:53 2012
Local ID                      66719ae7-cd7f-474e-a7c5-b70e0739ab91

Raw Audit Messages
type=AVC msg=audit(1354611833.269:24): avc:  denied  { getattr } for  pid=1429 comm="httpd" path="/var/www/html/index2.html" dev=dm-0 ino=42 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:admin_home_t:s0 tclass=file

type=SYSCALL msg=audit(1354611833.269:24): arch=i386 syscall=stat64 success=no exit=EACCES a0=16f78d8 a1=bfc9d120 a2=4c6ff4 a3=8170 items=0 ppid=1425 pid=1429 auid=0 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm=httpd exe=/usr/sbin/httpd subj=unconfined_u:system_r:httpd_t:s0 key=(null)

Hash: httpd,httpd_t,admin_home_t,file,getattr

audit2allow

#============= httpd_t ==============
allow httpd_t admin_home_t:file getattr;

audit2allow -R

#============= httpd_t ==============
allow httpd_t admin_home_t:file getattr;

--===============0185241993==--

Redirigir tráfico http a https en Sun Java System Web Server

Vamos a ver como forzar la redirección de tráfico HTTP a HTTPS para una instancia web de Sun Java System Web Server o si fuera necesario únicamente para una sección concreta del website. Por seguridad es muy probable que queramos evitar que a un sitio web o partes del mismo se pueda acceder sin protocolo seguro (ssl-https).

En el fichero de configuración obj.conf ó foo-obj.conf de la instancia podemos establecer estas configuraciones de redirección. Para ello utilizaremos la etiqueta Client dentro del objeto Default.

En el siguiente ejemplo forzamos el uso de https para la url (urlhost) test.rm-rf.es y para todo el website (from=”/” y from=”/*”. Lo que nos indica que el origen del tráfico tiene que ser siempre http es el atributo security=”false”, es decir, todo el tráfico que no sea https y que cumpla lo que indican los NameTrans ejecutará la redirección:

<Object name="default">
<Client match="all" security="false" urlhost="test.rm-rf.es">
NameTrans fn="redirect" from="/" url-prefix="https://test.rm-rf.es/"
NameTrans fn="redirect" from="/*" url-prefix="https://test.rm-rf.es/"
</Client>
....
....
....
</Object>

Si quisiéramos redirigir únicamente una ruta concreta en lugar de especificar ” podemos indicar la ruta:

<Object name="default">
<Client match="all" security="false" urlhost="test.rm-rf.es">
NameTrans fn="redirect" from="/prueba/" url-prefix="https://test.rm-rf.es/"
</Client>
....
....
....
</Object>

Una vez realizados los cambios reiniciamos la instancia para hacerlos efectivos:

# ./stopserv; ./startserv

En la documentación oficial encontraréis más información sobre cada una de las directivas y atributos (NameTrans, fn, urlhost, security…)

Generar un certificado SSL con genkey (Red Hat Keypair Generation)

Hoy vamos a ver una alternativa a la generación de certificados SSL con OpenSSL. Genkey (Red Hat Keypair Generation) es un comando disponible como parte del paquete crypto-utils:

# yum whatprovides */genkey
Loaded plugins: fastestmirror, presto
Loading mirror speeds from cached hostfile
....
....

crypto-utils-2.4.1-24.2.el6.i686 : SSL certificate and key management utilities
Repo        : base
Matched from:
Filename    : /usr/bin/genkey

Aprovechamos entonces para instalarlo:

# yum install crypto-utils

Echando un vistazo a la ayuda podemos ver las opciones del comando:

# genkey 
Usage: genkey [options] servername
    --test   Test mode, faster seeding, overwrite existing key
    --genreq Generate a Certificate Signing Request (CSR)
    --makeca Generate a self-signed certificate for a CA
    --days   Days until expiry of self-signed certificate (default 30)
    --renew  CSR is for cert renewal, reusing existing key pair, openssl certs only
    --cacert Renewal is for a CA certificate, needed for openssl certs only
    --nss    Use the nss database for keys and certificates
    --gdb    For package maintainers, to trace into the nss utilities

¡Qué motivo podríamos tener para utilizar genkey en lugar de openssl? Corregidme si hay algún otro más, pero en principio lo que yo veo es que no tenemos que acordarnos de los comandos de openssl ya que genkey es un asistente en modo text/gráfico desde línea de comandos que nos guía con todos los pasos.

Si quisieramos generar un certificado self-signed para ssl.rm-rf.es seguiríamos estos pasos:

# genkey ssl.rm-rf.es

Comienza el asistente, que ya nos indica donde van a guardarse los ficheros resultantes (llaves privadas, certificados, certificate requests, CA requests, etc.)

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 1

Indicamos el tamaño de la llave, a mayor tamaño en bits, mayor seguridad, también costará más tiempo generarla:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 2

Esperamos a la generación de los bits aleatorios:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 3

Y la generación de datos aleatorios. Se recomienda mover el ratón o escribir en la consola del servidor/máquina para acelerar el proceso:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 4

Si quisiéramos enviar una petición de CSR a una entidad certificadora autoritativa (CA) este sería el momento:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 5

Para mayor seguridad podemos encriptar la llave privada del certificado. La frase de paso (passphrase) que indiquemos tendrá que ser introducida cada vez que arranquemos el servicio web seguro.

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 6

Por último introducimos los datos de nuestro certificado:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 7

Una vez aceptado podremos ver en la línea de comandos la ejecución del proceso por genkey:

/usr/bin/keyutil -c makecert -g 1024 -s "CN=ssl.rm-rf.es, OU=IT, O=Rm-RF, L=Zaragoza, ST=Zaragoza, C=ES" -v 1 -a -z /etc/pki/tls/.rand.2492 -o /etc/pki/tls/certs/ssl.rm-rf.es.crt -k /etc/pki/tls/private/ssl.rm-rf.es.key
cmdstr: makecert

cmd_CreateNewCert
command:  makecert
keysize = 1024 bits
subject = CN=ssl.rm-rf.es, OU=IT, O=Rm-RF, L=Zaragoza, ST=Zaragoza, C=ES
valid for 1 months
random seed from /etc/pki/tls/.rand.2492
output will be written to /etc/pki/tls/certs/ssl.rm-rf.es.crt
output key written to /etc/pki/tls/private/ssl.rm-rf.es.key

Generating key. This may take a few moments...

Made a key
Opened tmprequest for writing
(null) Copying the cert pointer
Created a certificate
Wrote 882 bytes of encoded data to /etc/pki/tls/private/ssl.rm-rf.es.key 
Wrote the key to:
/etc/pki/tls/private/ssl.rm-rf.es.key

Y nuestra private key y certificado ya están disponibles para su uso.

Comprobar la integridad de las descargas de archivos con md5sum, sha256sum…

Cuando descargamos archivos a través de Internet, por ejemplo ISOs de sistemas operativos, o paquetes RPM, DEB, etc, vienen acompañados de un “código” (hash MD5 del archivo) que sirve para verificar, una vez descargado el archivo, que no ha sido alterado por terceras partes y que podemos confiar en que es lo que realmente buscamos.

Por ejemplo, si accedemos a uno de los mirrors de CentOS vermos que además de las ISOs podemos descargar sus correspondientes checksum MD5, PGP, SHA…(*.asc y *.txt):

0_README.txt 06-Jul-2012 06:01 2.0K
CentOS-6.3-x86_64-LiveCD.iso 07-Jul-2012 13:26 692M
CentOS-6.3-x86_64-LiveCD.torrent 09-Jul-2012 14:03 217K
CentOS-6.3-x86_64-LiveDVD.iso 06-Jul-2012 09:07 1.6G
CentOS-6.3-x86_64-LiveDVD.torrent 09-Jul-2012 13:50 263K
CentOS-6.3-x86_64-bin-DVD1.iso 06-Jul-2012 06:20 4.0G
CentOS-6.3-x86_64-bin-DVD1to2.torrent 09-Jul-2012 14:15 217K
CentOS-6.3-x86_64-bin-DVD2.iso 06-Jul-2012 06:20 1.4G
CentOS-6.3-x86_64-minimal-EFI.iso 21-Aug-2012 14:30 364M
CentOS-6.3-x86_64-minimal.iso 06-Jul-2012 06:23 330M
CentOS-6.3-x86_64-netinstall-EFI.iso 18-Sep-2012 05:39 234M
CentOS-6.3-x86_64-netinstall.iso 06-Jul-2012 06:14 200M
README.txt 06-Jul-2012 06:01 2.0K
md5sum.txt 18-Sep-2012 17:31 734 md5sum.txt.asc 18-Sep-2012 17:31 1.6K
sha1sum.txt 18-Sep-2012 17:31 822
sha1sum.txt.asc 18-Sep-2012 17:31 1.7K
sha256sum.txt 18-Sep-2012 17:31 1.1K
sha256sum.txt.asc 18-Sep-2012 17:31 1.9K

En el caso de los checksum MD5 el fichero tiene el siguiente contenido:

a991defc0a602d04f064c43290df0131  CentOS-6.3-x86_64-bin-DVD1.iso
410c1c5188e6076d62d6107153738a15  CentOS-6.3-x86_64-bin-DVD2.iso
087713752fa88c03a5e8471c661ad1a2  CentOS-6.3-x86_64-minimal.iso
690138908de516b6e5d7d180d085c3f3  CentOS-6.3-x86_64-netinstall.iso
9953ff1cc2ef31da89a0e1f993ee6335  CentOS-6.3-x86_64-LiveCD.iso
0d28b5f9c9f562bd3a17c68ef05b3998  CentOS-6.3-x86_64-LiveDVD.iso
21157a19ec6a32b4fd71f0e45b9aa951  CentOS-6.3-x86_64-bin-DVD1to2.torrent
9015d02b4e22efd547a6bd8b19bce0ec  CentOS-6.3-x86_64-LiveCD.torrent
3b9c1c463cfe8983c0835f46f2db39db  CentOS-6.3-x86_64-LiveDVD.torrent
4dd1ff9a521823e033dde6b152196de7  CentOS-6.3-x86_64-minimal-EFI.iso
c750ba06d83a38494dbf100bf33014d4  CentOS-6.3-x86_64-netinstall-EFI.iso

Cada línea hace referencia al checksum de cada descarga. Una vez descargado, en GNU/Linux debemos comparar ese hash con el del fichero que hemos descargado. Para ello utilizamos el comando “md5sum“:

~$ md5sum CentOS-6.3-x86_64-netinstall.iso
690138908de516b6e5d7d180d085c3f3  CentOS-6.3-x86_64-netinstall.iso

En este caso hemos visto que efectivamente coincide, por lo que es fiable hacer uso del archivo. En el caso de que el hash fuera distinto detectaríamos que el archivo ha sido comprometido y no es fiable su descarga o utilización:

~$ md5sum CentOS-6.3-x86_64-netinstall.iso
d41d8cd98f00b204e9800998ecf8427e  CentOS-6.3-x86_64-netinstall.iso

Podéis hacer lo mismo con los hash sha y los comandos sha1sum, sha256dum, etc:

~$ sha[TAB]
sha1pass sha224sum sha384sum shasum
sha1sum sha256sum sha512sum

! bad user (foo) en los cron jobs de Solaris

Suponiendo que tenemos un usuario en Solaris que debería estar ejecutando los cron jobs establecidos en su crontab pero no está siendo así, lo primero que debemos hacer es revisar los logs de cron para encontrar el origen del problema. Podemos consultarlos en /var/cron/log.

Si lo que vemos es entradas similares a la siguiente en el log…

! bad user (foo) Tue Sep 12 15:30:10 2012

… puede significar que el usuario foo no tiene privilegios para la ejecución de crontabs, habiendo sido denegado a través del fichero /etc/cron.deny (ver “Cron linux: autorizar o denegar su uso a usuarios“):

foo:~$ crontab -l foo
You (foo) are not allowed to use this program (crontab)
See crontab(1) for more information

Pero también es muy probable que el usuario se encuentre bloqueado a nivel de sistema operativo, ya sea porque su password ha expirado, bloqueo de cuenta por excesivos logins incorrectos, etc. Puede haber muchas causas. En este caso veremos que la cuenta está marcada como el prefijo \*LK\* en el password (locked) de su entrada en el fichero /etc/shadow:

foo:\*LK\*asd73jasd80kj:::::::

También podríamos averiguarlo sin mirar el fichero shadow, con el comando passwd -s:

# passwd -s foo
foo    LK

Para desbloquearla utilizamos el parámetro -u (unlock) de passwd:

# passwd -u foo
passwd: password information changed for foo
# passwd -s foo
foo       PS

Y ya podemos ejecutar crons. El prefijo LK ha desaparecido del fichero /etc/shadow:

foo:asd73jasd80kj:::::::