Skip to content

Instantly share code, notes, and snippets.

@Avamander
Last active October 24, 2025 01:03
Show Gist options
  • Select an option

  • Save Avamander/55168932f09b8ba0af268a1e02e74493 to your computer and use it in GitHub Desktop.

Select an option

Save Avamander/55168932f09b8ba0af268a1e02e74493 to your computer and use it in GitHub Desktop.
Dummy ident protocol server

This really barebones "ident" protocol server is intended for use with IRC and works trivially inside a Docker container.

You can obviously modify it to return any ident you want, but it's currently set to "parse" .oidentd.conf (mounted inside the container) as generated by IRC clients such as ZNC.

I've also included an example on how to create an nftables rule to only allow ident queries from IRC servers you first connect to. This means that the ident responder is not usually accessible, but becomes available to IRC servers. Reverse port-knocking of sorts.

#!/usr/bin/python3
from os import path
from time import time
from select import select
import socket
def handleIdent(fd):
fd.settimeout(5)
try:
data = fd.recv(1024).decode("UTF-8").strip()
except:
fd.send(b"0,0:ERROR:UNKNOWN-ERROR\r\n")
return
ports = data.split(",", 2)
ports = list(map(validPort, ports))
if len(ports) < 2 or not all(ports):
fd.send(b"0,0:ERROR:INVALID-PORT\r\n")
else:
try:
with open("oidentd/.oidentd.conf", "r") as inputfile:
user = (inputfile.read().replace('global { reply "', "").replace('" }', ""))
if len(user) <= 0:
raise Exception()
ident_response = (",".join(map(str, ports)) + ":USERID:UNIX:" + user + "\r\n")
print(f"Responding to ident request: {ident_response}", end="")
fd.send(ident_response.encode("UTF-8"))
except:
fd.send((",".join(map(str, ports)) + ":ERROR:NO-USER\r\n").encode("utf-8"))
fd.close()
def validPort(port):
try:
port = int(port)
except ValueError:
return False
if 0 < port < 65536:
return port
return False
listeners = [("0.0.0.0", 1113)]
if __name__ == "__main__":
servers = []
for host, port in listeners:
if ":" in host:
servers.append(socket.socket(socket.AF_INET6, socket.SOCK_STREAM))
else:
servers.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
servers[-1].bind((host, port))
servers[-1].listen(5)
servers[-1].setblocking(0)
print(f"Started listening on {host}:{port}")
while True:
inready, _, _ = select(servers, [], [])
for ready in inready:
if ready in servers:
client, addr = ready.accept()
inready.append(client)
else:
try:
handleIdent(ready)
except:
pass
table inet filter {
set ident_clients_ipv4 {
type ipv4_addr
flags timeout
}
chain input {
type filter hook input priority filter; policy accept;
# ...
tcp dport 113 ip saddr @ident_clients_ipv4 accept;
# ...
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# ...
tcp dport { 6697, 6667, 7000 } add @ident_clients_ipv4 {ip daddr timeout 5s} accept;
# ...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment