¿Bloquear el acceso a la red de un proceso?

74

¿Es posible bloquear el acceso a la red (saliente) de un solo proceso?

larkee
fuente
66
¿Cómo piensa identificar el proceso? PID, nombre, ruta?
Marco
1
¿Qué acceso quieres bloquear? Algunos programas utilizan el acceso a la red a través de localhost(a la misma máquina) para hacer su trabajo.
vonbrand
Consulte también LD_PRELOAD o similar para evitar el acceso a la red , si el proceso está cooperando.
Gilles 'SO- deja de ser malvado'

Respuestas:

78

Con Linux 2.6.24+ (considerado experimental hasta 2.6.29), puede usar espacios de nombres de red para eso. Debe tener habilitados los 'espacios de nombres de red' en su kernel ( CONFIG_NET_NS=y) y util-linux con la unshareherramienta.

Luego, iniciar un proceso sin acceso a la red es tan simple como:

unshare -n program ...

Esto crea un espacio de nombres de red vacío para el proceso. Es decir, se ejecuta sin interfaces de red, incluido sin loopback . En el ejemplo a continuación, agregamos -r para ejecutar el programa solo después de que el usuario efectivo actual y las ID de grupo se hayan asignado a los superusuarios (evite sudo):

$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable

Si su aplicación necesita una interfaz de red, puede configurar una nueva:

$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms

Tenga en cuenta que esto creará un nuevo loopback local . Es decir, el proceso generado no podrá acceder a los puertos abiertos del host 127.0.0.1.


Si necesita obtener acceso a la red original dentro del espacio de nombres, puede usarlo nsenterpara ingresar al otro espacio de nombres.

El siguiente ejemplo se ejecuta pingcon el espacio de nombres de red que utiliza el PID 1 (se especifica a través de -t 1):

$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms

--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms
Michał Górny
fuente
44
unshare -nparece lanzar "Operación no permitida" sin rootprivilegios, ¿me falta algo?
calvas
1
Tal vez una pregunta estúpida ... ¿este espacio de nombres también se aplica a procesos secundarios / llamados procesos de la aplicación no compartida?
bonanza
3
Si. Es heredado por todos los hijos generados después de cambiar el espacio de nombres.
Michał Górny
2
Me parece que cualquier programa que me gustaría dejar de compartir, por ejemplo, sudo unshare -nhereda la raíz correcta. Como necesito el sudo para llamar a unshare, me pregunto cómo puedo asegurarme de que el programa llamado no tenga los derechos de root.
bonanza
3
Un revestimiento para restringir el proceso a un usuario. Solo sudo dos veces: sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Jakub Bochenski
21

Linux tiene una característica llamada espacios de nombres de red que le permiten esencialmente tener múltiples pilas de red en la misma máquina, y asignar una a un programa cuando se ejecuta. Esta es una característica que generalmente se usa para contenedores, pero también puede usarla para lograr lo que desea.

Los ip netnssubcomandos lo gestionan. Crear un nuevo espacio de nombres de red sin acceso a nada es fácil, es el estado predeterminado de un nuevo espacio de nombres:

root@host:~# ip netns add jail

Ahora, si cambia a ese espacio de nombres, puede configurarlo con bastante facilidad. Probablemente quieras mencionarlo, y eso es todo:

root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit

Ahora, cuando desee ejecutar su comando sin red, simplemente ejecútelo en esa cárcel:

root@host:~# ip netns exec jail su user -c 'ping  8.8.8.8'
connect: Network is unreachable

La red es, como se desea, inalcanzable. (Puede hacer todo tipo de cosas interesantes ya que una pila de red separada incluye iptablesreglas, etc.)

derobert
fuente
Aunque necesitaba sudo ipejecutar los comandos de ip, una vez que estaba en bash, simplemente ejecuté su someuserpara obtener un shell sin privilegios para el usuario 'someuser'.
sabio
11

Puede usar iptables y mover ese proceso a un cgroup:

mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid

iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP

echo [pid] > /sys/fs/cgroup/net_cls/block/tasks
Jan Mueller
fuente
1
cómo quitar el pid de que las tareas presentar su da un error cuando estoy tratando de eliminar o borrar los datos de ese archivo aunque im con usuario root
PKM
@pkm para habilitar la conexión de red, solo necesita hacer eco [pid] a /sys/fs/cgroup/net_cls/tasks(sin 'bloqueo' en la ruta)
Duelo
10

Sí, con un perfil de apparmor personalizado, es decir

/usr/bin/curl {
    ...

    # block ipv4 acces
    deny network inet,
    # ipv6 
    deny network inet6,
    # raw socket
    deny network raw,

}

Pero de esa manera, también necesitará generar una lista de archivos permitidos para acceder, todo el procedimiento puede ser un poco complicado. Y mira el documento de ayuda aquí

margarita
fuente
7

Puede usar el entorno limitado de firejail (debería funcionar en núcleos con la función seccomp).

Para usarlo solo haz

firejail --noprofile --net=none <path to executable>

--noprofiledeshabilita el sandbox predeterminado --net=nonedeshabilita las redes

Creo que la mayoría de las distribuciones ya proporcionan el paquete, pero incluso si no tienen una jaula de fuego, prácticamente no tiene dependencias aparte de la construcción de la cadena de herramientas y el núcleo habilitado para el espacio de nombres / seccomp.

Hay algunas otras características interesantes de firejail que se pueden mostrar con firejail --helprespecto a las redes (como proporcionar solo una interfaz de bucle invertido o bloquear ip / dns, etc.) pero esto debería hacer el trabajo. Además, eso doesn't require root.

