Páginas

martes, 23 de septiembre de 2025

Supervisar Disco con smartmontools en FreeBSD 14.2

Configurar smartmontools en FreeBSD 14.2 para supervisar el estado de discos SSD y/o nvme y enviar correos mediante DMA usando los servidores de Gmail


Instalar smartmontools

 pkg install smartmontools

Habilitar el servicio smartd para que inicie al arrancar el sistema

 sysrc smartd_enable="YES"

Iniciar servicio

 service smartd start

Identificar el disco SSD

Primero listar los discos disponibles

 smartctl --scan

/dev/da0 -d sat # /dev/da0 [SAT], ATA device
/dev/nvme0 -d nvme # /dev/nvme0, NVMe device

Configurar smartd para monitorear el SSD

Editar el archivo de configuración

 cp /usr/local/etc/smartd.conf.sample /usr/local/etc/smartd.conf

Agregar esta línea para monitorear el SSD y enviar alertas por correo electrónico

 /dev/da0 -d sat -H -l error -l selftest -f -m tucorreo@protonmail.com
Explicación
 -H Comprueba el estado general SMART
 -l error Revisa el log de errores
 -l selftest Revisa el log de autopruebas
 -f Revisa fallos futuros
 -m Dirección de correo para notificaciones

Comprobar que el disco habla con el disco /dev/da0

