Páginas

jueves, 26 de febrero de 2026

mount FreeBSD Cifrado ZFS desde liveCD y encontrar partición root

Montar FreeBSD 14.3 cifrado ZFS desde liveCD

 mkdir /tmp/mountado
 geli attach /dev/nda0p4
 zpool import -f -R /tmp/montado zroot
 zfs list zroot
 NAME                                         USED  AVAIL  REFER  MOUNTPOINT
zroot                                          223G   211G    96K  /zroot
zroot/ROOT                                    82.9G   211G    96K  none
zroot/ROOT/14.3-RELEASE-p8-26-Feb-2026     	 8K   211G  21.1G  /
zroot/ROOT/default                            82.9G   211G  21.3G  /
zroot/cache                                   3.04G   211G    96K  /zroot/cache
zroot/cache/ccache                            3.04G   211G  3.04G  /var/cache/ccache
zroot/home                                    75.3G   211G    96K  /home
zroot/home/carlos                             75.3G   211G  67.4G  /home/carlos
zroot/reserved                                50.0G   261G    96K  /zroot/reserved
zroot/tmp                                      320K   211G   180K  /tmp
zroot/usr                                     9.89G   211G    96K  /usr
zroot/usr/ports                               6.99G   211G  2.91G  /usr/ports
zroot/usr/src                                 2.90G   211G  2.63G  /usr/src
zroot/var                                     1.61G   211G    96K  /var
zroot/var/audit                                 96K   211G    96K  /var/audit
zroot/var/crash                               1.60G   211G  1.60G  /var/crash
zroot/var/log                                 3.11M   211G  2.00M  /var/log
zroot/var/mail                                 356K   211G   260K

Propiedad canmount de zroot/ROOT/default

zfs get mountpoint,canmount,mounted zroot/ROOT/default
NAME                PROPERTY    VALUE       SOURCE
zroot/ROOT/default  mountpoint  /           local
zroot/ROOT/default  canmount    noauto      local
zroot/ROOT/default  mounted     yes         -

¿Qué hace canmount=noauto?

La propiedad canmount en ZFS controla si un dataset puede ser montado. Tiene tres valores posibles:

on - El dataset se monta automáticamente cuando es necesario (por ejemplo, al importar el pool o al ejecutar zfs mount -a).

off - El dataset no puede ser montado en absoluto.

noauto - El dataset no se monta automáticamente por operaciones generales del sistema (como zfs mount -a o la importación del pool), pero puede ser montado manualmente con zfs mount. Es un estado intermedio que lo hace "disponible pero no automático".

Montar zroot/ROOT/default con el comando mount

 zfs mount zroot/ROOT/default

Despues de finalizar los cambios exportar el zpool

zpool export zroot

Reiniciar y arrancar desde el disco duro NVMe (nda0)

 shutdown -r now
FreeBSD es genial!.

jueves, 19 de febrero de 2026

Migración de SSD a disco de mayor capacidad en FreeBSD 14.3 send receive vía USB

Estado actual del sistema

zpool status
zpool list 
zpool list -t all

Identificar discos

geom disk list
camcomtrol devlist

Anotar el disco actual (ada0) y el nuevo disco USB (da0)


Limpiar el disco nuevo completamente

gpart destroy -F da0
dd -if=/dev/zero of=/dev/da0 bs=1M count=100

Crear tabla de particiones GPT

gpart create -s gpt da0

Partición de arranque EFI (si el sistema usa UEFI)

gpart add -t efi -s 260M -l efiboot-new da0

Partición de arranque BIOS/GPT (para compatibilidad legacy)

gpart add -t freebsd-boot -s 512k -l gptboot-new da0

Partición swap

gpart add -t freebsd-swap -s 8G -a 1M -l swap0 da0

Particion ZFS (el resto del disco)

gpart add -t freebsd-zfs -a 1M -l zroot-new da0

Para sistemas UEFI


Montar partición EFI del disco nuevo

newfs_msdos -F 32 -c 1 /dev/da0p1
mount -t msdosfs /dev/da0p1 /mnt

Copiar EFI loader desde el actual disco

mkdir -p /mnt/EFI/BOOT
cp -r /boot/efi/EFI/BOOT /mnt/EFI/

umount /mnt

Crear pool temporal en el nuevo disco

Crear pool temporal con nombre diferente para evitar conflictos
zpool create -o altroot=/mnt \
             -o ashift=12 \
             -O compression=lz4 \
             -O atime=off \
             -O xattr=sa \
             -O acltype=posix \
             -m none \
             zroot-new /dev/da0p3

Verificar

zpool status zroot-new

Listar todos los datasets a migrar

zfs list -H -o name -t filesystem,volume

Tomar snapshot recursivo de todo el pool (Shell zsh)

