El SysAdmin del 3er Mundo

todo lo que expliqué mientras nadie prestaba atención

rails en alpine

| Comments

Finalmente el boom de docker llegó a Cuba. En mi caso personal, hace rato lo uso para desplegar aplicaciones de Ruby on Rails y siempre me pareció que debian era la mejor base para hacer una imagen. Si bien, hay containers de rails, eso de usar en producción, con una distro hecha por un cualquiera, como que me da cosa. Hacer una a partir de la oficial, es más sencillo que verificar la integridad de una ya hecha.

AlpineLinux para docker es un batazo, eso es in-negable. Pero instalar rails en alpine, resultó ser más complicado de lo que yo pensaba.

“docker y alpine”
1
2
docker pull alpine
docker run -ti alpine /bin/sh

Ante todo necesitamos instalar las librerías requeridas para compilar, sobre todo las dependencias de nokogiri. Instalaremos los paquetes: build-base, nodejs, tzdata, libxml2-dev, libxslt-dev, sqlite-dev y claro, ruby

En este caso, usaremos sqlite como ejemplo, pero a ti quizás te cuadre más con mariadb-dev (mysql) o postgresql-dev

“apk add”
1
2
3
4
apk update
apk add build-base nodejs tzdata libxml2-dev  libxslt-dev
apk add sqlite-dev mariadb-dev postgresql-dev
apk add ruby ruby-dev ca-certificates libffi libffi-dev

Como nokogiri es un caso tan peculiar, le diremos que compile usando las librerías del sistema, para ellos lo instalaremos aparte. Alpine no usa glibc, usa musl-libc y nokogiri NO compila, por tanto, hay que usar las librerías del sistema; en vez de las que provee nokogiri.

“nokogiri”
1
gem inst --no-document nokogiri -- --use-system-libraries

Con eso ya tenemos los cimientos echados. Nuestra imagen habrá crecido 200 megas. Ahora vamos instalar rails.

“gem”
1
gem inst --no-document rails io-console

El paso de instalar rails como gema del sistema es cuestionable para una pila de gente; pero ten en cuenta que es la manera de saber si rails funciona, recuerda que esto es un ejemplo. La primera vez me topé con que debía instalar io-console, ya que a pesar de ser dependencia, nadie la requería. Bueno a ver…

“rails”
1
2
/ # rails -v
Rails 5.0.0.1

Tengo una imagen llamada “alpine_ruby” en la que tengo todo lo necesario para instalar y No tengo la gema de rails instalada. Entonces, con cada versión de rails, por ejemplo, derivar de “alpine_ruby” la imagen alpine_rails50 , así cuando salga el rails 5.1 le llamaré alpine_rails51

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ

squid3 bloquear user-agent

| Comments

Recién, he tenido algunos problemas con descargadores multi-hilos que se chupan el ancho de banda y se cagan en los delay_pools. Buscando como bloquear dichos descargadores, el colega Agustín Ybarra me recomienda bloquear los user_agent.

Pero pensándolo bien, resolví unos cuantos problemas. Pues por ejemplo, google play service de los teléfonos android, consume muchísimo y resuelve poco, de forma que el que navega en un delay_pool, ve afectado su ancho de banda por cosas que ignora.

Solución, bloquear los User-Agent. La idea suena bien, pero primero hay que loguear los user agent. Para ellos usaremos un custom_log de squid, loguearemos los usuarios y los user-agent. A mi me quedó así:

“squid.conf”
1
2
3
# loguea los user-agent
logformat useragent  %un "%{User-Agent}>h"
access_log daemon:/var/log/squid3/user_agent.log useragent

Ahora tenemos el fichero user_agent.log, logueando usuario y user_agent; claro está, podría loguear, usuario, user-agent y url, pero la linea queda muy larga.

Una vez que hallas encontrado el user-agent que te moleste, crea una ACL arriba de la ACL que autorize la navegación.

“squid.conf”
1
2
3
4
# por ejemplo, blqueamos zapya y se fana
acl zapya browser ^com\.dewmobile
http_access deny zapya
http_reply_access deny zapya

Seguiré aquí, como el pescador del centeno, esperando a que vuelva a usar su descargadorcito multi-hilo de mierda… aunque seguro puede cambiarle el user-agent.

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ

redimensionar lvm

| Comments

Este post es a método de memorando, ya que SIEMPRE se me olvida como hacerlo.