# smartctl -d sat -a /dev/da0
smartctl 7.5 2025-04-30 r5714 [FreeBSD 14.3-RELEASE-p2 amd64] (local build)
Copyright (C) 2002-25, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Toshiba 2.5" HDD MQ04UBD...
Device Model:     TOSHIBA MQ04UBD200
Serial Number:    Y0JKT0QOT
LU WWN Device Id: 0 000000 000000000
Firmware Version: JT001U
User Capacity:    2,000,398,934,016 bytes [2.00 TB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    5400 rpm
Form Factor:      2.5 inches
Zoned Device:     Device managed zones
Device is:        In smartctl database 7.5/5706
ATA Version is:   ACS-3 T13/2161-D revision 5
SATA Version is:  SATA 3.3, 3.0 Gb/s (current: 3.0 Gb/s)
Local Time is:    Tue Sep 23 15:03:29 2025 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
...

Configurar DMA para enviar correos por Gmail


https://gnulinuxcodigo.blogspot.com/2024/12/freebsd-dma-dragonfly-mail-agent.html

FreeBSD 14.2 usa DMA como agente de correo por defecto.

Probando el envío de correos

echo "Prueba de correo desde FreeBSD" | mail -s "Prueba" tucorreo@protonmail.com

o, otra forma para lograr el mismo resultado

 cat >> mensaje.txt<<EOF
Esto es una prueba de correo desde usando el agente DMA.
EOF

 mail -v -s prueba tucorreo@protonmail.com < mensaje.txt

Verificar el log de DMA

 tail -f /var/log/maillog
...
Sep 19 08:59:00 tormenta dma[dd67.2b6bad248050][86005]: trying remote delivery to smtp.gmail.com [74.125.133.109] pref 0
Sep 19 08:59:00 tormenta dma[dd67.2b6bad248050][86005]: using SMTP authentication for user tucorreo@gmail.com
Sep 19 08:59:01 tormenta dma[dd67.2b6bad248050][86005]:  delivery successful

Para que smartmontools vigile un disco NVMe

Averiguar el nodo del NVMe

 nvmecontrol devlist
 nvme0: CT500P2SSD8
    nvme0ns1 (476940MB)

 ls -l /dev/nvme*
crw-------  1 root wheel 0x33 Sep 20 15:41 /dev/nvme0
crw-------  1 root wheel 0x40 Sep 20 15:41 /dev/nvme0ns1

Comprobar que smartctl habla con el NVMe

 smartctl -d nvme /dev/nvme0ns1 -i

smartctl 7.5 2025-04-30 r5714 [FreeBSD 14.2-RELEASE-p1 amd64] (local build)
Copyright (C) 2002-25, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       CT500P2SSD8
Serial Number:                      2216E629B1D4
Firmware Version:                   P2CR048
PCI Vendor/Subsystem ID:            0xc0a9
IEEE OUI Identifier:                0x00a075
Total NVM Capacity:                 500,107,862,016 [500 GB]
Unallocated NVM Capacity:           0
Controller ID:                      1
NVMe Version:                       1.3
Number of Namespaces:               1
Namespace 1 Size/Capacity:          500,107,862,016 [500 GB]
Namespace 1 Formatted LBA Size:     512
Namespace 1 IEEE EUI-64:            00a075 61b0000125
Local Time is:                      Fri Sep 19 09:36:00 2025 CEST

Mostrará modelo, serial, versión NVMe, etc.

Crear una entrada específica para el NVMe en /usr/local/etc/smartd.conf

 /dev/nvme0ns1 -d nvme -H -l error -l selftest -f -m tucorreo@protonmail.com -M test

Explicación

 -d nvme - le dice a smartd que use el backend NVMe
 -H - atributo "Health"
 -l error - log de errores
 -l selftest - log de autopruebas 
 -f - predicción de fallos
 -m - destinatario
 -M test - envía un correo de bienvenida al arrancar smartd (útil para verificar).

Contenido del fichero /usr/local/etc/smartd.conf

 sed -e '/^[ ]*#/d' -e '/^$/d' /usr/local/etc/smartd.conf
 
/dev/da0 -d sat -H -l error -l selftest -f -m tucorreo@protonmail.com
/dev/nvme0ns1 -d nvme -H -l error -l selftest -f -m tucorreo@protonmail.com

service smartd restart

En /var/log/daemon.log se verá

 tail -f /var/log/daemon.log 
...
Sep 19 09:55:34 tormenta smartd[87644]: Device: /dev/nvme0, opened
Sep 19 09:55:34 tormenta smartd[87644]: Device: /dev/nvme0, CT500P3SSD8, S/N:2240E6733488, FW:P9CR30A
Sep 19 09:55:34 tormenta smartd[87644]: Device: /dev/nvme0, is SMART capable. Adding to "monitor" list.
Sep 19 09:55:34 tormenta smartd[87644]: Monitoring 1 ATA/SATA, 0 SCSI/SAS and 1 NVMe devices

Arrancar o reiniciar el demonio

 service smartd restart

En /var/log/daemon.log se verá la línea "Device:/dev/nvme0ns1,opened" y si se incluye -M test, un correo inmediato.

Crear el helper de notificación

En FreeBSD el paquete smartmontools no instala helper de notificación; hay que crearlo.

Crear el script que smartd invoca y asegurarse de que llame a /usr/bin/mail smartd siempre ejecuta el script con sh, por lo que la shell personal (csh) no afecta en absoluto.

cat > /usr/local/sbin/smartdnotify-mailout <<'EOF'
#!/bin/sh
# SMARTD_ADDRESS direccion destino
# SMARTD_SUBJECT asunto
# SMARTD_MESSAGE cuerpo del mensaje
exec /usr/bin/mail -s "$SMARTD_SUBJECT" "$SMARTD_ADDRESS" <<EOF_MAIL
$SMARTD_MESSAGE
EOF_MAIL
EOF

Contenido del archivo /usr/local/sbin/smartdnotify-mailout

#!/bin/sh
# SMARTD_ADDRESS direccion destino
# SMARTD_SUBJECT asunto
# SMARTD_MESSAGE cuerpo del mensaje
exec /usr/bin/mail -s "$SMARTD_SUBJECT" "$SMARTD_ADDRESS" <<EOF
$SMARTD_MESSAGE
EOF

Hay que darle permisos de ejecución

chmod 755 /usr/local/sbin/smartdnotify-mailout

Verificar que smartd lo va a usar

grep ^mailout /usr/local/etc/smartd.conf

Si tuviera una línea como

MAILER /usr/local/libexec/smartdnotify

comentarla o borrarla para que smartd use el helper estándar.

Simular las variables que smartd exporta (shell csh)

setenv SMARTD_ADDRESS "tucorreo@protonmail.com"
setenv SMARTD_SUBJECT "SMART alerta"
setenv SMARTD_MESSAGE "Problema en disco detectado"

En csh las variables anteriores sólo existen en esa shell; Cuando smartd arranca como servicio, no las ve.

La solución es asegurarse de que smartd exporte esas variables él mismo

Forzar un correo de prueba

service smartd restart

si smartd ya está corriendo

pkill -USR1 smartd

Verificar la entrega

tail -f /var/log/maillog
...
Sep 21 16:14:42 tormenta dma[8210.32674c848000][49835]: trying remote delivery to smtp.gmail.com [64.233.184.109] pref 0
Sep 21 16:14:43 tormenta dma[f8210.32674c848000][49835]: using SMTP authentication for user tucorreo@gmail.com
Sep 21 16:14:43 tormenta dma[f820e.57c02fa48000][49825]: <tucorreo@protonmail.com> delivery successful
Sep 21 16:14:44 tormenta dma[f8210.32674c848000][49835]: <tucorreo@protonmail.com> delivery successful

El mensaje "SMART daemon startup" llegará a la bandeja de entrada

Comprobaciones

smartd invoca realmente el helper?

Verlo en tiempo real

service smartd stop
smartd -d -c /usr/local/etc/smartd.conf

En otra terminal forzar el envío

pkill -USR1 smartd

En la primera terminal debe aparecer

Executing "/usr/local/sbin/smartdnotify-mailout"

Si no aparece el problema es parseo de smartd.conf (espacio, salto de línea, falta -M test, etc.)

Borrar las variables del shell (no hacen falta), csh

unsetenv SMARTD_SUBJECT SMARTD_MESSAGE SMARTD_ADDRESS

No se necesita setenv en ningún fichero. Reiniciar smartd con service smartd restart y el demonio exportará las variables antes de llamar al helper.

Ahora ya se puede quitar -M test de ambas líneas cuando ya no se desee recibir el correo de bienvenida cada vez que reinicie smartd

-M test sólo fuerza el envío de un aviso al arrancar el demonio. No afecta a las alertas reales; esas se mandan siempre cuando ocurran.

A partir de ahora no se recibirá el mail "SMART daemon startup". Sí recibirás cualquier alerta real cuando smartd la detecte.

Verificar el estado actual y forzar una alerta en cualquier momento sin reiniciar el servicio.

Lectura rápida en caliente (sin detener smartd)

 smartctl -d nvme -A /dev/nvme0ns1
 smartctl -d nvme -H /dev/nvme0ns1
 smartctl -d nvme -l /dev/nvme0
 smartctl -d sat -A /dev/da0
 smartctl -d sat -H  /dev/da0
 smartctl -d sat -l error /dev/da0

Forzar un evento para comprobar que las alertas siguen funcionando

 kill -USR1 $(pgrep smartd) # sh
 kill -USR1 `pgrep smartd` # csh

Ver que está vigilando smartd en este momento

 tail -f /var/log/daemon.log | grep smartd

Cada 30 minutos, que es el valor por defecto, vuelve a comprobar y registrará cualquier cambio.

Mensajes recibidos en mi correo (uno por cada disco)


Primer mensaje

This message was generated by the smartd daemon running on:

   host name:  tormenta
   DNS domain: [Empty]

The following warning/error was logged by the smartd daemon:

TEST EMAIL from smartd for device: /dev/da0 [SAT]

Device info:
TOSHIBA MQ04UBD200, S/N:Y0JKT0QOT, WWN:0-000000-000000000, FW:JT001U, 2.00 TB

For details see host's SYSLOG.

Segundo mensaje

This message was generated by the smartd daemon running on:

   host name:  tormenta
   DNS domain: [Empty]

The following warning/error was logged by the smartd daemon:

TEST EMAIL from smartd for device: /dev/nvme0ns1

Device info:
CT500P3SSD8, S/N:2240E6733488, FW:P9CR30A, NSID:1

For details see host's SYSLOG.
FreeBSD es genial!.

martes, 26 de agosto de 2025

Poudriere en FreeBSD ZFS 14.2

Instalación y configuración de poudriere FreeBSD 14.2 ZFS


Referencias bibliográficas:

https://freebsdfoundation.org/wp-content/uploads/2023/11/reushling_poudrier.pdf
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-poudriere-build-system-to-create-packages-for-your-freebsd-servers


Intel core i5-8350U 1.7 GHz
Procesador 4 cores
Procesador 8 hilos
RAM 16 GB
SWAP 16 GB
NVMe Pcie 4.0

ZPOOL=zroot
ZROOTFS=/poudriere
BASEFS=/usr/local/poudriere

FreeBSD 14.2-RELEASE (amd64) instalado El dataset raíz de poudriere estará en zroot/poudriere y se montará en /usr/local/poudriere

Paquetes mínimos

pkg install -y poudriere \
	       git-lite
	       vim
	       screen
	       curl
	       ca_root_nss

Crear datasets ZFS.

Ventajas: posibilidad de hacer snapshots, rollback y compression por separado

zfs create -o mountpoint=/usr/local/poudriere -o compression=lz4 zroot/poudriere
zfs create zroot/poudriere/jails
zfs create zroot/poudriere/ports
zfs create zroot/poudriere/data
zfs create zroot/poudriere/data/packages
zfs create zroot/poudriere/data/logs

Archivo /usr/local/etc/poudriere.conf

ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
CCACHE_DIR=/var/cache/ccache
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos

Descargar y crear la jail base (14.2-RELEASE)

poudriere jail -c -j 142amd64 -v 14.2-RELEASE -a amd64

Esto descarga sets.txz y crea un dataset zroot/poudriere/jails/142amd64

Git -

poudriere ports -c -p default -m git -U https://git.FreeBSD.org/ports.git     

poudriere ports -l

PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2025-08-24 18:50:19 /usr/local/poudriere/ports/default
local     null      2025-08-24 16:41:27 /usr/local/poudriere/ports/default

poudriere jails -l

JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
142amd64 14.2-RELEASE-p5 amd64 http   2025-08-24 18:42:25 /usr/local/poudriere/jails/142amd64

Ajustes globales

Archivo /usr/local/etc/poudriere.d/make.conf

# general
DEFAULT_VERSIONS+=ssh=openssl
OPTIONS_UNSET+=DOCS NLS EXAMPLES X11 IPV6
WITH_PKGNG=yes
DISABLE_LICENSES=yes

Crear listas de paquetes

Archivo /usr/local/etc/poudriere.d/port-list.txt

security/sudo
ports-mgmt/pkg

Primer bulk build

poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt

Servidor de paquetes local (nginx)

pkg install nginx
sysrc nginx_enable=YES

Archivo de configuración de nginx

$ sed -e '/^[ ]*#/d' -e '/^$/d' /usr/local/etc/nginx/nginx.conf
    
    server {
        listen       80 default;
        server_name  localhost;
	    root /usr/local/share/poudriere/html;
        
        location /data {
            alias  /usr/local/poudriere/data/logs/bulk;
            autoindex on;
        }
	
	location /packages {
		root /usr/local/poudriere/data;
		autoindex on;
	}
}

Configurar pkg en la máquina anfitriona

mkdir /usr/local/etc/pkg/repos

Archivo /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Generar clave (una sola vez)

Crear el directorio donde se guardarán las claves

mkdir -p /usr/local/etc/poudriere

Generar la clave privada (4096 bits)

openssl genrsa -out /usr/local/etc/poudriere/poudriere.key 4096
chmod 600 /usr/local/etc/poudriere/poudriere.key

Extraer la clave pública

openssl rsa -in /usr/local/etc/poudriere/poudriere.key -pubout -out \
/usr/local/etc/poudriere/poudriere.pub
chmod 644 /usr/local/etc/poudriere/poudriere.pub

Asegúrarse de que poudiere la use al firmar.

Añadir esta línea al archivo /usr/local/etc/poudriere.conf

PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key

El archivo /usr/local/etc/poudriere.conf queda así:

ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos
PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key

Firmar el repositorio con la clave nueva

poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt

Monitorear durante la compilación


poudriere status

SET PORTS JAIL BUILD STATUS  QUEUE BUILT FAIL SKIP IGNORE FETCH REMAIN TIME     LOGS
- default 142amd64 2025-08-26_08h57m21s parallel_build  3  0  0  0 0 0  3 00:00:22 \
/usr/local/poudriere/data/logs/bulk/142amd64-default/2025-08-26_08h57m21s

poudriere jail -l

JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
142amd64 14.2-RELEASE-p5 amd64 http   2025-08-25 23:10:54 /usr/local/poudriere/jails/142amd64

poudriere ports -l

PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2025-08-26 08:55:04 /usr/local/poudriere/ports/default
local     null      2025-08-24 16:41:27 /usr/local/poudriere/ports/default
root@solaris:/usr/local/etc/pkg/repos# poudriere 
FreeBSD.conf        packagesite.yaml    
poudriere.conf     

Logs en tiempo real

poudriere log -f -j 142amd64 -p default 

Configurar pkg en los clientes, (o en la misma máquina), para que use la clave pública

mkdir -p /usr/local/etc/pkg/repos/
$ cat /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Tras esto, pkg install validará las firmas sin errores.

Comandos útiles de rescate. Limpiar paquetes obsoletos

poudriere pkgclean -j 142amd64 -p default -f port-list.txt

Destruir jail y volver a crear (por ejemplo, tras nueva RELEASE)

poudriere jail -d -j 142amd64
poudriere jail -c -j 142amd64 -v 14.3-RELEASE -a amd64

Actualizar paquetes

pkg update -f
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB  10.4MB/s    00:01    
Processing entries: 100%
FreeBSD repository update completed. 35669 packages processed.
Updating poudriere repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%    2 KiB   2.0kB/s    00:01    
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
pkg upgrade
curl -I http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.28.0
Date: Tue, 26 Aug 2025 12:07:38 GMT
Content-Type: text/html
Content-Length: 13036
Last-Modified: Sat, 09 Aug 2025 09:58:45 GMT
Connection: keep-alive
ETag: "68971bd5-32ec"
Accept-Ranges: bytes

Actualizar el árbol existente (lo mantiene, solo descarga nuevos commits)

poudriere ports -u -p default

Listo para compilar y servir paquetes locales con poudriere en FreeBSD 14.2


Opciones

Poudriere no guarda automáticamente las elecciones que se hacen al ejecutar poudriere options, pero le indicamos con la bandera -z myset que lo guarde.

Ejecutar una vez poudriere options para el port que quiera

Las opciones seleccionadas se guardan en /usr/local/etc/poudriere.d/myset-options

poudriere options -z myset -c security/sudo

el flag -c fuerza que aparezca el menú incluso si ya existen opciones guardadas.


Un directorio "myset-options" es generado automaticamente por make config

/usr/local/etc/poudriere.d/myset-options/

y dentro del directorio los directorios categoria_paquete

ls /usr/local/etc/poudriere.d/myset-options
converters_libiconv/ devel_autoconf/      devel_m4/            lang_tcl86/
databases_sqlite3/   devel_kyua/          lang_lua54/          security_sudo/
devel_atf/           devel_lutok/         lang_perl5.42/

y dentro de esos directorio un archivo llamado options contiene las opciones de configuración.


cat /usr/local/etc/poudriere.d/myset-options/security_sudo/options
# This file is auto-generated by 'make config'.
# Options for sudo-1.9.17p2
_OPTIONS_READ=sudo-1.9.17p2
_FILE_COMPLETE_OPTIONS_LIST=AUDIT DISABLE_AUTH DISABLE_ROOT_SUDO DOCS EXAMPLES \
INSULTS LDAP NLS NOARGS_SHELL OPIE PAM PYTHON SSL GSSAPI_BASE GSSAPI_HEIMDAL \
GSSAPI_MIT
OPTIONS_FILE_SET+=AUDIT
OPTIONS_FILE_UNSET+=DISABLE_AUTH
OPTIONS_FILE_UNSET+=DISABLE_ROOT_SUDO
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_SET+=INSULTS
OPTIONS_FILE_UNSET+=LDAP
OPTIONS_FILE_UNSET+=NLS
OPTIONS_FILE_UNSET+=NOARGS_SHELL
OPTIONS_FILE_UNSET+=OPIE
OPTIONS_FILE_SET+=PAM
OPTIONS_FILE_UNSET+=PYTHON
OPTIONS_FILE_SET+=SSL
OPTIONS_FILE_UNSET+=GSSAPI_BASE
OPTIONS_FILE_UNSET+=GSSAPI_HEIMDAL
OPTIONS_FILE_UNSET+=GSSAPI_MIT

...

Compilar paquetes

poudriere bulk -j 142amd64 -p default -z myset -f /usr/local/etc/poudriere.d/port-list.txt

Para que pkg use los paquetes que acaba de compilar poudriere necesitas:
- Que poudriere haya terminado de firmar y publicar los paquetes.
- Un repositorio local servido por nginx (u otro)
- Un fichero /usr/local/etc/pkg/repos/poudriere.conf correctamente escrito

fichero /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  # url = "file:///usr/local/poudriere/data/packages/142amd64-default",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# pkg repo .
Creating repository in .: 100%
Packing files for repository: 100%
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# ls
data.pkg            meta.conf           pkg-2.2.2.pkg
data.tzst           packagesite.pkg     pkgconf-2.4.3,1.pkg
meta                packagesite.tzst    sudo-1.9.17p2.pkg

Desactivar el repositorio oficial (opcional)

#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
#   mkdir -p /usr/local/etc/pkg/repos
#   echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#

FreeBSD: {
 url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
 mirror_type: "srv",
 signature_type: "fingerprints",
 fingerprints: "/usr/share/keys/pkg",
 enabled: no
}

Otra opción. La prioridad define el orden en que se utilizan estos repositorios

Por defecto, se utiliza el repositorio upstream de FreeBSD.org. Pero como queremos que nuestros propios paquetes tengan precedencia, le daremos una prioridad más alta que cero para que use nuestro repositorio de paquetes primero.

Quedaría así:

#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
#   mkdir -p /usr/local/etc/pkg/repos
#   echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#

FreeBSD: {
 url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
 mirror_type: "srv",
 signature_type: "fingerprints",
 fingerprints: "/usr/share/keys/pkg",
 enabled: yes
}

Archivo /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  # url = "file:///usr/local/poudriere/data/packages/142amd64-default",
  enabled = yes,
  priority: 23,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Veamos en acción

 pkg update
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%    2 KiB   2.0kB/s    00:01    
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
root@solaris:/usr/local/etc/pkg/repos# pkg upgrade
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking for upgrades (206 candidates): 100%
Processing candidates (206 candidates): 100%
The following 4 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	p5-Crypt-URandom: 0.54 [FreeBSD]

Installed packages to be UPGRADED:
	nss: 3.115 -> 3.115.1 [FreeBSD]
	p5-Authen-SASL: 2.18 -> 2.1900 [FreeBSD]
	perl5: 5.40.2_2 -> 5.40.3_2 [FreeBSD]

Number of packages to be installed: 1
Number of packages to be upgraded: 3

18 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/4] Fetching nss-3.115.1.pkg: 100%    2 MiB   2.3MB/s    00:01    
[2/4] Fetching p5-Crypt-URandom-0.54.pkg: 100%   17 KiB  17.6kB/s    00:01    
[3/4] Fetching perl5-5.40.3_2.pkg: 100%   16 MiB  16.4MB/s    00:01    
[4/4] Fetching p5-Authen-SASL-2.1900.pkg: 100%   44 KiB  44.7kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/6] Deinstalling p5-Authen-SASL-2.18...
[1/6] Deleting files for p5-Authen-SASL-2.18: 100%
[2/6] Deinstalling perl5-5.40.2_2...
[2/6] Deleting files for perl5-5.40.2_2: 100%
[3/6] Upgrading nss from 3.115 to 3.115.1...
[3/6] Extracting nss-3.115.1: 100%
[4/6] Installing perl5-5.40.3_2...
[4/6] Extracting perl5-5.40.3_2: 100%
[5/6] Installing p5-Crypt-URandom-0.54...
[5/6] Extracting p5-Crypt-URandom-0.54: 100%
[6/6] Installing p5-Authen-SASL-2.1900...
[6/6] Extracting p5-Authen-SASL-2.1900: 100%
tree /usr/local/poudriere/data/packages/
/usr/local/poudriere/data/packages/
└── 142amd64-default
    ├── All -> .latest/All
    ├── Latest -> .latest/Latest
    ├── data
    ├── data.pkg -> .latest/data.pkg
    ├── data.tzst -> .latest/data.tzst
    ├── logs -> .latest/logs
    ├── meta -> .latest/meta
    ├── meta.conf -> .latest/meta.conf
    ├── packagesite.pkg -> .latest/packagesite.pkg
    ├── packagesite.tzst -> .latest/packagesite.tzst
    └── packagesite.yaml

