1. Overview

IP addresses are unique identifiers assigned to devices connected to a network, allowing them to communicate with one another. However, some IP addresses have special meanings, such as IP addresses 127.0.0.1 and 0.0.0.0.

In this tutorial, we’ll learn the difference between the IP address 127.0.0.1 and 0.0.0.0.

2. IP Address 127.0.0.1 and 0.0.0.0

The IP address 127.0.0.1 and 0.0.0.0 are similar in terms of their status as a reserved IP address. They do not uniquely identify a device on a network as other IP addresses do. Instead, section 3.2.13 of RFC 1122 defines both of these IP addresses as special-purpose IP addresses with different intentions. Let’s look at each of the IP addresses in detail.

2.1. The Loopback Address, 127.0.0.1

The loopback IP address, denoted as 127.0.0.1, serves as a self-reference to our current device. In fact, all the IP addresses in 127.0.0.1/8 are reserved for loopback purposes. This means the Linux kernel will use its loopback interface to route packets internally if the packet has a destination set to any IP address in 127.0.0.1/8.

We can take a look at our loopback interface using the ip addr show command:

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

From the output, we can find the loopback interface as the interface with the name lo. The equivalent IP address for loopback in IPv6 is 0000:0000:0000:0000:0000:0000:0000:0001, or its shortened form ::1.

2.2. The Unspecified Address, 0.0.0.0

Similar to 127.0.0.1, the IP address 0.0.0.0 is another reserved IP address. In the official RFC 1122, it says that no packet should have its destination set as 0.0.0.0, and it’s only accepted to set 0.0.0.0 as its source address during the IP address initialization stage. Specifically, when a device first joins a network, it will send a packet indicating its source address as 0.0.0.0. This would let the DHCP server know that the device needs an IP address assignment.

However, unlike the loopback IP address, the IP address 0.0.0.0 can take on different meanings depending on our context. Let’s take a look at the different meanings of the IP address 0.0.0.0 in different contexts.

3. Meaning of 0.0.0.0 in Different Contexts

The IP address 0.0.0.0 is a common occurrence in different layers on the network stack. Let’s look at some examples.

3.1. Server Listening Interface

When we run services that listen to incoming network traffic, usually we can specify the interface it’s listening on. For instance, we can specify the interface NGINX listens on using the listen key in the config file. In the context of interface binding, the address 127.0.0.1 means that the server only listens to the loopback interface. On the other hand, binding our server to the 0.0.0.0 interface means we want to accept traffic from all of the available interfaces. Let’s look at an example.

Firstly, let’s check our available interfaces:

$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:a9:1b:40 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp0s3
       valid_lft 86258sec preferred_lft 86258sec
    inet6 fe80::737b:15d1:2041:2a5f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ae:a2:97:89 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

From the output, we can see that there are 3 interfaces available in the system. Specifically, we have a loopback interface lo, an ethernet interface enp0s3, and a virtual interface for Docker docker0. Then, we configure the NGINX with the listen 127.0.0.1 directive:

listen        127.0.0.1:80;

With this configuration in place, the NGINX will listen on port 80 of the loopback interface. This means the NGINX process will not accept packets coming from the other 2 interfaces: enps03 and docker0. To make NGINX listen to all 3 of the interfaces, we can bind it to interface 0.0.0.0 using the same listen directive:

listen        0.0.0.0:80;

3.2. Routing and Gateway

In Linux, there’s a routing table that stores the packet routing policy. Each entry consists of the destination IP address to match the packet with, the gateway to forward the packet to, and finally, the interface to move the packet. To can get the routing table on our system, we can run route -n:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG    100    0        0 enp0s3
10.0.2.0        0.0.0.0         255.255.255.0   U     100    0        0 enp0s3
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp0s3
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

From the table, we can see that there’s an entry of the IP address 0.0.0.0 in the Destination column. For a routing destination, the IP address 0.0.0.0 means the default route. In other words, it’s a catch-all rule for the case when a packet’s destination does not match any other entries in the table.

For instance, a packet with a destination IP address of 188.32.1.38 will not match the  172.17.0.0169.254.0.0, and 10.0.2.0 entries. The router will route the packet using the default route configuration, which is to the gateway at 10.0.2.2. Then, the routing table may also have 0.0.0.0 in the Gateway column, which indicates that the gateway to the relevant destination subnet has not been specified. This typically means that the system is directly connected to the destination and does not require any intermediate routing steps.

For example, a packet with the destination IP address of 172.17.2.3 will match the last entry with the gateway IP address of 0.0.0.0. Since there’s no gateway to forward to, it will perform an ARP to obtain the destination MAC address and send over the packet. Note that we are purposely excluding the Genmask column in this article because the value 0.0.0.0 under that column is technically a network mask bit, not an IP address.

4. Conclusion

In this tutorial, we’ve learned that both the 127.0.0.1 and 0.0.0.0 IP addresses are special reserved addresses. Then, we learned that 127.0.0.1 is specifically referring to the loopback address, and semantically it means the current device we are on. On the other hand, we’ve also seen how the 0.0.0.0 IP address will take on different meanings depending on the context we are working in.

Furthermore, we’ve learned that 0.0.0.0 means to bind to all the interfaces in a server process such as NGINX and Apache. Finally, we see how the IP address 0.0.0.0 means the default route in the routing table usage.