¿Es posible bloquear el acceso a la red (saliente) de un solo proceso?
localhost
(a la misma máquina) para hacer su trabajo.
¿Es posible bloquear el acceso a la red (saliente) de un solo proceso?
localhost
(a la misma máquina) para hacer su trabajo.
Respuestas:
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 unshare
herramienta.
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 nsenter
para ingresar al otro espacio de nombres.
El siguiente ejemplo se ejecuta ping
con 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
unshare -n
parece lanzar "Operación no permitida" sin root
privilegios, ¿me falta algo?
sudo unshare -n
hereda 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.
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
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 netns
subcomandos 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 iptables
reglas, etc.)
sudo ip
ejecutar los comandos de ip, una vez que estaba en bash, simplemente ejecuté su someuser
para obtener un shell sin privilegios para el usuario 'someuser'.
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
/sys/fs/cgroup/net_cls/tasks
(sin 'bloqueo' en la ruta)
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í
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>
--noprofile
deshabilita el sandbox predeterminado
--net=none
deshabilita 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 --help
respecto 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
.
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 owner
mó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.
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.
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
consulte con:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
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
sg no-internet
por ahora.
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.
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 socket
llamada 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.
Puede usar un programa de línea de comando llamado "proxychains" y probar una de las siguientes posibilidades:
Configurar que usa ...
No lo he probado yo mismo, así que no sé si funciona ...