# Tips sobre la administración de Linux Tips recogidos a lo largo de mi vida, que al no ser mucho uso, se van olvidando. # Administración de usuarios Administrar usuarios y grupos # Cambiar el username en linux

Cambiar el username o nombre de usuario

Muchas veces nos encontramos con situaciones en las que heredamos un sistema con usuarios, cuyo nombre queremos normalizar con nuestra infraestructura.

En un sistema Linux, sin panel de control, es una operación sencilla siempre que no exista ningún proceso del usuario ejecutandose.

sudo usermod -l nuevoNombreDeUsuario antiguoNombreDeUsuario

Pero este comando solo cambiara el nombre del usuario, sin cambiar el nombre de su home.

Para cambiar el nombre del home del usuario ejecutaremos el código de abajo, después de haber ejecutado el anterior:

sudo usermod -d /home/nuevoHomeDir -m nuevoNombreDeUsuario

Explicación

Los sistemas Unix desacoplan el nombre de usuario de la identidad del usuario, por lo que es seguro cambiar el nombre del usuario sin afectar al ID. Todos los permisos, archivos, están vinculados a su identidad (uid), no a su nombre de usuario.

Para administrar todos los aspectos de la base de datos de usuarios, se utiliza la herramienta, usermod.

Tips

Algunos ficheros o programas pueden tener referencias absolutas a su antiguo directorio, por lo que se aconseja crear un enlace simbólico como forma de compatibilidad hacia atrás.

ln -s /home/nuevoNombre /home/viejoNombre

Advertencias

No usar con paneles de  hosting, como cPanel, Directadmin, Plesk, porque el desastre puede ser mayúsculo. En su lugar tratar de localizar la documentación de ellos, y leer en sus foros, pues algunas veces sus propias herramientas pueden darte un buen disgusto.

Atención especial si el sistema esta encriptado. No he probado jamas este tip en esa situación. 