En materia de virtualización, el sistema de plantillas nunca me ha gustado, porque NO SÉ quién instala esos sistemas operativos ni como.

Yo prefiero por ejemplo, instalar un debian, acomodarle todo a mi manera y usar esa instalación para generar nuevas máquinas, con todo ya listo. Por ejemplo, un prototipo de firewall, las configuraciones de interfaz puesta con dhcp, pero una configuración estática bien comentada, etc..

Mantengo esa máquina detenida y la arranco de vez en cuando para actualizar. Cuando voy a hacer una nueva, simplemente clono esa máquina.

Prefiero llamarlo matriz que plantilla. El resto del tiempo, dicha máquina permanece detenida (apagada) evitando así desgaste, envejecimiento, generación de logs, etc…

Eso en la práctica, es lo mismo que una plantilla (para los criticones y amantes de la moda).

Un inconveniente que afronté al principio con esto, fue “el tamaño asignado al disco duro”. Por ejemplo, el servidor de correo que me lleva 500 gigas, mientras que en el sistema de monitoreo (nagios) solo se lleva 5 gigas.

La matriz tiene un disco de 5 gigas donde se instaló todo. Sobra espacio, ya que borrando /usr/share/doc/ y la cache de apt, se quedo en menos de un giga. El problema (con Xen) viene a la hora de agrandar el disco.

No se como proxmox maneja esa situación y sinceramente, no me interesa, ya que:

LVM resuelve el problema!

Si no tienes la costumbre de instalar sobre LVM, deberías hacértela… Es muy versátil.

BTRfs es otra buena opción, pero su rendimiento decae mucho con el tiempo (mi experiencia).

Añadir un disco al volumen lógico y aumentar su tamaño resuelve el problema.

Claro, el sistema de archivos que instalaste, debe soportar tal operación, pero por suerte, ext4 lo hace perfectamente y sin tener que desmontar el sistema de archivos.

El problema es que NUNCA ME ACUERDO de los comandos para redimensionar el volumen lógico.

“la nota”
1
2
3
4
pvcreate /dev/xvdb
vgextend lvm /dev/xvdb
lvm lvextend -l +100%FREE /dev/lvm/lv1
resize2fs -p /dev/lvm/lv1

Note que mi grupo de volúmenes se llama lvm y que el volumen lógico se llama lv1 (no soy muy creativo con nombres para lvm). O sea, el disco quedaría así:

/dev/mapper/lvm-lv1

Nota para los retardados: El dispositivo /dev/xvdb es OTRO disco que se le añadió a la máquina para aumentar su espacio. Tenía /dev/xvda con 5 gigas y se le añádió otro disco, el llamado /dev/xvdb, con más espacio. Oséase colocaste otro disco en la máquina virtual o simplemente conectaste otro disco duro en el canal sata de una máquina física

Entonces, linea por linea, en cámara lenta:

1- Convierte el disco /dev/xvdb en un volumen físico (mete el disco pal saco de LVM) En mi caso, el grupo de volúmenes se llama lvm, así que:

2- Extenderemos el grupo llamado lvm añadiendo el volumen físico /dev/xvdb al volumen lógico lv1.

3- La parte que siempre se me olvida (el parámetro está raro con cojone) Redimensionar el volumen lógico lv1 a su máxima capacidad.

4- Por último, redimensionar el ext4 en /dev/lvm/lv1 a su máxima capacidad.

Y listo! Ya tienes tu disco del tamaño que te de la gana ;-)

Puedes correr lvmdiskscan -l para cerciorarte de que todo esté como esperas, no sea que hallas metido la delicada.

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ

sysinfo en el motd

| Comments

Desde que lo vi en unbuntu server, había querido hacer que mi servidores mostraran un overview en el MOTD)

Al menos debian, tiene una manera de cambiar el MOTD dinamicamente. Para sazonar bien el MOTD, vamos a usar figlet, una aplicación que genera letras en ascii-art a partir de una palabra dada.

“instalando todo”
1
aptitude install figlet

El directorio /etc/update-motd.d/ ejecutará en orden alfabético (o numérico en nuestro caso) aquellos script cuya salida estandard, compondrán nuestro MOTD.

