Páginas

Mostrando entradas con la etiqueta Redes. Mostrar todas las entradas
Mostrando entradas con la etiqueta Redes. Mostrar todas las entradas

lunes, 6 de abril de 2026

Configuración de LAGG failover en FreeBSD 14.4

LAGG failover en FreeBSD 14.4 em0 (primaria) y wlan0 (respaldo via iwm0)

Fuente:


https://www.ccammack.com/posts/configure-a-wifi-client-on-freebsd
https://wiki.freebsd.org/Devd
https://headthirst.com/freebsd-suspend.html
https://forums.freebsd.org/threads/freebsd-command-line-wifi-manager.89090/
https://www.dwarmstrong.org/freebsd-network-laptop/
https://libreboot.org/docs/bsd/suspend-resume-speedup.html
https://forums.freebsd.org/threads/freebsd-command-line-wifi-manager.89090/
https://forums.freebsd.org/threads/wifi-stops-working-after-suspend-resume.85889/
https://www.reddit.com/r/voidlinux/comments/1lfxurz/wifi_disappears_after_waking_from_suspend_i

Nombres de los dispositivos 802.11 disponibles

sysctl net.wlan.devices
net.wlan.devices: iwm0

Tomando como ejemplo mi computadora portátil (Dell Latitude 7390), la interfaz Ethernet em0 funcionará como puerto maestro y la interfaz inalámbrica wlan0 será el dispositivo de respaldo. Combino las dos interfaces en una interfaz virtual sobrescribiendo la dirección MAC de la interfaz Ethernet con la dirección MAC de la interfaz inalámbrica.

Determinar la dirección MAC de la interfaz inalámbrica

ifconfig wlan0 | grep ether
	ether 18:56:80:f8:98:e6

Cambiar la dirección MAC de la interfaz Ethernet para que coincidan

ifconfig em0 ether 18:56:80:f8:98:e6	

/etc/rc.conf

...
ifconfig_em0="ether 18:56:80:f8:98:e6"
wlans_iwm0="wlan0"
ifconfig_wlan0="WPA"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport em0 laggport wlan0 SYNCDHCP"
create_args_wlan0="country ES"
defaultrouter="192.168.88.1"
defaultroute_delay="10"
background_dhclient_lagg0="YES"
... 
Archivo /etc/wpa_supplicant
/etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
eapol_version=2
fast_reauth=1

network={
	ssid="MikroTik-39F9C0"	
        psk=755862a5b1a4ef59e2e62590677a75f5317193637a8629dccb18c40e8634a68e
}

Reiniciar

Estado general del LAGG

ifconfig lagg0
lagg0: flags=1008843 UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP metric 0 mtu 1500
	options=0
	ether 18:56:80:f8:98:e6
	hwaddr 00:00:00:00:00:00
	inet 192.168.88.50 netmask 0xffffff00 broadcast 192.168.88.255
	laggproto failover lagghash l2,l3,l4
	laggport: em0 flags=1 MASTER
	laggport: wlan0 flags=4 ACTIVE
	groups: lagg
	media: Ethernet autoselect
	status: active
	nd6 options=29 PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL

Ver puerto activo

ifconfig lagg0 | grep -E "laggport|status"
	laggport: em0 flags=1 MASTER 
	laggport: wlan0 flags=4 ACTIVE
	status: active

Estadísticas en detalle

sysctl net.link.lagg
net.link.lagg.lacp.default_strict_mode: 1
net.link.lagg.lacp.debug: 0
net.link.lagg.default_flowid_shift: 16
net.link.lagg.default_use_numa: 1
net.link.lagg.default_use_flowid: 0
net.link.lagg.failover_rx_all: 0

En /etc/rc.conf em0 no debe tener IP propia, es gestionado por lagg0 wlan0 no debe tener DHCP propio cuando está bajo lagg0; el DHCP lo gestiona lagg0. El failover es automático, al detectar pérdida de carrier en em0, el tráfico pasa a wlan0 sin intervención manual.

Sin conexión a Internet después de salir de hibernación

Al salir de hibernación, devd no recrea lagg0 de forma automática. La solución es un script de resume que se ejecute al despertar.

Crear el script de resume-network.sh

/usr/local/sbin/resume-network.sh

#!/bin/sh
sleep 3

# Destruir interfaces
ifconfig lagg0 destroy 2>/dev/null
ifconfig wlan0 destroy 2>/dev/null

# Recrear wlan0 sin country (lo hereda de rc.conf al crear)
ifconfig wlan0 create wlandev iwm0
ifconfig wlan0 country ES 2>/dev/null

# Recrear lagg0
ifconfig lagg0 create
ifconfig lagg0 laggproto failover
ifconfig lagg0 laggport em0
ifconfig lagg0 laggport wlan0
ifconfig lagg0 up

# Arrancar wpa_supplicant
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf

# Esperar asociacion (max 30s)
i=0
while [ $i -lt 30 ]; do
    status=$(ifconfig wlan0 | grep "status:" | awk '{print $2}')
    [ "$status" = "associated" ] && break
    sleep 1
    i=$((i + 1))
done

logger "resume-network: wlan0 status=$status tras ${i}s"

# Matar dhclient previo si existe
pkill -F /var/run/dhclient/dhclient.lagg0.pid 2>/dev/null
sleep 1

# Obtener IP
dhclient lagg0

# Ruta por defecto si dhclient no la puso
sleep 2
netstat -rn | grep -q "^default" || route add default 192.168.88.1

logger "resume-network: completado"

Aumentar timeout de dhclient

vim /etc/dhclient.conf
interface "lagg0" {
    timeout 60;
    retry 10;
}

Configurar devd para se ejecute al despertar

vim /etc/devd/resume-network.conf
notify 100 {
    match "system"      "ACPI";
    match "subsystem"   "Resume";
    action "/usr/local/sbin/resume-network.sh &";
};

Reinicar devd

sudo service devd restart

Comprobar que devd capta el evento revisando tras salir de hibernación

tail -5 /var/log/messages
Apr  5 16:11:50 solaris dhclient[13642]: New IP Address (lagg0): 192.168.88.50
Apr  5 16:11:50 solaris dhclient[13646]: New Subnet Mask (lagg0): 255.255.255.0
Apr  5 16:11:50 solaris dhclient[13650]: New Broadcast Address (lagg0): 192.168.88.255
Apr  5 16:11:50 solaris dhclient[13654]: New Routers (lagg0): 192.168.88.1
Apr  5 16:11:51 solaris root[13671]: resume-network: completado

Al hibernar, FreeBSD destruye las interfaces clonadas (lagg0) y en algunos casos también wlan0. Al despertar, rc.conf no se reprocesa. devd es el mecanismo correcto para reaccionar a eventos ACPI como Resume.

El sleep 3 inicial es importante porque iwm0 necesita unos segundos para que el firmware del adaptador WiFi Intel esté operativo tras el resume.

Ver si devd captó el evento Resume

grep -E "Resume|resume-network" /var/log/messages | tail -5