sudo zfs snapshot -r zroot@migracion

Verificar snapshot creado

zfs list -t snapshot -o name | grep "$migracion" 
zroot@migracion
zroot/ROOT@migracion
zroot/ROOT/14.3-RELEASE-filebrowser-tailscale-serve-certs-https@migracion
zroot/ROOT/14.3-RELEASE_2026-02-14_193200@migracion
zroot/ROOT/default@2026-02-14-19:32:00-0
zroot/ROOT/default@2026-02-17-17:48:09-0
zroot/ROOT/default@migracion
zroot/home@migracion
zroot/home/carlos@migracion
zroot/tmp@migracion
zroot/usr@migracion
zroot/usr/ports@migracion
zroot/usr/src@migracion
zroot/var@migracion
zroot/var/audit@migracion
zroot/var/crash@migracion
zroot/var/log@migracion
zroot/var/mail@migracion
zroot/var/tmp@migracion

Enviar snapshot raíz primero

zfs send -Lec zroot@migration-$(date +%Y%m%d) | \
    zfs receive -Fuv zroot-new

Enviar recursivamente todos los datasets hijos

zfs send -RLec zroot@migration-$(date +%Y%m%d) | \
    zfs receive -Fuv zroot-new

Banderas (flags)

-R Recursivo (todos los datasets hijos)
-L Incluye large blocks
-e Embed data (bloques pequeños inline)
-c Comprime el stream
-F En receive: fuerza rollback si es necesario
-u No monta los datasets al recibirlos
-v Verbose

Comprobar la replicación


Comparar conjuntos de datos entre pools

zfs list -r zroot
zfs list -r zroot-new

Verificar propiedades

zfs get all zroot
zfs get all zroot-new

Cantidad de instantáneas

zfs list -t snapshot -r zroot | wc -l
zfs list -t snapshot -r zroot-new | wc -l

Configurar bootfs en el nuevo pool

zpool set bootfs=zroot-new/ROOT/default zroot-new

Verificar

zpool get bootfs zroot-new

Ajustar cachefile y otros parámetros del pool

zpool set cachefile=/boot/zfs/zpool.cache zroot-new

Ver propiedades del pool original para replicarlas

zpool get all zroot

Montar el dataset raíz del nuevo disco

zfs set mountpoint=/mnt zroot-new/ROOT/default
zfs mount zroot-new/ROOT/default

Verificar /boot/loader.conf

cat /mnt/boot/loader.conf

Debe contener algo como:

zfs_load="YES"
vfs.root.mountfrom="zfs:zroot/ROOT/default"

Si el nombre del pool cambió, actualizar:

sed -i '' 's/zroot-new/zroot/g' /mnt/boot/loader.conf

También verificar /etc/fstab (en ZFS puro suele estar sin referencias a ada0)

cat /mnt/etc/fstab

Cambiar el disco y primer arranque


Apagar el sistema

shutdown -p now

Desconectar el disco viejo Conectar el nuevo disco en el slot interno (ya no como USB) Comprobar en BIOS/UEFI que el nuevo disco sea el primero en el orden de arranque Arrancar

Verificación después del arranque


Comprobar salud del pool

zpool status
zpool list

Verificar que todos los datasets montaron

zfs list -t filesystem

Verificar espacio disponible (debe reflejar el disco nuevo mayor)

df -h

Verificar que el sistema arrancó desde el disco correcto

geom disk list
camcontrol devlist

Limpiar snapshots de migración

zfs destroy -r zroot@migracion

Problemas y posibles soluciones después del primer arranque


Renombrar zpool zroot-new a zroot

zpool import -f zroot-new zroot

Error

zpool export zroot-new Cannot unmount /

Es el error clásico: el dataset raíz (/) está montado desde zroot-new, así que ZFS no puede desmontarlo en caliente

Solución Desde loader prompt o LiveCD


Desde el LiveCD

zpool import -f zroot-new zroot
zpool set bootfs=zroot/ROOT/default zroot
zpool export zroot

zpool import -f zroot-new zroot
   zpool set bootfs=zroot/ROOT/default zroot
   zpool export zroot hecho.

Reiniciar

shutdown -r now

FreeBSD al arrancar y no encontrar zroot buscará pools disponibles. Si el disco nuevo ya está interno, lo encontrará como zroot-new y podrás importarlo con el nombre correcto.

Después de reiniciar sin el LiveCD el sistema arranca desde el nuevo disco duro.

Estos dos errores son normales y esperables en este proceso.

1. swapon: /dev/da0p3: No such file or directory, 
2. Import of zpool cache /etc/zfs/zpool.cache failed

El archivo /etc/fstab del sistema nuevo todavía referencia el dispositivo del disco USB (da0) que ya no existe. Ahora el disco está interno, probablemente como ada0 o nvme0ns1.

