Dos años sin pasar por aquí (que no estaba muerto, que estaba de parranda)

Ahora si. No se si muerto, pero al menos en coma profundo. Dos años sin pasar por aquí (a escribir, se entiende, que el mantenimiento es otra cosa…) es mucho tiempo. Los que anunciaban la muerte de los blogs por fin han acertado. En el fondo son como mi madre: a fuerza de decir lo mismo una y otra vez al final aciertan. Era cuestión de tiempo. Si nos ponemos todos a decir que las tortillas de patatas han muerto seguro que llega el día en que podremos decir que hemos acertado. Bueno, a lo mejor me estoy pasando…

El problema, al menos en mi caso, es que por primera vez en los 25 años que llevo desde que estrené presencia en Internet no encuentro motivación alguna para pasar por aquí. He publicado aquí (o en sitios anteriores a este) por experimentar, por frustración laboral, por compartir cosas con otras personas, por mantener un contacto informal con los amigos… Hoy en día la última faceta está mas que satisfecha con las redes sociales y el resto son temas que ya no me preocupan o no aplican… Es lo que hay: prefiero dedicar este tiempo a otras cosas. Imagino que al resto de los viejos que se van retirando les pasará otro tanto y los jóvenes… ¿Blogs?¡Eso es de abuelos! 😀

Pero bueno, como estas cosas cuestan poquito de mantener y nunca se sabe, aquí estará esto aún por un tiempo. Quién sabe: lo mismo dentro de unos años esto se vuelve vintage y me dan ganas de resucitarlo.

Hasta entonces, cuidaos!

WordPress. El misterioso caso del cuelgue diario a las 9 de la mañana

icono de php Los blogs están muertos. Por fin. Bueno, no todos. Hay alguno que resiste hoy y siempre a la invasión de las redes sociales. A ratos me gusta pensar que este es uno de ellos… pero si soy sincero conmigo mismo ciertamente está un poco desnutrido. No le presto mucha antención, no… Hace meses, por ejemplo, que se cuelga durante aproximadamente media hora todas las mañanas y ni siquiera me he preocupado de ver que le pasa. Bueno, ya no. Ya está arreglado. Los malos hados subestiman el poder de esas tareas tediosas y desagradables que hacen que hasta te den ganas de ponerte a planchar o a limpiar los baños. Bueno, yo me he conformado con arreglar por fin este problemilla. Los baños otro día. 🙂

¿Síntomas mi querido Watson? Apenas nada: la indisponibilidad se producía por un elevado consumo de CPU y mirando con htop resulta que la responsable es mariadb (aunque en el pantallazo aparezca mysql ya sabéis que son compatibles a nivel binario).

Alguna pista mas: conéctandome a mariadb observo que lo que se están ejecutando son consultas aparentemente bastante simples sobre la tabla wp_options:

MariaDB [unlugar] show processlist;
+-------+---------+-----------+---------+---------+------+--------------+------------------------------------------------------------------------------------------------------+----------+
| Id    | User    | Host      | db      | Command | Time | State        | Info                                                                                                 | Progress |
+-------+---------+-----------+---------+---------+------+--------------+------------------------------------------------------------------------------------------------------+----------+
| 29462 | unlugar | localhost | unlugar | Query   | 1043 | Sending data | DELETE a, b FROM wp_options a, wp_options b
WHERE a.option_name LIKE '\\_transient\\_%'
AND a. |    0.000 |
| 29552 | root    | localhost | unlugar | Query   |    0 | init         | show processlist                                                                                     |    0.000 |
| 29559 | unlugar | localhost | unlugar | Query   |   40 | update       | INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('jetpack_nonce_15275779 |    0.000 |
| 29560 | unlugar | localhost | unlugar | Query   |   22 | updating     | UPDATE `wp_options` SET `option_value` = '1527578481.1030609607696533203125' WHERE `option_name` = ' |    0.000 |
| 29561 | unlugar | localhost | unlugar | Query   |    7 | updating     | UPDATE `wp_options` SET `option_value` = '1527578505', `autoload` = 'yes' WHERE `option_name` = 'jet |    0.000 |
| 29562 | unlugar | localhost | unlugar | Query   |    0 | updating     | UPDATE `wp_options` SET `option_value` = '1527578503.1177010536193847656250' WHERE `option_name` = ' |    0.000 |
+-------+---------+-----------+---------+---------+------+--------------+------------------------------------------------------------------------------------------------------+----------+

Así que le echamos un vistazo a esa tabla y resulta que tiene la friolera de más de 40.000 registros y consume cerca de 38 Megas de espacio ¿Qué tiene dentro?¿Los casos de corrupción del PP? Porque la estructura de la tabla también es bastante simplona:

MariaDB [unlugar] describe wp_options;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| option_id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| option_name  | varchar(191)        | NO   |     | NULL    |                |
| option_value | longtext            | NO   |     | NULL    |                |
| autoload     | varchar(20)         | NO   |     | yes     |                |
+--------------+---------------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

Un último dato: la exactitud en la periodicidad me escamaba también. Incluso uno de esos días de puentes con un tiempo maravilloso donde no queda ni el friki más irredento paseándose por algo donde no despachan cerveza el blog también se caía. Y a la misma hora, así que le eché un vistazo al cron del sistema y no había nada que se lanzara a esa hora. ¿Y? De repente recordé que wordpress viene con su propio planificador de tareas y que estas se pueden inspeccionar fácilmente. Por ejemplo a través del plugin WP Cron Cleaner. Bingo. Ahí la tengo: Justo a las 9.04 y todos los días hay una tarea que se llama delete_expired_transients. Y eso de «transient» ya era algo que habíamos visto por ahí arriba en la consulta que se estaba realizando en mariadb.

Tocaba googlear a ver que es eso de los transients pero ya teníamos datos suficientes para reunir en la biblioteca a todos los implicados y desvelar quien es el asesino.

Los transients, al parecer, son registros con información temporal que proviene de los plugins que tenemos instalados. ¿Sirven para algo? Pues una vez que caducan no, para nada. De hecho precisamente por eso está ahí esa tarea que elimina los caducados. ¿Qué es lo que ocurre entoces? Pues que es evidente que muy bien no funciona porque la mayoría de esos 40.000 registros son transients. Más de 35.000, de hecho. Y la búsqueda se realiza a través del campo wp_options que como vemos no está indexado. Fatal. La primera aproximación al problema pasa, pues, por crear un índice sobre esa columna:

MariaDB [unlugar] alter table wp_options add index (option_name);
Query OK, 0 rows affected (3 min 47.86 sec)
Records: 0  Duplicates: 0  Warnings: 0

Mano de santo, oigan. Al día siguiente a las 9.04 por primera vez en meses el blog no se colgó. ¿Lo dejo así?¿Con una tabla diez veces mas grande que el contenido de todo lo escrito en el blog?¿Hasta donde la dejo crecer entonces? Toca hacer otra búsqueda y por ahí me encuentro con mucha mas gente que ha tenido problemas similares y que asegura que se puede hacer tábula rasa y borrarlos todos. Así que hago un backup rápido, los elimino… y parece que todo va bien. Fantástico 🙂

¿Cómo eliminarlos? Pues a través de línea de comando es fácil:

MariaDB [unlugar] DELETE FROM `wp_options` WHERE `option_name` LIKE ('%\_transient\_%')

Puestos a buscar una solución más cómoda y permanente para no llegar de nuevo aquí dentro de 10 años encontré otro plugin (Transient Cleaner) que te permite borrarlos puntualmente y/o programar una tarea para hacer una limpieza mas efectiva que la de wordpress de forma periódica.

Y listo. O eso parece. Mañana los baños. Sin falta 🙂

Bootstrap 4. Primeros pasos

icono de php Bootstrap es una colección de elementos, plantillas y componentes HTML, CSS y Javascript para crear rápidamente páginas web con un aspecto moderno y «responsivo» (¡menudo palabro!) al tamaño de pantalla de cualquier dispositivo. Su versión 4 se liberó hace un par de meses y aporta algunos cambios significativos como, por ejemplo, la inclusión de Popper como librería javascript para «tooltips» y otros elementos emergentes y la eliminación de las tipografías Glyphicons para introducir símbolos y pictogramas.

Podemos trabajar con Bootstrap bien descargandonosla en nuestro propio servidor web, o bien usando sus librerías directamente desde los CDN que nos ofrecen. Aquí usaremos este segundo método por sus evidentes ventajas de cara a montar una primera plantilla para pruebas. Necesitamos incluir simplemente el siguiente tag en :

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />

Si vamos a usar los elementos javascript necesitamos incluir también las librerías correspondientes y, ademas, las de jquery y popper en nuestro proyecto las cuales también tienen disponible la posibilidad de enlazarlas directamente sin necesidad de descargarlas en local:

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.1/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

IMPORTANTE: los enlaces anteriores corresponden a las versiones estables más recientes en el momento de escribir esto. No suelen eliminar las versiones anteriores, pero conviene que te cerciores si llegas a este texto en un futuro lejano.

Con todo esto, la plantilla mínima de HTML para empezar a trabajar (incluyendo los enlaces correspondientes a las librerías javascript comentados) sería esta:

<!DOCTYPE html>
<html lang="es">
    <head>
    	<meta charset="utf-8" />
    	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
    	<title>Plantilla Bootstrap</title>
  	</head>
  	<body>
		<h1>Plantilla Bootstrap</h1>

    
		<!-- Javascript opcional -->
		<!-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    	     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.1/umd/popper.min.js"></script>
    	     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> -->
  	</body>
</html>

Sosa, verdad? Claro, aún no hemos empezado a trabajar… Si quieres ver algo más impactante, bootstrap dispone de plantillas con algo mas de chicha para tus diseños. Las tienes disponibles en este enlace. Si prefieres empezar desde cero, tienes disponible un montón de La documentación bastante fácil de seguir que incluye multitud de ejemplos prácticos para empezar a trabajar desde el primer minuto.

Laravel 5.6. Estructura y primeros pasos: Autenticación de usuarios

icono de php Ya yenemos Laravel 5.6 instalado en alguno de los dos entornos que hemos visto antes. ¿Qué sigue? Lo primero, entender un poquito la estructura de directorios que nos ha creado composer. Sólo lo imprescindible. El resto lo iremos viendo a medida que avanzamos.

josemaria@valeria /var/www/html/prueba $ ls -la
total 236
drwxr-xr-x 12 root www-data   4096 mar  9 19:31 .
drwxr-xr-x  3 root www-data   4096 mar  9 18:29 ..
drwxr-xrwx  6 root www-data   4096 ene  3 17:52 app
-rwxr-xrwx  1 root www-data   1686 ene  3 17:52 artisan
drwxr-xrwx  3 root www-data   4096 ene  3 17:52 bootstrap
-rw-r--rw-  1 root www-data   1413 ene  3 17:52 composer.json
-rw-r--rw-  1 root www-data 143565 mar  8 07:37 composer.lock
drwxr-xrwx  2 root www-data   4096 ene  3 17:52 config
drwxr-xrwx  5 root www-data   4096 ene  3 17:52 database
-rw-r--r--  1 root www-data    612 mar  9 19:31 .env
-rw-r--r--  1 root www-data    565 ene  3 17:52 .env.example
-rw-r--r--  1 root www-data    111 ene  3 17:52 .gitattributes
-rw-r--r--  1 root www-data    146 ene  3 17:52 .gitignore
-rw-r--rw-  1 root www-data   1125 ene  3 17:52 package.json
-rw-r--rw-  1 root www-data   1040 ene  3 17:52 phpunit.xml
drwxr-xrwx  4 root www-data   4096 ene  3 17:52 public
-rw-r--rw-  1 root www-data   3550 ene  3 17:52 readme.md
drwxr-xrwx  5 root www-data   4096 ene  3 17:52 resources
drwxr-xrwx  2 root www-data   4096 ene  3 17:52 routes
-rw-r--rw-  1 root www-data    563 ene  3 17:52 server.php
drwxrwxrwx  5 root www-data   4096 ene  3 17:52 storage
drwxr-xrwx  4 root www-data   4096 ene  3 17:52 tests
drwxr-xrwx 36 root www-data   4096 mar  8 07:38 vendor
-rw-r--rw-  1 root www-data    549 ene  3 17:52 webpack.mix.js

El directorio public ejerce de DocumentRoot. Allí encontraremos el index.php que da entrada a nuestra aplicación web así como las hojas de estilos, etc. El fichero .env que vemos aquí arriba en el directorio raiz de nuestra aplicación es el fichero de configuración principal. De hecho, puesto que vamos a empezar a trabajar con bases de datos en este momento podemos aprovechar para editar las siguientes directivas:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secreto

Importante: aunque usemos mariadb la directiva DB_CONNECTION debe de ser mysql porque Laravel no entiende otra y, a fin de cuentas, ambas son compatibles a nivel binario. Para que Laravel sea capaz de hacer uso de esa base de datos debemos de crearla. A ella y al usuario que le hemos dicho que va a usar para manejarla. Entramos en nuestro gestor (mysql o mariadb) y ejecutamos lo siguiente:

CREATE DATABASE laravel;
CREATE USER laravel@localhost IDENTIFIED BY 'secreto';
GRANT ALL ON laravel.* TO laravel@localhost;

Vamos ahora a crear nuestro sistema de autenticación. Laravel viene ya con un módulo llamado User.php que reside en el directorio app. Para generar el resto de lo que necesitamos ejecutamos lo siguiente:

php artisan make:auth
php artisan migrate

La primera línea crea el código y rutas necesario para la gestión de usuarios. En particular, creará o modificará los siguientes ficheros:

routes/web.php
resources/views/auth/login.blade.php
resources/views/auth/register.blade.php
resources/views/auth/passwords/email.blade.php
resources/views/auth/passwords/reset.blade.php

La segunda instrucción crea la estructura de tablas necesaria en la base de datos que hemos configurado previamente. Si ahora volvemos a cargar la web de nuestro aplicación veremos que en la esquina superior derecha tenemos dos nuevos enlaces correspondientes a las funcionalidades de Login y Registro:

Laravel 5.6 con la funcionalidad de login y registro

Las pantallas de registro y login por defecto son estas:

Pantalla de registro en Laravel 5.6
Pantalla de login en Laravel 5.6

Y una vez hecho login vemos que en la barra de menú se nos identifica con nuestro nombre de usuario y tenemos la posibilidad de cerrar sesión:

Logout en Laravel 5.6

Si le echamos un vistazo a «las tripas» vemos que nos ha creado dos tablas una de las cuales, la de usuarios, es la que guardará la información relativa a los registros de usuarios.
Tablas creadas por Laravel 5.6 para la autenticación de usuarios

Además, tal y como está mandado, vemos que no almacena las contraseñas en claro sino un hash de las mismas:

hash de las passwords en Laravel 5.6

La castellanización de los recursos es tan sencilla como editar alguno de los ficheros php que hemos indicado anteriormente. Por ejemplo, el fichero login.blade.php es el que contiene la ventana de login y register.blade.php la de registro. Con muy poco esfuerzo tendremos las ventanas anteriores en perfecto castellano. Pero eso ya os lo dejo a vosotros 😉

Instalando Laravel en Windows 7 con XAMPP

icono de php Hace unos minutos hemos publicado la forma de instalar Laravel en una Debian con Apache. Vamos ahora a ver como se hace en un windows 7 con xampp. Imagino que hacerlo en cualquier otra versión de windows más moderna será igual de fácil.

Partimos entonces de ese windows instalado, funcionando, y con xampp también instalado y funcional. Lo primero que tenemos que instalarnos es composer, el gestor de paquetes PHP que utiliza Laravel para crear la estructura que necesistan sus proyectos. Para ello nos descargamos el instalador para windows y ya sabéis: siguiente-siguiente-siguiente-aceptar 😀

Y ya está. Ya tenemos todo lo que necesitamos. Vamos ahora a crear la estructura para nuestra primera aplicación con Laravel. La versión del framework en el momento de escribir esto es la 5.6. Suponemos que se llamará prueba y que la instalaremos en el directorio web por defecto que usa xampp. Nos vamos a la línea de comandos y, suponiendo que trabajamos sobre el disco C:, ejecutamos lo siguiente:

cd c:\xampp\htdocs
composer create-project laravel/laravel prueba --prefer-dist

En segundo lugar tenemos que crear el virtual host necesario para esta aplicación. Xampp usa para ello el archivo httpd-vhosts.conf que reside en el directorio c:\xampp\apache\conf\extra. Editamos este archivo y añadimos lo siguiente:

<VirtualHost *:80>
  DocumentRoot "C:\xampp\htdocs\prueba\public"
  DirectoryIndex index.php
  <Directory "C:\xampp\htdocs\prueba">
        AllowOverride All
  </Directory>
  ErrorLog "logs/pruebalaravel-error.log"
  CustomLog "logs/pruebalaravel-access.log" combined
</VirtualHost>

Y listo. Reiniciamos apache y abrimos un exporador. Si escribimos http://localhost veremos la página de bienvenida de Laravel:

Laravel 5.6 en windows con Xampp

Instalando Laravel en Debian 9

icono de php Repasando el «histórico» del blog que a menudo me sirve como memoria veo que he recurrido en los últimos 12 años a dos frameworks para php: cake y codeigniter. Ahora que me toca volver a decidirme por alguno y teniendo en cuenta que tengo totalmente olvidado a ambos he preguntado por ahí y todo el mundo parece estar de acuerdo en que lo mejor del momento es Laravel. La versión actual de Laravel es la 5.6. Vamos, pues, a por el tercero.

La instalación de Laravel es bien sencilla. En esta entrada tocaremos un entorno «clásico» en este blog: una Debian sin entorno gráfico. En una entrada posterior tocaremos la instalación en un windows 7 con Xampp que en este caso me resulta también imprescindible. Vamos a ello.

Partimos de una Debian 9.3.0 (la versión estable en el momento de escribir esto) recién instalada y sin ningún tipo de personalización. Lo primero que necesitamos instalar son ciertos paquetes de utilidades y el entorno web necesario para trabajar con laravel: apache2, php y mysql-server:

apt install curl unzip git
apt install apache2 libapache2-mod-php
apt install mysql-server
apt install php-mysql php-xml php-mbstring

En segundo lugar tenemos que instalar composer, un gestor de paquetes php que nos servirá para instalar el entorno necesario para trabajar con Laravel. Así:

cd /usr/local/bin
curl -sS https://getcomposer.org/installer | php

Esto bajará un archivo llamado composer.phar y lo depositará en el directorio /usr/local/bin. Y ya hemos acabado. ¿Y he leído por ahí que alguien decía que era difícil? ¡Tendrían que haber instalado alguna red Novell en su vida! 😀

Como decía, ya tenemos todo lo que necesitamos para crear nuestra primera aplicación con Laravel. Empezamos. Nuestro primer proyecto se llamará prueba y estará en el directorio /var/www/html/prueba. Lo primero que tenemos que hacer es hacer que composer nos cree toda la estructura necesaria:

cd /var/www/html
composer.phar create-project laravel/laravel prueba --prefer-dist

Asignamos los permisos adecuados en la estructura que se ha creado:

chgrp -R www-data /var/www/html/your-project
chmod -R 775 /var/www/html/your-project/storage

Creamos un virtual host adecuado en el directorio /etc/apache2/sites-availables. En mi caso le he puesto laravel.conf y el contenido creado es este:

<VirtualHost *:80>
    DocumentRoot /var/www/html/prueba/public
    DirectoryIndex index.php
    <Directory /var/www/html/prueba>
        AllowOverride All
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Por último, deshabilitamos el virtual host que apache crea por defecto, habilitamos el nuestro, habilitamos el modulo rewrite de apache y reiniciamos el servidor web:

a2dissite 000-default.conf
a2ensite laravel.conf
a2enmod rewrite
systemctl restart apache2

Si ahora apuntamos con un navegador a la ip de nuestra máquina debian veremos la página de inicio de Laravel:

Laravel 5.6 en Debian 9.4

Chuletillas (y XXXXVIII) – Cambiar el formato de tablas de MySQL o MariaDB de Antelope a Barracuda (para instalar o actualizar Moodle)

chuletaLas últimas versiones de moodle exigen que las tablas usen InnoDB con formato Barracuda en lugar de Antelope. De hecho, en algunos casos puede que la actualización falle sólo por el hecho de no cumplir este requisito y sin que medie ningún comentario informativo acerca de cual es el origen del problema.

Para evitar este problema tenemos que añadir las siguientes líneas en el archivo my.cnf de configuración de mysql o mariadb:

innodb_large_prefix=ON
innodb_file_format=Barracuda
innodb_file_per_table=ON
innodb_file_format_check=ON
innodb_file_format_max=Barracuda

No soy un gran experto en bases de datos, mi lector habitual ya lo sabe, pero tengo entendido que la principal ventaja que aporta Barracuda es la compresión de datos. Quién quiera hablar sobre ello con propiedad puede echarle un vistazo a este texto. En cualquier caso, si quieres seguir usando moodle no tienes mas remedio que pasar por el aro. Son lentejas, ya sabes 😉

Script desatendido para eliminar ficheros antiguos de un servidor ftp

Hace ya un tiempo que dejamos por aquí el «esqueleto» de un script para realizar una conexión y transferencia desatendida a un servidor ftp. La finalidad del mismo era automatizar los backups en nuestro hosting cuando lo que nos proporcionan para ello es este medio. Auxiliar a este tenía uno que eliminaba los backups antiguos, pero nunca llegué a estar demasiado satisfecho de él. Hace poco buscando mejorarlo vi una solución maravillosamente elegante en stackoverflow. El script original es este:

#!/bin/bash
# get a list of files and dates from ftp and remove files older than ndays
ftpsite="ftp.yourserver.com"
ftpuser="loginusername"
ftppass="password"
putdir="/public_ftp/admin/logs"

ndays=7

# work out our cutoff date
MM=`date --date="$ndays days ago" +%b`
DD=`date --date="$ndays days ago" +%d`

echo removing files older than $MM $DD

# get directory listing from remote source
listing=`ftp -i -n $ftpsite <<EOMYF 
user $ftpuser $ftppass
binary
cd $putdir
ls
quit
EOMYF
`
lista=( $listing )

# loop over our files
for ((FNO=0; FNO<${#lista[@]}; FNO+=9));do
  # month (element 5), day (element 6) and filename (element 8)
  #echo Date ${lista[`expr $FNO+5`]} ${lista[`expr $FNO+6`]}          File: ${lista[`expr $FNO+8`]}

  # check the date stamp
  if [ ${lista[`expr $FNO+5`]}=$MM ];
  then
    if [[ ${lista[`expr $FNO+6`]} -lt $DD ]];
    then
      # Remove this file
      echo "Removing ${lista[`expr $FNO+8`]}"
      ftp -i -n $ftpsite <<EOMYF2 
      user $ftpuser $ftppass
      binary
      cd $putdir
      delete ${lista[`expr $FNO+8`]}
      quit
EOMYF2

    fi
  fi
done

Por comentarlo un poco y «ganarnos el pan», el script tiene tres bloques: el primero de definición de variables que tendrás que personalizar con tus datos (hasta la línea 8 incluida), el segundo en el que se realiza una conexión con el servidor y se obtiene un listado de todos los ficheros que están en el directorio que indicamos (hasta la línea 25) y por último un tercer bloque en el que se realiza el borrado propiamente dicho.

En el primer bloque la variable ndays en la línea 8 define la máxima antigüedad de los ficheros que no se eliminaran (7 días en este caso) y la variable putdir en la 6 el directorio del servidor ftp donde dejamos los archivos. Si, como yo, dejas los backups directamente en el raiz del servidor ftp puedes eliminar (o comentar) las líneas 6, 20 y 42

En el segundo bloque, la línea 14 indica la fecha límite de los ficheros que se conservaran. Todos los anteriores a esta se eliminarán. Si no quieres que aparezca en la salida puedes eliminarla o comentarla.

En el tercer bloque, si quieres hacer pruebas de que el script funciona antes de lanzarlo en modo real, puedes comentar la línea 43. Esto te mostrará en la consola los ficheros que se eliminarían pero no te los borrará realmente con lo cual podrás comprobar que el script hace lo que realmente necesitas. La línea 38 es la que te muestra el fichero que va a borrarse. Puedes eliminarla o comentarla también cuando ya no te interese. Por último, la línea 30 que aparece comentada muestra un listado de todos los ficheros del servidor ftp antes de realizar el borrado. Puedes descomentarla también para evaluar si está trabajando de forma correcta.

Problemas de postgrey y las listas grises con los servidores de correo de outlook y hotmail de Microsoft

correo Hace ya años que contamos por aquí en que consisten las listas grises a la hora de validar como bueno un correo y combatir contra el spam y enseñamos a configurarlas en un servidor con Debian y postfix. Recientemente he tenido muchos problemas con los correos que vienen de servidores de Microsoft (¡como no!) que provocaban retrasos de hasta algunos días o pérdida de correos en algunas ocasiones. Vamos a contar que es lo que ocurre y como solucionarlo.

El problema que tenemos con los servidores de correo de Microsoft es que el reintento de envío del correo que exige el sistema de listas grises no se realiza desde el mismo servidor que realiza el envío original con lo que nuestro sevidor toma el reintento como un correo diferente al original y no lo valida como correcto. La solución es fácil y seguramente estará «parcheada» en un futuro en nuestras Debian, pero por el momento tienes que solucionarla por ti mismo. Vamos a verlo.

En el directorio /etc/postgrey tenemos dos ficheros: whitelist_clients y whitelist_recipients. En ellos podemos incluir manualmente los servidores y direcciones de correo (respectivamente) que queremos validar automáticamente sin pasar por el sistema de listas grises. No obstante, hacerlo es una mala idea: en estos ficheros (sobre todo en el primero) es donde los mantenedores de Debian incluyen los servidores de correo que ya saben que dan problemas con el sistema de listas grises pero son servidores válidos. Posiblemente nuestro problema se resolverá en un futuro próximo cuando la gente de Debian incluya los servidores de Microsoft en este fichero pero mientras tanto tenemos que buscarnos una solución. Postgrey admite incluir en este mismo directorio dos nuevos ficheros con la misma funcionalidad pero donde podamos incluir nuestros propios servidores y direcciones de correo sin miedo a perder actualizaciones: whitelist_clients.local y whitelist_recipients.local.

Ahora ya sólo nos hace falta saber cuales son las direcciones de los servidores de correo de Microsoft. Afortunadamente están casi todas publicadas aquí. En algún foro he leído que es interesante añadir un par de líneas adicionales para validar los servidores de los servidores de Office 365. Al final, mi fichero whitelist_clients.local ha quedado así:

23.103.132.0/22
23.103.136.0/21
23.103.144.0/20
23.103.156.0/22
23.103.191.0/24
23.103.198.0/23
23.103.198.0/24
23.103.199.0/24
23.103.200.0/22
23.103.212.0/22
40.92.0.0/14
40.107.0.0/17
40.107.128.0/18
52.100.0.0/14
65.55.88.0/24
65.55.169.0/24
94.245.120.64/26
104.47.0.0/17
104.212.58.0/23
134.170.132.0/24
134.170.140.0/24
157.55.234.0/24
157.56.110.0/23
157.56.112.0/24
207.46.51.64/26
207.46.100.0/24
207.46.163.0/24
213.199.154.0/24
213.199.180.128/26
216.32.180.0/23
2a01:111:f400:7c00::/54
2a01:111:f403::/48
104.47.0.0/17
40.107.0.0/16
/.*outbound.protection.outlook.com$/
/outlook/

Ahora sólo queda reiniciar los daemons de postgrey y postfix para que los cambios tomen efecto y listo

Chuletillas (y XXXXVII) – Instalar un programa de debian Stretch mientras que usas debian stable (Jessie)

chuletaSi quieres instalar un determinado programa (y sus dependencias obligatorias) incluido en la próxima versión de Debian (Stretch) mientras continuas usando la versión stable (Jessie) puedes hacerlo de la siguiente forma:

En primer lugar edita tu fichero sources.list (en el directorio /etc/apt) e incluye al final las direcciones de los repositorios de Stretch pero sin eliminar ni modificar los que ya usas de Jessie. Por ejemplo así:

# Repositorios de Jessie
deb http://http.debian.net/debian/ jessie main contrib non-free
deb-src http://http.debian.net/debian/ jessie main contrib non-free
deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free

# Updates de Jessie, antes conocidos como 'volatile'
deb http://http.debian.net/debian/ jessie-updates main contrib non-free
deb-src http://http.debian.net/debian/ jessie-updates main contrib non-free

# Backports de Jessie
deb http://http.debian.net/debian jessie-backports main contrib non-free

#Repositorios de Stretch
deb http://http.debian.net/debian/ stretch main contrib non-free
deb-src http://http.debian.net/debian/ stretch main contrib non-free
deb http://security.debian.org/ stretch/updates main contrib non-free
deb-src http://security.debian.org/ stretch/updates main contrib non-free

# Updates de Stretch
deb http://http.debian.net/debian/ stretch-updates main contrib non-free
deb-src http://http.debian.net/debian/ stretch-updates main contrib non-free

A continuación creamos un fichero llamado stretch en el directorio /etc/apt/preferences.d y escribimos en el lo siguiente:

Package: *
Pin: release n=jessie
Pin-Priority: 900

Package: *
Pin: release n=stretch
Pin-Priority: 100

Con esto estamos modificando la prioridad con la que Debian actualizará nuestros paquetes. Por defecto instala siempre la versión más moderna de todas las que tenga disponibles en sus repositorios. Con este fichero le dará preferencia a cualquier paquete de jessie frente a uno de stretch aunque tenga una versión menor. Es decir, mantendremos nuestro sistema con las versiones de jessie salvo que un paquete no exista en esta y si en stretch… O se lo indiquemos manualmente durante la instalación que es lo que vamos a ver a continuación. Si quieres maś información sobre la forma de establecer preferencia para apt puedes echarle un vistazo a esta página.

Y ya lo tenemos todo listo. Ahora, tenemos que actualizar nuestros repositorios (apt update) y cuando queramos instalar un paquete directamente de stretch lo especificamos manualmente en el comando apt. Por ejemplo, si quisiéramos instalar la versión de apache de stretch lo haríamos así:

apt-get install -t stretch apache2

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información

ACEPTAR
Aviso de cookies