Enlaces
##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como esta, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Como eliminar kernels antiguos # Introducción Algunas distribuciones suelen hacer una instalación por defecto con la particion */boot* o incluso a nosotros nos guste hacerlo asi. Pero se el tamaño suele ser exiguo y con el paso del tiempo los kernels han ido cogiendo tamaño y nos podemos quedar con el espacio justo o incluso hacer un update que del kernel que falle por no poder grabarse el archivo de arranque. Mejor dejarlo en lo justo. ## Centos ### Centos 7.X #### Listado de kernels instalados ``` [root@fail401 ~]# rpm -q kernel kernel-3.10.0-1160.11.1.el7.x86_64 kernel-3.10.0-1160.15.2.el7.x86_64 kernel-3.10.0-1160.21.1.el7.x86_64 kernel-3.10.0-1160.24.1.el7.x86_64 kernel-3.10.0-1160.25.1.el7.x86_64 ``` #### Kernel en ejecución ``` [root@fail401 ~]# uname -a Linux fail401.xxxxx.com 3.10.0-1160.15.2.el7.x86_64 #1 SMP Wed Feb 3 15:06:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux ``` ### Método con el comando package-cleanup Este comnado esta dentro dle paquete yum-utils ``` [root@fail401 ~]# package-cleanup --oldkernels --count=2 Complementos cargados:fastestmirror --> Ejecutando prueba de transacción ---> Paquete kernel.x86_64 0:3.10.0-1160.11.1.el7 debe ser eliminado ---> Paquete kernel.x86_64 0:3.10.0-1160.15.2.el7 debe ser eliminado ---> Paquete kernel.x86_64 0:3.10.0-1160.21.1.el7 debe ser eliminado --> Resolución de dependencias finalizada Dependencias resueltas ============================================================================================= Package Arquitectura Versión Repositorio Tamaño ============================================================================================= Eliminando: kernel x86_64 3.10.0-1160.11.1.el7 @updates 64 M kernel x86_64 3.10.0-1160.15.2.el7 @updates 64 M kernel x86_64 3.10.0-1160.21.1.el7 @updates 64 M Resumen de la transacción ============================================================================================= Eliminar 3 Paquetes Tamaño instalado: 193 M Está de acuerdo [s/N]:s Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Eliminando : kernel.x86_64 1/3 Eliminando : kernel.x86_64 2/3 Eliminando : kernel.x86_64 3/3 Comprobando : kernel-3.10.0-1160.15.2.el7.x86_64 1/3 Comprobando : kernel-3.10.0-1160.11.1.el7.x86_64 2/3 Comprobando : kernel-3.10.0-1160.21.1.el7.x86_64 3/3 Eliminado(s): kernel.x86_64 0:3.10.0-1160.11.1.el7 kernel.x86_64 0:3.10.0-1160.15.2.el7 kernel.x86_64 0:3.10.0-1160.21.1.el7 ¡Listo! ``` ### Versión manual Tendremos que usar el comando *rpm -e* ``` [root@fail401 ~]# rpm -e kernel-3.10.0-1160.11.1.el7.x86_64 kernel-3.1X.X0-XXXXX.XX.X.el7.x86_64 ... ``` ## Ubuntu ### ¿Cómo concoer la lista de kernels de linux instalados? ``` sudo dpkg --list | egrep -i --color 'linux-image|linux-headers' ``` ### Ubuntu Focal 20.04 ``` sudo apt --purge autoremove ``` ``` sudo apt-get --purge autoremove ``` #### Agrdecimientos y enlaces - [Ubuntu 18.04 remove all unused old kernels](https://www.cyberciti.biz/faq/ubuntu-18-04-remove-all-unused-old-kernels/) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Seguridad, SSl, etc. Todos sobre seguridad, certificados, comprobación de ciphers # Verificar versiones y ciphers soportados de TLS, SSL ### Introducción Una de los mayores problemas al que se enfrenta el soporte es lidiar con los clientes y los problemas derivados del uso de sistemas (windows, MacOSX, Ios, Android, ...) obsoletos. ### Verificar TLS soportado por un protocolo ``` h=nombre_del_host p=port ## Tls 1.2 openssl s_client -connect $h:$p -tls1_2 ### Tls 1.1 openssl s_client -connect $h:$p -tls1_1 ### Tls 1 openssl s_client -connect $h:$p -tls1 ``` El retorno debe tener una linea como esta ``` Verification: OK ``` ### Enumerar los ciphers ssl ``` h=nombre_del_host p=port nmap --script ssl-enum-ciphers -p $p $h ``` ``` Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-15 17:43 CEST Nmap scan report for kvm468.ceinor.com (5.135.93.99) Host is up (0.056s latency). PORT STATE SERVICE 465/tcp open smtps | ssl-enum-ciphers: | TLSv1.2: | ciphers: | TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A | TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A | compressors: | NULL | cipher preference: client |_ least strength: A Nmap done: 1 IP address (1 host up) scanned in 2.81 seconds ``` ### Links y agradecimientos - [Command prompt to check TLS version requiere by a host](https://stackoverflow.com/questions/40557031/command-prompt-to-check-tls-version-required-by-a-host) - [Checking ssl tls Version Support of a Remnote Host from Command line](https://maxchadwick.xyz/blog/checking-ssl-tls-version-support-of-remote-host-from-command-line) # CSF error: *WARING* URLGET set to use LWP but perl module is not installed, fallback to using CURL/WGET ## Introducción Casi siempre que se instala CSF Firewall en una distribución linux tenemos el mismo problema relativo a la ausencia de las librerías de perl LWP requeridas por CSF o mejor dicho preferidas ya que el propio CSF nos ofrece 3 posibilidades de configuración para la descarga de listas u otros elementos desde sitios remotos vía HTTPS. 1. HTTP::Tiny 2. LWP::UserAgent 3. CURL/WGET (set location at the bottom of csf.conf) ### LWP::UserAgent Es la opción deseada y configurada por CSF, y esta configuración al no encontrar disponible el binario correspondiente, te lanza la advertencia cada vez que ejecutes un comando de csf. ``` *WARNING* URLGET set to use LWP but perl module is not installed, fallback to using CURL/WGET ``` Realmente en su propio fichero de configuración se encuentra el cómo, pero si has llegado hasta aquí, es que no lo leiste. (Es lo normal. No solemos leer los LEAME.txt vamos a leer los cientos de comentarios de algunos ficheros de configuración) ##### Distribuciones basada en RPM (Centos, AlmaLinux, CloudLinux,..) ``` yum install perl-libwww-perl.noarch perl-LWP-Protocol-https.noarch ``` #### Distribuciones basadas en APT (Debian, Ubuntu,...) ``` apt-get install libwww-perl liblwp-protocol-https-perl libgd-graph-perl ``` #### Via cpan ``` # perl -MCPAN -eshell cpan> install LWP LWP::Protocol::https ``` ##### Documentación original CSF (ConfigServer Firewall) ``` # The following option can be used to select the method csf will use to # retrieve URL data and files # # This can be set to use: # # 1. Perl module HTTP::Tiny # 2. Perl module LWP::UserAgent # 3. CURL/WGET (set location at the bottom of csf.conf if installed) # # HTTP::Tiny is much faster than LWP::UserAgent and is included in the csf # distribution. LWP::UserAgent may have to be installed manually, but it can # better support https:// URL's which also needs the LWP::Protocol::https perl # module # # CURL/WGET uses the system binaries if installed but does not always provide # good feedback when it fails. The script will first look for CURL, if that # does not exist at the configured location it will then look for WGET # # Additionally, 1 or 2 are used and the retrieval fails, then if either CURL or # WGET are available, an additional attempt will be using CURL/WGET. This is # useful if the perl distribution has outdated modules that do not support # modern SSL/TLS implementations # # To install the LWP perl modules required: # # On rpm based systems: # # yum install perl-libwww-perl.noarch perl-LWP-Protocol-https.noarch # # On APT based systems: # # apt-get install libwww-perl liblwp-protocol-https-perl # # Via cpan: # # perl -MCPAN -eshell # cpan> install LWP LWP::Protocol::https # # We recommend setting this set to "2" or "3" as upgrades to csf will be # performed over SSL as well as other URLs used when retrieving external data # # "1" = HTTP::Tiny # "2" = LWP::UserAgent # "3" = CURL/WGET (set location at the bottom of csf.conf) URLGET = "2" # If you need csf/lfd to use a proxy, then you can set this option to the URL # of the proxy. The proxy provided will be used for both HTTP and HTTPS # connections URLPROXY = "" ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Limitar en el tiempo (expirar en una fecha) una llave openSSH en el authorized_keys # Introducción Un serio handicap en los modelos de administración de sistemas basados en el ser humano, es que un despiste puede ser fatal para nuestra seguridad. Cuando necesitamos añadir una llave SSH a un servidor para el acceso del propietario de dicha llave, y necesitamos que sea temporal, suele ocurrir, que al final, la llave termina por olvidarse. > Por mi trabajo, muchas veces accedo a servidor en los que tengo que realizar trabajos de auditoría o de tunning, y me encuentro llaves autorizadas desde el principio de los tiempos. ## Añadir un limite de tiempo a una llave OpenSSH autorizada Al igual que podemos limitar los comandos que el propietario de dicha llave SSH pueda hacer en nuestro sistema, también podemos limitar la validez de la llave en el tiempo. Si nuestro servidor esta ejecutando una version [OpenSSH 7.7](https://www.openssh.com/txt/release-7.7) o superior, podremos hacerlo añadiendo `expiry-time` a la entrada de la llave a la que queremos limitar en el tiempo el acceso con el formato `expiry-time="YYYYMMDD" ssh-rsa AAAAB3Nz...w== Algun comentario ` ``` expiry-time="20210621" ssh-rsa AAAAB3NzaC1yc2.. ...MXhBut9HKkWI9/ root@prox03 ``` También puedes especificar un tiempo más concreto, usando `YYYYMMDDhhmm` (la versión `YYYYMMDD` entiende como si fuera la media noche, `2020-06-21 00:00:00` ## Enlaces [Adding expiration date to SSH key](https://superuser.com/questions/1598311/adding-expiration-date-to-ssh-key) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Comprobar una conexión SMTP autentificada en el shell con SSL o TLS # Introducción Muchas veces el soporte técnico o nosotros, tenemos que comprobar si los datos que tenemos y si el servidor **SMTP remoto**, están operando correctamente. No es necesario hacer como hacen algunos un cambalache creando una cuenta en el programa de correo electrónico, sino que como casi siempre podemos acudir a nuestra shell para realizar las pruebas pertinentes. ## Comprobar la autenticación SMTP y la conexión SSL usando la línea de comandos o shell. ### Autenticación SMTP La autentificación (autenticación) es el mecanismo por el cual un usuario se identifica a sí mismo en un **servicio** de un servidor. En este caso el servicio es el **correo electrónico saliente** o **SMTP** y es necesario para que podamos **enviar** correo electrónico. ### Preparación, prueba y verificación Para hacer la prueba es necesario tener instalado el paquete **openssl** de nuestro ordenador. #### Crear la cadena de autenticación para una login basado en PLAIN ~~~ Generalmente los servidores de correo electrónico, usan como medio de autenticación uno denominado **PLAIN**, que consiste en pasar un texto plano (ASCII) que contiene el par **usuario + contraseña** ~~~ Antes de realizar la prueba debemos obtener la cadena de caracteres ASCII que contiene el par usuario_smtp + contraseña. ##### Usando Bash En el momento de escribir esto, el tip que tenía en mi entrada original [Cómo comprobar la autenticación SMTP SMTP Auth y la conexión con StartTLS en el shell](https://castris.com/como-comprobar-la-autenticacion-smtp-smtp-auth-y-la-conexion-con-starttls-en-el-shell/) me da error. La verdad es que he comprobado si había un error en mi escritura, y revisado con otros colegas. Así que he optado por no hacer el comando en una línea sino dividirlo en dos que si me funciona ``` $ echo -ne usuario@servidor.smtp.com | base64 emFiYml4QQDlbnRyYWwuY2FzdHJpcy5jb20= $ echo -ne 4Mmr8Hop3FsmQvKtb8Ei | base64 NE1tcjVUb3BhRnNtUXZLdGI4RWk= ``` Ahora conectamos vía openssl ~~~ h y p son variables de entorno para poder trabajar más fácilmente ~~~ El puerto deberá ser el apropiado a la conexión, en este caso **startssl** ``` $ h=servidor.smtp.com $ p=455 $ openssl s_client -connect $h:$p -starttls smtp CONNECTED(00000003) depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R3 verify return:1 depth=0 CN = servidor.smtp.com verify return:1 --- Certificate chain 0 s:CN = servidor.smtp.com … Extended master secret: no Max Early Data: 0 --- read R BLOCK ``` Esto ya nos indica que el servidor está activo, escuchando en el puerto solicitado, y admitiendo la conexión vía startssl Ahora podemos usar `EHLO there`para obtener los comandos disponibles ``` EHLO there 250-servidor.smtp.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-DSN 250-SMTPUTF8 250 CHUNKING ``` O pasar directamente a la autenticación ``` AUTH LOGIN 334 VXNlcm5hbWU6 emFiYml4QQDlbnRyYWwuY2FzdHJpcy5jb20= 334 UGFzc3dvcmQ6 NE1tcjVUb3BhRnNtUXZLdGI4RWk= 235 2.7.0 Authentication successful ``` ##### Usando Perl ~~~ Si el usuario contiene la @ esta deberá escaparse con la barra invertida (\) de otra manera perl interpretará un arreglo (array) en lugar de una cadena (string) ~~~ Con Perl no tengo problemas para hacer lo mismo pero en lugar de usar AUTH LOGIN usar **AUTH PLAIN** usando la única cadena codifica del par usuario y contraseña ``` $ perl -MMIME::Base64 -e 'print encode_base64("\000usuario\@servidor.remoto.tld\000PaSsW0rD")' AHphYmJpeEBjZW50cmFsLkTgqW3RyaXMuY29tADRNbXI1VG9wM0ZzbVF2S3RiOEVp $ h=servidor.smtp.com $ p=455 $ openssl s_client -connect $h:$p -starttls smtp … --- read R BLOCK AUTH PLAIN AHphYmJpeEBjZW50cmFsLkTgqW3RyaXMuY29tADRNbXI1VG9wM0ZzbVF2S3RiOEVp 235 2.7.0 Authentication successful ``` ## Enlaces relacionados - [Verificar versiones y ciphers soportados de TLS, SSL](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/verificar-versiones-y-ciphers-soportados-de-tls-ssl) - [Test SMTP with telnet or openssl](https://www.stevenrombauts.be/2018/12/test-smtp-with-telnet-or-openssl/) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # CSF Firewall: añadir IPs al deny de forma definitiva. ## Firewall y bloqueo definitivo para indeseables A veces, trabajando ves que hay algunas IP que pertenecen a alguien, o incluso a un grupo de IP del mismo proveedor, que no para de aparecer en tus logs. Además, si manda un correo al `abuse@` de l proveedor de servicios, se hace el loco y no te contesta. Pues que mejor que banear la IP de forma definitiva. ## CSF Firewall bloqueo permanente Esta ahí, en los comentarios del `/etc/csf/csf.deny`, pero es una de los mas desconocidos del CSF. ```bash # Note: If you add the text "do not delete" to the comments of an entry then # DENY_IP_LIMIT will ignore those entries and not remove them ``` Maravilloso verdad? Ya sólo queda banearle desde el shell. ```bash ❯ csf -d 179.43.128.0/18 "do not delete - Panama datacenter sin respuesta" Adding 179.43.128.0/18 to csf.deny and iptables DROP... csf: IPSET adding [179.43.128.0/18] to set [chain_DENY] ❯ cat /etc/csf/csf.deny | grep 179.43.128 179.43.128.0/18 # do not delete - Panama datacenter sin respuesta - Sat Aug 17 17:47:12 2024 ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Certificados Letsencrypt sin servidor web o sin resolver en el servidor web ## Como obtener el certificado Letsencrypt para un dominio que no resuelve aun en una migración o nuevo servidor Algunas veces es necesario hacer pruebas antes de levantar una migración en un nuevo servidor en producción. Para ello, deberemos de forma manual, obtener un nuevo certificado basándonos en el desafio llamado **challenge** en el que solicitaremos el certificado porque tenemos capacidad de administración de la zona DNS. También se conoce como **acme-dns-certbot** ### Requisitos En este doc presuponemos que: - Tienes cierto nivel de usuario Linux. - Que tienes instalado **certbot** con *snap*. Si no, acude a las [Instrucciones de Cerbot](https://certbot.eff.org/instructions) - Que tienes instalado **Python 3**, lo cual es ya lo mas común en una instalación de **Linux.** ### Instalar acme-cerbot Una vez instalado necesitamos descargar el script de phyton que nos permitirá trabajar con este tipo de desafío, o validación mediante DNS. > Antes descargar nada, es buena práctica revisar el repositorio desde el que vamos a descargar el script. Antiguamente, no había forma salvo que conocieras un poco el programa y los sistemas implicados. Hoy día puedes usar si no alcanzas a esto, una chat de IA para que te verifique el scripts y te lo explique, como si fueras un novato en sistemas Linux y Python. ```bash wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py ``` Lo hacemos ejecutable ```bash chmod +x acme-dns-auth.py ``` Lo editamos para decirle que use Python 3 ``` nano acme-dns-auth.py #!/usr/bin/env python3 ... ``` Una vez que hallamos realizado el cambio, movemos el fichero ``` sudo mv acme-dns-auth.py /etc/letsencrypt/ ``` ### Configurar y usar acem-dns-cerbot La cuestión es hora simple ```bash sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.tu-dominio -d tu-dominio ``` > Eso es una idea, basándonos en que tienes un * en tu zona dns. Pero puedes dejarlo en la simpleza del dominio normal, el que contiene *www* y otros como *mail*, etc. Pero el consejo es que **todos resuelvan a la ip** Ejemplo ficticio que surge de tener todo lo que te pida respecto de la zona DNS del dominio solicitado. Antes de darle a continuar **Press Enter to Continue** es evidente que ya has creado el registro en la zona del dominio, tal y como te solicitan, o de lo contrario fallará la generación del certificado Let's Encrypt. ```zsh certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d nodo1.midominio.tld Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for nodo1.midominio.tld Hook '--manual-auth-hook' for nodo1.midominio.tld ran with output: Please add the following CNAME record to your main DNS zone: _acme-challenge.nodo1.midominio.tld CNAME cc94069f-6419-4c31-b079-d4408ec2bac6.auth.acme-dns.io. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Challenges loaded. Press continue to submit to CA. Pass "-v" for more info about challenges. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/nodo1.midominio.tld/fullchain.pem Key is saved at: /etc/letsencrypt/live/nodo1.midominio.tld/privkey.pem This certificate expires on 2025-08-11. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ``` Con esto ya puedes configurar el sitio de manera temporal, hasta que resuelva en la maquina. Después lo suyo seria revocarlo y comenzar un proceso normal, basado en web. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Cambio de hostname permanentemente # Introducción Algunas veces nos equivocamos, no teníamos el hostname definitivo o bien hemos instalado un VPS desde una plantilla, y necesitamos cambiar de forma permanente el hostname. El fichero habitual que controla el hostname habitualmente es `/etc/hostname` pero puedo y suele, haber más ficheros implicados ## Conocer el hostname en el shell Aquí tenemos el comando hostnamectl para ver los datos ``` # hostnamectl Static hostname: template2004 Icon name: computer-vm Chassis: vm Machine ID: 1169e389ab834b238027f744b7cf1ae6 Boot ID: e47b8b52d7fe46bf9659f9758d475a73 Virtualization: kvm Operating System: Ubuntu 20.04.2 LTS Kernel: Linux 5.4.0-73-generic Architecture: x86-64 ``` Y también podemos ver el propio fichero ``` # cat /etc/hostname template2004 ``` ### Cambiar el hostname permanentemente en Ubuntu 20.04 LTS Ejecutar hostname con opciones ```bash sudo hostnamectl set-hostname newNameHere ``` Editar el fichero `/etc/hosts` reemplazando cualquier concurrencia del viejo nombre. También podemos utilizar sed pero quizás sea mejor hacerlo manualmente con nuestro editor favorito. ``` sed -i -e ‘s/viejo_nombre/nuevo_nombre/g’ /etc/hosts ``` ### Cambiar el hostname sin reiniciar en Ubuntu 20.04 LTS El procedimiento anterior es válido. Lo unico es que en el terminal seguiremos viendo el nombre antiguo en lugar del actual que podemos verificar con ``` # hostnamectl Static hostname: kvm300 Icon name: computer-vm Chassis: vm Machine ID: 1169e389ab834b238027f744b7cf1ae6 Boot ID: e47b8b52d7fe46bf9659f9758d475a73 Virtualization: kvm Operating System: Ubuntu 20.04.2 LTS Kernel: Linux 5.4.0-73-generic Architecture: x86-64 ``` Para ver el cambio en el indicador del terminal, debemos salir de nuestra shell o hacer un reload de nuestro intérprete de comandos. ## Otros ficheros Si tenemos instalado Postfix u otros demonios que requieren el uso de su propia variable o línea con el nombre del host, puede ser interesante ejecutar el comando de abajo para ver si existe algún otro fichero que debemos corregir. ``` # find /etc/ -type f -exec grep -il 'template2004' {} \; /etc/ssh/ssh_host_rsa_key.pub /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ed25519_key.pub /etc/postfix/main.cf /etc/aliases.db ``` Algunos de ellos, requerirán un reinicio o la aplicación de algún comando para actualizarse. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Hardware El trabajo con el hardware también es necesario y configurable. # Añadir un disco via LVM: Nuevo Grupo VG, Nuevo Volumen Lógico LVM ## Introducción a LVM Nunca me cansare de usar LVM, por la habilidad que ofrece de permitir la amplicación de cualquier montaje del sistema, ya sea con nuevos discos, ampliando los existentes o añadiendo otros. ### Ejemplo nuevo disco, para backups En este caso tenemos un sistema en marhca, al que queremos dotarle de un disco de backups para sicronizarlo con el servidor de backups. No quremos ruido ni operaciones I/O en el disco principal. En mi caso es una máquina virtual #### Añadir el disco # Conocer el hardware en linea de comandos (shell) # Comandos para identificar hardware y configuraciones especificas ## Hardware ### Información procesador ``` # grep 'vendor_id' /proc/cpuinfo ; grep 'model name' /proc/cpuinfo ; grep 'cpu MHz' /proc/cpuinfo vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel vendor_id : GenuineIntel model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz model name : Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz cpu MHz : 848.767 cpu MHz : 950.482 cpu MHz : 800.024 cpu MHz : 869.512 cpu MHz : 823.590 cpu MHz : 800.024 cpu MHz : 799.822 cpu MHz : 851.184 cpu MHz : 802.642 cpu MHz : 1182.916 cpu MHz : 1121.081 cpu MHz : 802.441 ``` ### Marca procesador Si el procesdor es intel el comando de abajo devolvera algo ``` # grep -i vmx /proc/cpuinfo ``` Si el procesador es AMD el comnado de abjo devolverá algo ``` # grep -i svm /proc/cpuinfo ``` ### Discos duros #### lsblk (info particiones) ``` lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 3,7T 0 disk ├─sda1 8:1 0 511M 0 part /boot/efi ├─sda2 8:2 0 50G 0 part │ └─md2 9:2 0 50G 0 raid1 / ├─sda3 8:3 0 511M 0 part [SWAP] ├─sda4 8:4 0 1000G 0 part │ └─md4 9:4 0 1000G 0 raid1 /var └─sda5 8:5 0 2,6T 0 part └─md5 9:5 0 2,6T 0 raid1 /home sdb 8:16 0 3,7T 0 disk ├─sdb1 8:17 0 511M 0 part ├─sdb2 8:18 0 50G 0 part │ └─md2 9:2 0 50G 0 raid1 / ├─sdb3 8:19 0 511M 0 part [SWAP] ├─sdb4 8:20 0 1000G 0 part │ └─md4 9:4 0 1000G 0 raid1 /var └─sdb5 8:21 0 2,6T 0 part └─md5 9:5 0 2,6T 0 raid1 /home loop0 7:0 0 2,2G 0 loop /var/tmp ``` #### Discos duros (Atributos) ``` # blkid /dev/md4: LABEL="/var" UUID="bfa920a1-48e4-4d4e-ad9a-1f5289ec630e" TYPE="ext4" /dev/sdb4: UUID="0ceedb71-9478-ba95-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="logical" PARTUUID="9ba975e1-1b14-49d3-8971-b936e8d5e4e4" /dev/sda4: UUID="0ceedb71-9478-ba95-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="logical" PARTUUID="66b5b2c5-7be1-49e5-a792-9f87e2f7b4f5" /dev/sda1: LABEL="EFI_SYSPART" UUID="42B6-5CF2" TYPE="vfat" PARTLABEL="primary" PARTUUID="da4d4fc9-d837-41d9-a107-e742798f9335" /dev/sda2: UUID="facf2df2-7b51-d62e-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="primary" PARTUUID="d9d59890-5495-4d5c-b1a1-9c7cb06ea760" /dev/sda3: LABEL="swap-sda3" UUID="b3455011-b526-4882-9103-53aea1ba8861" TYPE="swap" PARTLABEL="primary" PARTUUID="b5bd8cbf-6bd4-484d-a66f-95e026322fe3" /dev/sda5: UUID="8841cb2a-ce20-324b-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="logical" PARTUUID="0a0c4007-1aa6-4bbd-8c94-b059e5e47a0e" /dev/sdb1: LABEL="EFI_SYSPART" UUID="42EC-11F4" TYPE="vfat" PARTLABEL="primary" PARTUUID="96828372-cc5c-4f44-bfc4-0758c394b1bb" /dev/sdb2: UUID="facf2df2-7b51-d62e-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="primary" PARTUUID="ea54dfc3-e5c8-4436-be12-9515d1f1f0f1" /dev/sdb3: LABEL="swap-sdb3" UUID="7bf2c3e0-e995-4dbf-9edf-de91db5cc4e0" TYPE="swap" PARTLABEL="primary" PARTUUID="0581737a-20c0-44b7-957c-6190b583f1af" /dev/sdb5: UUID="8841cb2a-ce20-324b-a4d2-adc226fd5302" TYPE="linux_raid_member" PARTLABEL="logical" PARTUUID="c02afe0d-c242-4dd9-8ec7-77ecd90e510b" /dev/md2: LABEL="/" UUID="424a9e66-51b2-4947-97b2-0d632d79a97f" TYPE="ext4" /dev/md5: LABEL="/home" UUID="0de14a77-8d9e-4f25-9c1b-bec542d45f22" TYPE="ext4" /dev/loop0: UUID="8fa0ffb8-aaa1-4321-9d4f-d55a9b021bcc" TYPE="ext3" ``` #### Estado solido o mecánico Devuelve 0 por SSD y 1 por discos mencánicos ``` cat /sys/block/sda/queue/rotational ``` #### Discos NVMe Necesitamos ewl paquete (Ubuntu) nmve-cli para comprobar discos de tipo NVMe ``` # nvme list Node SN Model Namespace Usage Format FW Rev ---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- -------- /dev/nvme0n1 S439NE0N101969 SAMSUNG MZQLB1T9HAJR-00007 1 958.95 GB / 1.92 TB 512 B + 0 B EDA5202Q /dev/nvme1n1 S439NE0N101968 SAMSUNG MZQLB1T9HAJR-00007 1 1.69 TB / 1.92 TB 512 B + 0 B EDA5202Q ``` #### Discos duros (hdparam) El comando hdparm puede que no este instalado en tu distribución. ``` yum install hdparm -y ``` ``` # hdparm -I /dev/sda /dev/sda: ATA device, with non-removable media Model Number: HGST HUS726040ALA610 Serial Number: N8GNY2YY Firmware Revision: A5GNT920 Transport: Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0; Revision: ATA8-AST T13 Project D1697 Revision 0b Standards: Used: unknown (minor revision code 0x0029) Supported: 9 8 7 6 5 Likely used: 9 Configuration: Logical max current cylinders 16383 16383 heads 16 16 sectors/track 63 63 -- CHS current addressable sectors: 16514064 LBA user addressable sectors: 268435455 LBA48 user addressable sectors: 7814037168 Logical Sector size: 512 bytes Physical Sector size: 512 bytes device size with M = 1024*1024: 3815447 MBytes device size with M = 1000*1000: 4000787 MBytes (4000 GB) cache/buffer size = unknown Form Factor: 3.5 inch Nominal Media Rotation Rate: 7200 Capabilities: LBA, IORDY(can be disabled) Queue depth: 32 Standby timer values: spec'd by Standard, no device specific minimum R/W multiple sector transfer: Max = 16 Current = 16 Advanced power management level: 254 DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 Cycle time: min=120ns recommended=120ns PIO: pio0 pio1 pio2 pio3 pio4 Cycle time: no flow control=120ns IORDY flow control=120ns Commands/features: Enabled Supported: * SMART feature set Security Mode feature set * Power Management feature set * Write cache * Look-ahead * Host Protected Area feature set * WRITE_BUFFER command * READ_BUFFER command * NOP cmd * DOWNLOAD_MICROCODE * Advanced Power Management feature set Power-Up In Standby feature set * SET_FEATURES required to spinup after power up SET_MAX security extension * 48-bit Address feature set * Device Configuration Overlay feature set * Mandatory FLUSH_CACHE * FLUSH_CACHE_EXT * SMART error logging * SMART self-test * Media Card Pass-Through * General Purpose Logging feature set * WRITE_{DMA|MULTIPLE}_FUA_EXT * 64-bit World wide name * URG for READ_STREAM[_DMA]_EXT * URG for WRITE_STREAM[_DMA]_EXT * WRITE_UNCORRECTABLE_EXT command * {READ,WRITE}_DMA_EXT_GPL commands * Segmented DOWNLOAD_MICROCODE * unknown 119[6] unknown 119[7] * Gen1 signaling speed (1.5Gb/s) * Gen2 signaling speed (3.0Gb/s) * Gen3 signaling speed (6.0Gb/s) * Native Command Queueing (NCQ) * Host-initiated interface power management * Phy event counters * NCQ priority information * unknown 76[15] Non-Zero buffer offsets in DMA Setup FIS * DMA Setup Auto-Activate optimization Device-initiated interface power management In-order data delivery * Software settings preservation unknown 78[7] unknown 78[10] unknown 78[11] * SMART Command Transport (SCT) feature set * SCT Write Same (AC2) * SCT Error Recovery Control (AC3) * SCT Features Control (AC4) * SCT Data Tables (AC5) * reserved 69[3] * reserved 69[4] * WRITE BUFFER DMA command * READ BUFFER DMA command Security: Master password revision code = 65534 supported not enabled not locked not frozen not expired: security count not supported: enhanced erase Logical Unit WWN Device Identifier: 5000cca244c984a4 NAA : 5 IEEE OUI : 000cca Unique ID : 244c984a4 Checksum: correct ``` ### lshw ``` lshw -class disk -class storage *-sata description: SATA controller product: Cannon Lake PCH SATA AHCI Controller vendor: Intel Corporation physical id: 17 bus info: pci@0000:00:17.0 logical name: scsi0 logical name: scsi1 version: 10 width: 32 bits clock: 66MHz capabilities: sata msi pm ahci_1.0 bus_master cap_list emulated configuration: driver=ahci latency=0 resources: irq:125 memory:91200000-91201fff memory:91203000-912030ff ioport:4050(size=8) ioport:4040(size=4) ioport:4020(size=32) memory:91202000-912027ff *-disk:0 description: ATA Disk product: HGST HUS726040AL physical id: 0 bus info: scsi@0:0.0.0 logical name: /dev/sda version: T920 serial: N8GNY2YY size: 3726GiB (4TB) capabilities: gpt-1.00 partitioned partitioned:gpt configuration: ansiversion=5 guid=9aa4231a-644b-40c9-9105-0e980dbeeeaa logicalsectorsize=512 sectorsize=512 *-disk:1 description: ATA Disk product: HGST HUS726040AL physical id: 1 bus info: scsi@1:0.0.0 logical name: /dev/sdb version: T920 serial: K4KRJ0KB size: 3726GiB (4TB) capabilities: gpt-1.00 partitioned partitioned:gpt configuration: ansiversion=5 guid=2c1a29d1-8bb6-4d02-9990-b9f2fb7b3414 logicalsectorsize=512 sectorsize=512 ``` ``` # lshw -short -C disk H/W path Device Class Description ==================================================== /0/100/17/0 /dev/sda disk 4TB HGST HUS726040AL /0/100/17/1 /dev/sdb disk 4TB HGST HUS726040AL ``` ### smartctl Importante para ver el estado de tus discos. Sobre todo cuando compras o alquilas hardware ``` smartctl -d ata -a -i /dev/sda smartctl 7.0 2018-12-30 r4883 [x86_64-linux-3.10.0-962.3.2.lve1.5.49.el7.x86_64] (local build) Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org === START OF INFORMATION SECTION === Model Family: HGST Ultrastar 7K6000 Device Model: HGST HUS726040ALA610 Serial Number: N8GNY2YY LU WWN Device Id: 5 000cca 244c984a4 Firmware Version: A5GNT920 User Capacity: 4.000.787.030.016 bytes [4,00 TB] Sector Size: 512 bytes logical/physical Rotation Rate: 7200 rpm Form Factor: 3.5 inches Device is: In smartctl database [for details use: -P show] ATA Version is: ACS-2, ATA8-ACS T13/1699-D revision 4 SATA Version is: SATA 3.1, 6.0 Gb/s (current: 6.0 Gb/s) Local Time is: Sun May 16 17:57:14 2021 CEST SMART support is: Available - device has SMART capability. SMART support is: Enabled === START OF READ SMART DATA SECTION === SMART overall-health self-assessment test result: PASSED General SMART Values: Offline data collection status: (0x84) Offline data collection activity was suspended by an interrupting command from host. Auto Offline Data Collection: Enabled. Self-test execution status: ( 0) The previous self-test routine completed without error or no self-test has ever been run. Total time to complete Offline data collection: ( 113) seconds. Offline data collection capabilities: (0x5b) SMART execute Offline immediate. Auto Offline data collection on/off support. Suspend Offline collection upon new command. Offline surface scan supported. Self-test supported. No Conveyance Self-test supported. Selective Self-test supported. SMART capabilities: (0x0003) Saves SMART data before entering power-saving mode. Supports SMART auto save timer. Error logging capability: (0x01) Error logging supported. General Purpose Logging supported. Short self-test routine recommended polling time: ( 2) minutes. Extended self-test routine recommended polling time: ( 571) minutes. SCT capabilities: (0x003d) SCT Status supported. SCT Error Recovery Control supported. SCT Feature Control supported. SCT Data Table supported. SMART Attributes Data Structure revision number: 16 Vendor Specific SMART Attributes with Thresholds: ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE 1 Raw_Read_Error_Rate 0x000b 100 100 016 Pre-fail Always - 0 2 Throughput_Performance 0x0005 135 135 054 Pre-fail Offline - 112 3 Spin_Up_Time 0x0007 184 184 024 Pre-fail Always - 265 (Average 315) 4 Start_Stop_Count 0x0012 100 100 000 Old_age Always - 80 5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 0 7 Seek_Error_Rate 0x000b 100 100 067 Pre-fail Always - 0 8 Seek_Time_Performance 0x0005 128 128 020 Pre-fail Offline - 18 9 Power_On_Hours 0x0012 097 097 000 Old_age Always - 27686 10 Spin_Retry_Count 0x0013 100 100 060 Pre-fail Always - 0 12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 75 192 Power-Off_Retract_Count 0x0032 080 080 000 Old_age Always - 24197 193 Load_Cycle_Count 0x0012 080 080 000 Old_age Always - 24197 194 Temperature_Celsius 0x0002 162 162 000 Old_age Always - 37 (Min/Max 19/52) 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 0 197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 0 198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 0 199 UDMA_CRC_Error_Count 0x000a 200 200 000 Old_age Always - 0 SMART Error Log Version: 1 No Errors Logged SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Short offline Completed without error 00% 26073 - # 2 Short offline Completed without error 00% 26058 - # 3 Short offline Completed without error 00% 26058 - # 4 Short offline Completed without error 00% 16865 - # 5 Short offline Completed without error 00% 16850 - # 6 Short offline Completed without error 00% 16850 - # 7 Short offline Completed without error 00% 15329 - # 8 Short offline Completed without error 00% 15314 - # 9 Short offline Completed without error 00% 15314 - #10 Short offline Completed without error 00% 15288 - #11 Short offline Completed without error 00% 15278 - #12 Short offline Completed without error 00% 15264 - #13 Short offline Completed without error 00% 15264 - #14 Short offline Completed without error 00% 15249 - #15 Short offline Completed without error 00% 15249 - #16 Short offline Completed without error 00% 15099 - #17 Short offline Completed without error 00% 29 - #18 Short offline Completed without error 00% 23 - #19 Short offline Completed without error 00% 23 - #20 Short offline Completed without error 00% 2 - SMART Selective self-test log data structure revision number 1 SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS 1 0 0 Not_testing 2 0 0 Not_testing 3 0 0 Not_testing 4 0 0 Not_testing 5 0 0 Not_testing Selective self-test flags (0x0): After scanning selected spans, do NOT read-scan remainder of disk. If Selective self-test is pending on power-up, resume after 0 minute delay. ``` #### Estado del RAID pro software ``` cat /proc/mdstat Personalities : [raid1] md5 : active raid1 sda5[0] sdb5[1] 2804960192 blocks [2/2] [UU] bitmap: 12/21 pages [48KB], 65536KB chunk md4 : active raid1 sdb4[1] sda4[0] 1048573888 blocks [2/2] [UU] bitmap: 4/8 pages [16KB], 65536KB chunk md2 : active raid1 sdb2[1] sda2[0] 52427712 blocks [2/2] [UU] ``` ### Hardware información general #### Hardware información general resumida ``` # lshw -short H/W path Device Class Description ==================================================== system To Be Filled By O.E.M. (To Be Filled By O.E.M.) /0 bus E3C242D4U2-2T /0/0 memory 64KiB BIOS /0/9 memory 32GiB System Memory /0/9/0 memory 16GiB DIMM DDR4 Synchronous 2666 MHz (0,4 ns) /0/9/1 memory DIMM [empty] /0/9/2 memory 16GiB DIMM DDR4 Synchronous 2666 MHz (0,4 ns) /0/9/3 memory DIMM [empty] /0/14 memory 384KiB L1 cache /0/15 memory 1536KiB L2 cache /0/16 memory 12MiB L3 cache /0/17 processor Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz /0/100 bridge 8th Gen Core Processor Host Bridge/DRAM Registers /0/100/8 generic Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model /0/100/12 generic Cannon Lake PCH Thermal Controller /0/100/14 bus Cannon Lake PCH USB 3.1 xHCI Host Controller /0/100/14/0 usb1 bus xHCI Host Controller /0/100/14/1 usb2 bus xHCI Host Controller /0/100/14.2 memory RAM memory /0/100/15 bus Cannon Lake PCH Serial IO I2C Controller #0 /0/100/15.1 bus Cannon Lake PCH Serial IO I2C Controller #1 /0/100/16 communication Cannon Lake PCH HECI Controller /0/100/16.4 communication Cannon Lake PCH HECI Controller #2 /0/100/17 scsi0 storage Cannon Lake PCH SATA AHCI Controller /0/100/17/0 /dev/sda disk 4TB HGST HUS726040AL /0/100/17/0/1 /dev/sda1 volume 510MiB Windows FAT volume /0/100/17/0/2 /dev/sda2 volume 49GiB EXT4 volume /0/100/17/0/3 /dev/sda3 volume 510MiB Linux swap volume /0/100/17/0/4 /dev/sda4 volume 999GiB EXT4 volume /0/100/17/0/5 /dev/sda5 volume 2675GiB EXT4 volume /0/100/17/1 /dev/sdb disk 4TB HGST HUS726040AL /0/100/17/1/1 /dev/sdb1 volume 510MiB Windows FAT volume /0/100/17/1/2 /dev/sdb2 volume 49GiB EXT4 volume /0/100/17/1/3 /dev/sdb3 volume 510MiB Linux swap volume /0/100/17/1/4 /dev/sdb4 volume 999GiB EXT4 volume /0/100/17/1/5 /dev/sdb5 volume 2675GiB EXT4 volume /0/100/1b bridge Cannon Lake PCH PCI Express Root Port #21 /0/100/1b/0 eth0 network Ethernet Controller 10G X550T /0/100/1b/0.1 eth1 network Ethernet Controller 10G X550T /0/100/1c bridge Cannon Lake PCH PCI Express Root Port #1 /0/100/1c/0 bridge AST1150 PCI-to-PCI Bridge /0/100/1c/0/0 display ASPEED Graphics Family /0/100/1d bridge Cannon Lake PCH PCI Express Root Port #9 /0/100/1e communication Cannon Lake PCH Serial IO UART Host Controller /0/100/1f bridge Intel Corporation /0/100/1f.4 bus Cannon Lake PCH SMBus Controller /0/100/1f.5 bus Cannon Lake PCH SPI Controller /0/1 system PnP device PNP0c02 /0/2 system PnP device PNP0c02 /0/3 communication PnP device PNP0501 /0/4 communication PnP device PNP0501 /0/5 system PnP device PNP0c02 /0/6 generic PnP device INT3f0d /0/7 system PnP device PNP0c02 /0/8 system PnP device PNP0c02 /0/a system PnP device PNP0c02 /0/b system PnP device PNP0c02 ``` #### Hardware información general detallada ``` # lshw | less ``` ### MegaCli MegaCli es una herramienta especifica de la familia de controladoras **LSI MegaRaid** Auqne muchos manuales idtentifican los caomando unas veces en minusculas, otros con alternacia de mayúsculas y minúsculas, lo qmejor es crear un alias, apuntado al que corresponda. Si te falla alguna información en al gun tip, que ves por internet esa es la razón. En mi caso uso MegaCli ya que hice en su día `ln -s /usr/sbin/megacli MegaCli` #### Conocer el estado de la controladora ``` root@pro02:~# MegaCli -EncInfo -aALL Number of enclosures on adapter 0 -- 1 Enclosure 0: Device ID : 252 Number of Slots : 8 Number of Power Supplies : 0 Number of Fans : 0 Number of Temperature Sensors : 0 Number of Alarms : 0 Number of SIM Modules : 1 Number of Physical Drives : 8 Status : Normal Position : 1 Connector Name : Unavailable Enclosure type : SGPIO FRU Part Number : N/A Enclosure Serial Number : N/A ESM Serial Number : N/A Enclosure Zoning Mode : N/A Partner Device Id : Unavailable Inquiry data : Vendor Identification : AVAGO Product Identification : SGPIO Product Revision Level : N/A Vendor Specific : Exit Code: 0x00 ``` ## Sistema ### Arquitectura lshw no tiene porque estar disponible en tu distribucion. Si es asi instalalo o busca alternativa. ``` # sudo lshw -C CPU | grep width width: 64 bits ``` ### Enlaces y agradecimientos - [How to find out Hard Disk Specks /Deatis on Linux](https://www.cyberciti.biz/faq/find-hard-disk-hardware-specs-on-linux/) - [Using NVMe Command Line Tools to Check NVMe Flash Health](https://www.percona.com/blog/2017/02/09/using-nvme-command-line-tools-to-check-nvme-flash-health/) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Uso de UUID para montar particiones linux ## Introducción El UUID ([Identificador único universal](https://es.wikipedia.org/wiki/Identificador_%C3%BAnico_universal)) es un identificador estandarizado usado en el desarrollo del software por la OSF (Open Software Foundation) y es parte del Entorno de Distribución de Software (DCE). El objetivo del uso del UUID es permitir que los sistemas distribuidos identifiquen de manera única y sin una coordinación central los elementos de hardware y software. Cualquier administrador puede crear un UUID y usarlo para identificar algo con confianza razonable que nadie involuntariamente usará el mismo identificador en otros elemento o dispositivo. ### Beneficios del uso de UUID Su uso es especialmente útil, en un entorno personal, para asignar por ejemplo, el montaje de discos externos o internos, sin temor a que por razones del hardware, la asignación numérica habitual, haga fracasar el montaje de discos, cuando añadimos o eliminamos algún dispositivo nuevo. Dispositivos, SAN, iSCSI, DAS, volúmenes externos, son los mejores candidatos para el uso de UUID en el fichero `fstab`. ### Comando blkid el sustituto de vol_id Muchos de los tutoriales se han quedado obsoletos, ya que hacen uso del comando `vol_id` sustituido por `blkid` ``` sudo vol_id --uuid /dev/sdb2 sudo: vol_id: orden no encontrada ``` En su lugar podemos usar blkid ``` ❯ sudo blkid /dev/nvme0n1p1: UUID="9047-9E81" TYPE="vfat" PARTUUID="cb856993-8dff-48f8-8646-0a4f333d2e7a" /dev/nvme0n1p2: UUID="dcV8h8-Ie6y-9yey-5RUE-YfPP-E0ra-fZAXSy" TYPE="LVM2_member" PARTUUID="d7a787ab-2143-46c5-b2aa-e46941a9210d" /dev/sda1: UUID="8aa6c0d2-c18e-4606-b1da-f5f1f7617f00" TYPE="xfs" PARTLABEL="backup3t" PARTUUID="f6b13129-366f-4d3c-8b79-05514ebcaff5" /dev/sdb1: LABEL="ssd" UUID="297ddd6c-f224-4385-8f89-e44f4a6912f3" TYPE="ext4" PARTUUID="57b4c3da-5bde-4a2f-83d5-fa43c13b63cb" /dev/mapper/kubuntu--vg-root: UUID="3c55b16d-1ad7-4ced-a552-874cc97ba0d3" TYPE="ext4" /dev/mapper/kubuntu--vg-swap_1: UUID="f6655751-5635-4acb-9ba6-5d3530aace9d" TYPE="swap ❯ sudo blkid /dev/nvme0n1p1 /dev/nvme0n1p1: UUID="9047-9E81" TYPE="vfat" PARTUUID="cb856993-8dff-48f8-8646-0a4f333d2e7a" ❯ sudo blkid /dev/sda1 /dev/sda1: UUID="8aa6c0d2-c18e-4606-b1da-f5f1f7617f00" TYPE="xfs" PARTLABEL="backup3t" PARTUUID="f6b13129-366f-4d3c-8b79-05514ebcaff5" ``` ### Uso de UUID en el fichero /etc/fstab Sintaxis ``` UUID={YOUR-UID} {/path/to/mount/point} {file-system-type} defaults,errors=remount-ro 0 1 ``` Ejemplo para discos XFS Editamos el fichero `/etc/fstab` para que contenga el punto de montaje ``` ❯ sudo cat /etc/fstab | grep 8aa6 UUID=8aa6c0d2-c18e-4606-b1da-f5f1f7617f00 /backups xfs rw,noquota,nofail 0 1 ``` #### Comprobar ``` ❯ sudo mount -a ❯ df -h |grep backups /dev/sda1 2,8T 1,2T 1,6T 43% /backups ``` > Yo uso habitualmente XFS ya que estoy más especializado en sistemas de backup y correo, donde el número de ficheros es mucho más elevado que otros, por lo que el uso de inodos es importante. XFS me permite un mayor control y calidad que ext4 para este tipo de sistemas. Por eso necesito usar `noquota,nofail`en lugar de la sintaxis común de ext4 #### Enlaces - [What is the difference between 'nobootwait' and 'nofail' in fstab?](https://unix.stackexchange.com/questions/53456/what-is-the-difference-between-nobootwait-and-nofail-in-fstab) - [Debian fstab](https://wiki.debian.org/fstab) - [Arch Linux Fstab](https://wiki.archlinux.org/title/Fstab) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Instalación GPT con el instalador Centos 7 en discos < 2 TiB # Introducción Uno de los problemas comunes en la generación de templates e incluso en algunas instalaciones, es el uso del obsoleto MBR. **MBR** es anticuado, y además presenta problemas en el caso de que en entornos virtuales, tengamos que hacer una ampliación de disco mayor de 2TiB. La eficiacia de **GPT** es muy superior y recomendable. Además si algun día nuestro disco quiere crecer por encima de los 2 TiB, ya no lo podrá hacer con MBR. **Anaconda** que es el sistema de Centos 7 para particionar el disco, hará lo siguiente: - Si el disco ya está formateado, respetará el esquema de partición. - Si el disco tiene más de 2 32 sectores (2 Tib) usará GPT - Si el disco es de menor tamaño usará MBR. ## Instalar Centos 7 con tabla de particiones GPT ### Aviso Si bien existen algunos artículos sobre cómo convertir una partición con esquema MBR a GPT, esto no es recomendable, ya que GPT sólo es válido en sistemas compatibles con **UEFI**, y por tanto requiere una partición EFI `/boot/efi` de al menos 50 MiB (recomendado 200 MiB) y aunque podemos hacerlo mejor comenzar bien desde el principio. ### Discos menores de 2TiB Al mostrarse el instalador, debemos pulsar Tab para poder añadir a la linea de arranque `inst.gpt` lo cual de forma silenciosa, hará que **anaconda** realice la instalación usando el esquema de particiones GPT. ![AnaCONDA- Instalador Centos](https://multimedia.castris.com/imagenes/wiki/sysadmin/installation_centos_7_anaconda_parted.jpg) Una vez finalizada la instalación tu disco tendrá un esquema de particiones GPT, que podrás ampliar sin problema mas allá de los 2 TiB ![fdisk](https://multimedia.castris.com/imagenes/wiki/sysadmin/installation_centos_7_parted.jpg) #### Enlaces - [CentOs - Installation Destination](https://docs.centos.org/en-US/centos/install-guide/StorageSpoke-x86/#sect-bootloader-x86) - [Anaconda](https://es.wikipedia.org/wiki/Anaconda_(instalador) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Ampliación de disco en sistema virtualizado KVM (proxmox) # Introducción En un escenario de uso de discos virtuales, como KVM, Proxmox y otros, a veces es necesario una ampliación del disco. Si usamos LVM esto es posible y sencillo. ## Convenciones Ciertas cosas que hay en esta entrada, así como en otras, requieren un conocimiento previo. No es un sitio para **copiar y pegar** sino para **entender y hacer** No siempre es el disco **vda**, no siempre es la **partición 1**, y así sucesivamente. ## Ampliación de una disco virtual KVM La ampliación de un disco LVM es posible una vez que hemos realizado el cambio virtual del tamaño de la unidad LVM. En el caso de Proxmox acudimos a la administración de nuestro proxmox - Seleccionamos el VPS - Click en **Resize Disk" - Incrementamos el tamaño. > Si el aumento de tamaño implica un tamaño final mayor de 2 TiB deberás tener el esquema de particiones **GPT** de lo contrario, tendrás que modificar bajo tu responsabilidad el esquema MBR a GPT. Esta entrada no trata de eso, y para ello es aconsejable el uso de [Gparted Live](https://gparted.org/livecd.php), lo cual no siempre es posible. > El artículo interpreta que conoces el uso de ciertos comando, que sustituirán el dispositivo (disco) por el tuyo, y que sabes como obtener el esquema de tu disco (particiones) ### Consejo sobre particionamiento durante la instalación Es aconsejable el uso de GPT y de ello hablamos en nuestra wiki, [Instalación GPT con el instalador Centos 7 en discos < 2 TiB](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/instalacion-gpt-con-el-instalador-centos-7-en-discos-2-tib) ![Resize Disk - Proxmox](https://multimedia.castris.com/imagenes/wiki/sysadmin/resize_disk_kvm_proxmox.jpg) ### Verirficación en un KVM basado en LVM Una vez que hemos ampliado el disco, podemos verificar el cambio de tamaño en nuestro VPS. Esto funcionará hasta que reiniciemos la máquina. Después ya no nos informará. > vda, vdb, sda, ... son nombres de dispositivos. Debes consultar cuales son tus dispositivos de disco usando `fdisk -l` y usar el apropiado en el comando ``` # dmesg | grep vda ... [ 222.436098] vda: detected capacity change from 32212254720 to 37580963840 ``` ### Imprimir la tabla actual del disco ``` # fdisk -l /dev/vda | grep ^/dev /dev/vda1 * 2048 1026047 512000 83 Linux /dev/vda2 1026048 62914559 30944256 8e Linux LVM ``` ### Conocer el uso de las particiones en el sistema LVM ``` # pvscan PV /dev/vda2 VG centos lvm2 [<29,51 GiB / 40,00 MiB free] Total: 1 [<29,51 GiB] / in use: 1 [<29,51 GiB] / in no VG: 0 [0 ] # lvscan ACTIVE '/dev/centos/swap' [3,00 GiB] inherit ACTIVE '/dev/centos/root' [<26,47 GiB] inherit ``` ### Ampliar la partición física ``` parted /dev/vda GNU Parted 3.1 Usando /dev/vda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print Model: Virtio Block Device (virtblk) Disk /dev/vda: 37,6GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Numero Inicio Fin Tamaño Typo Sistema de ficheros Banderas 1 1049kB 525MB 524MB primary xfs arranque 2 525MB 32,2GB 31,7GB primary lvm (parted) resizepart 2 100% (parted) quit ``` #### Mensajes de error A veces, es posible que tras un acceso con `parted` a nuestro dispositivo, podemos encontrar mensajes relativos a problemas derivados de los instaladores de Centos, de Ubuntu, según cuándo y cómo se hizo la partición que estamos tratando de modificar. Es importante leer y comprender estos mensajes, o corremos el riesgo de perder nuestros datos. En el caso de abajo, viene del instalador de **Centos 7** el cual no hizo del todo bien su trabajo. ``` Error: La copia de la tabla GPT no está al final del disco, como debería ser. Esto quiere decir que otro sistema operativo cree que el disco es más pequeño. ¿Lo quiere arreglar moviendo la copia al final (y borrando la copia vieja)? Arreglar/Fix/Descartar/Ignore/Cancelar/Cancel? Fix Aviso: Not all of the space available to /dev/vda appears to be used, you can fix the GPT to use all of the space (an extra 3005218816 blocks) or continue with the current setting? Arreglar/Fix/Descartar/Ignore? F Model: Virtio Block Device (virtblk) Disk /dev/vda: 1571GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: pmbr_boot Numero Inicio Fin Tamaño Sistema de ficheros Nombre Banderas 1 1049kB 2097kB 1049kB bios_grub 2 2097kB 1076MB 1074MB xfs 3 1076MB 32,2GB 31,1GB lvm ``` ### Asignar el nuevo tamaño al volumen físico de LVM ``` pvresize /dev/vda2 Physical volume "/dev/vda2" changed 1 physical volume(s) resized or updated / 0 physical volume(s) not resized ``` ### Redimensionar el volumen lógico de LVM al nuevo tamaño #### Todo para una particion ``` [root@kvm476 httpd]# lvresize --extents +100%FREE --resizefs /dev/centos/root Size of logical volume centos/root changed from <26,47 GiB (6776 extents) to <31,51 GiB (8066 extents). Logical volume centos/root successfully resized. meta-data=/dev/mapper/centos-root isize=256 agcount=4, agsize=1734656 blks = sectsz=512 attr=2, projid32bit=1 = crc=0 finobt=0 spinodes=0 data = bsize=4096 blocks=6938624, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=0 log =internal bsize=4096 blocks=3388, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 data blocks changed from 6938624 to 8259584 [root@kvm476 httpd]# df -h S.ficheros Tamaño Usados Disp Uso% Montado en devtmpfs 2,9G 0 2,9G 0% /dev tmpfs 2,9G 0 2,9G 0% /dev/shm tmpfs 2,9G 65M 2,8G 3% /run tmpfs 2,9G 0 2,9G 0% /sys/fs/cgroup /dev/mapper/centos-root 32G 25G 7,3G 77% / /dev/vda1 497M 256M 241M 52% /boot stor01.tamainut.net:/srv/storage/backup/kvm476/backupremote 32T 30T 1014G 97% /backupremote2 tmpfs 581M 0 581M 0% /run/user/0 ``` #### Resize Volumen Lógico por tamaño extacto a añadir En un sistema con distintas particiones es diferente: ``` ❯ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 392M 1.3M 390M 1% /run /dev/mapper/ubuntu--vg-ubuntu--lv 10G 2.7G 7.4G 27% / /dev/disk/by-id/dm-uuid-LVM-c0exIQsrkEu9W74ltbUferOjY7bxLxtDCc3OvS3nDmQvIcUKcNPxopClK4fEszol 6.0G 5.6G 450M 93% /usr tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock /dev/vda2 2.0G 131M 1.7G 8% /boot /dev/mapper/ubuntu--vg-lv--home 5.0G 88M 5.0G 2% /home /dev/mapper/ubuntu--vg-lv--var 6.0G 1.3G 4.8G 21% /var tmpfs 392M 4.0K 392M 1% /run/user/0 ❯ dmesg | grep vda [40225.482258] virtio_blk virtio1: [vda] new size: 83886080 512-byte logical blocks (42.9 GB/40.0 GiB) [40225.482268] vda: detected capacity change from 67108864 to 83886080 ❯ lvscan ACTIVE '/dev/ubuntu-vg/ubuntu-lv' [10.00 GiB] inherit ACTIVE '/dev/ubuntu-vg/lv-var' [6.00 GiB] inherit ACTIVE '/dev/ubuntu-vg/lv-usr' [6.00 GiB] inherit ACTIVE '/dev/ubuntu-vg/lv-home' [5.00 GiB] inherit ❯ pvscan PV /dev/vda3 VG ubuntu-vg lvm2 [<30.00 GiB / <3.00 GiB free] Total: 1 [<30.00 GiB] / in use: 1 [<30.00 GiB] / in no VG: 0 [0 ] ❯ parted /dev/vda GNU Parted 3.4 Using /dev/vda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print Warning: Not all of the space available to /dev/vda appears to be used, you can fix the GPT to use all of the space (an extra 16777216 blocks) or continue with the current setting? Fix/Ignore? F Model: Virtio Block Device (virtblk) Disk /dev/vda: 42.9GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 2097kB 1049kB bios_grub 2 2097kB 2150MB 2147MB ext4 3 2150MB 34.4GB 32.2GB (parted) resizepart 3 100% (parted) quit Information: You may need to update /etc/fstab. ❯ pvresize /dev/vda3 Physical volume "/dev/vda3" changed 1 physical volume(s) resized or updated / 0 physical volume(s) not resized ❯ lvextend -L+2G /dev/ubuntu-vg/lv-usr Size of logical volume ubuntu-vg/lv-usr changed from 6.00 GiB (1536 extents) to 8.00 GiB (2048 extents). Logical volume ubuntu-vg/lv-usr successfully resized. # Es una partición xfs por eso usamos xfs_growfs ❯ xfs_growfs /dev/ubuntu-vg/lv-usr meta-data=/dev/disk/by-id/dm-uuid-LVM-c0exIQsrkEu9W74ltbUferOjY7bxLxtDCc3OvS3nDmQvIcUKcNPxopClK4fEszol isize=512 agcount=4, agsize=393216 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 bigtime=0 inobtcount=0 data = bsize=4096 blocks=1572864, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 data blocks changed from 1572864 to 2097152 ❯ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 392M 1.3M 390M 1% /run /dev/mapper/ubuntu--vg-ubuntu--lv 10G 2.7G 7.4G 27% / /dev/disk/by-id/dm-uuid-LVM-c0exIQsrkEu9W74ltbUferOjY7bxLxtDCc3OvS3nDmQvIcUKcNPxopClK4fEszol 8.0G 5.6G 2.5G 70% /usr tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock /dev/vda2 2.0G 131M 1.7G 8% /boot /dev/mapper/ubuntu--vg-lv--home 5.0G 88M 5.0G 2% /home /dev/mapper/ubuntu--vg-lv--var 6.0G 1.3G 4.8G 21% /var tmpfs ``` ## Actualizacion 2024-03-21 En nuevas versiones de parted, por ejemplo en ALmalinux 8, no es posible usar el comando como lo hacia anteriormente. Debes de hacerlo directamente en el shell - `sd`, `vd`, el prefijo que corresponda ``` parted /dev/sdx --script resizepart NumeroParticion 100% ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Parted mejor que fdisk ## Introducción Además de que fdisk no puede particionar creando particiones mayores de 2TB, es mucho mejor amigo del sysadmin `parted`. En este artículo dejo escrito el cómo hacerlo en el caso de discos que uso en montajes de Proxmox con OVH. ### Parted : Creando particiones #### Label si esta no existe Si no existe etiqueta del formato de disco es necesaria así que la creamos ```bash # parted -s /dev/nvme1n1 mklabel gpt ``` ### Hacer la partición disponible al 100% Cómo uso los discos para LVM es necesario crear una partición al 100% [Recomendación LVM Howto](https://tldp.org/HOWTO/LVM-HOWTO/initdisks.html) ```bash # parted -s /dev/nvme1n1 mkpart primary 0% 100% # parted /dev/nvme1n1 GNU Parted 3.4 Using /dev/nvme1n1 Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print Model: SAMSUNG MZVL2512HCJQ-00B07 (nvme) Disk /dev/nvme1n1: 512GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 512GB 512GB primary ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Añadir un volumen físico nuevo a un volumen lógico de LVM ## Introducción A veces, queremos o podemos ampliar un grupo de volumenes VG con un nuevo dispositivo. ## Preparación del dispotivo La recomendación es primero [formatear con parted](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/parted-mejor-que-fdisk) y hacer una partición al 100% de ese dispositivo. ## Control de lo existente ```bash pvs WARNING: PV /dev/nvme0n1p5 in VG vg is using an old PV header, modify the VG to update. PV VG Fmt Attr PSize PFree /dev/nvme0n1p5 vg lvm2 a-- 454.43g 0 /dev/nvme1n1p1 lvm2 --- <476.94g <476.94g ``` Como vemos aqui, tenemos ya un **volumen** llamado "vg" con un disco de 450G y el nuevo disco de otros 450G que queremos añadir al grupo. En mi caso y procedente del instalador de proxmox de OVH, vemos que el dispositivo momntado en el VG tiene una cabacera anticuada, asi que me lo cargo. Si no quisiera hacerlo puedo saltar ese paso. ``` pvdisplay WARNING: PV /dev/nvme0n1p5 in VG vg is using an old PV header, modify the VG to update. --- Physical volume --- PV Name /dev/nvme0n1p5 VG Name vg PV Size <454.44 GiB / not usable 2.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 116335 Free PE 0 Allocated PE 116335 PV UUID 1NEKQh-mYX6-e6CR-Ddud-fY1w-XFhd-dLlOqc "/dev/nvme1n1p1" is a new physical volume of "<476.94 GiB" --- NEW Physical volume --- PV Name /dev/nvme1n1p1 VG Name PV Size <476.94 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID ZENJmY-wgGf-Ahag-3U7N-zc3J-odzn-W5w4ek ``` ## Añadir una partición Nunca añadimos discos fisiciosino particiones. ``` root@pro30:~# pvs PV VG Fmt Attr PSize PFree /dev/nvme0n1p5 vg lvm2 a-- 454.43g 0 root@pro30:~# pvcreate /dev/nvme1n1p1 Physical volume "/dev/nvme1n1p1" successfully created. root@pro30:~# vgextend vg /dev/nvme1n1p1 Volume group "vg" successfully extended ``` # Directadmin Un panel como otro cualquiera. # Cosas rápidas para novatos en Directadmin ## Introducción Son una serie de tips sobre administraciónd e un sistema con el panel de control Directadmin. Cuando uno viene acostumbrado de otro panel, o de servidores sin panel, a veces se pierde en las peculuariades de un nuevop panel. ### mysql password root # Actualizar la licencia DirectAdmin en el shell # Introducción Tratamos de entrar en nuestro servidor con DirectAdmin como administradores y nos encontramos con el problema de que no funciona y la licencia esta expirada, o la habiamos renovado o comprado, pero no esta actualizada. No hay problema, acudamos al shell. ## Actualziación de la licencia DirectAdmin en shell ### Automático ![Actualziacion licencias DirectAdmin en el shell](https://multimedia.castris.com/imagenes/wiki/sysadmin/actualizaci%C3%B3n_licencia_directadmin_shell.jpg) Accedemos a nuestro servidor via ssh y ejecutamos los dos comandos: - Uno para descargar la licencia - Otro para reiniciar DirectAdmin ``` ~# /usr/local/directadmin/scripts/getLicense.sh auto --2021-06-15 09:39:45-- https://www.directadmin.com/cgi-bin/licenseupdate?lid=240714&uid=92645 Resolving www.directadmin.com (www.directadmin.com)... 167.172.23.237 Connecting to www.directadmin.com (www.directadmin.com)|167.172.23.237|:443... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [application/octet-stream] Saving to: ‘/usr/local/directadmin/conf/license.key.temp’ /usr/local/directadmin/conf/license.key.temp [ <=> ] 1.78K --.-KB/s in 0s 2021-06-15 09:39:46 (241 MB/s) - ‘/usr/local/directadmin/conf/license.key.temp’ saved [1820] root@tiendas:~# service directadmin restart ``` ## Enlace esxterno oficial con otras alternativas [Updating your DirectAdmin License manually](https://help.directadmin.com/item.php?id=30) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # MySQL - MariaDb Un mundo difícil, en el que las diferencias entre los motores SQL del tipo MySQL, comienzan a ser muy problemáticas. Incluso entre las versiones del mismo motor. # Página nueva # ERROR 1118 (42000) at line XXXXX: Row size too large (> 8126) # Introducción Los upgrades de versión han sido un problema desde MySQL 5 y en MariaDB desde la 10. Muchas veces se quedan flecos que producen errores, que en caso de recuperación de desastres pueden ser un serio handicap. ## Error ``` [root@servidor02b mysql]# bunzip2 < dbdump.db.bz2 | mysql ERROR 1118 (42000) at line 13300: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline. [root@servidor02b mysql]# bunzip2 < dbdump.db.bz2 | mysql ``` ## Solución Editamos el fichero de configuración de mysql (generalmente /etc/my.cnf o dentro de /etc/mysql/) para añadir en la sección `[mysqld]` el siguiente contenido (puedes adaptarlo a tu sistema, necesidades o posibilidades) ``` [mysqld] innodb_log_file_size=512M innodb_strict_mode=0 ``` Después realizamos un restart del servidor e intentamos de nuevo el restore. ### Enlaces - [Troubleshooting Row Size Too Large Errors with InnoDB](https://mariadb.com/kb/en/troubleshooting-row-size-too-large-errors-with-innodb/) - [Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline](https://www.techrunnr.com/row-size-too-large-8126-changing-some-columns-to-text-or-blob-may-help-in-current-row-format-blob-prefix-of-0-bytes-is-stored-inline/) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Errores con MariaDB 10.3 al restaurar o hacer backups arrastrando versiones antiguas # Introducción Los síntomas son variados, pero afectan todos a la base de datos `sys` la cual existía con anterioridad a la versión 10.3 de MariaDB y que ya está en desuso. ``` mysqldump: Got error: 1356: "View 'sys.host_summary' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them" when using LOCK TABLES ``` ### Base de datos sys Esta base de datos, no se incluye desde la 10.3, pero ha sido incorporada en la versión 10.6.0 (Alpha) y 10.6.1 (Beta), [bundle sys schema - MDEV-9077](https://jira.mariadb.org/browse/MDEV-9077), y si no la usas (probablemente) es seguro eliminarla. ``` $ mysql mysql > DROP DATABASE sys; ``` Si la necesitas, deberás intentar resolver los problemas descritos en los mensajes de error. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Como extraer de un backup de MySQL completo una base de datos y/o una tabla # Introducción Lo habitual en sistemas es tener un backup de bases de datos, por database o esquema. Pero a veces, sólo tenemos un backup completo. Mucho menos habitual es tener backups por tablas, así que en esta entrada, te explicamos cómo obtener el backup de una base de datos obtenida de un backup completo de mysqldump, y/o como extraer una tabla de un backup completo o de un esquema de la base de datos. ## Mysql --one-database Una opción muy potente, que puede ser muy útil en ciertos escenarios (trabajo con logs binarios) pero que requiere un conocimiento profundo de MySQL. Así que mejor ir a lo práctico. ## Filtrar el fichero mysqldump con sed Para mi es la mejor opción para extraer una base de datos o una tabla de un fichero SQL de mysqldump. ``` $ sed -n '/^-- Current Database: `nombre_de_la_base_de_datos`/,/^-- Current Database: `/p' nombre_del_backup.sql > nombre_de_la_base_de_datos.sql ``` ### Tip sed. Pasar una variable a un comando sed El mismo comando se puede pasar de forma más fácil, usando variables. En mi caso uso este tip, aunque existen otras fórmulas para pasar variables, en este caso muchas de ellas fallaran por las comillas simples invertidas. ``` $ bd=nombre_de_la_bd $ mydump=nombre_del_fichero_dump_sql $ sed -n '/^-- Current Database: `'"${bd}"'`/,/^-- Current Database: `/p' $mydump > ${bd}.sql ``` ## Extraer una tabla de un fichero mysqldump ¿Necesitas restaurar una sóla tabla? Sencillo. Cambiamos un poco la estructura de la consulta (trabajando sobre el fichero de **una sola base de datos** ``` $ tabla=nombre_de_la_tabla $ sed -n '/^-- Table structure for table `'"${tabla}"'`/,/^-- Table structure for table /p' ${bd}.sql > ${tabla}.sql ``` ### Nota de actualización para MacOs 2024/11/23 Algunas veces a sed en macos le da por mostrar problemas derivados la codificación. (Eso de no ser POSIX al MacosX le mata a veces) La solución (no lo intentes con las IA que a todas se les va la pinza...) ```bash sed -i -n '/^-- Current Database: `'"${bd}"'`/,/^-- Current Database: `/p' $mydump > ${bd}.sql sed: RE error: illegal byte sequence ``` Solución ```bash LC_ALL=C sed -i -n '/^-- Current Database: `'"${bd}"'`/,/^-- Current Database: `/p' $mydump > ${bd}.sql ``` ## Renombrar el backup de la tabla extraída para usarlo en la misma base de datos Atención porque si queremos usar ese backup para crear una copia clonada de la tabla con otro nombre hay que modificar el fichero, ya que de lo contrario volcaremos el contenido en la misma tabla, y si es un backup antiguo, el lío esta servido. ``` -- Table structure for table `nombre_de_la_tabla` DROP TABLE IF EXISTS `nombre_de_la_tabla`; CREATE TABLE `nombre_de_la_tabla` ( -- Dumping data for table `nombre_de_la_tabla` LOCK TABLES `nombre_de_la_tabla` WRITE; /*!40000 ALTER TABLE `nombre_de_la_tabla` DISABLE KEYS */; ``` Asi que debemos cambiarlo. Y una manía muy preocupante es la de usar editores de texto, sobre todo en windows, lo cual puede ser terrorífico, aparte de poco efectivo. Usaremos **sed** otra vez. ``` # newtabla=nueva_tabla # sed -i -e 's/'"${tabla}"'/'"${newtabla}"'/g' ${tabla}.sql ``` ## Enlaces - [Passing a variable to sed](https://unix.stackexchange.com/questions/84063/passing-a-variable-to-sed#:~:text=The%20safest%20way%2C%20in%20my,t%22'%2F%2F'.) - [How can I use variables in the LHS and RHS of a sed substitution?](https://unix.stackexchange.com/questions/69112/how-can-i-use-variables-in-the-lhs-and-rhs-of-a-sed-substitution) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Como crear un usuario Mysql/MariaDB con Grant Privileges # Introducción La organización es muy adecuada en nuestro trabajo. Crear usuarios y bases de datos sin control alguno, y sin una nomenclatura es signo de desorganización, y el camino previo para las dificultades cuando necesitemos escalar nuestro proyecto. Además, a veces, no podemos dar permiso para todo (root) a todos. Eso sería un grave error en nuestra política de seguridad. El siguiente artículo, ha sido creado con MariaDb 10.6 pero con algunas diferencias sutiles que podréis encontrar en la documentación de los respectivos motores y versiones. Permite crear un usuario con privilegios suficientes para crear una base de datos y tener privilegios globales para es base de datos, siempre que cumpla, la nomenclatura de nombres basado en **prefijo_** ## Crear una Database Si no tienes una base de datos creada, tendrás que crearla. ~~~ Los comandos de este documento presuponen que tienes conocimientos básicos de MySQL. ~~~ ``` # mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 49 Server version: 10.6.3-MariaDB-1:10.6.3+maria~focal-log mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> CREATE DATABASE mibasedatos_pre; Query OK, 1 row affected (0.000 sec) MariaDB [(none)]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | mibasedatos_pre | +--------------------+ 6 rows in set (0.000 sec) ``` ~~~ El comando accede como root porque lo tengo configurado a tal fin siendo root. Pude ser que en tu sistema tengas que usar `mysql -u root -p` ~~~ ## Crear un usuario nuevo de MariaDB ``` MariaDB [(none)]> CREATE USER 'mibasedatos_usr'@'localhost' IDENTIFIED BY 'UnACoNtRaSeñaAdECuADa'; Query OK, 0 rows affected (0.001 sec) ``` Comprobamos ``` MariaDB [(none)]> SELECT User FROM mysql.user; +--------------+ | User | +--------------+ | mariadb.sys | | mysql | | root | | mibasedatos_pre | +--------------+ 4 rows in set (0.001 sec) ``` ## Otorgamos privilegios al user de MariaDB ```sql GRANT CREATE USER, CREATE ON *.* TO 'mibasedatos_usr'@'localhost' IDENTIFIED BY 'CKWor4Jh9CC4UskUg'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON `mibasedatos\_%`.* TO 'mibasedatos_usr'@'localhost' WITH GRANT OPTION; Query OK, 0 rows affected (0.001 sec) ``` ## Otorgamos privilegios al user en MySQL 8 + ```sql CREATE USER, CREATE ON *.* TO 'mibasedatos_usr'@'localhost' IDENTIFIED BY 'CKWor4Jh9CC4UskUg'; GRANT ALL PRIVILEGES ON *.* TO 'myroot'@'localhost'; ``` ## Comprobación ``` MariaDB [(none)]> USE mibasedatos_pre; Database changed MariaDB [mibasedatos_pre]> CREATE TABLE test (id INT); Query OK, 0 rows affected (0.003 sec) ``` ~~~ Esto permite al usuario **crear cualquier base de datos** pero solo **usar aquellas que comienzan por el prefijo** Si deseas algo más especifico en mi opinión, necesitas hacer un script que genere el usuario y los permisos sucesivos cuando cree una tabla, forzando al uso dle prefijo (estilo cpanel) ~~~ ## Enlaces - [How to Create MariaDB User and Grant Privileges](https://phoenixnap.com/kb/how-to-create-mariadb-user-grant-privileges) - [MySQL granting privileges on wildcard database name to new user](https://stackoverflow.com/questions/27335060/mysql-granting-privileges-on-wildcard-database-name-to-new-user) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Restaurar mysqldump completo con problemas relacionados con VIEW y sus permisos ### Mysqldump, restore, vistas y seguridad Algunas veces, sobre todo cuando estamos trabajando con backups de otros servidores mysql, con problemas para restaurar un backup de una base de datos individual, que se hizo de forma completa. Esta incluye las vistas, y por ende, los usuarios con permisos para las vistas, conocido en MySQL como `SQL SECURITY DEFINER` . Si en nuestro sistema no existen esos usuarios, a los que hace referencia el fichero sql, obtendremos un fallo, en el volcado o restauración de la copia de seguridad, incluso si lo ejecutamos como root Por ejemplo ```bash ERROR 1356 (HY000) at line 1693: View 'database.view_condition_xx_table' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them ``` Podemos intentar algunos tips, que hay por ahí, incluso hacer un restore forzado pero nos quedaríamos con la duda de si está todo bien. ### Solución propuesta: desactivar al usuario afectado en su SQL SECURITY DEFINER Primero para ver el tema y si este es el problema realmente (copiar y pegar artículos de internet no es buena idea si no se sabe lo que se hace) vamos a ver si los tiros van por ahí. ```bash ❯ cat my-database-dump.sql | grep -i DEFINER /*!50013 DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER */ /*!50013 DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER */ /*!50013 DEFINER=`otrouser`@`%` SQL SECURITY DEFINER */ ``` Vemos que existe un usuario que no existe en nuestro servidor, y ese el portanto el que produce el problema en el volcado. La mejor opción en mi opinión, no es tratar de saltarse o modificar nada en el servidor, sino de obviar ese usuario, salvo que sea de interés crearlo en nuestro sistema, por otras causas. ### Desactivación del SQL SECURITY DEFINER problemático Usando `sed` podremos cambiar el definer que nos falla a root y volver a intentar la restauración de la copia de seguridad de mysql que nos falló a causa `definer/invoker of view lack rights to use them` ```bash sed -i.bak 's/DEFINER\=\`otrouser/DEFINER\=\`root/g' my-database-dump.sql ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Desactivación de las reglas de modos SQL de un sevidor MySQL/MariaDB/Percona ## Introducción Hay una gran diferencia entre usar la desactivación de los modos SQL de un servidor SQL, por necesidad imperiosa, y otra muy distnta de persistir en la creencia de que es lo correcto. Muchos de los modos SQL, cambia a lo largo de las vidas útiles de una versión de un sistemas de bases de datos, tipo SQL, y esto hace que en el momento más crucial ese cambio: - Haga inservible, al menos rápidamente, un backup en un escenario de recuperación de desastres. - No sepueda realziar una migración a un nuevo sistema por incompatibilidad de los datos contenidos. - Por el fin de soporte de ese **workaround** que ha sido elminado de la ecuación en la versión nueva. ## Consideraciones al Usar sql_mode="": 1. Desactivación de Validaciones: Al establecer sql_mode="", se desactivan validaciones como: - `STRICT_TRANS_TABLES`: Permite que las inserciones y actualizaciones que no cumplen con los requisitos de tipo y tamaño se realicen, lo que potencialmente puede llevar a la corrupción de datos. - NO_ZERO_DATE: Previene la inserción de fechas nulas o cero que suelen considerarse inválidas. - ONLY_FULL_GROUP_BY: Asegura que las consultas que usan GROUP BY cumplan con las reglas estándar SQL. 2. **Compatibilidad con PHP**: Si estás trabajando con PHP y experimentas problemas con la inserción de datos, a veces desactivar modos restrictivos puede solucionar problemas. Sin embargo, esto puede llevar a que se introduzcan datos erróneos o inconsistencia. Es importante identificar por qué los datos no se estaban insertando correctamente en primer lugar. 3. **Prácticas Recomendadas**: En lugar de desactivar todos los modos, es una buena práctica intentar configurar el sql_mode de manera más específica. Por ejemplo, podrías excluir ciertos modos según sea necesario, en lugar de dejarlo vacío completamente: ```bash sql_mode="STRICT_TRANS_TABLES,NO_ZERO_DATE" ``` ## Configuración en my.cnf Para configurar esto en el archivo `my.cnf`, puedes agregar o modificar la línea en la sección [mysqld]: ```bash [mysqld] sql_mode="" ``` ### Reiniciar el Servidor Después de realizar cambios en my.cnf, asegúrate de reiniciar el servidor de MySQL o MariaDB para que los cambios surtan efecto. ```bash systemctl restart mariadb ```` ### Comprobación Acceso a MySQL shell. ``` MariaDB [(none)]> SHOW VARIABLES LIKE 'sql_mode'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_mode | | +---------------+-------+ 1 row in set (0.001 sec) ``` ## Conclusión Si decides establecer `sql_mode=""`, hazlo con precaución y asegúrate de revisar tu aplicación PHP para asegurarte de que todos los datos que se insertan sean válidos. También sería bueno investigar por qué ocurrían problemas sin establecer esto, ya que podrían haber soluciones más específicas y seguras sin necesidad de desactivar todas las validaciones. ### Links interesantes - [Como ejecutar tu acceso a mysql en un Directadmin sin usar root](https://wiki.castris.com/books/tips-para-programadores/page/mysql-conexion-via-socket-como-saber-donde-esta) - [Mysql conexión vía socket. Como saber donde está](https://wiki.castris.com/books/tips-para-programadores/page/mysql-conexion-via-socket-como-saber-donde-esta) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Backups Cuestiones sobre backups, tips con rsync, etc. # Rsync sobre sistemas remotos # Introducción [rsync](https://linux.die.net/man/1/rsync) es una aplicación que ofrece un sistema de transmisión de ficheros, de forma incremental que permite la generación de sistemas de backups muy efectivos. Uno de los mejores ejemplos es [Time Machine](https://support.apple.com/es-es/HT201250) de Apple, que no es sino una interface visual de rsync Sin embargo muchos sitios expresan o ponen a disposición de los usuarios ejemplos que usados en un escenario diferente del usado en un entorno personal o corporativo, son fuente de problemas. Como norma general se usa el parámetro `-a` o `--archive` el cual es el equivalente a `-rlptgoD` lo cual supone que los parámetros de usuario y grupo, y los permisos de lectura, escritura y ejecución intentarán ser clonados, cosa que no funcionará e incluso creará problemas silenciosos en un entorno en el que los usuarios y grupos no son los mismos en origen que en destino. ## Parámetros de rsync para usar en sistemas remotos no coincidentes El escenario es el de realizar un backup de un sistema completo (disco principal) en un usuario remoto (no root) ``` # rsync --devices --specials --hard-links --one-file-system --recursive --links --times --no-perms --no-group --no-owner --itemize-changes / remote_user@remote.host:/remote/path ``` ### Parámetros con rsync-time-backup Dado que es un programa basado en rsync con sus propias normas para anular su configuración debemos usar otro camino con `--rsync-set-flags` ``` --rsync-set-flags "-D --numeric-ids --links --hard-links -rlt --no-perms --no-group --no-owner --itemize-changes" ``` ### Parámetros Deberás ajustar los parámetros a tu escenario, pero te explico los que he usado aquí. | Corto | Normal | Descripción | | :------ | :--------- | :--------------- | | -D | | El mismo que --devices -aspecials | | -l | --links | copia los enlaces simbólicos como enlaces simbólicos | | -H | --hard-links | preserva los enlaces duros | | -x | --one-file-system | No copiará los dispositivos montados. Si tu sistemas tiene particiones como /var /usr y quieres copiar algo de aqui, esta opción NO debería estar aquí | | -r | --recursive | Copiara recursivamente | | -t | --times | Necesario sobre todo si no usamos -a, ya que será parte de la marca para saber si el fichero debe o no ser transferido o actualizado | | --no-perms | | No copiara los permisos originales. De esta forma no nos encontraremos con problemas de eliminación, uso, debidos a cuestiones de propietario /permisos. Como contrapartida, nos obliga a a tener un sistema de metadatos, que sí guarde esta información. | | --no-group | | Para evitar el uso del grupo del propietario del fichero | | --no-owner | | Para evitar actualizar el propietario del fichero | ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # rsync-time-backup: include y exclude ## Introducción [rsync-time-backup](https://github.com/laurent22/rsync-time-backup) es una buena herramienta con la salvedad de que no tiene limite por fechas de los backlups continuos basados en rsync. Es un clon de Time Machine de Mac. Si trabajamos con sistemas completos hay muchos directorios y ficheros que debemos excluir e incluir. ### Include and Exclude > Si trabajamos con sistemas remotos, deberías leer [Rsync sobre sistemas remotos](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/rsync-sobre-sistemas-remotos) o tendrás problemas con los permisos y el pruning en las rotaciones de backups expirados. - **-** Excluye el directorio o fichero - **+** Añade el directorio o fichero, siendo útil cuando hemos excluido un directorio superior. Ejemplo ```bash - /backupremote2/ - /bin - /boot - /cdrom - /dev - /lib - /lib32 - /lib64 - /libx32 - /media - /mnt - /opt - /proc - /run - /sbin - /snap - /srv - /swap.img - /sys - /tmp + /usr/local/ispconfig/ - /usr/* + /var/www/ - /var/backup/ - /var/lib/ - /var/log/ - /var/spool/ - /var/vmail/ - /var/webmin/ - /var/tmp/ - *.oh-my-zsh* - *.git* - /var/www/clients/client1/web4/web/media/catalog/product/cache/* - /var/www/clients/client1/web4/web/var/* - /var/www/newsexsations.es/web/var/* - /var/www/newsexsations.es/web/media/catalog/product/cache/* - */cache/* - */usr/* ``` Una [respuesta](https://stackoverflow.com/questions/8270519/rsync-exclude-a-directory-but-include-a-subdirectory#answer-8270881) que ta ayudará a entender el [RsyncTutorial](https://web.archive.org/web/20230126121643/https://sites.google.com/site/rsync2u/home/rsync-tutorial/the-exclude-from-option) que propone el desarrollador, algo lioso. ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Tips and Tricks Trucos para usuarios linux # Como convertir ficheros .flac a .mp3 en el shell de linux con ffmpeg # Introducción Algunas veces me descargo o me pasan algun disco de música clasica en forma [.flac](https://es.wikipedia.org/wiki/FLAC) y la verdad, ni tengo el equipo para tal audición, ni tanto espacio en mis saturados discos. Asi que lo mejor es convertirlos a [.mp3](https://es.wikipedia.org/wiki/MP3) (también puedes hacerlo a .ogg si eres muy OpenSource (aunque mp3 ya es formato abierto) ## Convertir todos los ficheros .flac de un directorio a .mp3 con ffmpeg en linux con el shell Bueno, ni que decir tiene que debes tener instalado **fmpeg** y los codecs, pero eso lo dejo para otro momento. ### Recursivo ``` find -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \; ``` ### Un solo nivel ``` find -maxdepth 1 -name "*.flac" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \; ``` ## Enlaces - [man ffmpeg](https://linux.die.net/man/1/ffmpeg) - [find](https://linux.die.net/man/1/find) - [Los 28 comandos más útiles de FFmpeg](https://www.thinkinglin.es/es/los-28-comandos-mas-utiles-de-ffmpeg/) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Teclas Inicio (Home) y Final (End) en ZSH y oh-my-zsh con Powershell # Introducción La verdad es que me encanta usar [ZHS](https://es.wikipedia.org/wiki/Zsh) en combinación de [Oh-My-Zsh](https://ohmyz.sh/) y el tema [PowerLevel10k](https://github.com/romkatv/powerlevel10k) pero tenía un problema con las teclas Inicio (Home) y Fin (End) que no funcionan. Al final lo solucioné y te cuento como lo hice. ## Solución al problema Para probar si te va a funcionar antes de editar el fichero de configuración de zsh, te aconsejo que ejecutes en el terminal y después pruebes las teclas: ``` ❯ bindkey "\033[1~" beginning-of-line ❯ bindkey "\033[4~" end-of-line ``` Si te funciona (debería), es necesario editar el fichero ~/.zshrc y añadirlo. Después ejecuta: ``` ❯ source ~/.zshrc ``` ## Enlaces - [Candrew34 en github -> Cannot using home/end key after install oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh/issues/3061) - [List of zsh bindkey commands](https://www.xspdf.com/resolution/55235069.html) - [Binding Keys in Zsh – jdhaos’s blog](https://jdhao.github.io/2019/06/13/zsh_bind_keys/) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Linux, paquetes instalados desde el shell # Introducción A veces necesitamos conocer que paquetes tenemos instalados en nuestra distribución linux. Y no usamos un entorno gráfico. ## Distribuciones basadas en .deb Para conocer qué paquetes están instalados en nuestra distribución linux, desde el shell ejecutaremos ``` # apt list --installed | grep nginx WARNING: apt does not have a stable CLI interface. Use with caution in scripts. nginx/stable,now 1.18.0-2~focal amd64 [installed,upgradable to: 1.20.1-1~focal] ``` ## Distribuciones basadas en .rpm ``` rpm -qa | grep apache ea-apache24-mod_bwlimited-1.4-47.52.2.cpanel.x86_64 ... ea-apache24-2.4.48-3.12.1.cpanel.x86_64 ... ``` ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Cómo instalar y activar el repositorio EPEL en Centos 7/8 # Introducción El repositorio EPEL (Extra Packages for Enterprise Linux) es un repositorio de un grupo de Fedora que crea, mantiene y administra una serie de paquetes **.rpm** ausentes o presentes en versiones anticuadas, para mejorar las capacidades de las distros basadas en Redhat (RHEL, CentOs, Scientific Linux, Fedora) Sus instalación en un servidor con cPanel requiere ciertas normas para evitar problemas posteriores, que algunas veces pueden ser bastante graves para nuestro sistema. ## Instalación EPEL (CentOs 7/8) ![Instalación EPEL (CentOs 7/8)](https://multimedia.castris.com/imagenes/wiki/cpanel/centos_epel_install.png) ``` [root@centos7 ~]# yum -y install epel-release Complementos cargados:fastestmirror Loading mirror speeds from cached hostfile * base: mirror.tedra.es * extras: mirror.tedra.es * updates: mirror.tedra.es Resolviendo dependencias --> Ejecutando prueba de transacción ---> Paquete epel-release.noarch 0:7-11 debe ser instalado --> Resolución de dependencias finalizada Dependencias resueltas ============================================================================================================================================================================================= Package Arquitectura Versión Repositorio Tamaño ============================================================================================================================================================================================= Instalando: epel-release noarch 7-11 extras 15 k Resumen de la transacción ============================================================================================================================================================================================= Instalar 1 Paquete Tamaño total de la descarga: 15 k Tamaño instalado: 24 k Downloading packages: epel-release-7-11.noarch.rpm | 15 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Instalando : epel-release-7-11.noarch 1/1 Comprobando : epel-release-7-11.noarch 1/1 Instalado: epel-release.noarch 0:7-11 ¡Listo! ``` ### Desactivación (cpanel consejo) Por defecto un repositorio se instalan activados, lo cual es bastante peligroso en un servidor con cPanel o con otro panel intrusivo (el 99,9% lo son) Deberemos editar el fichero de configuración del repositorio `/etc/yum.repos.d/epel.repo` editando la línea `enable=1` a `enable=0` ``` [epel] name=Extra Packages for Enterprise Linux 7 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch failovermethod=priority enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 ``` Cuando queramos instalar o actualizar algún paquete del repositorio epel deberemos usar la opción `--enablerepo=epel` en nuestro comando yum **Ejemplo** ``` [root@centos7 ~]# yum --enablerepo=epel -y install snapd ``` #### Verificacion doble de desactivación Como es importante, deberíamos hacer una doble verificación de que el repositorio no está activo, con el comando `yum repolist` que en caso de no estar activo, no lo mostrará. ``` [root@centos7 ~]# yum repolist Complementos cargados:fastestmirror Loading mirror speeds from cached hostfile * base: mirror.tedra.es * extras: mirror.tedra.es * updates: mirror.tedra.es id del repositorio nombre del repositorio estado base/7/x86_64 CentOS-7 - Base 10.072 extras/7/x86_64 CentOS-7 - Extras 498 updates/7/x86_64 CentOS-7 - Updates 2.579 repolist: 13.149 ``` ## Conocer los paquetes disponibles en EPEL Es un comando sencillo que mostrará la lista de paquetes del repositorio. ``` [root@centos7 ~]# yum --disablerepo="*" --enablerepo="epel" list available Complementos cargados:fastestmirror Loading mirror speeds from cached hostfile * epel: mirror.eixamcoop.cat Paquetes disponibles 0ad.x86_64 0.0.22-1.el7 epel 0ad-data.noarch 0.0.22-1.el7 epel 0install.x86_64 2.11-1.el7 epel 2048-cli.x86_64 0.9.1-1.el7 epel 2048-cli-nocurses.x86_64 0.9.1-1.el7 epel . . . ``` ![Lista de paquetes de EPEL disponibles](https://multimedia.castris.com/imagenes/wiki/cpanel/epel_list_available.png) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Conocer el tamaño de unas carpetas ignorando los enlaces duros (rsync) ## Rsync, enlaces duros y du En mi trabajo uso rsync con un sistema de enlaces duros, como el **Time Machine** de Apple. Y a veces es bueno saber o conocer, el tamaño de las carpetas ignorando los enlaces duros, en los que esta basado este sistema de backup continuo. ## du ``` $ du -hc --max-depth=1 path/ 24G rsync/2022-03-17-065908 1.6M rsync/2022-03-17-072202 1.2G rsync/2022-03-17-105858 1.1G rsync/2022-03-17-074333 79.9G rsync/ 79.9G total ``` - [Man page command du](https://linuxcommand.org/lc3_man_pages/du1.html) - [How to get folder size ignoring hard links?](https://unix.stackexchange.com/questions/118203/how-to-get-folder-size-ignoring-hard-links/471834#471834) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como esta, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Ssh se sale (break) de un ciclo (loop) en un script bash ## Introducción Uso [Rsync time backup](https://github.com/laurent22/rsync-time-backup) para algunos proyectos, pero el caso de uno en particular con más de 8TB de ficheros a mantener en backup, y con múltiples usuarios, prefiero usar una estrategia de copia de seguridad por usuario. Cuando programé el script bash rápido para hacer este trabajo, me encontré que la finalización del script se alcanzaba tras leer el completar la primera copia de seguridad. Tras finalizar correctamente el proceso de sincronización. El problema es que **ssh** lee desde la entrada estándar, por lo tanto, se come todas las líneas restantes. ## Solución al problema en ssh ```bash ssh $USER@$SERVER "COMMAND_IN_REMOTE" < /dev/null ``` También podemos usar `ssh -n` en lugar de la redirección a ninguna parte. > -n' Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A common trick is to use this to run X11 programs on a remote machine. For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel. The ssh program will be put in the background. (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.) ## Solución en Rsync time backup En este software no hay posibilidad de modificar o usar el parámetro -n asi que solo se puede hacer via redirección a ninguna parte `< /dev/null` ```bash while IFS= read -r line do case $line in appdata_ociz9efdik2y|transmission-daemon|updater-ociz9efdik2y) continue ;; *) echo "$line" /srv/mypath/diwan/rsync-time-backup/rsync_tmbackup.sh --rsync-set-flags "-D -zz --numeric-ids --links --hard-links -rlt --no-perms --no-group --no-owner --itemize-changes" --strate gy "1:1 7:7 30:30" -p 9999 root@mypath.domain.net:/data/"$line" /srv/storage/mypath/rsync/"$line" < /dev/null ;; esac done < "$input" ``` ## Agradecimientos - [ssh breaks out of while-loop in bash - duplicate](https://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash) - [While loop stops reading after the first line in Bash](https://stackoverflow.com/questions/13800225/while-loop-stops-reading-after-the-first-line-in-bash) - [ssh(1) - Linux man page](https://linux.die.net/man/1/ssh) #### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Redis Failed to start Advanced key-value store. ## Introducción En algún momento nuestro servidor **Redis** falla, y deja de estar operativo. Reiniciamos pero no arranca y en su lugar muestra un error cuando hacemos un `sudo systemctl status redis-server` ```bash jun 02 17:43:33 abkrim-nox systemd[1]: Failed to start Advanced key-value store. ``` Por más que lo intentamos no lo consigue. Veamos que podemos hacer. ### Analizando el problema #### Systemctl logs ``` journalctl -xeu redis-server.service ░░ The job identifier is 3699 and the job result is done. jun 02 17:45:14 abkrim-nox systemd[1]: redis-server.service: Start request repeated too quickly. jun 02 17:45:14 abkrim-nox systemd[1]: redis-server.service: Failed with result 'exit-code'. ░░ Subject: Unit failed ░░ Defined-By: systemd ░░ Support: http://www.ubuntu.com/support ░░   ░░ The unit redis-server.service has entered the 'failed' state with result 'exit-code'. jun 02 17:45:14 abkrim-nox systemd[1]: Failed to start Advanced key-value store. ``` Bueno ya tenemos una pista pero viendo los logs (bendita bitácora) podemos obtener más información. ``` sudo tail -n100 /var/log/redis/redis-server.log … 7471:M 02 Jun 2022 17:48:00.413 * DB loaded from base file appendonly.aof.66.base.rdb: 0.000 seconds 7471:M 02 Jun 2022 17:48:00.893 # Bad file format reading the append only file appendonly.aof.66.incr.aof: make a backup of your AOF file, then use ./redis-check-aof --fix ```` Con esto vemos que nuestra configuración de redis esta configurado para usar una estrategia AOF (append-only file) para evitar perdidas de datos en caso de una terminación brusca (energía, kill -9,..) que no permita la escritura de los datos activos a disco. ```appendonly yes``` Y además de esto, nuestro fichero AOF esta corrupto. Así pues hay que recuperarlo. ### Reparando el fichero AOF El comando general es `redis-check-aof –fix ahora falta encontrar tanto el binario de la utilidad como el fichero. En mi caso un Ubuntu 22.04 con redis instalado vía repositorio, siendo la versión 6.7 ```bash ❯ sudo ls -lisah /var/lib/redis total 16K 17170880 4,0K drwxr-x---  3 redis redis 4,0K jun  2 20:19 . 16777254 4,0K drwxr-xr-x 94 root  root  4,0K may 31 10:43 .. 17170910 4,0K drwxr-x---  2 redis redis 4,0K jun  2 18:34 appendonlydir 17170564 4,0K -rw-rw----  1 redis redis 1,6K jun  2 20:19 dump.rdb ❯ sudo ls -lisah /var/lib/redis/appendonlydir total 836K 17170910 4,0K drwxr-x--- 2 redis redis 4,0K jun  2 18:34 . 17170880 4,0K drwxr-x--- 3 redis redis 4,0K jun  2 20:19 .. 17171350 4,0K -rw-rw---- 1 redis redis 1,6K jun  2 18:34 appendonly.aof.67.base.rdb 17171130 820K -rw-r----- 1 redis redis 815K jun  2 20:21 appendonly.aof.67.incr.aof 17171294 4,0K -rw-r----- 1 redis redis   92 jun  2 18:34 appendonly.aof.manifest ``` Así pues el comando sería ```bash sudo /usr/bin/redis-check-aof --fix /var/lib/redis/appendonlydir/appendonly.aof.manifest Start checking Multi Part AOF Start to check BASE AOF (RDB format). [offset 0] Checking RDB file appendonly.aof.66.base.rdb [offset 26] AUX FIELD redis-ver = '7.0.0' [offset 40] AUX FIELD redis-bits = '64' [offset 52] AUX FIELD ctime = '1653893946' [offset 67] AUX FIELD used-mem = '5178616' [offset 79] AUX FIELD aof-base = '1' [offset 81] Selecting DB ID 0 [offset 3048] Checksum OK [offset 3048] \o/ RDB looks OK! \o/ [info] 19 keys read [info] 9 expires [info] 9 already expired RDB preamble is OK, proceeding with AOF tail... AOF analyzed: filename=appendonly.aof.66.base.rdb, size=3048, ok_up_to=3048, ok_up_to_line=1, diff=0 BASE AOF appendonly.aof.66.base.rdb is valid Start to check INCR files. AOF appendonly.aof.66.incr.aof format error AOF analyzed: filename=appendonly.aof.66.incr.aof, size=64241117, ok_up_to=64238121, ok_up_to_line=4261202, diff=2996 This will shrink the AOF appendonly.aof.66.incr.aof from 64241117 bytes, with 2996 bytes, to 64238121 bytes Continue? [y/N]: y Successfully truncated AOF appendonly.aof.66.incr.aof All AOF files and manifest are valid ``` Después de esto ya podremos iniciar redis ```bash ❯ sudo systemctl restart redis-server ❯ sudo systemctl status redis-server ● redis-server.service - Advanced key-value store     Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)     Active: active (running) since Thu 2022-06-02 17:56:19 CEST; 7min ago       Docs: http://redis.io/documentation,             man:redis-server(1)   Main PID: 12969 (redis-server)     Status: "Ready to accept connections"      Tasks: 6 (limit: 38330)     Memory: 3.9M        CPU: 1.538s     CGroup: /system.slice/redis-server.service             └─12969 "/usr/bin/redis-server 127.0.0.1:6379" "" "" "" "" "" "" "" jun 02 17:56:18 abkrim-nox systemd[1]: Starting Advanced key-value store... jun 02 17:56:19 abkrim-nox systemd[1]: Started Advanced key-value store. ``` ### Enlaces - [Redis persistence](https://redis.io/docs/manual/persistence/) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Comando find con -maxdepth excluyendo el propio directorio ## Comando find con -maxdepth excluyendo el propio directorio A veces es necesario ejecutar este comando de manera recursiva pero queremos obviar el propio directorio desde el que se ejecuta como por ejemplo para eliminar todos directorios de una carpeta de rsync con enlaces duros de forma ordenada. ```bash find . -maxdepth 1 -type d | sed -r '/^\.$/d' ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Du y los ficheros o directorios ocultos ## El comando du y los ficheros ocultos Muchas veces al usar el comando `du` para localiza directorios con elevado o anormal consumo de espacio en disco nos topamos, con un directorio en el que la información que `du` nos ofrece no se ajusta a nivel directorio con el nivel subdirectorios. ```bash ❯ du -sh * 1,3G api 7,1G investigo 5,2G sitelight 1,4G sitelight2 ❯ cd investigo ❯ du -sh * 179M investigo/backup 20K investigo/conf 408K investigo/logs 275M investigo/sitelight 3,2G investigo/web ``` Nos faltan casi 4 Gb. ## Comando du incluyendo los directorios ocultos ```bash du -hs investigo/.[^.]* 4,0K investigo/.bash_history 4,0K investigo/.bash_logout 4,0K investigo/.bashrc 3,4G investigo/.cache 604K investigo/.config 8,0K investigo/.emacs.d 4,0K investigo/.gitconfig 32K investigo/.java 96K investigo/.local 4,0K investigo/.mysql_history 32M investigo/.npm 18M investigo/.oh-my-zsh 92K investigo/.p10k.zsh 4,0K investigo/.profile 4,0K investigo/.shell.pre-oh-my-zsh 20K investigo/.ssh 4,0K investigo/.Xauthority 8,0K investigo/.yarn 4,0K investigo/.yarnrc 48K investigo/.zcompdump 52K investigo/.zcompdump-coresitelight-5.8 116K investigo/.zcompdump-coresitelight-5.8.zwc 28K investigo/.zsh_history 12K investigo/.zshrc ``` - [Man page command du](https://linuxcommand.org/lc3_man_pages/du1.html) - [du command does not parse hidden directories](https://superuser.com/questions/342448/du-command-does-not-parse-hidden-directories#answer-633808) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como esta, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Como vaciar o eliminar emails antiguos en dovecot sin usar find ## Dovecot y los comandos olvidados Muchas veces, y me incluyó yo, por vaguería y algo de desconocimiento, pues una se acostumbra a los fácil, usamos una combinación de `find` para hacer un vaciado de alguna cuenta o carpeta de correo que se llenó. Pues bien, eso es mejor hacerlo con las herramientas del propio Dovecot (si es este el sistema de servidor IMAP que usamos) ## Eliminación de correos IMAP por antigüedad ### Ejemplo ```bash doveadm expunge -u jane.doe@example.org mailbox Spam savedbefore 2w ``` ### Obtener la lista de buzones Dado que los buzones se escriben en el shell de distinta manera, para usarse en el comando es bueno obtener la liista ``` doveadm mailbox list -u jane.doe@example.org Archive Mantenimientos Mantenimientos/mysql ASSP Seguridad Seguridad/inmunifyAV Seguridad/Wordfence Services Services/Failed LFD [Gmail] [Gmail]/Importantes Junk Trash Sent Drafts INBOX ``` ### Purgado por asunto ``` doveadm expunge -u jane.doe@example.org mailbox 'Mantenimientos/mysql' HEADER Subject "Palabra Clave" ``` ### Purgado mas complejo HEADER y BODY ``` doveadm expunge -u jane.doe@example.org mailbox 'Mantenimientos/mysql' HEADER Subject "Palabra Clave" BODY "Otro texto" ``` - Consulta la documentación de Dovecot - Expunge - [doveadm: Delete messages older than date](https://serverfault.com/questions/769208/doveadm-delete-messages-older-than-date#answer-769223) ## Eliminación por linea de asunto ### Ejemplo ```bash doveadm expunge -u jane.doe@example.org mailbox INBOX subject Cron ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # rc.local en systemas Debian usando systemd. Ejemplo redis ## Introducción Algunos servicios como **redis** pueden requerir de ciertas configuraciones del sistema para su mejor fucnionamiento, como puede ser **Transparent Huge Pages (THP)** desactivado. Si puedes desactivarlo porque no afecta a otros servicios de tu servidor (atento a esto, que no es salir por la calle del medio sin pensar en las implicaciones) es bueno hacerlo. ```bash 3336867:M 04 Dec 2023 18:05:32.941 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. ``` ## Solución La solución pasa por desactivarlo en el sistema ```bash echo never > /sys/kernel/mm/transparent_hugepage/enabled ``` Pero necesitamos ejecutar esto al reinicio, o perdermos la configuración deseada. La opcion normal sería añadirl al scripot de arranque, como muchos dicen, en `/etc/rc.local` pero distors basadas en Debia, o otras basadas en RedHat, no tiene ese fiochero porque usan ya de hace tiempo **systemd** para la gestión de estas cuestiones. ### Crear un Servicio systemd para Desactivar THP Crear un Archivo de Servicio systemd: Abre un nuevo archivo en el directorio de servicios de systemd con un editor de texto como nano o vim. Por ejemplo: ``` sudo nano /etc/systemd/system/disable-thp.service ``` Donde añadimos ``` [Unit] Description=Disable Transparent Huge Pages (THP) [Service] Type=oneshot ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' [Install] WantedBy=multi-user.target ``` Lo habilitamos ``` sudo systemctl daemon-reload sudo systemctl enable disable-thp.service sudo systemctl start disable-thp.service ``` Verificamos ``` cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Bad Bots y la pesadilla del tráfico. Htaccess en Apache 2.4 Cada vez esta pero el tema. Un ejercito de web scrappers, de personas dedicadas a vivir de crear contenido falso, indexable, o de robar imáganes, pulula por la red. Una de las mejores formas de acabar con ellos es denegarles el acceso, en nuestro fichero `.htaccess` ## .htaccess anti bad bots La cuesgtión es añadir la lista de robots no deseados en nuestro fichero `.htaccces` usando para ello las directivas `setenvif` ``` # Start Bad Bot Prevention # SetEnvIfNoCase User-Agent ^$ bad_bot SetEnvIfNoCase User-Agent "^12soso.*" bad_bot SetEnvIfNoCase User-Agent "^192.comAgent.*" bad_bot SetEnvIfNoCase User-Agent "^1Noonbot.*" bad_bot ... Order Allow,Deny Allow from all Deny from env=bad_bot # End Bad Bot Prevention ``` - `` Esta directiva comprueba si el módulo mod_setenvif está habilitado. Si lo está, se ejecuta el código dentro de este bloque. - `SetEnvIfNoCase User-Agent "^12soso.*" bad_bot`: Esta directiva establece una variable de entorno llamada bad_bot si el User-Agent comienza con "12soso". - ``: Esta directiva limita las reglas dentro de este bloque a los métodos HTTP especificados (GET, POST y PUT). - `Order Allow,Deny`: Define el orden en el que se aplican las reglas de acceso. Primero se aplican las reglas `Allow` y luego las reglas `Deny` - `Allow from all`: Permite el acceso a todos por defecto. - `Deny from env=bad_bot`: Deniega el acceso a cualquier solicitud que tenga la variable de entorno bad_bot establecida. - los ` En Macos lo ficheros `/etc` realmente estan en `/private/etc/` ## Usar `visudo` para la edición (aconsejado) Editar el archivo `/etc/sudoers` directamente puede ser arriegado, ya que un error de sintaxis puede bloquear el acceso administrativo. Por ello, se recomienda utilizar el comando `visudo`, que verifica la sintaxis antes de aplicar los cambios. ### Hacer un backup antes de editar Antes de modificar el archivo `sudoers`, es prudente realizar una copia de seguridad: ```bash sudo cp /etc/sudoers /etc/sudoers.backup_$(date +%Y%m%d) ``` Este comando crea una copia del archivo `sudoers` con la fecha actual, facilitando la restauración en caso de errores. ### Editar con `visudo` Para editar el archivo `sudoers` de manera segura: ```bash sudo visudo ``` Este comando abre el archivo en el editor predeterminado configurado para `visudo` (generalmente `nano` o `vi`) y verifica la sintaxis al guardar. ### Diferentes posibilidades de configuración #### Permitir `sudo` sin pedir contraseña Para que un usuario pueda ejecutar comandos con `sudo` sin necesidad de ingresar una contraseña, añade la siguiente línea en el archivo `sudoers`: ```sudoers usuario ALL=(ALL) NOPASSWD:ALL ``` **Ejemplo:** ```sudoers javier ALL=(ALL) NOPASSWD:ALL ``` #### Permitir `sudo` sin pedir contraseña pero limitado a algunos comandos Para otorgar permisos de `sudo` sin contraseña pero restringidos a comandos específicos: ```sudoers usuario ALL=(ALL) NOPASSWD:/ruta/al/comando1, /ruta/al/comando2 ``` Si tenemos mas d eun comando puede ser mas pratico usar una variable, un fichero de .conf especifico. ```bash touch /etc/sudoers.d/mi_usuario_sudo visudo -f /etc/sudoers.d/mi_usuario_sudo ``` Añade la configuración deseada (es un ejemplo) ```bash Cmnd_Alias PRTG = /usr/sbin/csf, /usr/local/directadmin/scripts/letsencrypt.sh, /usr/bin/ls, /usr/bin/cat, /usr/bin/tail admin ALL=(ALL) NOPASSWD: PRTG ``` Guadar y cerrar. **Ejemplo:** ```sudoers javier ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx ``` **Atención:** En sistemas como macOS, una configuración incorrecta que elimina la solicitud de contraseña puede bloquear el acceso administrativo si no existe otro usuario con privilegios de superadministrador. ### Usar `/etc/sudoers.d/` para configuraciones específicas de usuarios En lugar de modificar directamente el archivo `sudoers`, es posible crear archivos individuales para cada usuario en el directorio `/etc/sudoers.d/`. Esto facilita la gestión y evita conflictos. #### Creación de un Archivo de Configuración para un Usuario 1. **Crear el Archivo:** ```bash sudo nano /etc/sudoers.d/usuario ``` 2. **Añadir las Reglas de `sudo`:** **Permitir `sudo` sin contraseña:** ```sudoers usuario ALL=(ALL) NOPASSWD:ALL ``` **Permitir `sudo` sin contraseña pero limitado a ciertos comandos:** ```sudoers usuario ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx ``` 3. **Guardar y Cerrar el Archivo:** Presiona `Ctrl + X`, luego `Y` y `Enter` para guardar los cambios. 4. **Verificar la Sintaxis:** `visudo` automáticamente verifica la sintaxis al editar el archivo. Sin embargo, puedes comprobar manualmente ejecutando: ```bash sudo visudo -cf /etc/sudoers.d/usuario ``` Este comando validará la configuración e inmformará de cualquier error. ## Resumen de comandos clave ```bash # Crear una copia de seguridad del archivo sudoers sudo cp /etc/sudoers /etc/sudoers.backup_$(date +%Y%m%d) # Editar el archivo sudoers de manera segura sudo visudo # Permitir a un usuario ejecutar todos los comandos sin contraseña usuario ALL=(ALL) NOPASSWD:ALL # Permitir a un usuario ejecutar comandos específicos sin contraseña usuario ALL=(ALL) NOPASSWD:/ruta/al/comando1, /ruta/al/comando2 # Crear un archivo de configuración específico para un usuario sudo nano /etc/sudoers.d/usuario # Verificar la sintaxis de un archivo en sudoers.d sudo visudo -cf /etc/sudoers.d/usuario ``` ## Consideraciones Adicionales - **Permisos de Archivos:** Asegúrate de que los archivos en `/etc/sudoers.d/` tengan permisos correctos (generalmente 0440) para evitar problemas de seguridad. ```bash sudo chmod 0440 /etc/sudoers.d/usuario ``` - **Evitar Errores de Sintaxis:** Siempre utiliza `visudo` o editores diseñados para manejar la configuración de `sudo` para prevenir errores que puedan bloquear el acceso administrativo. - **Uso Responsable de `NOPASSWD`:** Otorgar permisos sin contraseña debe hacerse con cautela, limitando el acceso solo a los comandos estrictamente necesarios para minimizar riesgos de seguridad. - **Documentación y Auditoría:** Mantén una documentación clara de las configuraciones realizadas y revisa periódicamente los permisos otorgados para asegurar que siguen siendo necesarios y seguros. - En **MacOS** una configuración erronea del usuario administrador puede ser fatal y muy complicada la recuperación del desastre. Se recomienda por esto y po rmuchas mas cosas, tener siempre un segundo usuario SuperAdmin en un sistema MacOs ## Conclusión El uso adecuado de `sudo` es esencial para la administración segura y eficiente de sistemas Linux. Configurarlo correctamente, utilizando herramientas como `visudo` y aplicando buenas prácticas de seguridad, garantiza que los usuarios puedan realizar tareas administrativas sin comprometer la integridad y seguridad del sistema. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Reparar el fichero .zsh_history: zsh: corrupt history file /home/USER/.zsh_history ## Introducción A ves por lo que sea se corrompe el fichero de historia de [ZSH](https://es.wikipedia.org/wiki/Zsh) `.zsh_history`y nos aparece el mensaje en el shell, cuando entramos al shell, actualizamos [Oh My Zsh](https://ohmyz.sh/) ```zsh zsh: corrupt history file /home/USER/.zsh_history ``` Se puede corregir el archivo de historial corrupto de Zsh (`.zsh_history`) siguiendo estos pasos. La corrupción del archivo de historial puede ocurrir por diversas razones, como cierres inesperados de la terminal o conflictos de escritura. Aquí te muestro cómo solucionarlo: ### Pasos para Corregir un Archivo de Historial Corrupto en Zsh 1. **Hacer una Copia de Seguridad**: Antes de realizar cualquier cambio, es recomendable hacer una copia de seguridad del archivo de historial corrupto: ```bash cp ~/.zsh_history ~/.zsh_history_backup ``` 2. **Eliminar Líneas Corruptas**: Abre el archivo de historial con un editor de texto como `nano` o `vim` y elimina las líneas corruptas o caracteres extraños. Puedes usar el siguiente comando para abrirlo con `nano`: ```bash nano ~/.zsh_history ``` Busca líneas que no tengan sentido o que estén incompletas y elimínalas. 3. **Reparar el Archivo de Historial**: Puedes intentar reparar el archivo de historial usando el siguiente comando, que eliminará líneas corruptas automáticamente: ```bash strings ~/.zsh_history > ~/.zsh_history_clean mv ~/.zsh_history_clean ~/.zsh_history ``` El comando `strings` extrae solo las cadenas de texto legibles, lo que puede ayudar a limpiar el archivo. 4. **Recargar el Historial**: Después de limpiar el archivo, recarga el historial en la sesión actual de Zsh: ```bash source ~/.zshrc ``` 5. **Verificar el Historial**: Asegúrate de que el historial se carga correctamente y que no hay mensajes de error al iniciar una nueva sesión de terminal. ### Notas Adicionales - **Permisos**: Asegúrate de tener los permisos adecuados para editar el archivo `.zsh_history`. - **Consistencia**: Si experimentas problemas frecuentes con el historial, verifica que no haya múltiples instancias de Zsh escribiendo en el archivo al mismo tiempo. Siguiendo estos pasos, deberías poder corregir el archivo de historial corrupto de Zsh y evitar problemas futuros. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # El archivo hosts para trabajar en un servidor o ip distinto del de la resolución DNS ## Introudccion fichero de sistema: hosts El archivo `hosts` es un archivo de texto simple que se utiliza para mapear nombres de host a direcciones IP. Esto es útil para redirigir nombres de dominio a direcciones IP específicas, lo que puede ser especialmente útil durante las migraciones de sistemas para probar configuraciones antes de pasar a producción. ### Ubicaciones del Archivo `hosts` - **Windows**: `C:\Windows\System32\drivers\etc\hosts` - **Linux**: `/etc/hosts` - **MacOS**: `/private//etc/hosts` ### Uso del Archivo `hosts` El archivo `hosts` permite redirigir un nombre de dominio a una dirección IP específica. Esto es útil para pruebas locales o para verificar un sitio web en un servidor diferente antes de cambiar los registros DNS. #### Formato del Archivo `hosts` El archivo `hosts` tiene un formato simple, donde cada línea contiene una dirección IP seguida de uno o más nombres de host. Los comentarios se pueden agregar usando el símbolo `#`. ```plaintext # Example of a hosts file entry 127.0.0.1 localhost 192.168.1.100 example.com www.example.com ``` #### Ejemplo de Uso para Migraciones Supongamos que estás migrando un sitio web a un nuevo servidor con la dirección IP `192.168.1.100` y quieres probar el sitio antes de actualizar los registros DNS. Puedes editar el archivo `hosts` para redirigir el dominio a la nueva IP: 1. **Abrir el Archivo `hosts`**: - Usa un editor de texto con privilegios de administrador para abrir el archivo `hosts` en tu sistema operativo. 2. **Agregar una Entrada para el Dominio**: - Añade una línea en el archivo `hosts` con la nueva dirección IP y el dominio que deseas redirigir. ```plaintext 192.168.1.100 example.com www.example.com ``` 3. **Guardar los Cambios**: - Guarda el archivo y cierra el editor. 4. **Verificar la Redirección**: - Abre un navegador web e ingresa el dominio `example.com`. Deberías ser redirigido a la dirección IP especificada en el archivo `hosts`. ### Consideraciones - **Privilegios de Administrador**: Necesitarás privilegios de administrador para editar el archivo `hosts`.(uso de sudo, su...) - **Cache de DNS**: Puede ser necesario limpiar la caché de DNS después de editar el archivo `hosts` para que los cambios surtan efecto. En Windows, puedes usar el comando `ipconfig /flushdns`. En MacOS y Linux, puedes usar `dscacheutil -flushcache` o `sudo systemd-resolve --flush-caches`. - **Temporalidad**: Recuerda que los cambios en el archivo `hosts` son locales a tu máquina y no afectan a otros usuarios o dispositivos. Este método es muy útil para pruebas y verificaciones antes de realizar cambios en los registros DNS públicos. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Cambiar repositorios de Ubuntu al mirror de OVH ## Objetivo Actualizar los repositorios APT de Ubuntu para que utilicen el mirror de OVH: - Mejora la velocidad y disponibilidad si el servidor está en OVH o cerca geográficamente - Evita usar mirrors como `es.archive.ubuntu.com` o `archive.ubuntu.com`, que pueden tener latencias o caídas ## Mirror recomendado para OVH el suyo propio ``` http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu/ ``` ## Sistemas con /etc/apt/sources.list (formato clásico) ### Copia de seguridad ```bash cp /etc/apt/sources.list /etc/apt/sources.list.bak ``` ### Sustitución automática del mirror ```bash sed -i 's|http://.*\.archive\.ubuntu\.com/ubuntu|http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu|g' /etc/apt/sources.list sed -i 's|http://\([a-z]*\.\)\?archive\.ubuntu\.com/ubuntu|http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu|g' /etc/apt/sources.list ``` - Cambia cualquier mirror genérico o regional por el de OVH - Aplica a todas las entradas (main, security, updates, etc.) ## Sistemas con /etc/apt/sources.list.d/ubuntu.sources (formato deb822) ### Copia de seguridad ```bash cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak ``` ### Sustitución automática del mirror ```bash sed -i 's|URIs: http://.*\.archive\.ubuntu\.com/ubuntu|URIs: http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources sed -i 's|URIs: http://security\.ubuntu\.com/ubuntu/|URIs: http://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources ``` - Cambia cualquier URI de mirror genérico o regional por el de OVH - Aplica a todas las entradas del archivo formato deb822 ## Verificación ```bash apt update ``` - Asegúrate de que todos los paquetes se descargan desde el mirror de OVH - No deberían aparecer errores ni advertencias de conexión ## Recomendaciones - Este cambio puede repetirse en otros ficheros dentro de `/etc/apt/sources.list.d/` - En entornos con múltiples servidores, se recomienda automatizar la sustitución con: - Scripts en bash - Ansible - Herramientas de orquestación o ejecución remota (como pssh) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # PHP PHP es indispensable para un servidor con capacidades Web. Pero existen muchas variantes de como configurar PHP para ser usado en con un servidor web. # PHP log cuando usamos PHP-FPM con host virtuales # Introducción Uno de esos tips que está infravalorado. Podremos ver, decenas de páginas, y cientos de respuestas, en las que todos hablan de cómo configurar el log, de si el path es incorrecto, o de si estas en linux o en windows. Al final el tema está en otro lugar, pues muchos de ellos, contestan si ni siquiera saber qué es PHP-FPM o cuando menos, sin verificar los que dicen que hace lo que escriben. ## Problema En una instalación estándar de PHP-FPM en sistemas Linux, es posible que los errores de PHP no se registren correctamente en los logs de los dominios virtuales. Esto dificulta enormemente la depuración de problemas, ya que los mensajes de error críticos pueden perderse o no quedar registrados en los archivos de log esperados. ## Causa Por defecto, PHP-FPM captura la salida estándar y de error de los workers (procesos de trabajo), pero no la redirige automáticamente a los logs. La directiva `catch_workers_output` está configurada como `no` en la configuración predeterminada, no existir o están simplemente comentada, lo que impide que los errores generados por los scripts PHP se registren adecuadamente. ## Solución Para resolver este problema, es necesario modificar el archivo de configuración del pool de PHP-FPM: 1. Abrir el archivo de configuración del pool (normalmente ubicado en `/etc/php/X.X/fpm/pool.d/www.conf`, donde X.X es la versión de PHP, por ejemplo 7.4, 8.0, 8.1, etc.) 2. Buscar la directiva `catch_workers_output` 3. Cambiar su valor de `no` a `yes`: ``` catch_workers_output = yes ``` 4. Guardar el archivo y reiniciar el servicio PHP-FPM: ```bash sudo systemctl restart php7.4-fpm.service # Ajustar según la versión de PHP ``` ## Explicación técnica Cuando `catch_workers_output = yes` está activado, PHP-FPM captura la salida de los procesos worker y la redirige adecuadamente al sistema de logs. Esto asegura que: - Los errores de PHP aparezcan en los logs específicos del dominio virtual - Los mensajes críticos no se pierdan - Sea más fácil identificar y solucionar problemas en aplicaciones PHP ## Consideraciones adicionales En versiones más recientes de PHP-FPM (7.3+), se recomienda usar las siguientes directivas en lugar de `catch_workers_output`: ``` php_admin_flag[log_errors] = on php_admin_value[error_log] = /ruta/a/error.log ``` Estas opciones ofrecen un mejor rendimiento y mayor control sobre el destino de los logs. ## Importancia Configurar correctamente los logs de error es un paso crucial para: - Facilitar la depuración de aplicaciones - Detectar problemas de seguridad - Monitorizar el rendimiento del servidor - Cumplir con buenas prácticas de administración de sistemas Sin esta configuración, podrías estar operando tus aplicaciones PHP "a ciegas", sin visibilidad sobre los errores que ocurren. ## Otros enlaces - [directive 'catch_workers_output = yes' don't work as I want](https://serverfault.com/questions/936409/directive-catch-workers-output-yes-dont-work-as-i-want) - [PHP-FPM doesn't write to error log](https://stackoverflow.com/questions/8677493/php-fpm-doesnt-write-to-error-log) ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # PHP. Como instalar una nueva versión de PHP en un sistema basado DEB # PHP. Como instalar una nueva versión de PHP en un sistema DEB basado Lo habitual en mis máquinas es tener varias versiones de PHP usando el paquete de XXXXXX. Cuando sale una nueva versión suelo clonar la configuración de módulos, ya que a fin de cuentas luego será la nueva versión en los sitios cuando los actualice y verifique que pueden usar la nuevas version de PHP: ## Proceso de clonado de PHP a otra versión ### Obtener la lista de paquetes de la versión actual Para obtener la lista de todos los paquetes de PHP 8.2 instalados en tu sistema Debian (Raspberry Pi), puedes usar dpkg con grep: ``` dpkg -l | grep php8.2 | awk '{print $2}' > php8.2-packages.txt ``` Esto creará un archivo php8.2-packages.txt que contiene todos los paquetes instalados relacionados con PHP 8.2. ### Crear un fichero con los nombres de paquete actualizados a la nueva versión Ahora, necesitas cambiar 'php8.2' por 'php8.3' en todos los nombres de los paquetes para preparar la instalación de la nueva versión. Puedes hacerlo con sed: ``` sed 's/php8.2/php8.3/g' php8.2-packages.txt > php8.3-packages.txt ``` Esto generará un nuevo archivo php8.3-packages.txt con los nombres de los paquetes modificados para PHP 8.3. ### Script para instalar los paquetes de PHP 8.3 Ahora puedes crear un script que lea el archivo php8.3-packages.txt y use apt para instalar cada paquete. Aquí tienes un ejemplo de cómo podría ser este script: ``` #!/bin/bash # Asegúrate de que el script se ejecute con privilegios de superusuario if [ "$(id -u)" != "0" ]; then echo "Este script debe ser ejecutado como root" 1>&2 exit 1 fi # Actualiza los repositorios e instala los paquetes apt update while read package; do apt install -y $package done < php8.3-packages.txt ``` Guarda este script como `upgrade_to_php8.3.sh`, por ejemplo. ### Ejecutar el script Antes de ejecutar el script, asegúrate de que es ejecutable: ``` chmod +x upgrade_to_php8.3.sh ``` Luego, ejecútalo como root o utilizando sudo: ``` sudo ./upgrade_to_php8.3.sh ``` Este script actualizará tus paquetes a la versión 8.3 de PHP, asegurándose de mantener las mismas extensiones y configuraciones que tenías para la versión 8.2. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Activar PHP8.2 JIT Compiler - Just-In-Time compilation (JIT) ## PHP8.2 JIT Compiler Los lenguajes de programación puramente interpretados no tienen una fase de compilación y ejecutan directamente el código en una máquina virtual. La mayoría de los lenguajes interpretados, incluyendo PHP, de hecho, tienen una ligera fase de compilación para mejorar su rendimiento. Por otro lado, los lenguajes de programación con compilación anticipada (AOT) requieren que el código sea compilado antes de su ejecución. La compilación **Just-In-Time (JIT)** es un modelo híbrido entre el intérprete y la compilación anticipada, donde parte o todo el código se compila, a menudo en tiempo de ejecución, sin que el desarrollador tenga que compilarlo manualmente. Históricamente, **PHP** fue un lenguaje interpretado, donde todo el código era interpretado por una máquina virtual **(Zend VM)**. Esto cambió con la introducción de Opcache y los **Opcodes**, que se generaban a partir del código PHP y podían ser almacenados en memoria caché. PHP 7.0 introdujo el concepto de **AST (Árbol de Sintaxis Abstracta**), que separó aún más el analizador sintáctico del compilador. El JIT de PHP utiliza internamente **DynASM de LuaJIT** y está implementado como parte del **Opcache**. El uso de JIT en PHP es altamente recomendable, no solo para propósito general, sino más aun, es aconsejable producir código de acuerdo a los cambios implementado desde PHP 8.0 que van mucho más allá de la activación de una forma de procesar en el servidor. En particular lo uso en mis servidores en los que hago despliegues con Laravel y francamente, es impresionante. ## Activarlo en el servidor En un servidor con PHP, en múltiples versiones, y con el modo FPM entre otros como uso con el servidor Web, y como ejemplo una Ubuntu, debemos activar JIT que por defecto no esta activado. Encontraremos sus variables disponibles en el fichero `php.ini` de la versión en la que queremos activar JIT, pero como consejo, es mejor no hacerlo ahí. En su lugar debemos hacerlo en `/etc/php/8.2/mods-available/` ya que es ahí donde están los ficheros parciales de cada modulo, y su configuración, tanto para PHP-FPM, como para **PHP en modo cli**. > Esta es una buena práctica que existe en Ubuntu y otras distribuciones de Linux. El fichero en cuestión es `/etc/php/8.2/mods-available/opcache.ini` y contiene por defecto. Esto no activará JIT sino que lo cargará pero lo mostrará **apagado**, por ejemplo usando `phpinfo()` ```bash ; configuration for php opcache module ; priority=10 zend_extension=opcache.so ``` > Si cambias los valores en el `php.ini` general es probable que todo este activado menos el par `JIT On` ![JIT Disable](https://multimedia.castris.com/imagenes/wiki/sysadmin/opcache-jit-disable.jpg) ### Configuración ejemplo Bien, os dejo una configuración bastante funcional en un sistema con uso muy intensivo tanto de php vía colas de Laravel usando php-cli y vía API externa en producción. > Las mejoras son de 8,2 segundos en operaciones intensas a solo 1,2s. ```bash zend_extension=opcache.so opcache.jit=on opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.max_wasted_percentage=5 opcache.validate_timestamps=1 opcache.revalidate_freq=2 opcache.jit_buffer_size=100M opcache.jit=tracing opcache.jit=1255 opcache.save_comments=0 opcache.file_cache=/var/cache/php/opcache ``` Tras el reinicio de PHP-FPM verás algo parecido a esto: ![JIT Activado](https://multimedia.castris.com/imagenes/wiki/sysadmin/opcache-jit-enable.jpg) > Esta configuración `opcache.file_cache` requiere que exista `/var/cache/php/opcache` para servir de segundo nivel de cache (o el que tu definas), y que tenga los permisos para el ejecutor. En algunos sitios veo de usar `www-data` que es el que usa en una Ubuntu con Nginx. Puedes dejarlo vacío, si eres generoso con la memoriza asignada. En realidad, es algo así como el swap en linux. Te aconsejo una vuelta por el fichero `php.ini` principal, para que veas todos los comentarios de cada uno delos valores. Ya sabes, el copia y pega, puede ser fatal, pues lo que a mi me funciona puede que a ti no. ### Enlaces - [Make your app faster with PHP 8.3](https://laravel-news.com/make-your-app-faster-with-php-83) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Instalar una versión de PHP con módulos en Ubuntu con Ondrej copiando de otra versión ya instalada ## Introducción Un sistema rápido para clonar, por asi decirlo, la instalación actual de PHP en modo PHP-FPM con el repositorio [Ondřej Surý](https://launchpad.net/~ondrej/+archive/ubuntu/php) En este caso vamos a describir el instala la 8.0 teniendo una 8.2 instalada ### Paso 1: Obtener la Lista de Paquetes de PHP 8.2 1. **Listar los Paquetes de PHP 8.2 Instalados**: - Usa el siguiente comando para listar los paquetes de PHP 8.2 y guardarlos en un archivo de texto: ```bash dpkg -l | grep php8.2 | awk '{print $2}' > php8.2-packages.txt ``` - Esto creará un archivo `php8.2-packages.txt` con los nombres de los paquetes instalados. ### Paso 2: Modificar la Lista para PHP 8.0 1. **Modificar el Archivo para Usar PHP 8.0**: - Usa `sed` para reemplazar `php8.2` por `php8.0` en el archivo: ```bash sed 's/php8.2/php8.0/g' php8.2-packages.txt > php8.0-packages.txt ``` - Ahora tendrás un archivo `php8.0-packages.txt` con los nombres de los paquetes que necesitas instalar para PHP 8.0. ### Paso 3: Instalar los Paquetes de PHP 8.0 1. **Instalar los Paquetes Usando el Archivo**: - Usa el siguiente comando para instalar todos los paquetes listados en `php8.0-packages.txt`: ```bash sudo xargs -a php8.0-packages.txt apt-get install -y ``` - Este comando usará `xargs` para pasar cada paquete listado en el archivo al comando `apt-get install`. ### Consideraciones Adicionales - **Verificar la Instalación**: Después de la instalación, verifica que PHP 8.0 y sus módulos estén correctamente instalados y configurados. - **Dependencias Adicionales**: Algunos módulos pueden requerir dependencias adicionales que no estén cubiertas por los paquetes listados. Asegúrate de revisar cualquier mensaje de error durante la instalación. Siguiendo estos pasos, podrás automatizar el proceso de instalación de PHP 8.0 y sus módulos basándote en los paquetes de PHP 8.2 que ya tienes instalados. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Proxmox Cosas sobre Proxmox # Git pull, error: server certificate verification failed. CAfile: none CRLfile: none # Introducción El problema me apareció en un proxmox desactualizado, cuando quise hacer un pull de mis utilidades. > git pull fatal: unable to access 'https://*****.castris.com/root/utilidades.git/': server certificate verification failed. CAfile: none CRLfile: none Tras verificar que el problema no estaba del lado de mi gitlab, sospeche de la desactualización de Proxmox. Como nunca actualizo un Proxmox, ya la solución de actualizar sólo los ca-certificates y paquetes relacionados, no funcionó opte por una tip rápido. > No actualizo los proxmox, porque desde la versión 3, que ya son años, he tenido 4 incidentes de actualización, con sus correspondientes problemas derivados. Así que prefiero hacer un un turn-over en mi proveedor, coger una máquina nueva cada dos o tres años, y dejarme de tonterías. Atención, a mis máquinas proxmox no se acceden sino es desde mis ips, otra imposición que me puse dado que he visto muchos proxmox hackeados vía web. Así que al estar capado, no tengo miedo a no "actualizar" ## Modificación de Git para no verificar ssl ``` root@pro12:~/utilidades# git config --global http.sslverify false root@pro12:~/utilidades# git pull remote: Enumerating objects: 23, done. remote: Counting objects: 100% (23/23), done. remote: Compressing objects: 100% (14/14), done. remote: Total 18 (delta 9), reused 12 (delta 4), pack-reused 0 Unpacking objects: 100% (18/18), done. From https://gitlab.castris.com/root/utilidades 10bda88..c93d331 master -> origin/master Updating 10bda88..c93d331 Fast-forward .gitignore | 2 + actualiza.sh | 2 +- basura.sh | 4 + compress-dovecot.sh | 164 ++++++++++ csf/proxmox.csf.conf | 2678 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fixpermisions.sh | 164 ++++++++++ 6 files changed, 3013 insertions(+), 1 deletion(-) create mode 100644 compress-dovecot.sh create mode 100644 csf/proxmox.csf.conf create mode 100644 fixpermisions.sh ``` ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # [PRIV] Instalar Proxmox desde 0 ## OVH ### Seguridad ```bash mkdir /root/soft;cd /root/soft/; wget https://download.configserver.com/csf.tgz; tar xvfz csf.tgz; cd csf; sh install.sh; cd ..; rm -Rf csf/ csf.tgz; \ echo '.cpanel.net .googlebot.com .crawl.yahoo.net .search.msn.com .paypal.com .paypal.es' > /etc/csf/csf.rignore;\ wget -O /etc/csf/csf.conf https://gitlab.castris.com/root/utilidades/-/raw/main/csf/proxmox.csf.conf; \ wget -O /etc/csf/csf.blocklists https://gitlab.castris.com/root/utilidades/-/raw/main/csf/csf.blocklists; \ wget -O /etc/csf/csf.allow ttps://gitlab.castris.com/root/utilidades/-/raw/main/csf/csf.allow; \ wget -O /etc/csf/csf.dyndns https://gitlab.castris.com/root/utilidades/-/raw/main/csf/csf.dyndns ``` ### Discos [Discos proxmox](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/lvm-practico-para-proxmox-y-ovh) ### Utilidades ```bash cd ~ && git clone https://gitlab.castris.com/root/utilidades.git ``` ### Red [Red OVH vrack para Proxmox 7](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/red-ovh-vrack-para-proxmox-7) ### zabbix ### Discos remotos # LVM Práctico para Proxmox y OVH ## Introducción Es un tip que uso para **mis necesidades**. Entre otras, no uso **ZSF** por la carga que supone para el sistema, y porque suplo sus bondades por decisión propia con otros mecanismo de salvaguarda. > Cada modelo de máquina de OVH y cada instalación deja diferencias sutiles que pueden hacer que uno tenga que modificar los datos de particiones, discos, interfaces de red. ## LVM En una instalación sin uso de RAID por software del instalador tenemos en la versión del instalador de OVH que instala 7.2-14 de Proxmox un **volumen** llamado **vg** en el disco primario ``` pvs PV VG Fmt Attr PSize PFree /dev/nvme0n1p5 vg lvm2 a-- 1.72t 0 lvscan ACTIVE '/dev/vg/data' [1.72 TiB] inherit ``` Sobre el cual ha creado un **volume** llamado **vg** y un **volumen lógico** llamado **data** con el tamaño máximo > Mal por todo, porque asigna todo el espacio y no permite hacer snapshots. Este modelo no me sirve pues yo nunca uso virtualización por **OpenVZ** así que hay que eliminar y reconstruir ### Copia de la partición #### Parada de proxmox Versiones anteriores a la 7/8 ``` systemctl stop pve-cluster pvedaemon pveproxy pvestatsd ``` Versiones 7/8 ``` systemctl stop pve-cluster pvedaemon pveproxy ``` #### Copia de /var/lib/vz ``` mkdir /old_vz rsync -avv --progress /var/lib/vz/ /old_vz/ umount /var/lib/vz ``` Debemos por seguridad editar `/etc/fstab` para eliminar o comentar el punto de montaje de `/var/lib/vz/` por si ocurriera algún reinicio por despiste #### Eliminación del volumen ``` lvchange -an /dev/vg/data lvremove /dev/vg/data Logical volume "data" successfully removed ``` #### Creación de un volumen menor Por si acaso, un dia queremos una instancia tipo **OpenVZ** crearemos un volumen lógico pequeño pero suficiente para que esté ahí, por si un día lo queremos usar. ``` lvcreate -n data --size 20GB vg WARNING: ext4 signature detected on /dev/vg/data at offset 1080. Wipe it? [y/n]: y Wiping ext4 signature on /dev/vg/data. Logical volume "data" created. pvscan PV /dev/nvme0n1p5 VG vg lvm2 [1.72 TiB / <1.71 TiB free] Total: 1 [1.72 TiB] / in use: 1 [1.72 TiB] / in no VG: 0 [0 ] mkfs.xfs /dev/vg/data meta-data=/dev/vg/data isize=512 agcount=16, agsize=327680 blks = sectsz=4096 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 bigtime=0 data = bsize=4096 blocks=5242880, imaxpct=25 = sunit=32 swidth=32 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 Discarding blocks...Done. ``` ##### Obtención del UUID ``` blkid … /dev/mapper/vg-data: UUID="c0ede30d-f8a6-4897-a392-39c9dfc542a6" BLOCK_SIZE="4096" TYPE="xfs" ``` ##### Edición de fstab ``` UUID=c0ede30d-f8a6-4897-a392-39c9dfc542a6 /var/lib/vz xfs defaults 0 0 ``` #### Restauración de ficheros del directorio ``` rsync -avv --progress /old_vz/ /var/lib/vz/ systemctl restart pve-cluster pvedaemon pveproxy pvestatsd ``` ## Creación de volúmenes LVM En mi caso, y en este en particular, no deseo ampliar el volumen, sino que prefiero tener 3 volúmenes independientes, por el tipo de máquina que uso y el uso que se va a dar, ya que la velocidad y cargas en el proceso, me son más interesante con 3 volúmenes, que con uno, a la par que la posibilidad de una rotura de LVM es mayor y un riesgo que llevo años sin querer sufrirlo (que alguna vez lo he sufrido) y en los últimos 8 años, no he tenido ningún percance con varias máquinas con este aprovechamiento. ### Reconocimiento de discos ``` disk -l Disk /dev/nvme1n1: 1.75 TiB, 1920383410176 bytes, 3750748848 sectors Disk model: SAMSUNG MZQL21T9HCJR-00A07 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 131072 bytes / 131072 bytes Disk /dev/nvme2n1: 1.75 TiB, 1920383410176 bytes, 3750748848 sectors Disk model: SAMSUNG MZQL21T9HCJR-00A07 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 131072 bytes / 131072 bytes Disk /dev/nvme0n1: 1.75 TiB, 1920383410176 bytes, 3750748848 sectors Disk model: SAMSUNG MZQL21T9HCJR-00A07 Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 131072 bytes / 131072 bytes Disklabel type: gpt Disk identifier: 991EADF9-826A-4A35-B37C-5A1C3D255A5D Device Start End Sectors Size Type /dev/nvme0n1p1 2048 1048575 1046528 511M EFI System /dev/nvme0n1p2 1048576 3145727 2097152 1G Linux filesystem /dev/nvme0n1p3 3145728 45088767 41943040 20G Linux filesystem /dev/nvme0n1p4 45088768 47185919 2097152 1G Linux filesystem /dev/nvme0n1p5 47185920 3750739967 3703554048 1.7T Linux LVM /dev/nvme0n1p6 3750744752 3750748814 4063 2M Linux filesystem Partition 6 does not start on physical sector boundary. // No importante Disk /dev/mapper/vg-data: 20 GiB, 21474836480 bytes, 41943040 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 131072 bytes / 131072 bytes ``` Tenemos pues los discos `nvme1n1`y `nvme2n1` disponibles ### Creación de los grupos de volúmenes Como uso una dinámica de nombres para así hacer más fácil las migraciones entre máquinas Proxmox, haré lo mismo. > Es importante crear los volúmenes de almacenamiento en **particiones** y no sobre el disco completo. #### Partición Usare mi [Parted mejor que fdisk](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/parted-mejor-que-fdisk) Creamos las etiquetas ``` parted -s /dev/nvme1n1 mklabel gpt parted -s /dev/nvme2n1 mklabel gpt ``` Creamos las particiones ``` parted -s /dev/nvme1n1 mkpart primary 0% 100% parted -s /dev/nvme2n1 mkpart primary 0% 100% ``` #### Creación de los volúmenes ``` vgcreate lvm /dev/nvme1n1p1 Physical volume "/dev/nvme1n1p1" successfully created. Volume group "lvm" successfully created vgcreate lvm2 /dev/nvme2n1p1 Physical volume "/dev/nvme2n1p1" successfully created. Volume group "lvm2" successfully created pvscan PV /dev/nvme1n1p1 VG lvm lvm2 [<1.75 TiB / <1.75 TiB free] PV /dev/nvme2n1p1 VG lvm2 lvm2 [<1.75 TiB / <1.75 TiB free] PV /dev/nvme0n1p5 VG vg lvm2 [1.72 TiB / <1.71 TiB free] Total: 3 [<5.22 TiB] / in use: 3 [<5.22 TiB] / in no VG: 0 [0 ] ``` ## Final A partir de aquí, ya tenemos nuestra estructura deseada en LVM para Proxmox. ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Red OVH vrack para Proxmox 7 ## Introducción El artículo es para un escenario de uso del **vrack** de **OVH** en un escenario específico. El alcance es dejar un tip, que uso muy a menudo, y en el que pongo énfasis en poder utilizar asegurándome de que si algo falla, puedo volver atrás con facilidad. ## Configurar la red para OVH Rack con Proxmox 7 ### Copiar configuracion original ```bash rsync -avv /etc/network/interfaces /root/interfaces.bak ``` ### Editar la configuración Editamos la interface que puede ser diferente en cada caso pues con el tiempo cambian, y con los modelos de OVH cambian su forma de conexión a OVH Es importante entender que hay dos interfaces de red y que esas son las que debemos configurar para usar vrack. El modelo que uso, es particular, para mis necesidades. Hay muchas formas de configurar la red con vrack dependiendo de que estemos desplegando en nuestra máquina Proxmox y la red que queremos. ``` auto lo iface lo inet loopback iface eno1 inet manual #auto vmbr0 #iface vmbr0 inet static # address IP.IP.IP.2/24 # gateway IP.IP.IP.254 # bridge-ports eno1 # bridge-stp off # bridge-fd 0 # hwaddress XX:XX:XX:XX:XX:XX # nuevo modelo OVH DHCP auto vmbr0 iface vmbr0 inet dhcp address IP.IP.IP.IP/24 gateway IP.IP.IP.254 bridge-ports eno1 bridge-stp off bridge-fd 0 # for routing auto vmbr1 iface vmbr1 inet manual bridge_ports dummy0 bridge_stp off bridge_fd 0 # Bridge vrack 1.5 auto vmbr2 iface vmbr2 inet manual bridge_ports eno2 bridge_stp off bridge_fd 0 ``` > Un consejo por si hay que reiniciar y usar el IPMI para arreglarlo si la cosa no ha funcionado. Cambiar la contraseña por una sin signos ya que el IPMI no es precisamente amigable con los teclados nacionales. ### Reinicio Hacemos un shutdown de la máquina, y ya tendríamos nuestra red con vrack instalada. ## Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Como arreglar el error Sender address rejected: need fully-qualified address (in reply to RCPT TO command) ## Introducción Algunas veces tenemos hosts (máquinas) de servicio, como Proxmox, en las que las peculiaridades y operativas, nos dejan con ciertos problemas de envío de correo, como los enviados por root (alertas, etc) que son enviados con el nombre corto de `host`en lugar del FQDN. Están configurados con **Postfix**, y el servidor remoto, no permite este tipo de envío de correos (normal) por lo que debemos hacer un mapping en el servidor que está enviando los correos con el hostname corto. ``` Jan 29 00:00:19 smtp postfix/smtpd[389410]: NOQUEUE: reject: RCPT from pro18.XXX.XXX[Z.Z.Z.Z]: 504 5.5.2 : Sender address rejected: need fully-qualified address; from= to= proto=ESMTP helo= ``` ## Solución Crear el fichero `/etc/postfix/canonical` ``` @local @pro18.mydomain.tld @pro18 @pro18.mydomain.tld ``` Añadir la referencia a este fichero de hash ``` canonical_maps = hash:/etc/postfix/canonical ``` Activar el fichero de hash ``` postmap /etc/postfix/canonical service postfix restart ``` ## Documentación [Postfix :: Canonical address mapping](https://www.postfix.org/ADDRESS_REWRITING_README.html#canonical) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Proxmox, Hetzner, y bloques de Ips adicionales en modo Routed ## Introducción Tra una experiencia desastrosa con el proveedor **Scaleway** y su sistema **Elastic Metal** decidí que lo mejor era marcharme. Dado que lo único que me queda allí, era una máquina de Proxmox con failover de máquinas en #OVH, revise los requerimientos de tráfico (Hetzner te da solo 20 TB de tráfico de salida) y me sobraba, ya que la mayoría casi 24TB es tráfico de entrada. Aunque ya había estado allí hace muchos años, nunca lo hice con Proxmox. Os dejo aquí mi experiencia, ya que sus manuales son un poco cuadriculados y ausente para ciertas cosas, y su soporte es nulo, más allá de enviarte a sus manuales. > Casi todos los soportes de grandes proveedores de Hosting y Colo, son parecidos. En cierta manera les entiendo, pero si dan 0 soporte sus manuales tienen que ser impecables. ### Proxmox Modo Routed en lugar de bridge El porqué es claro. Hetzner solo te permite 7 ips por servidor o pasas por caja para coger un bloque, y sus bloques no funcionan en modo bridge. > El modo bridge es como el OVH para IP Failover. Tienes que asignar un MAC vía ticket, robot, api.. El método routed no. El [Manual Hetztner](https://community.hetzner.com/tutorials/install-and-configure-proxmox_ve) es necesario leerlo, o puedes llevarte una sorpresa. En mi caso, la instalación estaba clara: Sin raid (por software es una patata, y además, el alcance de este servidor no requiere de raid), modelo de Routed forzado por el sistema de Hetzner para bloques de IPS adicionales. Bien lo primero que observe y que produjo un choque,m fue que las imágenes de las acciones en el frontend de Proxmox para crear y modificar la red, no concuerdan con lo que luego graba en el fichero `/etc/network/interfaces` Además hay algunos puntos sutiles respecto a la notación de algunas IP. ### IPV4/CIDR El ejemplo te puede llevar a error porque te pone un CIDR `/26` tanto en el texto como el gráfico, si mayor explicación. Resulta que Hetzner no te entrega toda la información en su Robot, y por tanto te aconsejo que calcules tu red. Por si te olvidaste cómo hacerlo mejor te dejo esta [calculadora de redes](https://labvirtual.webs.upv.es/ipcalc.html) aunque es posible que sea mejor que Hetzner te lo diga en un ticket. ### Fichero /etc/network/interfaces En vez del frontend pasamos a modo shell #### Notas sobe algunos elementos usados - CIDR [Classless Inter-Domain Routing](https://es.wikipedia.org/wiki/Classless_Inter-Domain_Routing) - enp41s0 es la interfaz de red que puede ser distinta según modelo. ```bash source /etc/network/interfaces.d/* auto lo iface lo inet loopback iface lo inet6 loopback auto enp41s0 iface enp41s0 inet static address IP_SERVIDOR/CIDR gateway GATEWAY_IP_SERVIDOR up route add -net IP_BLOQUE_IPS netmask 255.255.NETMASK_BLOQUE gw IP_SERVIDOR/ dev enp41s0 #Routed mode iface enp41s0 inet6 static address SUBNET_IPV6::2/64 # Atención al 2 gateway fe80::1 # Revisar al gateway que te da Hetzner para el bloque IPv6 auto vmbr0 iface vmbr0 inet static address IP_SERVIDOR/32 bridge-ports none bridge-stp off bridge-fd 0 iface vmbr0 inet6 static address SUBNET_IPV6::2/64 ``` ### /etc/network/interfaces.d/vm-routes ```bash iface vmbr0 inet static #up ip route add IP_BLOQUE_IPS/28 dev vmbr0 # no me funciono up ip route add IP_BLOQUE_IPS.193/32 dev vmbr0 up ip route add BLOQUE_IPS.194/32 dev vmbr0 up ip route add BLOQUE_IPS.195/32 dev vmbr0 up ip route add BLOQUE_IPS.196/32 dev vmbr0 up ip route add BLOQUE_IPS.197/32 dev vmbr0 up ip route add BLOQUE_IPS.198/32 dev vmbr0 up ip route add BLOQUE_IPS.199/32 dev vmbr0 up ip route add BLOQUE_IPS.200/32 dev vmbr0 up ip route add BLOQUE_IPS.201/32 dev vmbr0 up ip route add BLOQUE_IPS.202/32 dev vmbr0 up ip route add BLOQUE_IPS.203/32 dev vmbr0 up ip route add BLOQUE_IPS.204/32 dev vmbr0 up ip route add BLOQUE_IPS.205/32 dev vmbr0 up ip route add BLOQUE_IPS.206/32 dev vmbr0 iface vmbr0 inet6 static up ip -6 route add SUBNET_IPV6::/64 dev vmbr0 ``` ### Configserver Firewall A mi no me gusta nada el firewall que usa Proxmox, así que sigo usando Configserver CSF, pero esto requiere ciertos añadidos Necesitamos pasarle a CSF la interfaz que hace de Bridge o enrutador. Para ello añadimos el fichero `/etc/csf/csfpre.sh` con los siguientes datos. ``` #!/bin/sh iptables -A INPUT -i vmbr0 -j ACCEPT iptables -A OUTPUT -o vmbr0 -j ACCEPT iptables -A FORWARD -j ACCEPT -p all -s 0/0 -i vmbr0 iptables -A FORWARD -j ACCEPT -p all -s 0/0 -o vmbr0 ``` Y reiniciamos CSF con `csf -ra` Ahora el tráfico funcionará hacia los hosts. ## VPS KVM ### Centos 7 De momento solo he migrado dos máquinas con Centos 7, más adelante pondré los datos de máquinas con modelo Ubuntu y Debian. ``` cat /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR=BLOQUE_IPS.XXX NETMASK=255.255.255.255 SCOPE="peer IP_SERVIDOR_PROXMOX" IPV6INIT=no GATEWAY=peer IP_SERVIDOR_PROXMOX ``` #### Nota importante Tras dos problemas con sod VPS, he encontrado que esta configuración sólo funciona usando NetworkManager. (fecha: 26/02/2023). Espero el lunes o martes tener una respuesta distinta, ya que el NetworkManager nio debe estar axctivo con el pesado de cPanel. El problema reside en que no levanta la tabla de rutas de forma correcta, por lo que no hay enrutamiento correcto hacia internet Importante revisar por si venimos de algún proveedor con otro sistema, que no tengan algún fichero de rutas especificado de su despliegue. ## Lecturas por si acaso Por ejemplo si usas un Centos 6 que teneia el sistema udev antiguo, y cargaba las tarejtas de red con su mac - [Change Network Interface Name: eth0,eth1,eth2+](https://www.shellhacks.com/change-network-interface-name-eth0-eth1-eth2/) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Desactivar los mensajes de log en la consola (Proxmox) ## Introducción Una de las cosas que hago al comenzar con una nueva máquina de Proxmox, es desactivar la redirección de los mensajes de kernel log hacia la consola virtual. Es una pesadilla si te olvidas de de hacerlo, pues el próximo día que necesites acceder a tu servidor Proxmox, vía KVM a distancia (no la con sola de Proxmox si no la de OVH por ejemplo, la de Hetzner) sufrirás la continua emisión de logs a la consola virtual, lo cual hace muchas veces imnposible el trabajo en la consola. ## Solución para desactivar los mensajes del log en la consola virtual ### /etc/sysctl.conf Bien como Proxmox se ejecuta sobre una Debian, edita el fichero `/etc/sysctl.conf` y dejalo como esta aquí debajo: ```bash # Uncomment the following to stop low-level messages on console kernel.printk = 3 3 3 3 ``` No necesitas hacer un restart si no quieres. Puedes activar la configuración como siempre que modificas ese fichero con: ```bash sudo sysctl -p ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Network interfaces nuevo modelo OVH Procedente de Hector. Simpatico ``` auto lo iface lo inet loopback iface enp10s0f0np0 inet manual iface enp10s0f1np1 inet manual auto vmbr0 iface vmbr0 inet static address 91.134.71.252/32 gateway 100.64.0.1 bridge-ports enp10s0f0np0 bridge-stp off bridge-fd 0 hwaddress D8:43:AE:8A:D8:72 iface vmbr0 inet6 static address 2001:41d0:25c:fc00::/56 gateway fe80::1 auto vmbr1 iface vmbr1 inet manual bridge-ports none bridge-stp off bridge-fd 0 ``` # NFS cliente en un sistema linux (rpm o debian) ## Descripción Para montar un cliente NFS, es decir, para que en un sistema podamos montar un path remoto de un servidor NFS necesitamos instalar el cliente NFS. > Atención este artículo es un tip rápido sin entrar en cómo se debe configurar el servidor, ni que puertos abrir en el firewall. ### Instalación cliente ## Centos 7 ```bash yum install nfs-utils; systemctl enable rpcbind; systemctl start rpcbind ``` ### Debian ```bash apt-get install portmap nfs-common ``` ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # SSH SSH es el protocolo que nospermite conectar de forma remota ay segura a nuestra máquinas. # Unable to negotiate with X.X.X.X.X port YY: no matching host key type found. Their offer: ssh-rsa,ssh-dss ## Introduccón Es un extraño error que veces puede acontecer caubndo conectamos a determinados sistemas que han sido actualizados o no, que difieren de la norma general, o entran en conflicto con nuestro cliente SSH por ausencia o defecto de configuración. > Edición y lectura necesaria hasta el final 21/07/2022 ```bash ssh root@remotehost -p2244 Unable to negotiate with 99.99.99.99 port 2244: no matching host key type found. Their offer: ssh-rsa,ssh-dss ``` Con debug ```bash OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022 debug1: Reading configuration data /home/abkrim/.ssh/config debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /etc/ssh/ssh_config line 21: Applying options for * debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts' -> '/home/abkrim/.ssh/known_hosts' debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts2' -> '/home/abkrim/.ssh/known_hosts2' debug2: resolving "remotehost" port 2244 debug3: resolve_host: lookup remotehost:2244 debug3: ssh_connect_direct: entering debug1: Connecting to remotehost [99.99.99.99] port 2244. debug3: set_sock_tos: set socket 3 IP_TOS 0x10 debug1: Connection established. debug1: identity file /home/abkrim/.ssh/id_rsa type 0 debug1: identity file /home/abkrim/.ssh/id_rsa-cert type -1 debug1: identity file /home/abkrim/.ssh/id_ecdsa type -1 debug1: identity file /home/abkrim/.ssh/id_ecdsa-cert type -1 debug1: identity file /home/abkrim/.ssh/id_ecdsa_sk type -1 debug1: identity file /home/abkrim/.ssh/id_ecdsa_sk-cert type -1 debug1: identity file /home/abkrim/.ssh/id_ed25519 type -1 debug1: identity file /home/abkrim/.ssh/id_ed25519-cert type -1 debug1: identity file /home/abkrim/.ssh/id_ed25519_sk type -1 debug1: identity file /home/abkrim/.ssh/id_ed25519_sk-cert type -1 debug1: identity file /home/abkrim/.ssh/id_xmss type -1 debug1: identity file /home/abkrim/.ssh/id_xmss-cert type -1 debug1: identity file /home/abkrim/.ssh/id_dsa type -1 debug1: identity file /home/abkrim/.ssh/id_dsa-cert type -1 debug1: Local version string SSH-2.0-OpenSSH_8.9p1 Ubuntu-3 debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3 debug1: compat_banner: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000002 debug2: fd 3 setting O_NONBLOCK debug1: Authenticating to remotehost:2244 as 'root' debug3: put_host_port: [remotehost]:2244 debug3: record_hostkey: found key type RSA in file /home/abkrim/.ssh/known_hosts:57 debug3: load_hostkeys_file: loaded 1 keys from [remotehost]:2244 debug1: load_hostkeys: fopen /home/abkrim/.ssh/known_hosts2: No such file or directory debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory debug3: order_hostkeyalgs: prefer hostkeyalgs: rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256 debug3: send packet: type 20 debug1: SSH2_MSG_KEXINIT sent debug3: receive packet: type 20 debug1: SSH2_MSG_KEXINIT received debug2: local client KEXINIT proposal debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,sntrup761x25519-sha512@openssh.com,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,ext-info-c debug2: host key algorithms: rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com debug2: MACs ctos: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1 debug2: MACs stoc: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1 debug2: compression ctos: none,zlib@openssh.com,zlib debug2: compression stoc: none,zlib@openssh.com,zlib debug2: languages ctos: debug2: languages stoc: debug2: first_kex_follows 0 debug2: reserved 0 debug2: peer server KEXINIT proposal debug2: KEX algorithms: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 debug2: host key algorithms: ssh-rsa,ssh-dss debug2: ciphers ctos: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se debug2: ciphers stoc: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se debug2: MACs ctos: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96 debug2: MACs stoc: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96 debug2: compression ctos: none,zlib@openssh.com debug2: compression stoc: none,zlib@openssh.com debug2: languages ctos: debug2: languages stoc: debug2: first_kex_follows 0 debug2: reserved 0 debug1: kex: algorithm: diffie-hellman-group-exchange-sha256 debug1: kex: host key algorithm: (no match) Unable to negotiate with 99.99.99.99 port 24: no matching host key type found. Their offer: ssh-rsa,ssh-dss ``` ### Solución en nuestra fichero `~/.ssh/config` (si no existe podemo crearlo) añadimos. ```bash HostKeyAlgorithms ssh-rsa PubkeyAcceptedKeyTypes ssh-rsa ``` ### Problemas Tras el uso de este tip, al día siguiente aparecio una serie de problemas en el que me fallaban las conexiones a todas mis maquinas via ssh, no pudiendo logearme. ```bash No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_1000) ``` Tras una busqueda en internet niguna de las opciones me parecia correcta y algo me indicaba que la salida por la tangente de la edición del config de mi cliente **ssh** era la raíz del problema, desactive las valores indicados. Y todo volvio a funcionar de nuevo. Asi que dejo el tip, porque es posible que ayude a alguien, en ambos sentidos, y proque espero tener un hueco (que dificil) para ponerme con este problema y verlo en amplitud. ### Agradecimientos Iba con prisa y no pude pararme mucho, hasta que un dia el problema ya empezo a ser pesado. Gracias [How To Configure Custom Connection Options for your SSH Client](https://www.digitalocean.com/community/tutorials/how-to-configure-custom-connection-options-for-your-ssh-client) donde se explica superbien como configurar el fichero `~/.ssh/config` por hosts, y cadauno con sus cosas. > En mi caso tenia un fichero para conectarme rápidamente a los mas de 200 servidores que manejo, pero ahora los que me dan problema puedo llamarlos con `ssh` directemente. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # PasswordAuthentication yes pero no funciona ## PasswordAuthentication yes pero no funciona Uno de los problemas de los avances rápidos es que muchas veces pasamos de lego por la lectura de los changelogs. Y este es uno de ellos. Se instaló el servidor Ubuntu 22.04 sin acceso ssh por contraseña, y una vez instalado se decidió habilitarlo. Nada más fácil que como siempre que añadir o editar la línea `PasswordAuthentication yes` en el fichero de configuración y reiniciar el servicio SSH. Pero no, no funciona. Dos opciones a elegir ### Opción 1 Deshabilitar el include a los ficheros en el directorio `/etc/ssh/sshd_config.d/` editando el fichero `/etc/ssh/sshd_config` en la línea que lo incluye `# Include /etc/ssh/sshd_config.d/*.conf` ### Opción 2 Editar el fichero que contiene la línea `PasswordAuthentication no` ya que como norma general el include está al final, por lo que los valores existentes son sustituidos por los que existan en estos ficheros, cambiandolo por `PasswordAuthentication yes` > Esta es mala praxis pues el objeto de este método es sencillo, evitar que en las actualizaciones dejemos de lado la actualización de los ficheros de configuración, para no destruir nuestros cambios. Mucho mejor, usar este aprovechamiento, para poner nuestros valores en aquellas configuraciones existentes, que como norma general, no recibirán cambios. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/cart.php?gid=18). # Cambiar el puerto SSH en Ubuntu 24.04 y Debian Bookworm ## Introducción Cada un tiempo salen cambios, y en la época que vivimos son muy a menudo, y alguno, incluso olvidamos los tiempos de Slackware o mas duro aun, una [Gentoo](https://www.gentoo.org/) o un [Linux From Scratch](https://www.linuxfromscratch.org/). Uno de esos cambios que viene en las ultimas estables de Debian y derivados es uno que puede despistarte con el cambio de puerto para SSH. > En el caso de Redhat/CentOs y derivadas el lío sería otro pero también existe. ### Cambiar el puerto SSH en Ubuntu 24.04 /Debian Bookworn > Debian puede variar algo, pero la idea es la misma. La cuestión esta en que al margen de el cambio de la clave `Port` al puerto deseado en el fichero `/etc/ssh/sshd_config` necesitamos unos pasos adicionales. Si echamos una vista al `systemd` de nuestra distro Ubuntu vemos dos entradas para `ssh` siendo la interesante `/etc/systemd/system/ssh.service.requires` ![Ubuntu 24 : /etc/systemd/system](https://multimedia.castris.com/imagenes/wiki/sysadmin/ubuntu24-etc_systemd_system.jpg) ![Ubuntu 24 : /etc/systemd/system/ssh.service.requires](https://multimedia.castris.com/imagenes/wiki/sysadmin/ubuntu24-etc_systemd_system_service_requires.jpg) Editemos */etc/systemd/system/ssh.service.requires/ssh.socket* ![Ubuntu 24 : /etc/systemd/system/ssh.service.requires : Editar](https://multimedia.castris.com/imagenes/wiki/sysadmin/ubuntu24-etc_systemd_system_service_requires_edit.jpg) Y despues editemos */etc/ssh/sshd_config* ``` Port 0000 # 0000 es el número del puerto deseado y libre ``` Así que se trata de editar la clave `ListenStream` con el mismo puerto que hemos puesto en la configuración de SSHD. > No olvides que esto es después de que al cambiar el valor de `Port` no te funcione 😊 Después es lo habitual en `systemd` por que hay que hacer un reload tras los cambios en `systemd` ``` systemctl daemon-reload systemctl restart ssh ``` > No olvides el firewall 😊😊😊 ### Cambiar también en SSHD (Editado: 6/3/25) Algunos me han preguntado, y si es cierto que también hay que cambiar el puerto en el fichero `/etc/ssh/sshd_conf` ```bash Port XXXXX ``` ### Agradecimientos - [A samon en Forum ARMBian](https://forum.armbian.com/topic/30718-bug-cant-change-the-ssh-port-on-6416-bookworm/?do=findComment&comment=173106) - [A Ephraim Gariguez por su ampliación para la raspi](https://forum.armbian.com/topic/30718-bug-cant-change-the-ssh-port-on-6416-bookworm/?do=findComment&comment=195815) ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Apagando fuegos A veces hay cosas que son propias de un bombero de sistemas # Kernel panic: /init: conf/conf.d/zz-resume-auto: line 1: syntax error: unexpected "(" ## Introducción Nada peor que un kernel panic en un sistema linux y más si este esta en producción. > Que malo es tener servidores **baremetal** en lugar de virtualizar con KVM. Sonbre todo para el corazón. Me llamo un cliente, para apagar el fuego. Centralita de rendimiento espectacular (Dos a tres mil euros la hora de facturación por lineas). Como parta estar offline. E infraestructura sin HA o cuando menos espejos de backup. > Ya me han pedido presupuesto. ![Kernel panic](https://multimedia.castris.com/imagenes/wiki/kernel-panic-2024-ok.jpeg) Lo primero que se observa en [Google](https://www.google.com/search?q=zz-resume-auto+what+is) o [DuckDuckGo](https://duckduckgo.com/?q=zz-resume-auto&ia=web) es que es un problema recurrente con distintos sabores o variantes. Pero lo que nos queda claro es que no se trata de encontrar ese fichero sino de otra cosa. Estamos en OVH así que vamos a abrir un IPMI para tratar de entrar en modo rescate. ## Al rescate ### Consola remota IPMI de OVH Bueno la ilusión se nos fue, cuando vimos que el administrador del equipo, tenia configurado de tal forma no visualizar el screen de arranque, sino entrar directamente al trapo con la carga del kernel (Muy mal compañero). Tampoco el IPMI nos permitía una comunicación correcta del teclado, para forzar la pantalla de inicio, asi que opte por un arranque en modo rescue de OVH basado en una Debian 11. ### Modo rescue Lo primero es ver que tenemos con un fdisk ```bash root@rescue-customer-eu ~# fdisk -l /dev/nvme0n1p1 2048 1048575 1046528 511M EFI System /dev/nvme0n1p2 1048576 999161855 998113280 476G Linux RAID /dev/nvme0n1p3 999161856 1000210431 1048576 512M Linux filesystem /dev/nvme0n1p4 1000211120 1000215182 4063 2M Linux filesystem ``` Que bonito, un RAID por software en un sistema en producción de ese nivel. Vemos que nos cuenta ```bash root@rescue-customer-eu ~ # mdadm --examine --scan ARRAY /dev/md/md2 metadata=1.2 UUID=f3f612c5:98f99127:fd587ee0:8dc97d19 name=md2 root@rescue-customer-eu ~ # mount /dev/md/md2 /mnt mount: /mnt: special device /dev/md/md2 does not exist. ``` #### Limpieza con update-initramfs Bien, vamos a montarlo en modo chroot para poder limpiar el problema ```bash root@rescue-customer-eu ~ # cat /proc/mdstat Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath] [faulty] md127 : active (auto-read-only) raid1 nvme0n1p2[1] 498924544 blocks super 1.2 [2/1] [_U] bitmap: 4/4 pages [16KB], 65536KB chunk unused devices: ``` ¿Porqué? Basado en la salida de `cat /proc/mdstat`, parece que el dispositivo RAID que se ha ensamblado automáticamente al intentar arrancar el sistema en modo rescate es `/dev/md127` y no `/dev/md/md2` como se esperaba inicialmente. Esto puede suceder a veces, donde el número de dispositivo RAID puede cambiar dependiendo de cómo y cuándo se ensambla el RAID durante el arranque del sistema. La salida muestra que el dispositivo `/dev/md127` es un **RAID 1 (espejo)** y actualmente está en modo "auto-read-only" con uno de los dos discos funcionando (indicado por [2/1] [_U], donde _U significa que un disco está faltante o no está funcionando). Problemas a la vista con el raid. Continuar con algunas propuestas no tiene sentido, cuando el raid esta mal, pues se trata de trabajar con el `grub` y sin el raid consistente, ni lo intentes. ```bash update-grub Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.10.0-28-amd64 Found initrd image: /boot/initrd.img-5.10.0-28-amd64 /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. Found linux image: /boot/vmlinuz-5.10.0-27-amd64 Found initrd image: /boot/initrd.img-5.10.0-27-amd64 /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. Found linux image: /boot/vmlinuz-5.10.0-19-amd64 Found initrd image: /boot/initrd.img-5.10.0-19-amd64 /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. /usr/sbin/grub-probe: error: disk `mduuid/f3f612c598f99127fd587ee08dc97d19' not found. done ``` > En este punto decir que algunos de los tips de google, sobre este tema, podrán ser validos en determinadas circunstancias pero aquí, con un raid por software la cosa estaba más clara. Vamos a ensamblar manualmente el array. > ATENCION ⚠️ Lo que se hace, se hace en una máquina con backups, y consciente de lo que haces y de que puede pasar de todo. No soy responsable delos copy & paste sin tener ni idea de sistemas. ```bash mdadm --assemble /dev/md/md2 --uuid f3f612c5:98f99127:fd587ee0:8dc97d19 ``` Después vamos a ver el estado. Es necesario porque lo que haremos después no funcionaria, por los errores que ya tuvimos. ```bash root@rescue-customer-eu:/# cat /proc/mdstat Personalities : [linear] [raid0] [raid1] [raid10] [raid6] [raid5] [raid4] [multipath] [faulty] md127 : active raid1 nvme1n1p2[0] nvme0n1p2[1] 498924544 blocks super 1.2 [2/1] [_U] [===>.................] recovery = 19.6% (98150912/498924544) finish=32.4min speed=205769K/sec bitmap: 4/4 pages [16KB], 65536KB chunk ``` Bien esperaremos hasta que acabe > Si tienes un gran tamaño de discos, tardará. Si tienes discos mecanicos, y raid soft, mejor date una vuelta. Montemos en chroot cuando termine. ```bash mount /dev/md127 /mnt mount -t proc /proc /mnt/proc mount -t sysfs /sys /mnt/sys mount --rbind /dev /mnt/dev mount --make-rslave /mnt/dev chroot /mnt /bin/bash ``` Ahora ya puedes hacer un `update-grub` o editar el fichero por ejemplo para tener la venta splash del arranque para poder elegir un kernel o el modo rescue, etc. En mi caso sirvió el `update-grub` ```bash update-grub Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.10.0-28-amd64 Found initrd image: /boot/initrd.img-5.10.0-28-amd64 Found linux image: /boot/vmlinuz-5.10.0-27-amd64 Found initrd image: /boot/initrd.img-5.10.0-27-amd64 Found linux image: /boot/vmlinuz-5.10.0-19-amd64 Found initrd image: /boot/initrd.img-5.10.0-19-amd64 done ``` > Si estas en un entorno UEFI de arranque, tendrás que asegurarte. de que estas apuntando correctamente Desmontado ``` exit umount /mnt/sys umount /mnt/proc umount /mnt/dev umount /mnt/boot ``` Y finalmente desactivar el kernel rescue de OVH y hacer un shutdown. In Sha Allah... y a disfrutar de tu máquina. ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # your CPU is missing AVX instruction set flag para instalar mongoDb Jetbackup entre otros ## Introducción A veces, como administrador de sistemas, me sorprende la dirección que está tomando el software de uso común, comenzando a enfrentar los mismos problemas que JavaScript y otros lenguajes para cumplir con expectativas inusuales. Lo menciono porque tener que depender de ciertos conjuntos de instrucciones del procesador y habilidades de hardware específicas del modelo de procesador empieza a complicar las cosas. En el caso presentado, se trata de un problema para la instalación de Jetbackup (ver comentario) que requiere **MongoDB**, el cual necesita las banderas [AVX](https://es.wikipedia.org/wiki/Extensiones_Vectoriales_Avanzadas). > Con Jetbackup ya me he llevado unas cuantas sorpresas, como por ejemplo que se "olvida" indicar claramente en la zona de venta qué sistemas operativos están soportados como destino. Entre otras cosas, BusyBox no es compatible con rsync, aunque decían que lo era con SFTP y tampoco lo es. ### Proxmox y su virtualización En mi caso, era un servidor VPS sobre un Proxmox con **48 x AMD EPYC 7413 24-Core Processor**, relativamente moderno, que sí tiene dichas instrucciones: ``` grep -o 'avx' /proc/cpuinfo avx avx ... ## Una linea más por cada core ``` Asi que teniendo una versión de **Proxmox 7.2.14** me limite a usar `cpu: host` en el modelo de procesador del KVM. ``` root@ cat /etc/pve/qemu-server/.conf | grep host cpu: host ``` En versiones más modernas de Proxmox, puedes usar en este caso `EPYC-v3` (disponible en el desplegable de Procesadores de una KVM), que se ajustaría mejor. > Desde hace 15 años que uso Proxmox dejé de actualizarlo. Lo tengo cerrado por firewall completamente (denegar todo y autorizar lo necesario por IP) y cada dos años cambio la máquina y con el cambio la versión. Ya me llevé muchos disgustos con las **actualizaciones**. ##### Aviso Esta documentación y su contenido no implican que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido se entrega tal y como está, sin ninguna obligación ni responsabilidad por parte de [Castris](https://castris.com). Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional). # Nginx # Nginx, para servidores con multiples vhosts a pelo (sin panel) + PHP-FPM ## Nginx Instalado de forma oficial siguiendo la ruta de instalación estándar de Ubuntu. ### Mejoras sobre la configuración original A continuación se describen las mejoras implementadas sobre la configuración estándar. Estas optimizaciones se centran en: - Reducción del TTFB (Time To First Byte) - Refuerzo de seguridad (especialmente en ciphers) - Optimización de rendimiento general Las directivas que comienzan con `# comentario` son personalizaciones, ya sea por adición o modificación. ``` user www-data; worker_processes auto; worker_rlimit_nofile 65535; # Incrementa el límite de archivos abiertos # load_module modules/ngx_http_modsecurity_module.so; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; # Configuración optimizada de eventos events { worker_connections 1024; use epoll; # Método eficiente para Linux multi_accept on; # Acepta múltiples conexiones por proceso } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; ## Mejoras de rendimiento y seguridad probadas durante años sendfile on; # Optimiza el envío de archivos tcp_nopush on; # Optimiza paquetes TCP tcp_nodelay on; # Reduce latencia client_header_timeout 60s; # Tiempo máximo para recibir cabeceras client_body_timeout 60s; # Tiempo máximo para recibir cuerpo client_header_buffer_size 2k; # Tamaño del buffer para cabeceras client_body_buffer_size 256k; # Tamaño del buffer para el cuerpo client_max_body_size 256m; # Tamaño máximo de petición large_client_header_buffers 4 8k; # Buffers para cabeceras grandes send_timeout 60s; # Tiempo máximo de envío keepalive_timeout 30s; # Tiempo máximo de conexión persistente reset_timedout_connection on; # Libera conexiones que expiran server_tokens off; # Oculta la versión de Nginx server_name_in_redirect off; # No incluye nombre del servidor en redirecciones server_names_hash_max_size 512; # Tamaño máximo de la tabla hash server_names_hash_bucket_size 512; # Tamaño del bucket hash # Compresión para optimizar el tráfico gzip on; # Activa la compresión gzip_static on; # Busca versiones pre-comprimidas gzip_vary on; # Añade cabecera Vary gzip_comp_level 6; # Nivel de compresión (equilibrio rendimiento/tamaño) gzip_min_length 1024; # Tamaño mínimo para comprimir gzip_buffers 16 8k; # Buffers para compresión gzip_types text/plain text/css text/javascript text/js text/xml application/json application/javascript application/x-javascript application/xml application/xml+rss application/x-font-ttf image/svg+xml font/opentype; gzip_proxied any; # Comprime respuestas proxy gzip_disable "MSIE [1-6]\."; # Desactiva para IEs antiguos # Configuración de proxy proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass_header Set-Cookie; proxy_buffers 32 4k; proxy_connect_timeout 30s; proxy_send_timeout 90s; proxy_read_timeout 90s; # Configuración para Cloudflare (actualizada: 28/09/2023) # Permite identificar la IP real del visitante detrás de Cloudflare set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; #set_real_ip_from 2400:cb00::/32; # IPv6 (comentados por compatibilidad) #set_real_ip_from 2606:4700::/32; #set_real_ip_from 2803:f800::/32; #set_real_ip_from 2405:b500::/32; #set_real_ip_from 2405:8100::/32; #set_real_ip_from 2c0f:f248::/32; #set_real_ip_from 2a06:98c0::/29; real_ip_header CF-Connecting-IP; # Configuración SSL que cumple con PCI Compliance # Basado en https://blog.ss88.us/secure-ssl-https-nginx-vestacp ssl_protocols TLSv1.2 TLSv1.3; # Elimina protocolos obsoletos (SSLv3) ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM"; #ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; ssl_dhparam dh4096.pem; ssl_ecdh_curve secp384r1; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; # Configuración de caché # IMPORTANTE: Verificar permisos y propiedad de los directorios # Especialmente útil en entornos con alta carga de solicitudes proxy_cache_path /var/cache/nginx levels=2 keys_zone=cache:10m inactive=60m max_size=1024m; proxy_cache_key "$host$request_uri $cookie_user"; proxy_temp_path /var/cache/nginx/temp; proxy_ignore_headers Expires Cache-Control; proxy_cache_use_stale error timeout invalid_header http_502; proxy_cache_valid any 1d; # Bypass de caché para sesiones activas map $http_cookie $no_cache { default 0; ~SESS 1; ~wordpress_logged_in 1; } # Configuración de caché de archivos open_file_cache max=10000 inactive=30s; open_file_cache_valid 60s; open_file_cache_min_uses 2; open_file_cache_errors off; # Configuración de cabeceras y expiración # Mapa de tiempos de expiración según tipo de contenido map $sent_http_content_type $expires { default off; text/html epoch; # No cachear HTML (dinámico) text/css max; # Cachear CSS al máximo application/javascript max; # Cachear JS al máximo ~image/ max; # Cachear imágenes al máximo } ## # Configuración de Hosts Virtuales ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } ``` ### Permisos y propiedad del caché de Nginx Para que Nginx funcione correctamente con la configuración de caché definida, los directorios implicados deben tener los permisos y propiedad adecuados: #### Propiedad (Owner y Grupo) - **Propietario**: El usuario con el que se ejecuta Nginx (típicamente `www-data` en Ubuntu) - **Grupo**: El grupo correspondiente (típicamente `www-data` en Ubuntu) #### Permisos recomendados - `/var/cache/nginx`: 750 (drwxr-x---) - `/var/cache/nginx/temp`: 750 (drwxr-x---) #### Comandos para establecer estos permisos ```bash # Crear los directorios si no existen mkdir -p /var/cache/nginx/temp # Establecer la propiedad correcta chown -R www-data:www-data /var/cache/nginx # Establecer los permisos adecuados chmod 750 /var/cache/nginx chmod 750 /var/cache/nginx/temp ``` Estos permisos garantizan que los directorios sean accesibles únicamente por el usuario que ejecuta Nginx, mejorando la seguridad del sistema al evitar accesos no autorizados a posible información sensible almacenada en caché. ### Configuración de los Virtual Hosts Existen dos enfoques para gestionar los archivos de configuración de hosts virtuales: #### 1. Enfoque centralizado (recomendado para entornos de producción) Los archivos de configuración se colocan en `/etc/nginx/sites-available/` y se enlazan simbólicamente a `/etc/nginx/sites-enabled/`: ```bash ln -s /etc/nginx/sites-available/domain.tld.conf /etc/nginx/sites-enabled/ ``` Ventajas: - Mayor control y seguridad - Centralización de configuraciones - Facilita auditorías de seguridad - Previene cambios accidentales por usuarios sin privilegios #### 2. Enfoque por usuario (útil en entornos único administrador) Los archivos se colocan en directorios de usuario y se enlazan a la configuración principal. Limitaciones: - Los usuarios sin acceso `sudo` no podrán: - Validar configuraciones con `nginx -t` - Recargar el servicio con `systemctl reload nginx` - Reiniciar el servicio con `systemctl restart nginx` #### Configuración inicial (pre-certificado) Antes de obtener el certificado SSL, se debe crear un archivo de configuración sin asignación específica de puertos. Certbot (Let's Encrypt) se encargará de esto durante el proceso de certificación. Ejemplo: ```nginx server { server_name domain.tld www.domain.tld; root /home/user/web/domain.tld/domain/dist; # Ruta para despliegues JS/VUE/React index index.html; # Es ALTAMENTE RECOMENDABLE activar estas cabeceras de seguridad add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; charset utf-8; ## Logs ubicados en la carpeta del usuario para facilitar su acceso access_log /home/user/logs/web/domain.tld.log combined; error_log /home/user/logs/web/domain.tld.error.log error; expires $expires; # Utiliza la variable map definida en nginx.conf # Si has compilado y tienes operativo mod_security, descomenta la línea siguiente # include /etc/nginx/modsec/active.conf; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } #error_page 404 /index.php; location / { root /home/user/web/domain.tld/domain/dist/; index index.html; try_files $uri $uri/ /index.html; # Configuración para SPAs (React, Vue, etc.) #try_files $uri $uri/ =404; # Alternativa para sitios estáticos location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|css|js)$ { access_log off; log_not_found off; expires max; } } # Bloqueo de archivos de configuración sensibles location ~* "/\.(htaccess|htpasswd|env)$" { deny all; return 404; } # Bloqueo de archivos y directorios ocultos location ~ /\.(?!well-known).* { deny all; } } ``` ##### Configuración de la variable `$expires` Esta variable se declara mediante la directiva `map` en el archivo `nginx.conf`. Si no está declarada, su uso generará un error. ```nginx map $sent_http_content_type $expires { default off; text/html epoch; # No cachear HTML (fecha 1/1/1970) text/css max; # Cachear CSS al máximo application/javascript max; # Cachear JS al máximo ~image/ max; # Cachear imágenes al máximo } ``` > **Buena práctica**: Después de cada modificación, ejecutar `nginx -t` para verificar la sintaxis de la configuración antes de recargar el servicio. ## Certificados con Certbot Certbot ya viene instalado en la mayoría de distribuciones modernas. Para nuevas instalaciones, su [manual oficial](https://certbot.eff.org/instructions) proporciona instrucciones detalladas. Se recomienda crear certificados específicos por dominio en lugar de certificados wildcard: ```bash certbot --nginx -d domain.tld -d www.domain.tld ``` > **Nota**: En sistemas con restricciones de red, es necesario abrir temporalmente los puertos 80 y 443 durante el proceso de renovación. ## PHP Instalado desde el repositorio de [Ondrej Surý](https://launchpad.net/~ondrej), específicamente la versión PHP-FPM. ### Ubicaciones importantes: - Configuración de pools: `/etc/php/X.X/fpm/pool.d/www.conf` (donde X.X es la versión de PHP) - Configuración general: `/etc/php/X.X/fpm/php.ini` ### Configuración crítica para logging Es **esencial** modificar la configuración del pool para activar el registro de errores: - Editar `/etc/php/X.X/fpm/pool.d/www.conf` y cambiar: ``` catch_workers_output = yes ``` Sin esta modificación, PHP-FPM no registrará correctamente los errores en los logs de los dominios virtuales, lo que puede dificultar enormemente la depuración. Para más información, consulte [PHP log cuando usamos PHP-FPM con host virtuales](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/php-log-cuando-usamos-php-fpm-con-host-virtuales). ### JIT Compiler PHP 8.x introduce el compilador JIT (Just-In-Time), que puede mejorar significativamente el rendimiento en determinados escenarios. Sin embargo, puede presentar desafíos durante el desarrollo activo con cambios frecuentes. Para más información sobre la activación y configuración del JIT, consulte [Activar PHP8.2 JIT Compiler](https://wiki.castris.com/books/tips-sobre-la-administracion-de-linux/page/activar-php82-jit-compiler-just-in-time-compilation-jit). ##### Aviso Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de [Castris](https://castris.com) Si necesitas soporte profesional puedes contratar con Castris [soporte profesional](https://intranet.castris.com/store/soporte-profesional).