¿Como listar el tamaño de los directorios en linux?

En servidores linux es muy común quedarse sin espacio y volverse loco intentando buscar el fichero o directorio que nos esta ocupando el espacio.

Para ver cual es el directorio que nos esta haciendo la puñeta vamos a utilizar el comando du (disk usage).

Para el ejemplo usaremos el directorio /var/www/html, donde hay ubicados varios proyectos web.

Si utilizamos el comando du -h /var/www/html (añadimos -h para verlo en formato humano) nos encontramos con el problema de que nos muestra el tamaños de los directorios, subdirectorios y todo lo que se encuentra y eso no es lo que queremos.

du -h /var/www/html

20K     ./joomla_prueba/plugins/user/joomla
8.0K    ./joomla_prueba/plugins/user/profile/profiles
12K     ./joomla_prueba/plugins/user/profile/field
52K     ./joomla_prueba/plugins/user/profile
16K     ./joomla_prueba/plugins/user/contactcreator
124K    ./joomla_prueba/plugins/user

Para resolver esto añadimos la opción –max-depth=1 que nos limita la busqueda al primer directorio.

du -h --max-depth=1 /var/www/html

250M    ./pepino
154M    ./web_equipo
140M    ./tacita
195M    ./drbones
100M    ./alienta
164M    ./vibora
530M    ./bosque
220M    ./valiente
59M     ./drupal
289M    ./fundacionlobos


Esto comando ya nos gusta mas, ya que nos muestra el tamaño de lo directorios.

Como ultima opción lo podemos ordenar añadiendo un sort -n (-n ordena por numero), en el caso de ser un listado muy extenso.

du -h --max-depth=1 /var/www/html | sort -n

59M     ./drupal
100M    ./alienta
140M    ./tacita
154M    ./web_equipo
164M    ./vibora
195M    ./drbones
220M    ./valiente
250M    ./pepino
289M    ./fundacionlobos
530M    ./bosque

Como quitar el error “Null message body; hope that’s ok”

Tratandose de servidores en alguno momento os puede haerb llegado un mail de tipo “Null message body; hope that’s ok”, este mail lo envia el propio servidor a la cuenta de correo que tenga configurada en el fichero /root/.forward.

Despues de darle unas vueltas, di con el motivo de porque de porque llegaba este mensaje.

Esto sucede cuando se adjunta un fichero sin contenido en el envio de correos, sea por script o tarea progamada.

Ejemplo, un tipo de envio donde podria suceder:

echo "Prueba" | mail -s "Prueba" mail@mail.es < /tmp/fichero_a_enviar.txt

Si este fichero “/tmp/fichero_a_enviar.txt” esta vacio, nos llegara ese tipo de mensaje.

Podemos solucionarlo validandolo el contenido del mensaje con un condicional de este tipo:

if [ -s /tmp/fichero_a_enviar.txt ]
  then
    echo "Prueba" | mail -s "Prueba" mail@mail.es < /tmp/fichero_a_enviar.txt
fi

Enviar correo electronico con fichero adjunto desde un servidor linux

Hoy voy a explicar como enviar un correo electronico desde un servidor linux, para ello vamos a utilizar el comando mail.

Si no lo tenemos instalado, lo podemos instalar en debian/ubuntu con el comando:

apt-get install mailutils

y en centos/red-hat con el comando:

yum install mailx

El comando para enviar un correo es muy sencillo, con el comando mail enviariamos el mensaje “prueba” en el cuerpo (echo “Prueba”) y en el asunto del mail (-s “Prueba”).

echo "Prueba" | mail -s "Prueba" destino@mail.es

Si queremos adjuntar un fichero o haremos añadiendo el parametro -a

echo "Prueba" | mail -s "Prueba" -a fichero_a_enviar.txt destino@mail.es 

Si quremos enviar a mas de un destinatario bastaria con añadirlo entrecomillado “destino@mail.es destino2@mail.es”.

echo "Prueba" | mail -s "Prueba" -a fichero_a_enviar.txt "destino@mail.es destino2@mail.es"

Y por ultimo si quisieramos elegir el remitente del envio lo haremos con el parametro -r

echo "Prueba" | mail -s "Prueba" -a fichero_a_enviar.txt -r remitente@mail.es "destino@mail.es destino2@mail.es"

Con todas estas opciones podemos enviar los mails de una manera muy sencilla a la hora de programar las tareas que consideremos oportunas.

Redirección 301 de un dominio a otro en apache usando .htacess