Apr  5 15:48:07 solaris carlos[12362]: resume-network: wlan0 status=associated tras 3s
Apr  5 15:48:09 solaris carlos[12527]: resume-network: completado
Apr  5 16:11:39 solaris kernel: rtsx0: Resume
Apr  5 16:11:49 solaris root[13506]: resume-network: wlan0 status=associated tras 3s
Apr  5 16:11:51 solaris root[13671]: resume-network: completado

Comprobar que dhclient obtuvo IP

Apr  5 16:11:50 solaris dhclient[27343]: My address (192.168.88.50) was deleted, dhclient exiting
Apr  5 16:11:51 solaris dhclient[28339]: dhclient already running, pid: 28314.
Apr  5 16:11:51 solaris dhclient[28339]: exiting.
Apr  5 16:11:52 solaris dhclient[28317]: connection closed
Apr  5 16:11:52 solaris dhclient[28317]: exiting.
Apr  5 16:11:54 solaris dhclient[28659]: New IP Address (lagg0): 192.168.88.50
Apr  5 16:11:54 solaris dhclient[28663]: New Subnet Mask (lagg0): 255.255.255.0
Apr  5 16:11:55 solaris dhclient[28667]: New Broadcast Address (lagg0): 192.168.88.255
Apr  5 16:11:55 solaris dhclient[28671]: New Routers (lagg0): 192.168.88.1
FreeBSD es genial!.

martes, 16 de diciembre de 2025

Cifrado por Envoltorio (túnel) del tráfico NFSv4 con Wireguard FreeBSD 14.3

Implementar cifrado por envoltorio (Wireguard) y proteger conexiones NFS entre un servidor y su(s) cliente(s).

Objetivos:

NFSv4 puro y limpio (solo puerto 2049).
Acceso exclusivo a través del túnel WireGuard (cifrado punto a punto).
Imposible acceder a los recursos desde la LAN física (bloqueado por PF).
Montajes persistentes y estables en el cliente.
Todo seguro, mínimo y sin componentes innecesarios corriendo.

Cómo implementar el cifrado por envoltorio: WireGuard

El servidor NFSv4 corre FreeBSD 14.3 ZFS, red 192.168.88.0/24, dominio local.com, nombre de host tormenta.local.com, dirección IP 192.168.88.160, interfaz re0, cortafuegos PF.

El cliente es un portátil con sistema operativo FreeBSD 14.3 ZFS, dirección IP 192.168.88.51, nombre de host solaris.local.com, interfaz de red em0. El archivo /etc/exports actual

V4: /nfsv4 -tls
/nfsv4/dellhome     -maproot=root -network 192.168.88.0/24 
/nfsv4/poolrecovery -maproot=root -network 192.168.88.0/24 
/nfsv4/docs         -maproot=root -network 192.168.88.0/24 
/nfsv4/confsolaris  -maproot=root -network 192.168.88.0/24 
/nfsv4/conftormenta -maproot=root -network 192.168.88.0/24
root@tormenta:~ # zfs list | grep /nfsv4 
zroot/nfsv4 103G 212G 7.80G /nfsv4 
zroot/nfsv4/confsolaris 283M 212G 4.76M /nfsv4/confsolaris 
zroot/nfsv4/conftormenta 916K 212G 852K /nfsv4/conftormenta 
zroot/nfsv4/dellhome 56.6G 212G 56.6G /nfsv4/dellhome 
zroot/nfsv4/docs 7.80G 212G 7.80G /nfsv4/docs 
zroot/nfsv4/poolrecovery 1.88G 212G 1.88G /nfsv4/poolrecovery 

La idea es crear un túnel VPN punto a punto entre el servidor (tormenta.local.com, 192.168.88.160) y el cliente (solaris.local.com, 192.168.88.51). De esta forma, el tráfico NFS se enruta exclusivamente a través del túnel encriptado de WireGuard, y configurar el servidor NFS para que solo escuche en la IP del túnel (evitando accesos directos por la LAN).

Forzar el cifrado para NFS, ya que ambos hosts están en la misma red LAN (192.168.88.0/24). Usar IPs privadas para el túnel: 10.66.66.1/32 para el servidor y 10.66.66.2/32 para el cliente. No es necesario forwarding ni NAT, ya que es un túnel simple para cifrar el tráfico local.

Verificar que no haya conflictos con reglas PF existentes. Si se usa NFSv4 puro, no se necesita rpcbind ni mountd, lo que simplifica las cosas


Detener servicios TLS

root@tormenta:/home/carlos # service tlsservd status
tlsservd is running as pid 1278.
root@tormenta:/home/carlos # service tlsservd stop
Stopping tlsservd.
Waiting for PIDS: 1278.

root@solaris:~# service tlsclntd status
tlsclntd is running as pid 1596.
root@solaris:~# service tlsclntd stop
Stopping tlsclntd.
Waiting for PIDS: 1596, 1596.

Desactivar TLS

root@tormenta:/home/carlos # sysrc tlsservd_enable="NO"
tlsservd_enable: YES -> NO

root@solaris:~# sysrc tlsclntd_enable="NO"
tlsclntd_enable: YES -> NO

Instalar wireguard-tools en el servidor tormenta y el cliente solaris

pkg install wireguard-tools
sysrc wireguard_enable="YES"
sysrc wireguard_interfaces="wg0"

En el servidor tormenta Generar claves privadas y públicas

mkdir /usr/local/etc/wireguard
cd /usr/local/etc/wireguard

umask 077
wg genkey | tee server_priv.key | wg pubkey > server_pub.key
wg genkey | tee client_priv.key | wg pubkey > client_pub.key

ls -l /usr/local/etc/wireguard
-rw-------  1 root wheel  45 Dec 11 18:28 client_priv.key
-rw-r--r--  1 root wheel  45 Dec 11 18:28 client_pub.key
-rw-------  1 root wheel  45 Dec 11 18:27 server_priv.key
-rw-r--r--  1 root wheel  45 Dec 11 18:27 server_pub.key

Esto genera claves para servidor y cliente

Transferir las claves al cliente solaris (IP 192.168.88.51), usando scp

scp root@tormenta:/usr/local/etc/wireguard/client_priv.key /usr/local/etc/wireguard/client_priv.key
scp root@tormenta:/usr/local/etc/wireguard/client_pub.key /usr/local/etc/wireguard/client_pub.key

Asegurar permisos estrictos (chmod 600 *.key)

cd /usr/local/etc/wireguard/
chmod 600 *.key

ls -l /usr/local/etc/wireguard/
-rw-------  1 root wheel  45 Dec 11 18:30 client_priv.key
-rw-------  1 root wheel  45 Dec 11 18:31 client_pub.key

Configurar WireGuard en el servidor tormenta

Archivo /usr/local/etc/wireguard/wg0.conf

###########################################
[Interface]
Address = 10.66.66.1/32
PrivateKey = <contenido de server_priv.key>
ListenPort = 51820

[Peer]
PublicKey = <contenido de client_pub.key>
AllowedIPs = 10.66.66.2/32

Reemplazar las claves por las claves reales

