---
title: "Build a WHOIS compatibility server with Python and Nginx"
tags: ['WHOIS', 'Domain', 'Python', 'Nginx']
published: 2025-04-29 13:43:58
updated: 2025-05-18 17:52:51
excerpt: "Build a small WHOIS compatibility server with Python and Nginx that points old port 43 clients toward RDAP."
---
> This file is the raw Markdown source of an m.ac post; the canonical version lives at https://m.ac/build-whois-server-python-nginx/
> The full index of posts and pages is at https://m.ac/llms.txt — read the index first before crawling further.

## Background

ICANN's [January 27, 2025 update](https://www.icann.org/en/announcements/details/icann-update-launching-rdap-sunsetting-whois-27-01-2025-en) made RDAP the definitive source for gTLD registration data, with legacy WHOIS services retired. For new registration data lookups, use [RDAP](https://www.icann.org/en/contracted-parties/registry-operators/resources/registration-data-access-protocol).

The [Registration Data Access Protocol](https://en.wikipedia.org/wiki/Registration_Data_Access_Protocol) (RDAP) is the successor to the [traditional WHOIS protocol](https://en.wikipedia.org/wiki/WHOIS). It uses HTTPS and structured responses instead of unencrypted, loosely formatted text over port 43.

If you run registry or registrar infrastructure, move clients to RDAP rather than keeping a full WHOIS service around forever. We have already completed that migration for [xTom GmbH](https://xtom.com/) (IANA ID 3968).

Old applications still query WHOIS on port 43, so this server keeps compatibility clients from failing silently. It accepts the connection and returns a plain message that points users to RDAP.

---

## 1. Prerequisites

There are two straightforward ways to build this kind of WHOIS compatibility endpoint: Nginx stream alone, or a small Python service behind Nginx.

The commands below use `sudo`. If you prefer a root shell, run `sudo -i` first and drop `sudo` from the commands.

Install the required packages:

```bash
sudo apt update
sudo apt install -y lsb-release ca-certificates apt-transport-https curl gnupg dpkg python3
```

Add the N.WTF repository, which provides an Nginx mainline build with the stream module enabled:

```bash
curl -sS https://n.wtf/public.key | sudo gpg --dearmor -o /usr/share/keyrings/n.wtf.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirror-cdn.xtom.com/sb/nginx/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/n.wtf.list
```

Install Nginx:

```bash
sudo apt install nginx-extras -y
```

---

## 2. Build a WHOIS server with the Nginx stream module

The Nginx stream module can return a fixed message on port 43. Add this block to `/etc/nginx/nginx.conf`:

```nginx
stream {
    # Define rate limiting zone
    limit_conn_zone $binary_remote_addr zone=whois_stream_conn:10m;

    # simple whois server
    server {
        listen 43;
        listen [::]:43;

        # Connection limits
        limit_conn whois_stream_conn 5;

        proxy_timeout 10s;

        # Return a message to the client
        return "NOTICE: In accordance with ICANN compliance policies, our whois server has been discontinued. Please use the RDAP protocol for all domain whois queries.\n\nFor more information, please visit:\n\nhttps://www.icann.org/en/announcements/details/icann-update-launching-rdap-sunsetting-whois-27-01-2025-en\nhttps://www.icann.org/resources/pages/global-amendment-2023-en\n\n";
    }
}
```

Test the configuration and reload Nginx:

```bash
sudo nginx -t
sudo nginx -s reload
```

Some WHOIS clients do not like this version. A query may print:

```plaintext
fgets: Connection reset by peer
```

The Nginx stream `return` approach writes the message and closes the TCP session immediately. That is enough for some clients, but others report `fgets: Connection reset by peer` instead of printing the text cleanly.

Using a tiny Python service gives us better control over reading the query, writing the response, and closing the connection.

---

## 3. Build a WHOIS server with Python and Nginx

The Python script listens locally and returns a predefined message to each WHOIS client.

Clone the repository and copy `whois.py` to `/opt/`:

```bash
git clone https://git.m.ac/showfom/whois-server
cd whois-server
sudo cp -r whois.py /opt
```

Copy the systemd service template to `/etc/systemd/system/`:

```bash
sudo cp -r whois-server.service /etc/systemd/system/
```

Enable and start the service:

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now whois-server
```

Test the WHOIS service locally:

```bash
whois anything -h 127.0.0.1:10043
```

It should return the configured message:

```plaintext
NOTICE: In accordance with ICANN compliance policies, our whois server has been discontinued. Please use the RDAP protocol for all domain whois queries.

For more information, please visit:

https://www.icann.org/en/announcements/details/icann-update-launching-rdap-sunsetting-whois-27-01-2025-en
https://www.icann.org/resources/pages/global-amendment-2023-en
```

Now configure Nginx to proxy public port 43 traffic to the local Python service.

Add this block to `/etc/nginx/nginx.conf`:

```nginx
stream {
    # Define rate limiting zone
    limit_conn_zone $binary_remote_addr zone=whois_stream_conn:10m;

    # whois server
    server {
        listen 43;
        listen [::]:43;

        # Connection limits
        limit_conn whois_stream_conn 5;

        # Forward requests to the local Python script service
        proxy_pass 127.0.0.1:10043;
        proxy_timeout 30s;
    }
}
```

Test the configuration and reload Nginx:

```bash
sudo nginx -t
sudo nginx -s reload
```

Query the public WHOIS endpoint:

```bash
whois anything -h localhost
```

You can also create a WHOIS hostname with A and AAAA records pointing to this server, then submit that hostname wherever a registry still asks for an official WHOIS server.
