feat(templates): per-instance stealth via instance_seed in service servers
Every service template now pulls version strings, cluster/node UUIDs, auth salts, greeting banners, and uptime from the seeded per-instance RNG instead of hard-coded defaults. Scanners sweeping the fleet now see legitimately diverging fingerprints per decky while each decky's own responses stay internally consistent across restarts. Covers elasticsearch, ftp, http, https, ldap, mongodb, mqtt, mssql, mysql, postgres, redis, and smtp templates.
This commit is contained in:
@@ -9,6 +9,8 @@ received messages as JSON.
|
||||
import asyncio
|
||||
import os
|
||||
import struct
|
||||
|
||||
import instance_seed as _seed
|
||||
from syslog_bridge import syslog_line, write_syslog_file, forward_syslog
|
||||
|
||||
NODE_NAME = os.environ.get("NODE_NAME", "mongodb")
|
||||
@@ -16,6 +18,25 @@ SERVICE_NAME = "mongodb"
|
||||
LOG_TARGET = os.environ.get("LOG_TARGET", "")
|
||||
PORT = int(os.environ.get("PORT", "27017"))
|
||||
|
||||
# Per-instance (version, maxWireVersion) — paired per real MongoDB release.
|
||||
# Wire version is locked to major/minor per upstream release notes.
|
||||
_MONGO_RELEASES = [
|
||||
("4.4.22", 9),
|
||||
("5.0.25", 13),
|
||||
("6.0.5", 17),
|
||||
("6.0.14", 17),
|
||||
("7.0.5", 21),
|
||||
("7.0.8", 21),
|
||||
("7.0.11", 21),
|
||||
]
|
||||
_MONGO_VERSION, _MONGO_WIRE = _seed.pick(_MONGO_RELEASES)
|
||||
_MONGO_SET_NAME = os.environ.get("MONGO_REPL_SET", "") # empty = standalone
|
||||
|
||||
|
||||
def _new_objectid() -> bytes:
|
||||
"""12-byte BSON ObjectId — fresh per call."""
|
||||
return _seed.fresh_bytes(12)
|
||||
|
||||
# Minimal BSON helpers
|
||||
def _bson_str(key: str, val: str) -> bytes:
|
||||
k = key.encode() + b"\x00"
|
||||
@@ -98,14 +119,23 @@ class MongoDBProtocol(asyncio.Protocol):
|
||||
opcode = struct.unpack("<I", msg[12:16])[0]
|
||||
_log("message", src=self._peer[0], opcode=opcode, length=len(msg))
|
||||
|
||||
# Build a generic isMaster-style OK response
|
||||
reply_doc = _bson_doc(
|
||||
# Build a generic isMaster-style OK response with this instance's
|
||||
# version pair. Fresh topologyVersion on every reply (matches real
|
||||
# mongod behavior — clients use this to detect failover).
|
||||
fields = [
|
||||
_bson_bool("ismaster", True),
|
||||
_bson_int32("maxWireVersion", 17),
|
||||
_bson_bool("helloOk", True),
|
||||
_bson_int32("maxBsonObjectSize", 16777216),
|
||||
_bson_int32("maxMessageSizeBytes", 48000000),
|
||||
_bson_int32("maxWriteBatchSize", 100000),
|
||||
_bson_int32("maxWireVersion", _MONGO_WIRE),
|
||||
_bson_int32("minWireVersion", 0),
|
||||
_bson_str("version", "6.0.5"),
|
||||
_bson_str("version", _MONGO_VERSION),
|
||||
_bson_int32("ok", 1),
|
||||
)
|
||||
]
|
||||
if _MONGO_SET_NAME:
|
||||
fields.insert(1, _bson_str("setName", _MONGO_SET_NAME))
|
||||
reply_doc = _bson_doc(*fields)
|
||||
if opcode == 2013: # OP_MSG
|
||||
self._transport.write(_op_msg(request_id, reply_doc))
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user