5 directories, 8 files

Instalar paquete desde repositorio local

pkg install sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	sudo: 1.9.17p2 [poudriere]

Number of packages to be installed: 1

The process will require 2 MiB more space.

Proceed with this action? [y/N]: y
[1/1] Installing sudo-1.9.17p2...
[1/1] Extracting sudo-1.9.17p2: 100%
Comprobar security con INSULTS activado:
sudo vim /etc/rc.conf                 
Password:
Quizás si usaras más de dos dedos...
Password:
¡Este hombre no sabe cuándo está vencido! Tampoco sabe cuándo está ganando. 
No tiene... una especie de... aparato sensorial...
Password:
FreeBSD es genial!.

viernes, 4 de julio de 2025

Borrar Disco FreeBSD 14.2

Borrar disco

Arranque el dispositivo objetivo desde el medio de instalación. En el menú de arranque de FreeBSD, presione s para seleccionar el modo de usuario único de arranque.

Use geom para identificar discos

 geom disk list
Geom name: nda0
Providers:
1. Name: nda0
...

Use dd para sobrescribir todo el disco con ceros:

 dd if=/dev/zero of=/dev/nda0 bs=4M conv=fsync oflag=direct status=progress

Esta operación tomará un poco de tiempo. En mi nvme 500G, por ejemplo, tardó aproximadamente 14 minutos en borrar completamente el disco. Sea paciente.

