The Virtual Ethernet Bridge: docker0


docker Docker [Installation: click here] creates the virtual interface “docker0” which is virtual Ethernet bridge. This virtual bridge forwards the packets between the containers each other and between the host and the container.

You see this when you execute: “ip addr list docker0 or “ifconfig docker0.

output of “ifconfig docker0“:

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
inet  netmask  broadcast
ether 02:42:63:8f:85:df  txqueuelen 0  (Ethernet)
RX packets 0  bytes 0 (0.0 B)
RX errors 0  dropped 0  overruns 0  frame 0
TX packets 0  bytes 0 (0.0 B)
TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The IP address of this interface is a randomly chosen private IP that is not used by the host.  Here it is with the net mask of 16 bits ( and the MAC address 02:42:63:8f:85:df.

To display the virtual networks created by Docker, execute:

# docker network ls


NETWORK ID          NAME                DRIVER
dfc34cd75029        bridge              bridge 
3453b5653383        none                null
e9a375f4a8a2        host                host

The figure below describes how the virtual interfaces are connected to the bridge docker0.  All veth* interfaces are attached/linked to this bridge. Each veth* interface has a peer (virtual interface) in a specific container.


Some Notes:

  • The eth0 in the container and the veth* in the host are pairs and connected like a pipe. So the packets enter from one of them will reach the other and vice versa.
  • The eth0 has a private IP address from the same range of the bridge docker0’s IP address which is considered as a gateway. The MAC address is generated from the IP address.
  • The MAC address of the veth* interface is set.
  • The bridge docker0 connects veth* interfaces while sharing a single IP address.

To inspect the bridge network, execute:

# docker network inspect bridge


“Name”: “bridge”,
“Id”: “dfc34cd75029786a53356e554b34a14c290ef4969e38ecb1e4ae9c34598e93d7”,
“Scope”: “local”,
“Driver”: “bridge”,
“IPAM”: {
“Driver”: “default”,
“Config”: [
“Subnet”: “”
“Containers”: {},
“Options”: {
“”: “true”,
“”: “true”,
“”: “true”,
“”: “”,
“”: “docker0”,
“”: “1500”

Because there is no container created yet, we have the array “Containers” empty (“Containers”: {}). The bridge network can be created manually.

To run a container in a specific network, executes:

# docker run –net=<NETWORK> …..The rest ………..

Note: Instead of using a bridge, we can use iptables NAT configuration.

More Information


Docker Installation


Follow these steps to install Docker. I have Fedora 23:

  • Add Docker  repo. I will use the baseurl for Fedora 22 because Fedora 23 is new and no Docker repo for it:

cat >/etc/yum.repos.d/docker.repo <<-EOF


name=Docker Repository






  • Use dnf to install Docker (yum is deprecated): # sudo dnf -y -q install docker-engine
  • Start the daemon: # sudo systemctl start docker-engine
  • Enable the daemon so it will start on boot: # sudo systemctl enable docker
  • By default, docker listens on a UNIX socket (more secure): “unix:///var/run/docker.sock”. This allows only local connections. To list the permissions of the docker socket file:

ls -l  /var/run/docker.sock
srw-rw—-. 1 root docker 0 Nov 19 09:36 /var/run/docker.sock

As we see this file is readable and writable by the user (root) and the group (docker). So to send command to docker daemon from the docker client, we need to be either root user (directly or as sudo user) or add your user to the group “docker” (NOT secure). To add a user to the group “docker”, execute: # sudo usermod -aG docker your_username

To allow remote connections from docker clients (NOT Secure), we can use the option “-H”. Open the unit file of the docker service “/usr/lib/systemd/system/docker.service” and update the line “ExecStart=/usr/bin/docker daemon -H fd://” using “-H host:port”. If you update the unit file you need to restart the docker.

  • Log out and in or even reboot the system.
  • Verify the installation: # docker run hello-world


Hello from Docker.
This message shows that your installation appears to be working correctly.


First Steps In Securing Your Linux Server


Some notes here to keep it in mind when you manage your Linux server security:

  • Keep your system clean: Install ONLY the packages you need.
  • Check the enabled services and disable the services that you don’t need. The disabled services will NOT run automatically when system boot. To display the enabled services, execute this:

# systemctl list-unit-files –type=service | grep enabled

The unit files of the enabled services exist in “/usr/lib/systemd/system/”. To stop a running service, execute: # systemd stop $serviceName. To disable a service: # systemd disable $serviceName

  • Change the port of the sshd:
    • Edit the configuration file of the SSH daemon: # vim /etc/ssh/sshd_config
    • For Example, change the port to 1866:  “Port 1866” in the configuration file.
    •  If SELinux is enabled,  you have to tell SELinux about this change:
      # semanage port -a -t ssh_port_t -p tcp
    • Restart sshd : # systemctl restart sshd
    • By doing that, you need to use the option -p1866 when you login.
  • Disable sshing as root:
    • Disable Root Login:
      • Edit the configuration file of the SSH daemon: # vim /etc/ssh/sshd_config
      • Uncomment and change yes to no in the line “PermitRootLogin no”
      • Restart the SSH daemon: # systemctl restart sshd
    • Create an admin user so you can ssh into the server as an administrator:  As a root, do these: Create a new user and its password  using useradd and passwd. Then to make the new user (lets say it is binan) an administrator, execute visudo and do one of these:
      • Search for the line “%wheel  ALL=(ALL)       ALL” and uncomment it (delete the # at the begining of the line). This allows people in group wheel to run all commands. Add the user binan to the group wheel so the user binan can execute all commands using sudo: # usermod -aG wheel binan.
      • OR Instead of adding the user binan to the group wheel, you can add “binan ALL=(ALL) ALL”.  

Everything sudo users do will be logged so “who did what” is determined (that’s why we disable logging as root).

  • Generate SSH key pair on your machine:  # ssh-keygen  -t rsa. The generated private and the public keys will be stored in the .ssh directory in the home directory (e.g. private key: ~/.ssh/id_rsa and public key: ~/.ssh/
  • You must have the public key installed on the server (appended in ~/.ssh/authorized_keys). To copy the public key to the server, you can temporarily enable the sshing using passwords (“PasswordAuthentication yes” in the /etc/ssh/sshd_config and restart the sshd daemon).  Now copy the public key to the server as following: # cat ~/.ssh/ | ssh -p 1866 binan@Hostname/IP-Address “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys
  • Disable sshing using passwords: “PasswordAuthentication no” in the /etc/ssh/sshd_config. Restart the daemon. Now the login will be using public key authentication.
  • Check that you can login from another terminal using : Assuming you have the key pair (the public and private keys) on your local machine:

# ssh -p 1866 binan@Hostname/IP-Address
Last login: Wed Nov  4 09:40:00 2015

Cloning a GitHub Repository


To clone a GitHub hosted repository to local computer:

# git clone $RepoURL.

To get the RepoURL you need to go to the repository page on GitHub and copy the URL (HTTPS:…/$ProjectName.git, SSH:…/$ProjectName.git). In this way you will get the repository copied to a sub-directory of the current working directory. The sub-directory has the same name of the repository.

You don’t need to initialize git in the folder because it is already initialized (.git folder contains the git information).

The remote is a reference to repo. To list the references, execute: # git remote -v. You will see the automatically created references (origin). To add a reference to the origin: # git remote add origin $RepoURL