“aprovisionando el update-motd.d”
1
2
3
4
mkdir /etc/update-motd.d/
cd /etc/update-motd.d/
touch 00-header && touch 01-sysinfo && touch 02-footer
chmod +x /etc/update-motd.d/*

Finalmente, nos echamos el MOTD de debian por defecto; que no deja de restregarnos en cara la falta de garantía.

Además, el fichero /var/run/motd contendrá nuestro motd resultante, así que lo lincamos con el que borramos.

“aprovisionando el update-motd.d”
1
2
rm /etc/motd
ln -s /var/run/motd /etc/motd

Por una cuestión de organización, usaremos 3 ficheros:

00-header con lo que queremos poner primero. En este caso, el nombre y version de la distribución, además de un mensajito de bienvenida.

“00-header”
1
2
3
4
5
6
7
8
9
#!/bin/bash
[ -r /etc/lsb-release ] && . /etc/lsb-release
if [ -z "$DISTRIB_DESCRIPTION" ] && [ -x /usr/bin/lsb_release ]; then
        DISTRIB_DESCRIPTION=$(lsb_release -s -d)
fi
figlet $(hostname)
printf "\n"
printf "Welcome to %s (%s).\n" "$DISTRIB_DESCRIPTION" "$(uname -r)"
printf "\n"

Yo instalo los sistemas en inglés, así que para mantener todo parejo, escribimos güelcome y lo hacemos con printf para procesar mejor los “\n” y que pinche sin importar la shell que se esté usando.

El segundo fichero será 01-sysinfo y contendrá la parte linda, de la memoria RAM en uso, el CPU, la carga y la dirección ip de la primera interfaz.

“01-sysinfo”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
date=`date`
load=`cat /proc/loadavg | awk '{print $1}'`
root_usage=`df -h / | awk '/\// {print $(NF-1)}'`
memory_usage=`free -m | awk '/Mem:/ { total=$2 } /buffers\/cache/ { used=$3 } END { printf("%3.1f%%", used/total*100)}'`
swap_usage=`free -m | awk '/Swap/ { printf("%3.1f%%", "exit !$2;$3/$2*100") }'`
users=`users | wc -w`
time=`uptime | grep -ohe 'up .*' | sed 's/,/\ hours/g' | awk '{ printf $2" "$3 }'`
processes=`ps aux | wc -l`
ip=`ip a  s dev eth0|grep inet|awk '{print $2}'|cut -d '/' -f 1`

printf "System information as of: $date\n"
printf "System load:\t%s\tIP Address:\t%s\n" $load $ip
printf "Memory usage:\t%s\tSystem uptime:\t%s\n" $memory_usage "$time"
printf "Usage on /:\t%s\tSwap usage:\t%s\n" $root_usage $swap_usage
printf "Local Users:\t%s\tProcesses:\t%s\n\n" $users $processes

Por último 02-footer será la parte de abajo. Contendrá cualquier cosa que quieras poner en el fichero /etc/motd.tail por ejemplo, una anotación que quieras hacer específica para ese servidor. Se mostrará si existe el fichero.

“02-footer”
1
2
#!/bin/bash
[ -f /etc/motd.tail ] && cat /etc/motd.tail || true

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ

openvpn user+pass

| Comments

Si bien, openvpn con una llave estática es algo bastante sencillo de configurar; tiene un grave problema: Que solo un cliente puede conectarse a la vez. En un escenario donde por ejemplo, queremos crear una vpn para múltiples servidores que deben conectarse, usar un clave estática se vuelve un problema. Una topología de anillo podría ayudarnos resolverlo, pero cada servidor debería ser cliente y servidor a la vez. Una VPN autenticada por usuario y contraseña resuelve el problema de la manera más simplificada posible.

Creamos la infraestructura de certificados:

“aprovisionando easy-rsa”
1
2
3
[lazaro@artema ~]$ mkdir Downloads/vpn
[lazaro@artema ~]$ cd Downloads/vpn
[lazaro@artema vpn]$ cp -r /etc/easy-rsa/* ./

Si quieres, si te da la mariconería, edita los parámetros del fichero que acabas de copiar, pa que pongas los parámetros bonitillos, si no, espera a que openssl los pregunte; a lo mejor ni los pregunta.

“aprovisionamiento de certificados”
1
2
[lazaro@artema vpn]$ easyrsa init-pki
[lazaro@artema vpn]$ easyrsa build-ca nopass

Note que la cadena de texto tuservidor debe ser remplazada por el nombre de tu actor asiático preferido o, por algún nombre de tu agrado para el servidor.

“creando el certificado del servidor”
1
[lazaro@artema vpn]$ easyrsa build-server-full tuservidor nopass

Ahora el Diffie Hellman, MUY importante. Ponte cómodo que va pa largo:

“creando el diffie hellman”
1
[lazaro@artema vpn]$ easyrsa gen-dh

Tiramos todo eso para /etc/openvpn en un directorio que designaremos con el nombre de “servidor” (por una cuestión de orden).

“/etc/openvpn/”
1
2
3
4
5
[lazaro@artema vpn]$ mkdir /etc/openvpn/servidor
[lazaro@artema vpn]$ cp pki/ca.crt /etc/openvpn/servidor
[lazaro@artema vpn]$ cp pki/dh.pem /etc/openvpn/servidor
[lazaro@artema vpn]$ cp -r pki/private/*.* /etc/openvpn/servidor/
[lazaro@artema vpn]$ cp -r pki/issued/tuservidor.* /etc/openvpn/servidor/

Ya tenemos todo listo pa armar el muñeco. Ahora vamos a crear la configuración del servidor. A mi me quedó así:

“servidor.conf”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[lazaro@artema vpn]$ cd /etc/openvpn/
[lazaro@artema openvpn]$ cat servidor.conf
# como y por donde escuhan
port 1194
proto udp
dev tun

# los certificados
ca /etc/openvpn/servidor/ca.crt
cert  /etc/openvpn/servidor/tuservidor.crt
key /etc/openvpn/servidor/tuservidor.key

# el diffie hellman
dh /etc/openvpn/servidor/dh.pem

# la red que vamos a operar
server 10.8.0.0 255.255.255.0

# manda un ping cada 10 segundos
# y tumba el tunel si a los 120 no hay respuesta
keepalive 10 120

# usa la compresión lzo
comp-lzo

# opera con los siguientes privilegios
#user nobody
#group nogroup

# esto es para reforzarlo
persist-key
persist-tun

# que tan elocuente será
verb 3

# mándale estos parámetros al cliente
push "redirect-gateway def1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# y he aquí el truco de la autenticación
plugin /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so login
client-cert-not-required
username-as-common-name

Con eso tenemos el servidor pinchando. Ahora vamos a hacer un fichero .ovpn genérico, para dar a entender como sería la configuración de nuestro cliente.

OJO El certificado que se le dará al cliente será el ca.crt

A mi me quedó así:

“cliente.ovpn”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[lazaro@artema openvpn]$ cat tuservidor.ovpn
client
dev tun
proto udp
remote 192.168.0.1 1194
remote-cert-tls server
auth-user-pass ~/autenticacion.conf
comp-lzo
<ca>
-----BEGIN CERTIFICATE-----
Lorem ipsum ad his scripta blandit partiendo, eum fastidii
accumsan euripidis in, eum liber hendrerit an. Qui ut wisi
vocibus suscipiantur, quo dicit ridens inciderint id. Quo mundi
lobortis reformidans eu, legimus senserit definiebas an eos. Eu
sit tincidunt incorrupte definitionem, vis mutat affert
percipit cu, eirmod consectetuer signiferumque eu per. In usu
latine equidem dolores. Quo no falli viris intellegam, ut fugit
veritus placerat per.  Ius id vidit volumus mandamus, vide
veritus democritum te nec, ei eos debet libris consulatu. No
mei ferri graeco dicunt, ad cum veri accommodare. Sed at malis
omnesque delicata, usu et iusto zzril meliore. Dicunt maiorum
eloquentiam cum cu, sit summo dolor essent te. Ne quodsi
nusquam legendos has, ea dicit voluptua eloquentiam pro, ad sit
quas qualisque. Eos vocibus deserunt quaestio ei.
-----END CERTIFICATE-----
</ca>

Cada cliente de OpenVPN tiene su librito… Pero ese .ovpn genérico, debe ser capaz de ser importado sin problema.

Por una cuestión de orden y seguridad, yo borro la base con la que se creó todo:

“clear area”
1
[lazaro@artema ~]$ rm -rf Downloads/vpn

Por cierto, cada configuración que pongas en /etc/openvpn cuya extensión sea .conf se puede echar a andar con systemd.

“systemctl
1
2
3
4
5
[root@artema ~]# systemctl status openvpn@servidor
● openvpn@servidor.service - OpenVPN connection to servidor
   Loaded: loaded (/usr/lib/systemd/system/openvpn@.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:openvpn(8)

OJO!

En versiones recientes de archlinux, la unit del cliente y del servidor, son distintas. Por tanto, en el caso del servidor, que ha de estar en /etc/openvpn/server/fulanito usarás una unit llamda openvpn-server@fulanito

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ

recolección DomainPOP

| Comments

Esta entrada ha sido copiada de mi antiguo blog puheroska. Vale aclarar que la escribí en el 2012…

Se sabe poco sobre los orígenes de ese aborto de la naturaleza que es conocido por algunos como “recolección aPOP” o por otros como “DomainPOP”.

Haciendo referencia al hecho de bajar todo el correo para un dominio de un pop remoto. Muchos seguron lo identifican con un popular, potente y hermoso servidor de correo, para windows llamado MDeamon (pronunciado por algunos como “emodimons” y por otro como “emdaimons”). Muy conocido por su simple pero elegante cliente web, el World Client. Entre sus features, podemos ver el almacenamiento de TODO el correo de un dominio en un mismo buzón. Esto, sumado a que en cuba todo el software es gratis :D lo convirtió en la herramienta definitiva para las redes conmutadas.

Por otra parte, no todo se le impugna windows. Cuando aún el morro era de palo y los cañones tiraban taquitos; ya citmatel usaba un CuciPOP (vean que clase de nombre “Cubic Circles = CuCiPOP”) para depositar el correo de sus clientes por lineas conmutadas; una clara implementación de aPOP. Esto resolvió ser la manera mas burda pero eficiente para resolver el problema del correo en lineas conmutadas.

Lo único que perturba este barato panorama, es el hecho de que si el correo no tiene un To: bien claro, se jode todo y te ves obligado a usar MDeamon, que en ese aspecto se saca todos los premios. Por su puesto, él es una de la principales implementaciones de este modelo.

A menudo nos encontramos con que al bajar el correo con fetchmail, uno o varios correos no van a su destino, y, por el contrario, van al postmaster sin tener coincidencias de usuarios locales.

Hay quien esta acostumbrado a que el postmaster este LLENO de correos y eso le parece normal, cuando el buen funcionamiento de un servidor, se mide por el postmaster vacío.

Si un correo tiene un To: o un Cc: fetchmail lo parsea (del infintivo “parsear”) y localiza una dirección de nuestro dominio basándose en que tiene el dominio en la configuración. Como le dijimos ‘is * here’ buscará cual nombre que este delante de lo que se parezca a nuestro dominio y lo entregara.

Pero: Qué pasa si el To: o el Cc: NO tienen una dirección de nuestro dominio?

Supongamos que el correo viene Bcc: (blink carbon copy)

Como por ejemplo, los correos de listas de distribuciones, etc… En ese caso los destinos se especifican en la orden RCPTO durante la sesión SMTP. Algunos servidores incluyen encabezados como: “Delivery-To”,“Envelope-To” o “X-Orignial-To” En mi opinión todos están de más, porque el Received: tiene esta información; pero bueno, podríamos decirle a fetchmail que ademas de esos, parsee encabezados Received: Eso parecería una solución, el único problema es que no pincha :-P

Hasta aquí la entrada de puheroska.

En aquel momento consideraba eso “un problema sin solución”

Cuando llegué a salud, me encontré nuevamente con los DomainPOP, pero por suerte, los exim de infomed hacen bien esa pincha y dejan plasmado el destinatario en un encabezado “Envelope-To”

He aquí el fetchmailrc que tengo en el calixto:

“/etc/fetchmailrc”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Fichero de configuración de fethcmail, adecuado para los MultiPOP de infomed

set daemon 60
set postmaster "root"
set no bouncemail
set no spambounce
set logfile .fetchmail.log
set no syslog

defaults
    timeout 10
    no keep
    fetchall
    expunge 5
    dropstatus

poll multipop.sld.cu port 110 protocol pop3 localdomains tudominio.sld.cu
    envelope 1 "Envelope-to:"
    no dns
    username tuusuario
    password tupassword
    to * here
    limitflush
    smtphost localhost

Si este artículo te resultó interesante, considere donar 0.003 BTC: 1LgL9cfT2StNk9gdedMJZseMnKJCEgQJdQ