Instalación

Después de que termine la operación de borrado, ingrese el comando reboot para volver al Menú de Arranque. Presione <Enter> para iniciar el instalador.

 reboot
En la pantalla de bienvenida, elija Install.
FreeBSD es genial!.

jueves, 3 de julio de 2025

VLAN Mikrotik Basado en Puertos

VLANs Mikrotik - Basada en Puertos. Tenemos dos routers Mikrotik (RouterOS).

Internet

El router Mikrotik esta conectado desde el puerto ehter1 (WAN_ether1) a uno de los puertos ethernet del router ISP, usando DHCP Client.

[admin@R1] /ip dhcp-client> print
Flags: X - disabled, I - invalid, D - dynamic 
 #   INTERFACE    USE-PEER-DNS ADD-DEFAULT-ROUTE STATUS      ADDRESS           
 0   ether1        yes          yes               bound       192.168.88.12/24  

Todos los puertos de un switch por defecto pertenecen a la la vlan 1. El switch necesita de un router para mover (forwarding) el tráfico entre las vlan. Eso permite la comunicacion entre diferentes VLAN.

Las VLAN ID solo aparecen en Switch administrables y funcionan en capa 2. La segmentación se produce en el Switch.

El Switch tiene una base de datos llamada tabla CAM donde realiza un seguimiento de cada computadora conectada:

- MAC Address
- Numero de Puerto
- VLAN ID - Solo en Switches Administrables

Las VLANs se utilizan se utilizan para segmentar una red, lo que permite mejorar la seguridad, el rendimiento y la gestion de la red. Los dispositivos de una VLAN pueden ser configurados y administrados de forma separada.

Los dispositivos CRS (tienen capacidad de capa 3) se pueden utilizar como enrutador y conmutador al mismo tiempo, útil para redes que se centran en el rendimiento de la red interna.

VLAN - Laboratorio de pruebas

Ambos routers estan en blanco - System - Reset Configuration - No Default Configuration - Reset Configuration.

Tenemos un router 1 (R1) donde se crean las VLAN, vlan10 con vlan-id=10 y vlan20 con vlan-id=20 en la interfaz Ether3, cada una con su direccionamineto IP y un DHCP Server. Esas VLAN se envían Tagged (Trunk en Cisco) a través de Ether3 y se reciben Tagged en el router 2 (R2) en el puerto Ether1. Luego se entregan como Untagged (Access Port) en los puertos Ether3 y Ether4.

Configuración vía comandos del Router 1.

Nota: La dirección IP del dns-server correspnde al servidor DNS de mi red interna. Puede utilizar DNS públicos si no tiene un servidor DNS local, por ejemplo, 1.1.1.1 o los del propio router Mikrotik, por defecto 192.168.88.1.