Pruzinat
fuente
5

No puede hacerlo solo con iptables. Esta característica existió brevemente , pero no pudo hacerse funcionar de manera confiable y fue abandonada.

Si puede ejecutar el proceso como una ID de usuario dedicada, iptables puede hacerlo con el ownermódulo:

iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP

Vea ejemplos en Iptables: correspondencia del tráfico saliente con conntrack y propietario. Funciona con gotas extrañas , regla iptables / pf para permitir solo la aplicación / usuario XY?

Si puede ejecutar el proceso en su propio contenedor, puede cortafuegos de ese contenedor de forma independiente (incluso hacerlo completamente desconectado de la red).

Un módulo de seguridad puede filtrar el acceso de un proceso a las funciones de red. La respuesta de warl0ck da un ejemplo con AppArmor.

Gilles 'SO- deja de ser malvado'
fuente
3

Solución 1: Cortafuegos:

Podríamos usar firewalls como Douane u Opensnitch PERO esas aplicaciones no son 100% eficientes o están en una etapa temprana de desarrollo (tienen muchos errores, etc. a partir de 2019)

Solución 2: Kernel MAC:

Los MAC del kernel se pueden usar como firewall más conocidos como Tomoyo , Selinux y Apparmor. Esta solución es la mejor cuando se trata de estabilidad y eficiencia (solución de firewall), pero la mayoría de las veces configurar esto es de alguna manera complicado.

Solución 3: Firejail:

Firejail se puede usar para bloquear el acceso a la red para una aplicación, esto no requiere root, ningún usuario puede beneficiarse de ella

firejail --noprofile --net=none command-application

Solución 4: dejar de compartir

Unshare puede iniciar una aplicación en un nombre diferente sin red, pero esto requiere que la solución root firejail haga casi exactamente lo mismo, pero no requiere root

unshare -r -n application-comand

Solución 5: Proxify:

Una solución es proxificar la aplicación a un proxy nulo / falso . Podemos usar tsocks o proxybound . Aquí hay algunos detalles sobre la configuración

Solución 6: Iptables:

Otra solución fácil es iptables, podría configurarse para bloquear una aplicación.

  1. Crear, validar nuevo grupo ; agregue usuarios requeridos a este grupo:
    • Crear: groupadd no-internet
    • Validar: grep no-internet /etc/group
    • Agregar usuario: useradd -g no-internet username

      Nota: Si está modificando un usuario ya existente, debe ejecutarlo: usermod -a -G no-internet userName consulte con:sudo groups userName

  2. Cree un script en su ruta y hágalo ejecutable:
    • Crear: nano /home/username/.local/bin/no-internet
    • Ejecutable: chmod 755 /home/username/.local/bin/no-internet
    • Contenido: #!/bin/bash
                    sg no-internet "$@"

  3. Agregue la regla de iptables para eliminar la actividad de red para el grupo sin internet :


   4. Verifíquelo, por ejemplo en Firefox ejecutando:

  • no-internet "firefox"

   5. En caso de que desee hacer una excepción y permitir que un programa acceda a la red local :

  • iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
  • iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
  • iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP

   6. Hazlo permanente

   Una forma de aplicar la regla de iptables en el arranque es agregar la regla como un servicio con systemd

cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service

[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh
intika
fuente
1
Esta es una guía realmente excelente. Gracias. Aunque, para mí, mi comando sin internet nunca pareció pasar el parámetro, así que lo estoy usando sg no-internetpor ahora.
Zach Bloomquist
@Zach actualicé mi respuesta, puede que te interese firejail;)
intika
2

Depende de la distribución que esté utilizando, pero esa es una característica generalmente incluida en el sistema MAC del sistema operativo. Como se indicó anteriormente, Ubuntu o AppArmor de SuSE pueden hacer esto. Si está utilizando RHEL, puede configurar SELinux para permitir o denegar el acceso a un número de puerto en particular según la etiqueta del proceso de ejecución. Esto es todo lo que pude encontrar después de buscar rápidamente en Google, pero probablemente haya recursos más detallados en línea si buscas más y te da una idea general.

Bratchley
fuente
2

Puede usar seccomp-bpf para bloquear algunas llamadas al sistema. Por ejemplo, puede querer bloquear lasocket llamada al sistema para evitar que el proceso cree sockets FD.

Escribí un ejemplo de este enfoque que impide que la socketllamada del sistema funcione con libseccomp. El resumen es (sin verificación de errores):

scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);

Esto no necesita privilegios de root.

Sin embargo, un sandbox completo es mucho más complejo, por lo que no debe usarlo para bloquear programas no cooperativos / maliciosos.

ysdx
fuente
¿Podría dar un ejemplo de cómo usar esto? ¿Requiere privilegios de root para funcionar?
bonanza
-4

Puede usar un programa de línea de comando llamado "proxychains" y probar una de las siguientes posibilidades:

Configurar que usa ...

  • ... un proxy que no existe? (No sé si lo ejecutará con un proxy "no válido")
  • ... un proxy local (como "tinyproxy", "squid", "privoxy", ...) que limita el acceso a internet? (Solo use ACL)

No lo he probado yo mismo, así que no sé si funciona ...

drkhsh
fuente
Publicar soluciones no probadas generalmente no es una buena idea.
Twirrim
Sin embargo, las cadenas proxy con un proxy no existente (como localhost: 1234 o similar) en realidad podrían ser un enfoque sólido
phil294