This helped a lot last year. I enhanced the server.py script (e.g. to indicate missing data): https://blog.shimps.org/blogpost544-whois-h-localhost
import argparse
import asyncio
import maxminddb
import ipaddress
SEPARATOR = b"\r\n"
class Handler:
def __init__(self, database):
self.reader = maxminddb.open_database(database)
async def handle(self, reader, writer):
data = await reader.readuntil(SEPARATOR)
# Convert bytes to UTF-8 and lookup data in the MMDB.
ip = data.split(SEPARATOR)[0].decode()
info , prefix = self.reader.get_with_prefix_len(ip)
bgp = ipaddress.ip_network(f"{ip}/{prefix}", strict=False)
writer.write(f"route: {bgp}".encode() + SEPARATOR)
# Output one key/value pair per line.
if info:
for k, v in info.items():
writer.write(f"{k}: {v}".encode() + SEPARATOR)
writer.write(f"dbstatus: ok - data found".encode() + SEPARATOR)
else:
writer.write(f"dbstatus: warning - no data available".encode() + SEPARATOR)
await writer.drain()
# Close the connection.
writer.close()
await writer.wait_closed()
async def main():
parser = argparse.ArgumentParser()
parser.add_argument("database")
parser.add_argument("--host", default="localhost")
parser.add_argument("--port", default=43, type=int)
args = parser.parse_args()
handler = Handler(args.database)
server = await asyncio.start_server(handler.handle, args.host, args.port)
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
Maybe it is useful for someone else.