Entradas Mensuales

Síguenos en:

Canal Oficial Telegram de elhacker.NET Grupo Facebook elhacker.NET Twitter elhacker.NET Canal Youtube elhacker.NET Comunidad Steam: Grupo elhacker.NET Mastodon

Entradas populares

PostHeaderIcon Optimizar rendimiento de OPNsense: Tunables


 ¿A quién no le gusta un Internet más rápido y con mejor rendimiento? ¿Especialmente cuando estamos utilizando hardware de alto rendimiento? Vamos a ir en un viaje de ajuste de nuestro Firewall OpnSense para mejor su rendimiento.



Ejemplo de velocidad 4,2Gbps de bajada y 5,5Gbps de subida:



OPNsense Tunables (sysctl)

Tunning

  • OPNsense con una conexión FTTP de 1 Gbps y PPPoE

en OPNsense puedes ir a System -> Settings -> Tunables que en última instancia actualizará /boot/loader.conf por ti)


Activar y configurar Receive Side Scaling:

# un valor de -1 significa crear 1 por cpu core
net.isr.maxthreads = -1
net.isr.bindthreads = 1

# Permitir a los drivers NIC usar las colas ISR
net.isr.dispatch = deferred

# Habilitar RSS
net.inet.rss.enabled = 1

# porque tengo 4 núcleos
net.inet.rss.bits = 2

Entre ellas, estas opciones aseguran que hay múltiples hilos (1 por núcleo de CPU) para recibir paquetes y, al decirle a los controladores que usen las colas ISR, distribuyen la carga de procesamiento entre los núcleos. Para aquellos interesados, los documentos de OPNsense sobre este tema son bastante informativos.


Para ayudar a liberar algunos ciclos, también desactivar la mitigación de Spectre:


hw.ibrs_disable = 1 

La mitigación probablemente no estaba añadiendo mucho valor de todos modos: Estoy ejecutando en hardware dedicado, por lo que un atacante tendría que ser capaz de ejecutar algo en el firewall con el fin de aprovechar el canal lateral - en ese punto probablemente tengo mayores preocupaciones de todos modos.

También he aumentado la longitud de la cola de entrada IP:

#net.inet.ip.intr_queue_maxlen=2048 # (default 256)

net.inet.ip.intr_queue_maxlen = 3000

En realidad no estaba viendo problemas con la profundidad de la cola (se puede comprobar con sysctl net.inet.ip.intr_queue_drops), pero los diversos documentos que estaba leyendo sugieren que probablemente se convertiría en un problema si me las arreglé para conseguir la velocidad.


También ajustar algunos sintonizables para el controlador igc (utilizado para las NIC i225 e i226):


hw.igc.max_interrupt_rate = 20000
hw.igc.rx_process_limit = 5000

El primero aumenta la tasa de interrupciones, mientras que el segundo aumenta el número de paquetes que se pueden procesar. La mejora derivada de este cambio asciende a unas decenas de megabits.

Comprobar config:

comando:

sysctl -a | grep rss

Resultado:

net.inet.rss.bucket_mapping: 0:0 1:1 2:2 3:3
net.inet.rss.enabled: 1
net.inet.rss.debug: 0
net.inet.rss.basecpu: 0
net.inet.rss.buckets: 4
net.inet.rss.maxcpus: 64
net.inet.rss.ncpus: 4
net.inet.rss.maxbits: 7
net.inet.rss.mask: 3
net.inet.rss.bits: 2
net.inet.rss.hashalgo: 2
hw.bxe.udp_rss: 0
hw.ix.enable_rss: 1

 IP Socket buffer


# speed: 1 Gbit maxsockbuf: 2MB wscale: 6 in-flight: 2^6*65KB = 4MB (default)
# speed: 2 Gbit maxsockbuf: 4MB wscale: 7 in-flight: 2^7*65KB = 8MB
# speed: 10 Gbit maxsockbuf: 16MB wscale: 9 in-flight: 2^9*65KB = 32MB
# speed: 40 Gbit maxsockbuf: 150MB wscale: 12 in-flight: 2^12*65KB = 260MB
# speed: 100 Gbit maxsockbuf: 600MB wscale: 14 in-flight: 2^14*65KB = 1064MB


#kern.ipc.maxsockbuf=2097152 # (wscale 6 ; default)
#kern.ipc.maxsockbuf=4194304 # (wscale 7)
kern.ipc.maxsockbuf=16777216 # (wscale 9)
#kern.ipc.maxsockbuf=157286400 # (wscale 12)
#kern.ipc.maxsockbuf=614400000 # (wscale 14)

 TCP Buffers