En cientos de ocasiones me han pedido realizar una redirección de un dominio a otro y nunca recuerdo el comando a utilizar, ya que no soy muy bueno con las expresiones regulares.

Por eso voy a crear esta pequeña entrada a modo de recordatorio.

Bastaria con intruducir esta linea en el fichero .htacess de la web o en el fichero de configuración del apache (apache.conf, httpd.con ,etc)

Asegurandonos previamente de que el apache tiene instalado el modulo mod_rewrite

RewriteEngine On
RewriteRule ^(.*)$ https://nueva-url.es/ [R=301]

Replicación de base de datos maestro – maestro en mysql

La replicación de bases de datos en mysql, puede parecer una tarea sencilla, al venir todo explicado en el manual de mysql https://dev.mysql.com/doc/refman/8.0/en/replication-howto.html , pero leyendo foros y tutoriales es una tarea que da bastantes quebraderos de cabeza si no se realiza correctamente.

Por ese motivo después de varios intentos (y fallos), voy a explicar de una manera sencilla como realizar una replicación maestromaestro de una bbdd en mysql.

Para la tarea voy a utilizar dos servidores mysql con estas ips:

Server 1 – 192.168.0.2: 192.168.0.2

Server 2 – 192.168.0.3: 192.168.0.3

Vamos a simular el caso real de tener que replicar una bbdd que ya esta en producción, y lo que haremos sera importar la bbdd del server1 – 192.168.0.2 y exportarla en el server2 – 192.168.0.3.

Desde Server 1 – 192.168.0.2 importamos:

mysqldump -u root -p --databases BBDD_A_REPLICAR > dump.sql

Desde server2 – 192.168.0.3 nos logueamos creamos la bbdd y la exportamos:

mysqldump -u root -p 
create database BBDD_A_REPLICAR;

mysql -u root -p BBDD_A_REPLICAR < dump.sql

Ahora lo que realizaremos editar el fichero de configuración de mysql para que permita la replicación, con las siguientes variables:

server-id= los mysql tiene que tener id diferentes
master-host= ip del servidor opuesto
master-user=usuario del servidor opuesto
master-password=contraseña del del servidor opuesto
master-port= puerto del servidor opuesto
log-bin log binario de donde se leeran las consultas a replicar
binlog-do-db= base de datos que queremos replicar
replicate-do-db= ase de datos que queremos replicar
auto-increment-increment = 2 tenemos que poner el autoincrement a 2 para que cada mysql puede insertar
auto-increment-offset = en un mysql ponemos 1 y en otro 2 para que inserten id pares y el otro impares

En el Servidor 1 – 192.168.0.2 añadimos lo siguiente:

vi my.conf 

server-id=1
master-host=192.168.0.3
master-user=replicator
master-password=RepliPassword
master-port=3306
log-bin
binlog-do-db=BBDD_A_REPLICAR
replicate-do-db=BBDD_A_REPLICAR
auto-increment-increment = 2
auto-increment-offset = 1

En el Servidor 2 – 192.168.0.3 añadimos lo siguiente:

vi my.conf 

server-id=2
master-host=192.168.0.2
master-user=replicator
master-password=RepliPassword
master-port=3306
log-bin
binlog-do-db=BBDD_A_REPLICAR
replicate-do-db=BBDD_A_REPLICAR
auto-increment-increment = 2
auto-increment-offset = 1

Reinciamos los servicios mysql para que cojan los cambios.

Lo siguiente es crear en cada servidor el usuario que tendra acceso para replicar desde el servidor opuesto:

En el Servidor 1 – 192.168.0.2, creamos usuario para acceder desde Server 2 – 192.168.0.3

grant replication slave, replication client on *.* to replicator@192.168.0.3 identified by "RepliPassword";

En el Servidor 2 – 192.168.0.3, creamos usuario para acceder desde Server 1 – 192.168.0.2

grant replication slave, replication client on *.* to replicator@192.168.0.2 identified by "RepliPassword";

Ahora solo nos faltaría realizar el ultimo paso y es comunicar a cada bbdd desde que posición del mysqld-bin n-log debe de sincronizar.

Nos conectamos a server1 – 192.168.0.2 y realizamos esta consulta:

SHOW MASTER STATUS;
+-----------------------+----------+-----------------------------+--------------+
| File                          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------------+----------+-----------------------------+--------------+
| mysqld-bin.000006 |     1901 | BBDD_A_REPLICAR  |                     |
+-----------------------+----------+-----------------------------+--------------+

Ahora nos conectamos al server2 – 192.168.0.3 y lo indicamos que replico desde los datos obtenidos antes:

stop slave;

