Infiniroot Blog: We sometimes write, too.

Of course we cannot always share details about our work with customers, but nevertheless it is nice to show our technical achievements and share some solutions.

How to deploy your own remote public IP address lookup service (in Kubernetes using Rancher 2)

Published on December 11th 2020


Sometimes you might want to quickly look up your current public IP address. Or you might need to monitor the public IP address of an application as it is relevant to the health of the application (see article PowerDNS master slave replication stopped working due to AWS Elastic IP mysteriously gone).

In such scenarios, public (and free) services such as ifconfig.co or icanhazip.com are great helpers. But as these services are free and open to everyone, they might receive a lot of traffic. A lot of traffic.

Even with some limits on connections per second, icanhazip is still poised to top 14.3TB of bandwidth this month according to vnstat.
- Major Hayden (icanhazip.com)

Not seldomly these free services also suffer various attacks, such as DDoS. If such a service is down and your application somehow relies on a frequent remote IP lookup, your own application might go down.

Your own public IP lookup in PHP

Of course you could always deploy your quick public IP lookup. In PHP you'd simply use a snippet like this:

<?php echo $_SERVER['REMOTE_ADDR']; ?>

In case your web server runs behind a reverse proxy, you might want to change this to the HTTP header which contains the forwarded remote ip address (mostly X-Forwarded-For or X-Real-IP):

<?php echo $_SERVER['HTTP_X_FORWARDED_FOR']; ?>

It's as easy as this. However ifconfig.co offers much more than just showing the client's IP address. It also allows json output for application parsing, adds GeoIP based information and more. To "copy" this into your own PHP code will need someone really motivated (or bored). But there's an easier way.

Deploy your own ifconfig.co!

The whole website ifconfig.co including the backend service (written in Go) is actually available as echoip on GitHub. Even Docker images are available from Docker Hub. If you already have your own Container environment it's incredibly easy and fast to deploy your own ifconfig.co service! In this example we're using our Rancher 2 managed Kubernetes environment to deploy such a service.

The service (workload) was defined as a DaemonSet (one pod per node) and simply the Docker image name was entered: mpolden/echoip. If you're new to Docker images, this means download the latest "echoip" image from the public Docker Hub repository "mpolden".

Deploy ifconfig service (echoip) in Kubernetes using Rancher 2

After clicking on [Launch], it only took a couple of seconds and the service was deployed across all the nodes in that Kubernetes cluster. Now that the service is running, an Ingress rule needs to be added.

By default, echoip listens on the internal port tcp/8080. This means the Ingress rule with the public domain (here ifconfig.example.com) points to the workload using the internal IP 8080:

echoip in Kubernetes: Ingress rule

Now just point your public domain to the Ingress of that Kubernetes cluster and you're good to go!

But I get some internal IP?

When you launch a HTTP request to your public domain, you should be able to get your IP address as a response. However in a Kubernetes environment using Ingress for incoming http/https, the response most likely contains an internal IP:

$ curl ifconfig.example.com
10.10.2.148

Guess what? Yes, that's actually the IP address of the Ingress pod, forwarding the HTTP request to one of the echoip pods. To be able to return the "real" IP address from where the HTTP request originated, two requirements must be fulfilled:

  1. Ingress needs to forward the remote IP address in a HTTP header. In the default Kubernetes Ingress (Nginx) this should be enabled by default and is using the X-Forwarded-For header.
  2. The application (echoip) needs to be told that X-Forwarded-For should be used to determine the remote IP address.

When looking at the Dockerfile of echoip, the following entry point is used:

ENTRYPOINT ["/opt/echoip/echoip"]

This means that echoip is launched without any parameters inside the pod; the default settings are applied in this case.

To tell echoip to use a specific HTTP header as remote IP, the -H parameter can be used. Simply adjust the entrypoint configuration when deploying the workload to use the X-Forwarded-For header. In Rancher 2 you can overwrite the entrypoint from a Dockerfile using the Entrypoint field:

/opt/echoip/echoip -H X-Forwarded-For

Rancher 2: Overwrite a Dockerfile's entrypoint

Note: The "Command" section might be hidden by default. Use "Show advanced options" when deploying or editing a workload.

After the echoip workload was redeployed with the new entrypoint, the HTTP request from remote now shows the correct public IP:

$ curl ifconfig.example.com
212.103.71.210

Using a reverse proxy or load balancer in front of Ingress

Of course in a production environment, a Kubernetes node should never be directly accessible by Internet. For security reasons a reverse proxy or load balancer should be placed in between the Ingress and public Internet. Such an architecture could look like this:

Architecture with (AWS) Load Balancer or a Reverse Proxy in front of Kubernetes Ingress

From a point of view of the echoip application it doesn't matter though whether or not there are additional "hops" in front of the Ingress. The only thing which needs to be considered is that the reverse proxy or load balancer forwards the client's IP address as X-Forwarded-For header. In AWS Elastic Load Balancers (ELB) this is already configured by default. 

Looking for a managed dedicated Kubernetes environment?

If you are looking for a managed and dedicated Kubernetes environment, managed by Rancher 2, with server location Switzerland, check out our Private Kubernetes Container Cloud Infrastructure offer at Infiniroot.