Según Guía de Ajuste de Rendimiento de Red de FreeBSD, este era su valor recomendado para si tiene adaptadores de red de 10Gbps. El valor por defecto que venía con mi instalación de OPNsense correspondía con el valor de la guía para redes de 2Gbps. Decidí que ya que podría querer expandirme en el futuro, incrementaría esto a este absurdo nivel para no tener que lidiar con esto de nuevo. Es posible que desee establecer un valor más racional, 16777216 debe trabajar para 10Gbps. La guía enlazada arriba explica lo que hace este valor y otros valores que afecta en gran detalle.

net.inet.tcp.recvbuf_max=4194304
net.inet.tcp.recvspace=65536
net.inet.tcp.sendbuf_inc=65536
net.inet.tcp.sendbuf_max=4194304
net.inet.tcp.sendspace=65536

O bien:

    net.inet.tcp.recvbuf_inc=65536    # (default 16384)
    net.inet.tcp.recvbuf_max=4194304  # (default 2097152)
    net.inet.tcp.recvspace=65536      # (default 65536)
    net.inet.tcp.sendbuf_inc=65536    # (default 8192)
    net.inet.tcp.sendbuf_max=4194304  # (default 2097152)
    net.inet.tcp.sendspace=65536      # (default 32768) 

stream (TCP) sockets


También de la guía de ajustes, esto permite una interfaz de socket del kernel optimizada que puede reducir significativamente el impacto en la CPU de los flujos TCP rápidos.

net.inet.tcp.soreceive_stream = 1 # (default 0)

Tomé esto de la guía de ajuste también, es probable que no ayudó con mi problema de hoy, pero puede evitar problemas en el futuro. Esto aumenta el tamaño de la tabla hash del cortafuegos PF para permitir más conexiones en la tabla antes de que se deteriore el rendimiento. 

  •  PF: Increase the size of the pf(4) source nodes hashtable from 32k to 1M.

net.pf.source_nodes_hashsize = 1048576 # (default 32768)

Tomé estos valores de la guía de ajuste que están destinados a mejorar la eficiencia durante el procesamiento de fragmentos de IP. Hay valores ligeramente más agresivos que se pueden establecer aquí también, pero parece que estos son los valores más seguros, así que me fui con ellos.

net.inet.tcp.mssdflt=1240 # Option 1 (default 536)
#net.inet.tcp.mssdflt=1240 # Option 2 (default 536)

 Y

     net.inet.tcp.abc_l_var=44   # (default 2) if net.inet.tcp.mssdflt = 1460
    #net.inet.tcp.abc_l_var=52  # (default 2) if net.inet.tcp.mssdflt = 1240

Otro valor de la guía de ajuste en el que no me fijé demasiado, pero que configura el tamaño mínimo del segmento, o la carga útil más pequeña de datos que un único segmento TCP IPv4 aceptará transmitir, con el objetivo de mejorar la eficiencia.

net.inet.tcp.minmss = 536

Esto no está relacionado con la red en absoluto, pero era un valor recomendado por la guía de ajuste para mejorar la piscina entropía RNG. Dado que estoy haciendo cosas VPN en este sistema, me imagino que más RNG es mejor.

kern.random.fortuna.minpoolsize=128 # (default 64)


Este valor se originó en mi hilo de Reddit enlazado anteriormente, se añadió rápidamente durante el último lote de sintonizables que finalmente me llevó al límite en términos de rendimiento, y decidí que lo dejaría incluso si no estaba haciendo nada significativo. El aumento de los valores de cola parece haber sido un tema de la puesta a punto en general. 

# qlimit for igmp, arp, ether and ip6 queues only (netstat -Q) (default 256)

net.isr.defaultqlimit=2048

Otros parámetros:

# Enables a faster but possibly buggy implementation of soreceive

net.inet.tcp.soreceive_stream="1"  # (default 0)

  • NOTE: disable net.inet.tcp.soreceive_stream when using
  •     # rndc to update BIND DNS records otherwise the following error will trigger,
  •     # "rndc: recv failed: host unreachable". 


# increase the network interface queue link - the default (50) is way

# too low. txd should be half that

. If    # hw.igb.txd="1024" then set the net.link.ifqmaxlen="2048". 

hw.igb.txd="1024"

net.link.ifqmaxlen="2048" # (default 50)


  • enable /dev/crypto for IPSEC of custom seeding using the AES-NI Intel 

 

# enable hardware accelerated AES (can speed up TLS)