[Interface]
Address = 10.66.66.1/32
PrivateKey = oPtSkHSk8zNe9d3Z6gExZro9Cf8BELoahgZDsrc/7mk=
ListenPort = 51820

# conexion con clientes
[Peer]
PublicKey = tuu6a6EAPrQTC0tPatWJx2qcS6fEPcg4Z0u/8vY1pTs= 
AllowedIPs = 10.66.66.2/32
###########################################

Habilitar e iniciar el servicio

sysrc wireguard_interfaces="wg0"
sysrc wireguard_enable="YES"
service wireguard start
|

Acvitar desactivar interfaz wg0

wg-quick up wg0
wg-quick down wg0

Comprobar con wg show, debería mostrar la interfaz wg0 levantada

root@tormenta:/home/carlos # wg show
interface: wg0
  public key: UYbDhuNsq0geqJdsVKThSnNLzdc2oHWgUT8Gb0G3VXU=
  private key: (hidden)
  listening port: 51820

peer: tuu6a6EAPrPTC0tPatWJx2qcS6fEPcg4Z0u/8vY1pTs=
  allowed ips: 10.66.66.2/32

Configurar WireGuard en el cliente (solaris)

Archivo /usr/local/etc/wireguard/wg0.conf
###########################################
[Interface]
Address = 10.66.66.2/32
PrivateKey = <contenido de client_priv.key>

[Peer]
PublicKey = <contenido de server_pub.key>
AllowedIPs = 10.66.66.1/32
Endpoint = 192.168.88.160:51820

Reemplazar con las claves reales

[Interface]
Address = 10.66.66.2/32
PrivateKey = sAvZnwh/8xrLLNTxBu75UfvUPB/AhFQTJsUGqYTfUU0=

[Peer]
PublicKey = UYbDhuNsq0geqWdsVKXhSnNLzdc2oHWgUT8Zb0G3VXU=
AllowedIPs = 10.66.66.1/32
Endpoint = 192.168.88.160:51820
###########################################
sysrc wireguard_interfaces="wg0"
sysrc wireguard_enable="YES"
service wireguard start

Levantar interfaz wg0