CHANGE MASTER TO master_host='192.168.0.2', master_port=3306, master_user='replicator', master_password='RepliPassword', master_log_file='mysqld-bin.000006', master_log_pos=1901;

start slave;

Y realizamos estos dos pasos en el sentido opuesto:

Nos conectamos a server2 – 192.168.0.3 y realizamos esta consulta:

SHOW MASTER STATUS;
+-----------------------+----------+-----------------------------+--------------+
| File                          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------------+----------+-----------------------------+--------------+
| mysqld-bin.000004 |       106 | BBDD_A_REPLICAR  |                     |
+-----------------------+----------+-----------------------------+--------------+

Ahora nos conectamos al server1 – 192.168.0.2 y lo indicamos que replico desde los datos obtenidos antes:

stop slave;

CHANGE MASTER TO master_host='192.168.0.3', master_port=3306, master_user='replicator', master_password='RepliPassword', master_log_file='mysqld-bin.000004', master_log_pos=106;

start slave;

Después de estos pasos reiniciamos los mysql y ya deberia de estar replicando, para comprobarlo entramos en la consola mysql y realizamos esta consulta:

show slave status \G;

Y comprobamos que Slave_IO_Running y Slave_SQL_Running este en “yes”.

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Redirección de http a https en apache.

En los albores de internet, podríamos decir que todo era mas “seguro” y existían muchos menos ataques malintencionados que ahora, con lo que todas las webs funcionaban bajo el protocolo http.

Con el tiempo se detecto que ese protocolo era inseguro ya que el trafico viajaba sin cifrar, con lo que se creo el protocolo seguro “https”, con lo que si queremos que nuestra web funcione siempre en con el protocolos seguro debemos de redirigir todo el trafico http a https.

A continuación paso a explicar como hacerlo el servidor web apache.

Si lo hacemos en un entorno ubuntu/debian los pasos de instalación serian estos:

#Instalamos apache2 
apt-get install apache2

#Habilitamos el módulo SSL y  rewrite
a2enmod ssl
a2enmod rewrite 

Y en centos estos:

#Instalar apache2 
yum install http

# Instalamos el módulo SSL y openssl
yum install mod_ssl openssl

#Añadimos modulo en fichero configuracion
vi /etc/httpd/conf/httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so

A continuación en el fichero de configuración de apache redirigimos el trafico.

#debian/ubuntu
/etc/apache2/sites-enabled/000-default.conf
#centos
vim /etc/httpd/conf.d/000-vhost.conf

<VirtualHost *:80>
        RewriteEngine on
        ReWriteCond %{SERVER_PORT} !^443$
        RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</VirtualHost>

Con esta configuración forzaremos que todo trafico http vaya al puerto https.

Crear servicio para jetty en centos 7

Con la llegada de centos 7 se termino con el sistema clasico de servicios utilizando init.d y se cambio por servicios configurables con systemd

Voy a explicar a crear un servicio para un instalación de jetty desde codigo fuente como vimos en las entradas instalar-servidor-jetty-en-linux-desde-codigo-fuente y habilitar-https-en-jetty-con-certificado-autofirmado

Crearemos un fichero en la ruta /etc/systemd/system/jetty.service donde introduciremos como arrancar y parar el servicio.

vi /etc/systemd/system/jetty.service

Description=Jetty Web Application Server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/jetty/jetty.pid
ExecStart=/usr/local/jetty-distribution-9.4.24.v20191120/bin/jetty.sh start
ExecStop=/usr/local/jetty-distribution-9.4.24.v20191120/bin/jetty.sh stop
User=root

[Install]
WantedBy=multi-user.target

Una vez guardado el fichero lo que haremos sera recargar los demonios, arrancar el jetty y establecer el servicio y de esta manera ya tendremos el jetty arancada en cada encendido del servidor.

systemctl daemon-reload
systemctl start jetty.service
systemctl enable jetty

Habilitar https en jetty con certificado autofirmado

En la entrada instalar-servidor-jetty-en-linux-desde-codigo-fuente vimos como instalar jetty desde codigo fuente, hoy voy a explicar como habilitar el protocolo https con un certificado autofirmado.

Creamos y entramos en el directorio donde generaremos el certificado.

mkdir /usr/local/jetty-distribution-9.4.24.v20191120/ssl 
cd /usr/local/jetty-distribution-9.4.24.v20191120/ssl

Generamos la calve privada con OpenSSL con la contraseña “jetty9” (se puede utilizar la que se desee).

openssl genrsa -aes128 -out jetty.key