aesni_load="YES"

 HardenedBSD and DoS mitigation

 hw.kbd.keymap_restrict_change=4    # disallow keymap changes for non-privileged users (default 0)
    kern.ipc.shm_use_phys=1            # lock shared memory into RAM and prevent it from being paged out to swap (default 0, disabled)
    kern.msgbuf_show_timestamp=1       # display timestamp in msgbuf (default 0)
    kern.randompid=1                   # calculate PIDs by the modulus of an integer, set to one(1) to auto random (default 0)
    net.bpf.optimize_writers=1         # bpf is write-only unless program explicitly specifies the read filter (default 0)
    net.inet.icmp.drop_redirect=1      # no redirected ICMP packets (default 0)
    net.inet.ip.check_interface=1      # verify packet arrives on correct interface (default 0)
    net.inet.ip.portrange.first=32768  # use ports 32768 to portrange.last for outgoing connections (default 10000)
    net.inet.ip.portrange.randomcps=9999 # use random port allocation if less than this many ports per second are allocated (default 10)
    net.inet.ip.portrange.randomtime=1 # seconds to use sequental port allocation before switching back to random (default 45 secs)
    net.inet.ip.random_id=1            # assign a random IP id to each packet leaving the system (default 0)
    net.inet.ip.redirect=0             # do not send IP redirects (default 1)
    net.inet6.ip6.redirect=0           # do not send IPv6 redirects (default 1)
    net.inet.sctp.blackhole=2          # drop stcp packets destined for closed ports (default 0)
    net.inet.tcp.blackhole=2           # drop tcp packets destined for closed ports (default 0)
    net.inet.tcp.drop_synfin=1         # SYN/FIN packets get dropped on initial connection (default 0)
    net.inet.tcp.fast_finwait2_recycle=1 # recycle FIN/WAIT states quickly, helps against DoS, but may cause false RST (default 0)
    net.inet.tcp.fastopen.client_enable=0 # disable TCP Fast Open client side, enforce three way TCP handshake (default 1, enabled)
    net.inet.tcp.fastopen.server_enable=0 # disable TCP Fast Open server side, enforce three way TCP handshake (default 0)
    net.inet.tcp.finwait2_timeout=1000 # TCP FIN_WAIT_2 timeout waiting for client FIN packet before state close (default 60000, 60 sec)
    net.inet.tcp.icmp_may_rst=0        # icmp may not send RST to avoid spoofed icmp/udp floods (default 1)
    net.inet.tcp.keepcnt=2             # amount of tcp keep alive probe failures before socket is forced closed (default 8)
    net.inet.tcp.keepidle=62000        # time before starting tcp keep alive probes on an idle, TCP connection (default 7200000, 7200 secs)
    net.inet.tcp.keepinit=5000         # tcp keep alive client reply timeout (default 75000, 75 secs)
    net.inet.tcp.msl=2500              # Maximum Segment Lifetime, time the connection spends in TIME_WAIT state (default 30000, 2*MSL = 60 sec)
    net.inet.tcp.path_mtu_discovery=0  # disable for mtu=1500 as most paths drop ICMP type 3 packets, but keep enabled for mtu=9000 (default 1)
    net.inet.udp.blackhole=1           # drop udp packets destined for closed sockets (default 0)
    net.inet.udp.recvspace=1048576     # UDP receive space, HTTP/3 webserver, "netstat -sn -p udp" and increase if full socket buffers (default 42080)
    security.bsd.hardlink_check_gid=1  # unprivileged processes may not create hard links to files owned by other groups, DISABLE for mailman (default 0)
    security.bsd.hardlink_check_uid=1  # unprivileged processes may not create hard links to files owned by other users,  DISABLE for mailman (default 0)
    security.bsd.see_other_gids=0      # groups only see their own processes. root can see all (default 1)
    security.bsd.see_other_uids=0      # users only see their own processes. root can see all (default 1)
    security.bsd.stack_guard_page=1    # insert a stack guard page ahead of growable segments, stack smashing protection (SSP) (default 0)
    security.bsd.unprivileged_proc_debug=0 # unprivileged processes may not use process debugging (default 1)
    security.bsd.unprivileged_read_msgbuf=0 # unprivileged processes may not read the kernel message buffer (default 1)


Flow Control

hw.ix.flow_control=0
#Interface igc0 Flow Control (Increases CPU usage?)                
dev.igc.0.fc =0 # default 3
dev.igc.1.fc =0
dev.igc.2.fc =0
dev.igc30.fc =0
For ix and others, the flow control value can be further tuned:

    0:

        No Flow Control
    1:

        Receive Pause
    2:

        Transmit Pause
    3:

        Full Flow Control, Default