# wg-quick up wg0
[#] ifconfig wg create name wg0
[#] wg setconf wg0 /dev/stdin
[#] ifconfig wg0 inet 10.66.66.2/32 alias
[#] ifconfig wg0 mtu 1420
[#] ifconfig wg0 up
[#] route -q -n add -inet 10.66.66.1/32 -interface wg0
[+] Backgrounding route monitor

Comprobar wg show debería mostrar el peer conectado.

wg show
interface: wg0
  public key: tuu6a6EAPrPTC0tPatWJx2qcS6fEPcg4Z0u/8vY1pTs=
  listening port: 26481

peer: UYbDhuNsq0geqWdsVKThSnNLzdc2oHWgUT8Gb0G3VXU=
  endpoint: 192.168.88.160:51820
  allowed ips: 10.66.66.1/32
  

Reglas cortafuegos PF (tormenta)

# Regla PF Wireguard antes Anti-spoofing + bogons - permite solo desde el cliente
pass in quick on $lan_if proto udp from 192.168.88.51 to 192.168.88.160 port 51820 keep state
# permite todo dentro del tunel
pass in quick on wg0 keep state # <-- esta es la importante <-p>

Recargar PF

service pf reload 
pfctl -f /etc/pf.conf

Verificar ping, desde el cliente solaris

root@solaris:~# ping 10.66.66.1
PING 10.66.66.1 (10.66.66.1): 56 data bytes
64 bytes from 10.66.66.1: icmp_seq=0 ttl=64 time=0.463 ms
64 bytes from 10.66.66.1: icmp_seq=1 ttl=64 time=0.524 ms

--- 10.66.66.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.463/0.494/0.524/0.031 ms

Verificar ping, desde el servidor tormenta

root@tormenta:~# ping -c2 10.66.66.2
PING 10.66.66.2 (10.66.66.2): 56 data bytes
64 bytes from 10.66.66.2: icmp_seq=0 ttl=64 time=0.429 ms
64 bytes from 10.66.66.2: icmp_seq=1 ttl=64 time=0.526 ms

--- 10.66.66.2 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.429/0.478/0.526/0.049 ms

ping bidireccional exitoso.

Configurar el cortafuegos PF en el servidor (tormenta)

Para permitir el tráfico WireGuard (UDP puerto 51820), agregar reglas a /etc/pf.conf. Asume que ya tienes PF configurado.

pass in quick on re0 proto udp from 192.168.88.51 to 192.168.88.160 port 51820 keep state

Recargar PF

service pf reload
pfctl -p /etc/pf.conf

Configurar NFSv4 para que solo escuche en la IP del túnel


En el servidor (tormenta), asegurar NFSv4 puro en /etc/rc.conf

nsf_server_enable="YES"
nfsv4_server_enable="YES"
nfs_server_flags="-h 10.66.66.1" # Bind sólo a la IP del túnel
nfsuserd_enable="YES" # necesario si se usa dominio

Iniciar servicios

service nfsd start
service nfsuserd start

Es es para que nfsd sólo escuche en 10.66.66.1, (no en 192.168.88.160).

Deshabilitar rpcbind_enable y mountd_enable, no son necesarios para NFSv4 puro.

Realizar los cambios en /etc/exports para restringir accesos sólo al cliente del túnel
(cambiar de red a host -network a -host).

############################################
V4: /nfsv4
/nfsv4/dellhome -maproot=root 10.66.66.2
/nfsv4/poolrecovery -maproot=root 10.66.66.2
/nfsv4/docs -maproot=root 10.66.66.2
/nfsv4/confsolaris -maproot=root 10.66.66.2
/nfsv4/conftormenta -maproot=root 10.66.66.2
############################################

Esto permite solo desde 10.66.66.2 (el cliente vía túnel).

Reiniciar NFS y nfsuserd

service nfsd restart
service nfsuserd restart

Montar NFS en el cliente (solaris) a través del tŕunel


En el cliente montar usando la IP del túnel del servidor, por ejemplo:

mount -t nfs -o nfsv4 10.66.66.1:/docs /mnt/docs

Para montajes persistentes, se utiliza /etc/fstab

10.66.66.1:/poolrecovery     /nisc4    nfs     rw,nfsv4,noatime,bg    0  	0
10.66.66.1:/confsolaris      /nics4    nfs     rw,nfsv4,noatime,bg	  0  	0
10.66.66.1:/conftormenta     /nits4    nfs     rw,nfsv4,noatime,bg	  0  	0
10.66.66.1:/docs             /nids4    nfs     rw,nfsv4,noatime,bg    0  	0
10.66.66.1:/dellhome 	     /nihs4    nfs     ro,nfsv4,noatime,bg	  0  	0

Consideraciones adicionales

Asi queda el archivo /etc/rc.conf (solaris)

$ gsed -e '/^#/d' -e '/^\s*$/d'

syslogd_flags="-ss"
clear_tmp_enable="YES"
hostname="solaris.local.com"
gateway_enable="NO"
ifconfig_em0="inet 192.168.88.51 netmask 255.255.255.0"
defaultrouter="192.168.88.1"
background_dhclient=YES
defaultroute_delay=3
defaultroute_carrier_delay=3
sshd_enable="NO"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
powerd_enable="YES"
powerd_flags="-n hadp"
loader_conf_files="/boot/loader.conf /boot/loader.conf.local"
boot_efi_enable="YES"
webcamd_enable="YES"
moused_port=/dev/ums0
moused_enable="YES"
dumpdev="NO"
zfs_enable="YES"
dbus_enable="YES"
kld_list="i915kms"
nfs_client_enable="YES"
nfsuserd_enable="YES"
nfsv4_client_enable="YES"
nfsv4_domain="local.com"
tlsclntd_enable="NO"
hostid_enable="YES"
hostid_file="/etc/hostid"
autofs_enable="YES"
devd_enable="YES"
devfs_system_ruleset="system"
pf_enable="NO"
pf_rules="/etc/pf.conf"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
wireguard_enable="YES"
wireguard_interface="wg0"
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
lightdm_enable="YES"
zerotier_enable="YES"
vm_dir="zfs:zroot/vm"
vm_list=""
vm_delay="3"
poudriered_enable="YES"
nginx_enable="YES"
memcached_enable="YES"
memcached_flags="-l localhost -m 8192"
jackett_enable="YES"
linux_enable="NO"
ubuntu_enable="YES"
Asi queda /etc/pf.conf
lan_if   = "re0"
lan_net  = "192.168.88.0/24"
lan_ip   = "192.168.88.160"  
ssh_port     = "{ 22 }"
vpn_if="wg0"

set block-policy return         # responde ICMP/TCP-RST a paquetes bloqueados
set ruleset-optimization none   # en FreeBSD 14 no usa "basic" ni "high-latency"
set skip on lo0

match in all scrub (no-df random-id max-mss 1440)
table <bruteforce> persist       # aquí meterá sshguard, pf-badhost, etc.

pass in quick on $lan_if from $lan_net to $lan_ip keep state
pass in quick on $lan_if proto udp from 192.168.88.51 to 192.168.88.160 port 51820 keep state
pass in quick on wg0 keep state # <-- esta es la importante

block in quick on ! $lan_if from $lan_net to any
block in quick on ! $lan_if from 192.168.0.0/16 to any
block in quick on ! $lan_if from 172.16.0.0/12 to any
block in quick on ! $lan_if from 10.0.0.0/8 to any
block in quick from any to { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, ::/128, 0.0.0.0/8 }
block in quick from <bruteforce>

pass quick on lo0all
pass out quick inet keep state
pass in on $lan_if inet proto icmp from $lan_net to $lan_ip icmp-type echoreq keep state
pass out on $lan_if inet proto icmp from $lan_ip to $lan_net icmp-type echorep keep state
pass in on $lan_if proto tcp from $lan_net to $lan_ip port $ssh_port flags S/SFRA keep state
pass quick on $lan_if proto { tcp udp } from $lan_net to $lan_ip port 53
pass out proto udp from any to port 123 keep state
block log all

Asi queda /etc/exports

$ gsed -e '/^#/d' -e '/^\s*$/d' /etc/exports
V4: /nfsv4
/nfsv4/dellhome		-maproot=root 10.66.66.2
/nfsv4/poolrecovery 	-maproot=root 10.66.66.2
/nfsv4/docs 		-maproot=root 10.66.66.2
/nfsv4/confsolaris 	-maproot=root 10.66.66.2
/nfsv4/conftormenta 	-maproot=root 10.66.66.2

Commprobaciones finales En el servidor tormenta no debe aparecer rpcbind ni statd

root@tormenta:/etc # ps aux | grep -E "(statd|rpcbind|nfs)"
root    1192   0.0  0.0 14140  2380  -  Is   09:34      0:00.00 nfsuserd: master (nfsuserd)
root    1194   0.0  0.0 14140  2384  -  I    09:34      0:00.02 nfsuserd: server (nfsuserd)
root    1195   0.0  0.0 14140  2384  -  S    09:34      0:00.02 nfsuserd: server (nfsuserd)
root    1196   0.0  0.0 14140  2380  -  I    09:34      0:00.00 nfsuserd: server (nfsuserd)
root    1197   0.0  0.0 14140  2384  -  I    09:34      0:00.01 nfsuserd: server (nfsuserd)
root    2398   0.0  0.0 13756  2472  -  Ss   12:23      0:00.01 nfsd: master (nfsd)
root    2399   0.0  0.0 13756  2756  -  S    12:23      0:00.08 nfsd: server (nfsd)

En el cliente solaris remontar directorios

root@solaris:~# umount /nisc4 /nics4 /nits4 /nids4 /nihs4
root@solaris:~# mount -a

root@solaris:~# mount | grep 10.66.66.1
10.66.66.1:/poolrecovery on /nisc4 (nfs, noatime, nfsv4acls)
10.66.66.1:/confsolaris on /nics4 (nfs, noatime, nfsv4acls)
10.66.66.1:/conftormenta on /nits4 (nfs, noatime, nfsv4acls)
10.66.66.1:/docs on /nids4 (nfs, noatime, nfsv4acls)

NFSv4 puro, solo puerto 2049 a través del túnel WireGuard, sin dependencias de rpcbind ni demonios extra.

FreeBSD es genial!.

sábado, 6 de diciembre de 2025

FreeBSD 14.3 Cortafuegos PF

Sintaxis actualizada (FreeBSD 14 usa PF de OpenBSD 6.9–7.0 aproximadamente, hay cambios importantes).

# ====================== MACROS ======================
lan_if   = "re0"
zt_if    = "zt1ocu1pr8e2sac"
lan_net  = "192.168.88.0/24"
zt_net   = "192.168.192.0/24"
my_zt_ip = "192.168.192.204"
lan_ip   = "192.168.88.160"      # pon aquí la IP real de re0 si es fija

ssh_port     = "{ 22 }"
nfs_ports_tcp = "{ 111, 892, 2049 }"
nfs_ports_udp = "{ 111, 892 }"

# ====================== OPCIONES GLOBALES ======================
set block-policy return         # responde ICMP/TCP-RST a paquetes bloqueados
set ruleset-optimization none   # en FreeBSD 14 no usa "basic" ni "high-latency"
set skip on lo0
set skip on $zt_if              # ZeroTier ya tiene su propio cortafuegos interno

# Normalización moderna (recomendado)
match in all scrub (no-df random-id max-mss 1440)

# ====================== TABLAS ======================
table <bruteforce> persist       # aquí meterá sshguard, pf-badhost, etc.

# ====================== TRÁFICO CONFIABLE (LAN) =======================
pass in quick on $lan_if from $lan_net to $lan_ip keep state

# =================== EXCEPCIÓN PARA EL TÚNEL WIREGUARD ================
# Wireguard: handshake y todo el trafico dentro del tunel
pass in quick on $lan_if proto udp from 192.168.88.51 to 192.168.88.160 \
port 51820 keep state
pass in quick on wg0 keep state  # <-- esta es la importante

# ====================== REGLAS DE PROTECCIÓN BÁSICA ===================
# Anti-spoofing + bogons (bloqueo rápido)
block in quick on ! $lan_if from $lan_net to any
block in quick on ! $lan_if from 192.168.0.0/16 to any
block in quick on ! $lan_if from 172.16.0.0/12 to any
block in quick on ! $lan_if from 10.0.0.0/8 to any

block in quick from any to { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
10.0.0.0/8, ::/128, 0.0.0.0/8 }

# Bloqueo rápido de hosts en lista negra
block in quick from <bruteforce>

# ====================== LOOPBACK ======================
pass quick on lo0 all

# ====================== TRÁFICO SALIENTE (stateful) ======================
pass out quick inet keep state

# ====================== ICMP ======================
pass in on $lan_if inet proto icmp from $lan_net to $lan_ip icmp-type echoreq \
keep state
pass out on $lan_if inet proto icmp from $lan_ip to $lan_net icmp-type echorep \
keep state

# ====================== SSH CON PROTECCIÓN ======================
# Desde LAN (sin límite)
pass in on $lan_if proto tcp from $lan_net to $lan_ip port $ssh_port flags \
S/SFRA keep state

# Desde ZeroTier (con límite de tasa para evitar brute-force)
pass in on $zt_if proto tcp from $zt_net to $my_zt_ip port $ssh_port \
    flags S/SFRA keep state \
    (max-src-conn-rate 15/5, overload <bruteforce> flush global)

# ====================== DNS (Unbound local) ======================
pass quick on $lan_if proto { tcp udp } from $lan_net to $lan_ip port 53

# ====================== NTP cliente ======================
pass out proto udp from any to port 123 keep state

# ====================== NFS (solo LAN) ======================
pass in on $lan_if proto tcp from $lan_net to $lan_ip port $nfs_ports_tcp \
    flags S/SFRA keep state
pass in on $lan_if proto udp from $lan_net to $lan_ip port $nfs_ports_udp \
    keep state

# NFSv4 callback channel (solo desde clientes NFS de la LAN)
pass in on $lan_if proto tcp from $lan_net to $lan_ip port 3000:4000 \
    flags S/SFRA keep state

# ====================== ZeroTier (puerto de control) ======================
pass in quick on $zt_if proto udp from any to any port 9993

# ====================== BLOQUEO FINAL (por defecto) ======================
block log all

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!.

jueves, 19 de diciembre de 2024

Evitar el Doble NAT - Traduccion de Nombres de Red

Evitar el doble NAT


Cuando el router del módem y el router inalámbrico están conectados en serie, es posible que encuentre algunos problemas con su servicio de Internet debido a la doble NAT (traducción de direcciones de red).

Una posible solución

Crear una ruta estatica en el router de la operadora que cualquier paquete que llegue para la red 192.168.88.0/24 lo envie a la dirección del router 192.168.1.43 que él lo gestionará y el router neutro (Mikrotik) enviará los paquete al dispositivo conrrespondiente, suponiendo que tiene su propia LAN 192.168.88.0/24 y la IP de la puerta de enlace de los dispositivos que se conectan el segundo router seria la 192.168.88.1. Los dispositivos que se conectan a él le asignaria la direccion IP el DHCP del router neutro. La puerta de enlace del router neutro es la 192.168.1.1

Advanced Setup -> Routing -> Static Routes

IP Version DstIP/Prefix/Length Gateway 		Interface  metric
4 	   192.168.88.0/24     192.168.1.43     LAN/Br0    1


FreeBSD es genial!.

jueves, 26 de octubre de 2023

NFSv4 FreeBSD 14.2

NFSv4 - NFS Version 4 Protocol FreeBSD 14.2

Como administrador de un servidor NFS, puede configurarlo para que sólo admita NFSv4, lo que minimiza el número de puertos abiertos y servicios en ejecución en el sistema.

Opcionalmente, también puede deshabilitar la escucha de las llamadas de protocolo RPCBIND, MOUNT, y NSM, que no son necesarias en el caso de sólo NFSv4.

En este momento, es posible habilitar NFSv3 y/o NFSv4 sobre TCP, pero no NFSv3 sobre UDP, de todas maneras, NFSv3 sobre UDP está en desuso. Esto significa que la opción "-u" No se puede especificar para nfs_server_flags en el archivo /etc/rc.conf.

sharenfs=off|on Controla si el sistema de archivos se comparte a través de NFS y que acciones van a ser utilzadas. Un sistema de archivos con una sharenfs=off es administrado con el comando exportfs y entradas en el archivo /etc/exports. Por ejemplo

zfs get sharenfs zroot/usr/backup/dellhome
NAME                       PROPERTY  VALUE     SOURCE
zroot/usr/backup/dellhome  sharenfs  off       local

El archivo exports especifica puntos de montaje remotos para el protocolo NFS. Cada linea especifica el punto de montaje e indicadores de exportacion dentro de un sistema de archivos del servidor local o la raiz del arbol NFSv4 para uno o mas hosts.

En el servidor NFSv4 archivo /etc/rc.conf

sysrc nfs_server_enable="YES"
sysrc nfsv4_server_enable="YES"
sysrc nfs_server_flags="-u -t -n 24"
sysrc hostid_enable="YES"
sysrc hostid_file="/etc/hostid"
sysrc rpcbind_enable="YES"
sysrc rpcbind_flags="-h 192.168.88.160"
sysrc mountd_enable="YES"
sysrc mountd_flags="-r -p 892"
sysrc statd_flags="-p 32766"
sysrc lockd_flags="-p 32767"

Iniciar servicio hostid

service hostid start

Parametros des sysctl (/etc/sysctl.conf)

sysctl vfs.nfs.enable_uidtostring="1"      # Hacer que NFS siempre envíe nombres de propietario numéricos
sysctl vfs.nfsd.enable_stringtouid="1"     # Habilitar nfsd para aceptar nombres de propietario numéricos
sysctl vfs.nfsd.server_max_nfsvers="4"     # Fuerza NFSv4 max
sysctl vfs.nfsd.server_min_nfsvers="4"     # Fuerza NFSv4 min
sysctl vfs.nfsd.issue_delegations="1"      # Habilita delegaciones (mejora rendimiento)
sysctl vfs.nfsd.enable_locallocks="1"      # Bloqueos locales (compatible con ZFS)
sysctl kern.ipc.somaxconn="1024"           # Max conexciones pendientes (por defecto 128)
sysctl net.inet.tcp.delayed_ack="0"        # Mejora rendimiento TCP

Hacer que los cambios sean permanentes

echo vfs.nfs.enable_uidtostring="1" >> /etc/sysctl.conf
echo vfs.nfsd.enable_stringtouid="1" >> /etc/sysctl.conf
echo vfs.nfsd.server_max_nfsvers="4" >> /etc/sysctl.conf
echo vfs.nfsd.server_min_nfsvers="4" >> /etc/sysctl.conf
echo vfs.nfsd.issue_delegations="1" >> /etc/sysctl.conf
echo vfs.nfsd.enable_locallocks="1" >> /etc/sysctl.conf
echo kern.ipc.somaxconn="1024" >> /etc/sysctl.conf
echo net.inet.tcp.delayed_ack="0" >> /etc/sysctl.conf

Usamos el archivo /etc/hosts como resolución de nombres en la red local

...
192.168.88.160		tormenta
192.168.88.51		solaris
...

Configurar PF para permitir el tráfico NFS

...
lan_net ="{ 192.168.88.0/24 10.10.10.0/24 }"
nfs_puertos="{ 111, 892, 2049 }"
statd_lockd_puertos="{ 32766, 32767 }"

pass in proto { tcp } from $lan_net to any port ssh
pass in proto { tcp udp } from $lan_net to any port $statd_lockd_puertos
pass in proto { tcp udp } from $lan_net to any port $samba_puertos
pass in quick proto { tcp udp } from $lan_net to any port $nfs_puertos
...

Reiniciar servicios

tormenta: # service nfsd restart
Stopping nfsd.
Waiting for PIDS: 1391 1394.
Starting nfsd.

tormenta: # service rpcbind restart
Stopping rpcbind.
Waiting for PIDS: 1285.
Starting rpcbind.

tormenta: # service mountd restart
Stopping mountd.
Waiting for PIDS: 1382.
Starting mountd.

Crear los conjunto de datos en el servidor


Configurar canmount=off en zroot/nfsv4 para convertirlo en un contenedor puro (sin montaje, reduce cruces de fs crossings):

zfs set canmount=off zroot/nfsv4
zfs create -o mountpoint=/nfsv4/dellhome -p zroot/nfsv4/dellhome
zfs create -o mountpoint=/nfsv4/poolrecovery -p zroot/nfsv4/poolrecovery
zfs create -o mountpoint=/nfsv4/docs -p zroot/nfsv4/docs
zfs create -o mountpoint=/nfsv4/desarrollo -p zroot/nfsv4/desarrollo
zfs create -o mountpoint=/nfsv4/confsolaris -p zroot/nfsv4/confsolaris
zfs create -o mountpoint=/nfsv4/conftormenta -p zroot/nfsv4/conftormenta

Archivo de ejemplo /etc/exports, directorios compartidos en redes LAN

tormenta: # cat /etc/exports
V4: /nfsv4 # Define /nfsv4 como raiz global
/nfsv4/dellhome       -maproot=root -network 192.168.88.0/24
/nfsv4/poolrecovery   -maproot=root -network 192.168.88.0/24
/nfsv4/docs           -maproot=root -network 192.168.88.0/24 network 10.10.10.0/24
/nfsv4/desarrollo     -maproot=root -network 192.168.88.0/24 network 10.10.10.0/24
/nfsv4/confsolaris    -maproot=root -network 192.168.88.0/24
/nfsv4/conftormenta   -maproot=root -network 192.168.88.0/24

Puertos a la escucha (en el servidor)

root@tormenta:~ # netstat -an | grep -i listen     
tcp6       0      0 *.2049                 *.*                    LISTEN     
tcp4       0      0 *.2049                 *.*                    LISTEN     
tcp4       0      0 *.892                  *.*                    LISTEN     
tcp6       0      0 *.892                  *.*                    LISTEN          
tcp4       0      0 *.111                  *.*                    LISTEN     
tcp6       0      0 *.111                  *.*                    LISTEN 
carlos@tormenta:~ % sockstat -l4 | grep -E 'nfsd|rpcbind|mountd'
root     nfsd        1391 5   tcp4   *:2049                *:*
root     mountd      1382 8   udp4   *:892                 *:*
root     mountd      1382 9   tcp4   *:892                 *:*
root     rpcbind     1285 9   udp4   *:111                 *:*
root     rpcbind     1285 10  udp4   *:898                 *:*
root     rpcbind     1285 11  tcp4   *:111                 *:*

Programar mantenimiento

# crontab -e
@daily /sbin/service mountd reload
@daily /sbin/service nfsd restart

Logs de errorres:

 tail /var/log/messages | grep nfs

Capturar tráfico NFS:

 tcpdump -i re0 port 2049 -w nfs-captura.pcap

Leer paquetes capturados del archivo nfs-captura.pcap

root@tormenta:~ # tcpdump -r nfs-captura.pcap
...
21:14:42.658371 IP solaris.960 > tormenta.nfsd: Flags [P.], seq 976297794:976297922, \
ack 2292617495, win 4352, options [nop,nop,TS val 2858673986 ecr 2537679775], length 128: \
NFS request xid 755722369 124 getattr fh 0,5/2
21:14:42.658440 IP tormenta.nfsd > solaris.960: Flags [.], ack 128, win 29128, options \
[nop,nop,TS val 2537739395 ecr 2858673986], length 0
21:14:42.658497 IP tormenta.nfsd > solaris.960: Flags [P.], seq 1:93, ack 128, win 29128, \
options [nop,nop,TS val 2537739395 ecr 2858673986], length 92: NFS reply xid 755722369 \
reply ok 88 getattr LNK 12231267145 ids 1/53 sz 0
21:14:42.658797 IP solaris.960 > tormenta.nfsd: Flags [.], ack 93, win 4352, options \
[nop,nop,TS val 2858673987 ecr 2537739395], length 0
...

Configurar cliente FreeBSD

cat /etc/hosts...
192.168.88.160		tormenta
192.168.88.51		solaris
...

Para que el servicion nfs client se inicie con el sistema

solaris:~ # sysrc nfs_client_enable=YES
solaris:~ # sysrc nfsv4_client_enable="YES"
solaris:~ # sysrc hostid_enable="YES"
solaris:~ # sysrc hostid_file="/etc/hostid"
solaris:~ # sysrc rpc_statd_enable="YES"
solaris:~ # sysrc rpc_lockd_enable="YES"

Iniciar servicio hostid

service hostid start

Iniciar el servicio nfsclient

solaris:~ # service nfsclient start
NFS access cache time=60
solaris:~ nc -v tormenta 2049
  Connection to tormenta 2049 port [tcp/nfsd] succeeded!
solaris:~ nc -v tormenta 111
Connection to tormenta 111 port [tcp/sunrpc] succeeded!

Montar manualmente un directorio compartido (en el cliente)

solaris:~ # mkdir /mids4
# mount -t nfs -o nfsv4 tormenta:/docs /mids4

Archivo /etc/fstab para un montaje permanente y automático

# Device	Mountpoint	FStype	Options		Dump	Pass#
/dev/gpt/efiboot0	/boot/efi	msdosfs	rw		2	2
/dev/nvd0p3	 none	  	swap	sw			0	0
# 
fdesc		/dev/fd			fdescfs	rw		0	0
#
proc			/proc		procfs	rw		0	0
# nfsv4 shared
tormenta:/poolrecovery     /nisc4    nfs     rw,nfsv4,noatime,bg    0  0
tormenta:/development      /nixs4    nfs     rw,nfsv4,noatime,bg    0  0
tormenta:/docs             /nids4    nfs     rw,nfsv4,noatime,bg    0  0
tormenta:/dellhome 	   /nihs4    nfs     ro,nfsv4,noatime,bg    0  0

Archivo /etc/auto_master

cat /etc/auto_master
#
# Automounter master map, see auto_master(5) for details.
#
/net		-hosts		-nobrowse,nosuid,intr

Configurar el montaje automatico para montar dinámicamente cuando alguien acceda al recurso compartido NFS.

echo 'autofs_enable="YES"' >> /etc/rc.conf
service automountd start

Vamos a comprobar que podemos escribir en el directorio

 cd /nids4
 vim script-while-files.sh 
#!/bin/sh
i=0
while [ $i -le 10 ]
do
	 echo 'creando archivos con contenido'
	i=$(($i+1))
	echo Hola > "file$i.txt"
done
:wq

 chmod +x script-while-files.sh
 ./script-while-files.sh
 ls
 file3.txt             file8.txt
file1.txt             file4.txt             file9.txt
file10.txt            file5.txt             script-while-files.sh
file11.txt            file6.txt
file2.txt             file7.txt

solaris:~ % mount

...
map -hosts on /net (autofs)
tormenta:/poolrecovery on /nisc4 (nfs, nfsv4acls)
tormenta:/dellhome on /nihs4 (nfs, read-only, nfsv4acls)
tormenta:/docs on /nids4 (nfs, nfsv4acls)
tormenta:/development on /nics4 (nfs, nfsv4acls)
...

Verificar PF y reglas en tiempo real

 pfctl -f /etc/pf.conf
 pfctl -s rules
FreeBSD es genial!.

martes, 11 de julio de 2023

Servidor VPN con ZeroTier FreeBSD Raspberry Pi

Para crear una VPN se necesita:

1.- Un Servidor VPN
2.- Configuración de los clientes VPN
3.- Servicio DDNS (para conocer la IP pública de nuestro servidor)
4.- Abrir los puertos en el Router y poder acceder desde el exterior al servidor VPN
5.- No estar detrás de un CG-NAT.

Como acceder a nuestra red de una manera segura, cifrada (cifrado de 256 bits), saltándonos el CG-NAT en caso de que nuestro proveedor de Internet lo utilice, sin abrir puertos y sin servicio DDNS?.

La respuesta es el servicio ZeroTier, (SD-WAN), gratuito para uso personal (25 dispositivos). Con ZeroTier podremos unir equipos, unir redes, tanto si están dentro de la red como fuera de la misma. Podremos acceder desde cualquier ordenador, teléfono, cualquer dispositivo que tengamos dentro de nuestra red pero desde fuera de la red.

Para conseguirlo utilizaremos una raspberrypi (Raspberry Pi 3B) y la convertimos en un servidor VPN. Instalamos el sistema operativo raspbian en un disco externo SSD Intel de 40GB. No es necesario configurar una dirección estática porque no se usa el reenvío de puertos en el Router. Y sí, necesitamos el acceso vía SSH por lo que lo habilitaremos.

La red virtual asignada por ZeroTier es la 192.168.192.0/24, también puede crear su propia red o elegir otra red de las ofrecidas por ZeroTier desde su panel dec control. Debe ser una subred diferente a la subred que tenemos. Por ejemplo, yo tengo la subred 192.168.88.0/24 que no coincide con la red virtual de ZeroTier, la 192.168.192.0/24.

La dirección IP de mi servidor VPN es 192.168.8.12 accedemos a través de un portátil FreeBSD a la Raspberry Pi a través de la red.


% ssh carlos@192.168.88.12

ifconfig servidor VPN

ifconfig solaris FreeBSD

Como utilizaremos Zerotier para construir nuestro propio servidor VPN nos vamos a la página principal de ZeroTier, nos registramos (gratuito para uso personal y menos de 25 computadoras), habilitamos 2 factor authentication, creamos una Red y utilizamos el Network ID o identificador de red para conectar los clientes a esa red.


 

ZeroTier permite enrutar entre una red física y una red privada virtual para que los dispositivos remotos puedan acceder a los recursos locales a través de Internet.

Instalar Zerotier


carlos@raspberrypi3:~ $ sudo apt install zerotier-one

Unirse a la red


carlos@raspberrypi3:~ $ sudo zerotier-cli join 565799d8f6259736
	
carlos@raspberrypi3:~ $ sudo zerotier-cli status
200 info 7dd6...... 1.10.6 ONLINE

Listar redes


carlos@raspberrypi3:~ $ sudo zerotier-cli listnetworks
200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
200 listnetworks 565799d8f6259736 home_arpa 4e:0c:37:66:55:d8 OK PRIVATE zt2lrsbp44 fccc:d2b0:827d:d6b6:9b19::1/40,192.168.192.119/24

Mostrar información de estado


carlos@raspberrypi3:~ $ sudo zerotier-cli info
200 info 7dd....... 1.10.6 ONLINE

Conexión peer to peer listar peers


carlos@raspberrypi3:~ $ sudo zerotier-cli listpeers

A continuación vamos a la página de Zerotier nos logueamos y permitimos que esa computadora se una a la red de zerotier (autorizar - Auth?) y le ponemos un nombre para identificarlo. Repetimos lo mismo para los demás dispositivos (teléfono móvil, iPads, PC, etc.).

Instalar ZeroTier en FreeBSD 13.1


# pkg install zerotier
# sysrc zerotier_enable=YES

Iniciar el servicio


# service zerotier start

Unirse a la red


# zerotier-cli join 565799d8f6259736

Comprobar estado


# zerotier-cli status
200 info 6a58..... 1.10.2 ONLINE

Salir de la red


# zerotier-cli leave 565799d8f6259736

Para configuración adicional consulte la página de zerotier


https://www.zerotier.com/manual.shtml

Crear las rutas

A continuación enrute entre las dos redes; física y red virtual zerotier para que las computadoras remotas puedan acceder a la red local utilizando la computadora de destino.

Rango de mi red local 192.168.88.0/24


192.168.88.0/24 a través de la ip asignada a la raspberrypi3 (VPN) por ZetoTier -> 192.168.192.119

Add Routes 
Destination		    Via
192.168.88.0/24		192.168.192.119

FIGURA zerotier-rutas-4.png 

 


Ahora se configura el reenvío de puertos en la raspberrypi3 y activar el reenvío de tráfico entre las dos interfaces de red, la interface eth0 y la interfaz de red de Zerotier. Para ello:

Habilitar el reenvio de paquetes entre dos interfaces (IP forwarding), la interfaz de red fisica y la interfaz de zerotier


echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf

$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Y finalmente estos comandos para permitir el paso de tráfico entre las dos interfaces

https://zerotier.atlassian.net/wiki/spaces/SD/pages/224395274/Route+between+ZeroTier+and+Physical+Networks

PHY_IFACE=eth0; ZT_IFACE=zt2lrsbp44

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o zt2lrsbp44 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i zt2lrsbp44 -o eth0 -j ACCEPT

sudo apt install iptables-persistent
# bash -c iptables-save > /etc/iptables/rules.v4

1.- Apague el wifi en tu teléfono
2.- Únase a la red zerotier, autorízalo
3.- Intente acceder a algo en la LAN física

Desde mi iPhone descargo las App Zerotier y Termius: Terminal & SSH client

Estoy conectado a Internet a través de la VPN que acabo de crear, también puedo entrar vía SSH a los dispositivos configurados para ese fin.










 

 

Reglas del Firewall PF FreeBSD


###################################################################
int_if = "em0"
lan_net = "192.168.88.0/24"

rfc1918 = "{ 127.0.0.0/8, 172.16.0.0/12, \
169.254.0.0/16, 192.0.2.0/24, \
0.0.0.0/8, 240.0.0.0/4, 224.0.0.0/3 }"

#tcp_pass="{ 22 53  80 123 111 443 832 1110 1651 2049 3000 8000 8080 20049 }"
#udp_pass="{ 53 111 832 1110 1651 2049 20049 }"
#tcp_pass="{ 22 53  80 123 111 443 1110 3000 8000 8080 }"
#udp_pass="{ 53 111 1110 9993}"

# scrub incoming packets
scrub in all

# setup a default deny policy
block in all
block out all

# pass traffic on the loopback interface in either direction
pass quick on lo0 all

# activate spoofing protection for the internal interface.
antispoof quick for $int_if inet

############
block drop in quick on $int_if from $rfc1918 to any
block drop out quick on $int_if from any to $rfc1918
############

# only allow ssh connections from the local network if it‘s from the
# trusted computer, 192.168.0.15. use "block return" so that a TCP RST is
# sent to close blocked connections right away. use "quick" so that this
# rule is not overridden by the "pass" rules below.
# block return in quick on $int_if proto tcp from ! 192.168.0.15 \
# to $int_if port ssh flags S/SA
block return in quick proto tcp from ! 192.168.192.0/24 port ssh flags S/SA

# pass all traffic to and from the local network
pass in on $int_if from $lan_net to any
pass out on $int_if from any to $lan_net

# pass out on se refiere al trafico de salida
#pass out quick on $int_if proto tcp to any port $tcp_pass keep state
#pass out quick on $int_if proto udp to any port $udp_pass keep state

# pass tcp, udp, and icmp out on the external (Internet) interface.
# keep state on udp and icmp and modulate state on tcp.
pass out on $int_if proto tcp all modulate state flags S/SA
pass out on $int_if proto { udp, icmp } all keep state

# allow ssh connections in on the external interface as long as they‘re
# NOT destined for the firewall (i.e., they‘re destined for a machine on
# the local network). log the initial packet so that we can later tell
# who is trying to connect. use the tcp syn proxy to proxy the connection.
#pass in log on $ext_if proto tcp from any to { !$ext_if, !$int_if } \
#port ssh flags S/SA synproxy state
pass in log proto tcp from any to { !$int_if } port ssh flags S/SA synproxy state
#################################################################################
FreeBSD es genial!.

martes, 21 de febrero de 2023

FreeBSD Instalar Wordpress

Instalar Wordpress en la jail

1.- Creación de la Jail www con Bastille

2.- Instalar Apache MySQL PHP

3.- Instalar Wordpress. Activar rdr en Firewall PF

Creación de la base de datos para Wordpress


bastille console www

root@www: #

Instalación de Wordpress

Inicicar sesión en mysql como usuario root


root@www: # mysql -h 127.0.0.1 -u root -p
Password:

root@127.0.0.1 [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'su_password';
Query OK, 0 rows affected (0.01 sec)

root@127.0.0.1 [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

Crear un usuario, una base de datos para Wordpress y una contraseña, otorgar los derechos en la base de datos al usuario creado.


CREATE DATABASE db_wp;
Query OK, 1 row affected (0.00 sec)

USE db_wp;

CREATE USER 'db_wp'@'localhost' IDENTIFIED BY '57rMvRbev&5o$eE*sV';

GRANT ALL PRIVILEGES ON db_wp.* TO 'db_wp'@'localhost' IDENTIFIED BY \
'57rMvRbev&5o$eE*sV';
Query OK, 0 rows affected (0.00 sec)

Recargar las cachés internas de MySQL con el comando FLUSH


FLUSH PRIVILEGES;

Salir de mysql


root@localhost [(none)]> exit
Bye
root@www: #

Descargar y descomprimir la última version de Wordpress


root@www: # fetch https://wordpress.org/latest.tar.gz

Descomprimir el archivo


tar -zxvf latest.tar.gz

Entrar en el directorio de wordpress y copiar wp-config-sample.php a wp-config.php


cd wordpress
cp wp-config-sample.php wp-config.php

Edite el archivo wp-config.php e introduzca DB_NAME, DB_USER y DB_PASSWORD


 vim wp-config.php

define( 'DB_NAME', 'db_wp' );^M
^M
/** Database username */^M
define( 'DB_USER', 'db_wp' );^M
^M
/** Database password */^M
define( 'DB_PASSWORD', '57rMvRbev&5o$eE*sV' );^M

Reiniciar mysql-server


root@www: # service mysql-server restart

Mover el contenido del directorio de Wordpress a la ubicación reservada a los sitios de FreeBSD, /usr/local/www/apache24/data


 cp -r ~/wordpress/* /usr/local/www/apache24/data

Cambiar el propiepario y grupo de los archivos a www


 chown -R www:www /usr/local/www/apache24/data

Llegados a este punto, vamos a crear el archivo rdr.conf para hacer las reglas de redirección de puertos persistentes. Las reglas que se encuentran en este archivo (una por línea) se cargarán para la jail cada vez que se inicie, y se borran automáticamente cuando se detenga la jail.


cd /usr/local/bastille/jails/www
fstab     jail.conf     root

vim .conf
 tcp 80 80
 tcp 443 443
ls /usr/local/bastille/jails/www/
fstab     jails.conf    rdr.conf    root
FIGURA rdr.conf

Cambios en el archivo pf.conf

rdr pass inet proto tcp from any to any port {80, 443} -> $www_ip.
Redirigir, dejar pasar todo el tráfico TCP de cualquier origen, que tenga como destino los puertos 80 y 443, a la IP de la jail, utilizando la macro $www_ip que define la dirección IP 10.10.10.2

Firewall PF


carlos@solaris:~ $ cat /etc/pf.conf
#
ext_if="em0"
www_ip="10.10.10.2"

set skip on lo
set block-policy return
scrub in on $ext_if all fragment reassemble

table <jails> persist
nat on $ext_if from <jails> to any -> ($ext_if:0)
rdr-anchor "rdr/*"
rdr pass inet proto tcp from any to any port {80, 443} -> $www_ip

block in all
pass out quick keep state
antispoof for $ext_if inet

pass in inet proto tcp from any to any port ssh flags S/SA keep state

Reiniciar la jail


 bastille restart www

Apuntar Firefox a la dirección IP o nombre de dominio para proceder a la instalación de Wordpress


http://10.10.10.2:80/wp/wp-admin/install.php

Sólo falta instalar Wordpress usando el asistente de instalación y un nombre de usuario y una contraseña para la administración del sitio web.


FreeBSD es genial!.