/interface
add interface=ether2 name=vlan10 vlan-id=10
add interface=ether2 name=vlan20 vlan-id=20
/ip pool
add name=dhcp_pool0 ranges=10.10.10.200-10.10.10.254
add name=dhcp_pool1 ranges=172.24.1.200-172.24.1.254
/ip dhcp-server
add address-pool=dhcp_pool0 disable=no interface=vlan10 name=dhcp1
add address-pool=dhcp_pool1 disable=no interface=vlan20 name=dhcp2
/ip address
add address=10.10.10.1/24 interface=vlan10 network=10.10.10.0
add address=172.24.1.1/24 interface=vlan20 network=172.24.1.0
/ip dhcp-server network
add address=10.10.10.0/24 dns-server=192.168.88.200 gateway=10.10.10.1
add address=172.24.1.0/24 dns-server=192.168.88.200 gateway=172.24.1.1

En el Router R2 se crean las VLAN en el puerto Ether1 que es donde recibimos las VLAN con el nombre y vlan-id correspondiente, vlan10 vlan-id=10 y vlan20 vlan-id=20. Teniendo en cuenta que para que las VLAN se comuniquen entre dispositivos el id debe ser el mismo. Tambien hay que crear un bridge por cada VLAN Bridge_VLAN10 y Bridge_VLAN20. En la pestaña Bridge - Bridge - Ports, agregar dos interfaces: la propia VLAN y el puerto físico donde quiero entregarla como acceso (Access Port). En el caso de la VLAN vlan10 los puertos son: la propia VLAN vlan10 y el puerto Ether3. En la VLAN vlan20 los puertos son: la propia VLAN vlan20 y el puerto Ether4. Evidentemente, si quiero entregar la misma VLAN en más puertos este último paso se repite para todos los puertos involucrados.

Configuracion vía comandos Router 2 (R2)

/interface vlan
add interface=ether1 name=vlan10 vlan-id=10
add interface=ether1 name=vlan20 vlan-id=20
/interface bridge
add name=Bridge_VLAN10
add name=Bridge_VLAN20
/interface Bridge port
add bridge=Bridge_VLAN10 interface=vlan10
add bridge=Bridge_VLAN10 interface=ether3
add bridge=Bridge_VLAN20 interface=vlan20
add bridge=Bridge_VLAN20 interface=ether4

IP Route R1