Montar el sistema de ficheros rw

mount -u -o rw /

Averiguar cómo se llama el disco ahora geom disk list o camcontrol devlist.

geom disk list                                    
Geom name: ada0
Providers:
1. Name: ada0
   Mediasize: 250059350016 (233G)
   Sectorsize: 512
   Mode: r3w3e7
   descr: WDC WDS250G2B0A-00SM50
   lunid: 5001b448b8a2a91f
   ident: 192686806761
   rotationrate: 0
   fwsectors: 63
   fwheads: 16

Cambiar la línea de swap, por ejemplo

/dev/da0p3  none   swap  sw   0   0
 por
/dev/ada0p3  none   swap  sw   0   0

Mejor aún, usar la etiqueta (label) GPT que es independiente del nombre del dispositivo

gpart show -l ada0
=>       40  488397088  ada0  GPT  (233G)
         40     532480     1  efiboot0  (260M)
     532520       1024     2  gptboot0  (512K)
     533544        984        - free -  (492K)
     534528   16777216     3  swap0  (8.0G)
   17311744  471085056     4  zroot-new  (225G)
  488396800        328        - free -  (164K)
ls /dev/gpt/
efiboot0 gptboot0 swap0

En el archivo /etc/fstab usar la etiqueta en lugar del dispositivo

...
/dev/gpt/swap0	  none	  swap	  sw	 0	0
...

Error 2

Import of zpool cache /etc/zfs/zpool.cache failed

El zpool.cache fue generado cuando el pool se llamaba zroot-new y estaba en da0. Ahora el pool se llama zroot y el dispositivo cambió. El caché está obsoleto.

Sencillamente borrarlo, ZFS lo regenera automáticamente

rm /etc/zfs/zpool.cache

Antes de reiniciar para verificar el nombre correcto del dispositivo

swapinfo -h
Device              Size     Used    Avail Capacity
/dev/gpt/swap0      8.0G       0B     8.0G     0%

Si el sistema arrancó pero con errores no críticos Ambos errores no impiden el funcionamiento del sistema. El swap simplemente no está activo hasta que corrijas el fstab, y el zpool.cache se regenera solo. Si llegaste al prompt de login, la migración fue exitosa.

Reiniciar

shutdown -r now

Error 3.

Can't open /dev/gpt/efiboot0

Ese error indica que el bootloader está buscando la partición EFI por su label GPT (efiboot0) pero no la encuentra, probablemente porque el label en el disco nuevo es diferente o no se asignó correctamente

ls /dev/gpt
efiboot0 gptboot0 swap0

Montar el sistema de ficheros rw

mount -u -o rw /

Solución. Renombrar el label al esperado

...
/dev/gpt/efiboot0    /boot/efi	  msdosfs    rw	   2	2
...

Corregir el label

gpart modify -i 1 -l efiboot0 ada0

Si la partición EFI estaba vacía, reinstalar loader

newfs_msdos -F 32 -c 1 /dev/ada0p1
mount -t msdosfs /dev/ada0p1 /mnt
mkdir -p /mnt/EFI/BOOT
cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.EFI

umount /mnt

 

FreeBSD es genial!.

viernes, 6 de febrero de 2026

Alternativas cuando el Router no Permite el Reenvío de Puertos

Bibliografía:

Tailscale

En la página de Tailscale "Regístrese con su proveedor de identidad", inicie sesión con una cuenta de proveedor de identidad de inicio de sesión único (SSO).

como habilitar acceso remoto a un servidor local (FreeBSD 14.3), que está detrás de un NAT (una red doméstica donde el ISP no permite abrir puertos), sin necesidad de un dominio publico.

Tailscale, un servicio P2P basado en wireguard que implementa NAT traversal para crear una red VPN segura y privada. Permite conectar dispositivos de forma directa (P2P) cuando es posible, o a través de relays (DEP servers) si el NAT es estricto. No expone puertos públicos ni requiere configuraciones complejas en routers. Tailscale es gratuito para uso personal (hasta 3 usuarios y 100 dispositivos).

Tailscale no necesita dominio público porque el acceso se realiza a través de IPs privadas de Tailscale (en el rango 100.64.0.0/10 conocidas como CGNAT) o nombre de host automáticos en tu "tailnet" (red privada de Tailscale). 

Instalación, configuración, NAT traversal y acceso a servicios locales. Asumido que tiene acceso root en el servidor FreeBSD 14.3 y que el sistema está actualizado (pkg update && pkg upgrade).

Wireguard es el protocolo subyacente, un VPN moderno, ligero y seguro que usa criptografía de curva elíptica para túneles cifrados.