Generamos un certificado para la clave privada en el archivo jetty.crt (utilizando la misma contraseña y los valores que queramos).

 openssl req -new -x509 -newkey rsa:2048 -sha256 -key jetty.key -out jetty.crt

Creamos un llavero con las calves en el formato PKCS12:

 openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12

Ahora configuramos el fichero ssl.ini con las  variables del puerto, llavero y contraseñas para que jetty utilice nuestro certificado:

vim /usr/local/jetty-distribution-9.4.24.v20191120/start.d/ssl.ini
jetty.ssl.port=443
jetty.sslContext.keyStorePath=ssl/jetty.pkcs12
jetty.sslContext.keyStorePassword=jetty9
jetty.sslContext.keyManagerPassword=jetty9

Y ya podemos arrancar el jetty y verl el certificado https  en funcionamiento.

/usr/local/jetty-distribution-9.4.24.v20191120/bin/jetty.sh start
Certificado autofirmado en jetty9

En la siguiente entrada explico como crear un servicio en el arranque para centos 7 crear-servicio-para-jetty-en-centos-7

Instalar servidor jetty en linux desde código fuente

En muchas ocasiones queremos utilizar servidores ligeros y fáciles de administrar, pues para servir aplicaciones en java uno de los mejores es jetty.

Voy a explicar como ponerlos funcionamiento desde cualquier distribución de Linux (centos, red hat, Ubuntu, debian …)

Para poner en marcha el servidor de aplicaciones jetty necesitamos tener el Java Development Kit para (jdk), para servir aplicaciones hechas en java.

Para ello vamos a utilizar las versiones libres del jdk y lo descargaremos desde aquí: https://jdk.java.net/

Para el ejemplo voy a utilizar la versión: openjdk-13.0.1

Nos dirigimos al directorio /usr/local descargamos y descomprimimos:

cd /usr/local/
wget https://download.java.net/java/GA/jdk13.0.1/cec27d702aa74d5a8630c65ae61e4305/9/GPL/openjdk-13.0.1_linux-x64_bin.tar.gztar 
tar –xjvf openjdk-13.0.1_linux-x64_bin.tar.gz

Comprobamos que funciona.

/usr/local/jdk-13.0.1/bin/java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing---------------------------
jetty 9.4.12 

Ahora que ya tenemos el jdk funcionando lo siguiente en descargarnos y descomprimir la versión de jetty que queramos:

Para el ejemplo voy a utilizar la versión: jetty-distribution-9.4.24

wget https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.4.24.v20191120/jetty-distribution-9.4.24.v20191120.tar.gz
tar -xzvf jetty-distribution-9.4.24.v20191120.tar.gz

Ahora lo siguiente que haremos es añadir la ruta del jdk para que la utilice el jetty al arrancar.

vi /usr/local/jetty-distribution-9.4.24.v20191120/bin/jetty.sh

JAVA="/usr/local/jdk-13.0.1/bin/java"

Lo siguiente que haremos es configurar el jetty para que sirva por el puerto 80

vi /usr/local/jetty-distribution-9.4.24.v20191120/start.ini

jetty.http.port=80

Y ya podemos arrancar el jetty y verlo en funcionamiento, arrancando con el siguiente comando:

/usr/local/jetty-distribution-9.4.24.v20191120/bin/jetty.sh start

jetty 9 en funcionamiento

En las siguientes entradas explico como utilizar el protocolo https con un certificado autofirmado habilitar-https-en-jetty-con-certificado-autofirmado y como crear un servicio en el arranque para centos 7 crear-servicio-para-jetty-en-centos-7

Buscar ip y hora de acceso en el log de apache con cat, grep y cut

Dentro del mundo de los sistemas, es muy común que nos pidan que quieren saber a qué hora y que ip accedió a determinada página web.

Voy a explicarlo como hacerlo de una manera, muy sencilla concatenando los comandos cat , grep y cut.

Con cat listaremos el fichero de acceso

cat /var/log/apache/access_log

Lo uniremos con el comando grep para buscar los acceso a index.php

grep – 'index.php'

Y por último filtraremos las columnas que necesitamos con cut, seleccionando las filas de la ip y la hora (-f1,4,5) y el delimitador a usar (espacio en blanco-d’ ‘)

cut -f1,4,5 -d' '

La juntamos todo con pipes y lo pintamos en un fichero de texto.

cat /var/log/apache/access_log | grep -i 'php' | cut -f1,4,5 -d' ' > accesos.txt

Con esta manera sencilla podemos  controlar los acessos por ip y fecha en las paginas web