[admin@R1] /ip route> print
Flags: X - disabled, A - active, D - dynamic, 
C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, 
B - blackhole, U - unreachable, P - prohibit 
 #      DST-ADDRESS        PREF-SRC        GATEWAY         DISTANCE
 0 ADS  0.0.0.0/0                          192.168.88.1           1
 2 ADC  10.10.10.0/24      10.10.10.1      vlan10                 0
 3 ADC  172.24.1.0/24      172.24.1.1      vlan20                 0
 4 ADC  192.168.88.0/24    192.168.88.12   ether1                 0
 

Conecto un PC a Ether3 del router R2 y recibe una IP del DHCP-Server configurado en R1

[admin@R1] /ip dhcp-server lease print
Flags: X - disabled, R - radius, D - dynamic, B - blocked 
 #   ADDRESS              MAC-ADDRESS       H SE.. R STATUS  LAST-SEEN            
 0 D 10.10.10.251         E4:B9:7A:6B:96:CD s dh..   bound   4m6s  
 

(Opcional) -¿Cómo Permitir tráfico de VLANs?

/ip firewall filter
add chain=forward src-address=10.10.10.0/24 dst-address=172.24.1.0/24 \
connection-state=new,established action=accept comment="Permitir VLAN10 \
a VLAN20"
/ip firewall filter
add chain=forward src-address=172.24.1.0/24 dst-address=10.10.10.0/24 \
connection-state=new,established action=accept comment="Permitir VLAN20 \
a VLAN10"

Ubicación de las reglas:

Antes de cualquier regla que bloquee tráfico (ej. action=drop).
Usa el menú Drag & Drop en Winbox para ordenarlas.

Explicacion:

Las opciones connection-state=new,established permiten:
new: Conexiones iniciadas desde el origen.
established: Respuestas al tráfico iniciado.

Permitir acceso administrativo sólo desde la red 10.10.10.1/24

add chain=input src-address=10.10.10.1/24 protocol=tcp dst-port=22,8291,8728,8729 \
action=accept comment="Acceso administrativo (Winbox/SSH/API)"

Reglas de cortafuegos R1

admin@R1VLAN] > /ip firewall filter print
Flags: X - disabled, I - invalid, D - dynamic 
 0    ;;; Permitir conexiones establecidas
      chain=input action=accept connection-state=established,related log=no log-prefix="" 

 1    ;;; Permitir ICMP
      chain=input action=accept protocol=icmp log=no log-prefix="" 

 2    ;;; Permitir conexiones establecidas
      chain=forward action=accept connection-state=established,related log=no log-prefix="" 

 3    ;;; Bloquear conexiones inva/ip lidas
      chain=forward action=drop connection-state=invalid log=no log-prefix="" 

 4    ;;; Permitir trafico forward in wlan1 y out vlan10
      chain=forward action=accept in-interface=wlan1 out-interface=vlan10 log=no log-prefix="" 

 5    ;;; Permitir forward in vlan10 y out wlan1
      chain=forward action=accept in-interface=vlan10 out-interface=wlan1 log=no log-prefix="" 

 6    ;;; Permitir trafico forward in wlan1 y out vlan20
      chain=forward action=accept in-interface=wlan1 out-interface=vlan20 log=no log-prefix="" 

 7    ;;; Perimtir trafico forward in vlan20 out wlan1
      chain=forward action=accept in-interface=vlan20 out-interface=wlan1 log=no log-prefix="" 

 8    ;;; Bloquear trafico no permitido
      chain=forward action=drop log=no log-prefix="" 
FreeBSD es genial!.

jueves, 12 de junio de 2025

Firewall Mikrotik Protege LAN y Permite Acceso a Internet

Configuración de firewall para MikroTik (RouterOS)

Protege la red LAN (10.10.10.0/24) y permite acceso a Internet. Las reglas incluyen protección anti-spoofing, bloqueo de tráfico no autorizado, y permiten tráfico legítimo.

El router Mikrotik esta conectado al puerto ehter1 (WAN_ether1) y uno de los puertos ethernet del router ISP usando DHCP Client

Configuración básica de interfaces

/interface bridge
add name=LAN_bridge
/interface bridge port
add bridge=LAN_bridge interface=ether2
add bridge=LAN_bridge interface=ether3
add bridge=LAN_bridge interface=ether4
add bridge=LAN_bridge interface=ether5
add bridge=LAN_bridge interface=wlan1
add bridge=LAN_bridge interface=wlan2
/ip address
add address=10.10.10.1/24 interface=LAN_bridge

DHCP Client en WAN (WAN_ether1)

/ip dhcp-client
add interface=WAN_ether1

NAT para acceso a Internet

/ip firewall nat
add chain=srcnat out-interface=WAN_ether1 action=masquerade

POLÍTICAS POR DEFECTO (FILTER)

/ip firewall filter

CONEXIONES ESTABLECIDAS

add chain=input action=accept connection-state=established,related \
comment="Permitir conexiones Establecidas/Realacionadas (Input)"
add chain=forward action=accept connection-state=established,related \
comment="Permitir conexiones Establecidas/Relacionadas (Forward)"
add chain=output action=accept connection-state=established,related \
comment="Permitir conexiones Establecidas/Relacionadas (Output)"

ANTI-SPOOFING Y SEGURIDAD BÁSICA Bloqueo de IPs falsas en WAN