Nat Travesal. Tailscale utiliza técnicas como STUN (para descubrir IPs públicas y puertos), ICE (para negociar conexiones P2P) y relays DERP (servidores de Tailscale que actúan como intermediariso si el P2P falla debido a NAT simétrico o firewalls estrictos).

Tailnet. Su red privada virtual. Todos los dispositivos autenticados en su cuenta forman parte de ella.

Servicios locales. Para acceder a un servicio en el servidor (por ejemplo web en 80), el cliente se conecta a la IP de Tailscale + puerto, como si estuvieran en la misma LAN.

Dispositivo cliente (PC, teléfono móvil, etc.) desde donde se accederá instalando Tailscale (disponible para Windows, macOS, FreeBSD, iOS, Android, Linux).

Firewall en FreeBSD. Si usa PF (Packet Filter), asegurarse de que permita tráfico saliente (por defecto lo hace). No necesita reglas entrantes especiales para Tailscale, ya que utiliza la interfaz tailscale0.

Instalar Tailscale en el servidor local (FreeBSD 14.3)

pkg install tailscale

Esto instala tailscaled (el demonio) y tailscale (la CLI). Dependencias como Wireguard se instalan automáticamente.

Habilitar el servicio para que inicie al inicio

sysrc tailscaled_enable="YES"

Iniciar el servicio

service tailscaled start

Comprobar el estado

service tailscaled status

Autenticar el servidor en tu tailnet

tailscale up

Esto genera un URL de autenticación (ej. https://login.tailscale.com/a/65831eb3ddff0). Copiar y pegar en un navegador en cualquier dispositivo. Iniciar sesión con su cuenta de Tailscale para aprobar el dispositivo. Una vez aprobado, el comando completará y el servidor se unirá a su tailnet.

tailscale status
100.115.10.68   tormenta  nombreusuario@  freebsd

Se muestra el servidor con una IP de Tailscale y estado online

ifconfig tailscale0 para la interfaz VPN.

ifconfig tailscale0

tailscale0: flags=1008043< <UP,BROADCAST,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 1280
	options=4080000< <LINKSTATE,MEXTPG>
	inet 100.115.10.68 netmask 0xffffffff broadcast 100.115.10.68
	inet6 fd7a:115c:a1e0::cd01:687 prefixlen 48
	groups: tun
	nd6 options=101 <PERFORMNUD,NO_DAD>
	Opened by PID 27732
You are about to connect the device tormenta to the nombreususario@gmail.com tailnet.

Public key 		nodekey:af18fa705771d20c28856057767cafc...

Hostname    		tormenta

Operating system	freebsd (14.3-RELEASE-p7)

Tailscale version	1.94.1

tormenta		100.115.10.68

No es necesario configurar nada extra en su router o firewall.

Exponer Servicios Locales

Por defecto, Tailscale permite acceso a cualquer puerto en la IP de Tailscale del servidor, siempre que el servicio escuche en 0.0.0.0 o la interfaz tailscale0

Ejemplo para un servidor web (por ejemplo, Nginx en el puerto 80) se configura para escuchar en 0.0.0.0:80

Archivo de configuración /usr/local/etc/nginx/nginx.conf

---
server {
        listen       8000; #poudriere
        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;
        }

        location / {
                index index.html index.htm;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
}

# Servidor web principal en el puerto 80
server {
        listen 0.0.0.0:80; #nginx
        server_name localhost;

        root /usr/local/www/nginx;
        index index.html index.htm;

        # Paginas de error para el servidor principal
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
    }

}
---

Si se quiere acceder a toda la subred local (otros dispositivos en la red 192.168.88.0/24), se tiene que habilitar subnet routes:

tailscale up --advertise-routes=192.168.88.0/24. Posteriormenta se aprueba en el 
admin console.

Seguridad adicional

Usar ACLs (Access Control Lists) en el admin console para restringir accesos (por ejemplo, solo ciertos usuarios pueden acceder al servidor).

Habilitar MagicDNS. En el admin console, ir a DNS > Enable MagicDNS. Para usar nombre como fsb143 en lugar de IPs.

Para headless (sin interacción): Usar pre-auth keys

Acceso desde Internet (lado cliente)

Instalar Tailscale en el dispositivo
Ejecutar tailscale up y autenticar con el mismo URL/login utilizado para el servidor 
(unirse al mismo tailnet)

Una vez conectado acceder al servidor

Web:
abrir http://100.115.10.68:80 (reemplazar con la IP de Tailscale del servidor 
obtenida de tailscale status). Bienvenido al servidor FreeBSD nginx! Si ve esta pagina, el servidor web nginx se instalo correctamente y funciona
correctamente. Se requiere configuracion adicional. Para obtener documentacion y soporte en linea, consulte nginx.org. Gracias por usar nginx.
FreeBSD es genial!.