Energy Efficient Ethernet (EEE)

#Disable or enable Energy Efficient Ethernet Default 1 (disabled)                
hw.em.eee_setting=1

(System) Tunables:

dev.igb.0.eee_disabled=1
dev.igb.1.eee_disabled=1
dev.igb.2.eee_disabled=1
dev.igb.3.eee_disabled=1

This disabled Energy Efficient Ethernet (EEE) for the 4 ports.

Enable TCP Offload Engine

Las NIC de Intel pueden utilizar la «descarga de segmentación TCP por hardware». Para activar esta opción, vaya a System -> Settings -> Tunables y busque «TCP Offload Engine».

Configurando net.inet.tcp.tso a 1 habilitará la descarga de segmentación por hardware (TSO, TSO4, TSO6). TSO hace que la NIC se encargue de dividir los paquetes en trozos de tamaño MTU en lugar de hacerlo el sistema operativo. 

En nuestras pruebas, esta configuración aumentó el rendimiento. Dependiendo de la configuración de su cortafuegos, puede que quiera experimentar si este ajuste funciona igual de bien para su carga.

Enable Hardware Checksum Offloading


Al igual que en el caso anterior, las NIC de Intel pueden calcular las sumas de comprobación de los paquetes en el hardware en lugar de hacerlo en el sistema operativo. Esto descarga la CPU y aumenta el ancho de banda. 

Para activar esta opción, vaya a System -> Settings -> Tunables y busque «UDP Checksums».

El valor de net.inet.udp.checksum debe ser 1. La descarga de sumas de comprobación suele ser beneficiosa, ya que permite que la suma de comprobación se calcule (saliente) o verifique (entrante) en hardware a un ritmo mucho más rápido de lo que podría hacerse en software. 



Mbuf Exhaustion


Un problema común al que se enfrentan los usuarios de hardware básico es el agotamiento del mbuf. Para simplificar, los «mbufs» son búferes de memoria de red; porciones de RAM reservadas para ser utilizadas por la red para mover datos.

El recuento de mbufs activos se muestra en el panel de control y se controla mediante un gráfico en Estado > Monitorización.

Ver también: Para obtener más información sobre los mbufs y la supervisión de su uso, consulte Clústeres de mbufs.

Si el cortafuegos se queda sin mbufs, puede producirse un pánico en el núcleo y un reinicio bajo ciertas cargas de red que agoten todos los búferes de memoria de red disponibles. En ciertos casos, esta condición también puede provocar que las interfaces esperadas no sean inicializadas y puestas a disposición por el sistema operativo. Esto es más común con NICs que utilizan múltiples colas o que están optimizados para el rendimiento sobre el uso de recursos.

Además, el uso de mbufs aumenta cuando el cortafuegos utiliza determinadas funciones, como los limitadores.

Para aumentar la cantidad de mbufs disponibles, añada lo siguiente como un Loader Tunable:


kern.ipc.nmbclusters=1000000


En sistemas de 64 bits con varios GB de RAM, 1 millón (1000000) de clusters mbuf es un punto de partida seguro. En caso de que los clusters mbuf se asignen por completo, esto consumiría alrededor de 2,3 GB de memoria física:


1000000 memory buffer clusters available × (2048 KB per cluster + 256 bytes per

memory buffer)


La cantidad de clusters disponibles puede reducirse para sistemas con poca cantidad de RAM física, o incrementarse aún más según sea necesario, siempre y cuando el valor no exceda la memoria disponible.


Fuentes:

https://medium.com/@truvis.thornton/opnsense-firewall-configuration-performance-tuning-for-multi-gigabit-internet-and-better-speeds-in-cfc80c49c544

https://binaryimpulse.com/2022/11/opnsense-performance-tuning-for-multi-gigabit-internet/

https://www.bentasker.co.uk/posts/blog/general/opnsense-pfsense-fttp-and-1gbps-pppoe.html

https://teklager.se/en/knowledge-base/opnsense-performance-optimization/


0 comentarios :

Publicar un comentario

Los comentarios pueden ser revisados en cualquier momento por los moderadores.

Serán publicados aquellos que cumplan las siguientes condiciones:
- Comentario acorde al contenido del post.
- Prohibido mensajes de tipo SPAM.
- Evite incluir links innecesarios en su comentario.
- Contenidos ofensivos, amenazas e insultos no serán permitidos.

Debe saber que los comentarios de los lectores no reflejan necesariamente la opinión del STAFF.