add chain=input action=drop in-interface=WAN_ether1 src-address=10.10.10.0/24 \
comment="Bloquear LAN IP Spoofing (Input)"
add chain=forward action=drop in-interface=WAN_ether1 src-address=10.10.10.0/24 \
comment="Bloquear LAN IP Spoofing (Forward)"

Protección contra escaneos y ataques comunes

add chain=input action=drop in-interface=WAN_ether1 protocol=tcp psd=21,3s,3,1 \
comment="Bloquear TCP SYN Scans"
add chain=input action=drop in-interface=WAN_ether1 protocol=udp

REGLAS INPUT (TRÁFICO AL ROUTER) Permitir administración solo desde LAN

add chain=input action=accept in-interface=LAN_bridge protocol=tcp dst-port=22,8291,443 \
comment="Acceso Administracion (LAN)"

Permitir ICMP (ping)

add chain=input action=accept protocol=icmp comment="Allow ICMP"

Permitir DHCP desde ISP

add chain=input action=accept in-interface=WAN_ether1 protocol=udp src-port=67-68 dst-port=67-68 \
comment="DHCP Cliente"

Bloquear todo lo demás en WAN

add chain=input action=drop in-interface=WAN_ether1 \
comment="Bloquear Todo WAN Input"

REGLAS FORWARD (TRÁFICO A TRAVÉS DEL ROUTER)

Permitir LAN -> Internet

add chain=forward action=accept in-interface=LAN_bridge out-interface=WAN_ether1 \
connection-state=new comment="LAN a Internet"

Bloquear Internet -> LAN (excepto respuestas)

add chain=forward action=drop in-interface=WAN_ether1 out-interface=LAN_bridge \
connection-state=new comment="Bloquear Internet a LAN"

Permitir tráfico entre interfaces LAN (opcional)

add chain=forward action=accept in-interface=LAN_bridge out-interface=LAN_bridge \
comment="Inter-LAN Tráfico"

REGLAS OUTPUT (TRÁFICO DESDE EL ROUTER)

add chain=output action=accept comment="Permitir Router Output" disabled=no

REGLAS ADICIONALES DE SEGURIDAD Bloqueo de redes reservadas/rfc1918 desde WAN

add chain=input action=drop in-interface=WAN_ether1 src-address-list=private_ranges \
comment="Bloquear IPs Privada (Input)"
add chain=forward action=drop in-interface=WAN_ether1 src-address-list=private_ranges \
comment="Bloquear IPs Privada (Forward)"

Lista de redes reservadas

/ip firewall address-list
add address=172.16.0.0/12 list=private_ranges
add address=10.0.0.0/8 list=private_ranges
add address=192.168.0.0/16 list=private_ranges
add address=169.254.0.0/16 list=private_ranges

LOGGING (OPCIONAL)

add chain=input action=log log-prefix="[BLOQUEO DE CORTAFUEGOS] " \
comment="Log Bloqueado Input"
add chain=forward action=log log-prefix="[BLOQUEO DE CORTAFUEGOS] " 
comment="Log Bloqueado Forward"

Configurar servicios:

/ip service
set ssh address=10.10.10.0/24,192.168.88.0/24
set winbox address=10.10.10.0/24,192.168.88.0/24
set ftp disable=yes
set telnet disable=yes
set api disable=yes
set api-ssl disable=yes
set www disable=yes
set www-ssl disable=yes

Protección bridge:

/interfaces bridge settings
set use-ip-firewall=yes

Protección extra:

/ip firewall filter
add chain=forward protocol=tcp tcp-flags=syn,!ack action=drop comment="Bloquear SYN-flood"
add chain=forward protocol=udp limit=10/1m action=drop comment="Limite UDP floods"

Explicación:

1. Conexiones Establecidas: - Acepta tráfico de respuestas en todas las cadenas (input, forward, output).

2. Protección Anti-Spoofing: - Bloquea tráfico WAN con IPs de la LAN (10.10.10.0/24). - Bloquea redes reservadas (RFC 1918) desde WAN.

3. Reglas INPUT: - Solo permite administración (SSH, Winbox, WebFig) desde la LAN. - Permite ICMP (ping) y DHCP del ISP. - Bloquea todo el tráfico entrante no autorizado en WAN.

4. Reglas FORWARD: - Permite nuevas conexiones desde LAN hacia Internet. - Bloquea nuevas conexiones desde Internet hacia LAN. - Permite comunicación entre dispositivos LAN (opcional).

5. Reglas OUTPUT: - Permite todo el tráfico generado por el router (se puede ajustar si es necesario).

6. Protección Adicional: - Bloqueo de escaneos TCP/UDP desde Internet. - Logging de tráfico bloqueado para diagnóstico.

Notas: - Políticas por Defecto: - Input: drop (implícito por reglas). - Forward: drop (regla final bloquea tráfico no autorizado). - Output: accept.

- NAT: La regla masquerade en srcnat permite a la LAN acceder a Internet usando la IP WAN (asignada por DHCP).

- Personalización: - Para permitir acceso desde Internet (ej: servidor web), agregar reglas `forward` específicas. - Ajustar puertos de administración en reglas `input` según necesidades.

Esta configuración equilibra seguridad y funcionalidad, protegiendo la LAN de amenazas externas mientras permite acceso a Internet.

FreeBSD es genial!.