LazyCoder
LazyCoder

Reputation: 357

How to disable and enable internet connection from within Docker container?

I am clearing /etc/resolv.conf to disable network :

sudo mv /etc/resolv.conf /etc/resolv_backup.conf
sudo touch /etc/resolv.conf

Then to enable network:

sudo mv /etc/resolv_backup.conf /etc/resolv.conf

However the resource is busy and I cannot execute these commands.

I want to disable internet from within container and not using:

docker network disconnect [OPTIONS] NETWORK CONTAINER

which does this from server on which container is deployed. I am using Alpine.

Upvotes: 2

Views: 5044

Answers (3)

gluttony
gluttony

Reputation: 569

Inspired by @BMitch answer, but since I do not have route command, and even if I install it from net-tools-deprecated package it gives me an error, I then did a DisconnectReconnectNetwork.sh script that does this:

#!/bin/bash

# Get default via before disconnecting
DEFAULT_VIA=$(ip r | grep "default via")
# Disconnect
ip link set eth0 down
# Reconnect
ip link set eth0 up
# Set default via back
ip route add ${DEFAULT_VIA}

Note as mentioned in @BMitch answer, you must use --cap-add NET_ADMIN in docker run command, or if in a docker compose, add to your service:

cap_add:
  - NET_ADMIN

Upvotes: 0

BMitch
BMitch

Reputation: 263597

From inside of a container, you are typically forbidden from changing the state of the network:

$ docker run -it --rm alpine:latest /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
929: eth0@if930: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip link set eth0 down
ip: ioctl 0x8914 failed: Operation not permitted

This is intentional, for security, to prevent applications from escaping the container sandbox. If you do not need security for your containers (and therefore something I recommend against doing), you can run your container with additional network capabilities:

$ docker run -it --rm --cap-add NET_ADMIN alpine:latest /bin/sh
/ # netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         172.17.0.1      0.0.0.0         UG        0 0          0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
933: eth0@if934: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip link set eth0 down
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Network unreachable

When you try to bring the network back up, you'll need to also setup the default route again to be able to connect to external networks:

/ # ip link set eth0 up
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Network unreachable
/ # netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 eth0
/ # route add default gw 172.17.0.1
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=58 time=12.518 ms
64 bytes from 8.8.8.8: seq=1 ttl=58 time=11.481 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 11.481/11.999/12.518 ms

Upvotes: 4

aicastell
aicastell

Reputation: 2392

First of all, clearing resolv.conf is not the proper way to disable network for your container. That just avoids name resolution, but you still can use IP connectivity.

To disable the network you should use the proper script depending if you are using systemd or sysV. Something similar to this should work (it depends on your distro):

# /etc/init.d/networking stop
# systemctl stop networking

Hope this helps! :-)

Upvotes: 0

Related Questions