This project is intended for testing and learning, not for production use.
This repository is a fork of a fork:
- forked from
Py-KMS-Organization/py-kms - which is itself a fork of
SystemRage/py-kms
py-kms is a Python KMS server emulator with Docker-first runtime and a built-in WebUI.
Main capabilities:
- KMS protocol support:
v4,v5,v6 - SQLite persistence for client activations
- WebUI pages for clients, products, settings and license
- WebUI pagination and sorting for client overview
- Source IP tracking and startup backfill from log files
- Source IP blacklist (single IP, CIDR, range)
- Blocked-attempt counters per rule and source IP
- Country display (flag + name) next to source IP in clients table
Only one image variant is maintained.
ghcr.io/melroyb/py-kms:python3ghcr.io/melroyb/py-kms:latest
Container registries:
- GitHub Container Registry image tag:
ghcr.io/melroyb/py-kms:latest - Docker Hub image tag:
melroy/py-kms:latest
latest and python3 are built from the same Dockerfile and point to the same build output.
python3 py-kms/pykms_Server.py [IPADDRESS] [PORT]Help:
python3 py-kms/pykms_Server.py -h
python3 py-kms/pykms_Client.py -hdocker run -d \
--name py-kms \
--restart always \
-p 1688:1688 \
-p 8080:8080 \
-v pykms-db:/home/py-kms/db \
melroy/py-kms:latestYou can also start from the provided env example:
Docker-specific details are in:
Use this only for environments with valid Microsoft Volume Licensing.
Replace <KMS_HOST> with your server address (for example kms.example.local or 192.168.1.10).
Open an elevated Command Prompt and run:
slmgr /skms <KMS_HOST>:1688
slmgr /ato
slmgr /dlvNotes:
slmgr /skmssets the KMS host and port.slmgr /atotriggers activation.slmgr /dlvshows detailed activation status and current KMS host.
Open an elevated Command Prompt and run:
cd "%ProgramFiles%\Microsoft Office\Office16"
if not exist ospp.vbs cd "%ProgramFiles(x86)%\Microsoft Office\Office16"
cscript ospp.vbs /sethst:<KMS_HOST>
cscript ospp.vbs /setprt:1688
cscript ospp.vbs /act
cscript ospp.vbs /dstatusNotes:
ospp.vbs /sethstsets the KMS host.ospp.vbs /setprtsets the KMS port.ospp.vbs /acttriggers activation.ospp.vbs /dstatusshows Office activation status.
If activation fails, check:
- client can reach
<KMS_HOST>:1688 - system time is correct
- edition/channel is compatible with KMS
- firewall allows outbound TCP 1688
IP(default::)PORT(default1688)LOGLEVEL(defaultINFO)LOGFILE(defaultSTDOUT)LOGSIZE(default empty)CLIENT_COUNT(default26)HWID(defaultRANDOM)WEBUI(default1)
PYKMS_WEBUI_PASSWORD(required to enable login)PYKMS_WEBUI_USERNAME(defaultadmin)PYKMS_WEBUI_SECRET_KEY(recommended)PYKMS_WEBUI_COOKIE_SECURE(defaultfalse)PYKMS_WEBUI_COOKIE_SAMESITE(defaultLax)PYKMS_WEBUI_SESSION_TTL_SECONDS(default43200)PYKMS_WEBUI_LOGIN_RATE_LIMIT_ATTEMPTS(default5)PYKMS_WEBUI_LOGIN_RATE_LIMIT_WINDOW_SECONDS(default300)PYKMS_WEBUI_LOGIN_RATE_LIMIT_BLOCK_SECONDS(default900)- WebUI shows a visible warning when a default password value is used.
PYKMS_BLACKLIST_PATH(default/home/py-kms/db/pykms_blacklist.txt)PYKMS_BLACKLIST_STATS_PATH(default/home/py-kms/db/pykms_blacklist_stats.json)
PYKMS_SOURCEIP_BACKFILL_ON_START(default1)PYKMS_SOURCEIP_BACKFILL_GLOB(default/home/py-kms/db/pykms_logserver.log*)PYKMS_SOURCEIP_BACKFILL_LOGS(optional explicit comma-separated list; overrides glob)
PYKMS_GEOIP_ENABLED(default1)PYKMS_GEOIP_PROVIDER(defaultipapi.co)PYKMS_GEOIP_TIMEOUT_SECONDS(default2)PYKMS_GEOIP_CACHE_TTL_SECONDS(default604800)PYKMS_GEOIP_ERROR_CACHE_TTL_SECONDS(default900)PYKMS_GEOIP_MAX_LOOKUPS_PER_REQUEST(default20)
PYKMS_WEBUI_CLIENTS_PER_PAGE(default100)PYKMS_WEBUI_CLIENTS_MAX_PER_PAGE(default500)
PYKMS_DOCKER_UPDATE_ENABLED(default0, set to1to enable WebUI update checks and one-click container replacement)PYKMS_DOCKER_UPDATE_CHECK_INTERVAL_SECONDS(default21600)PYKMS_DOCKER_IMAGE(optional explicit image reference override, for examplemelroy/py-kms:latest)PYKMS_DOCKER_SOCKET_PATH(default/var/run/docker.sock)
- For persistence, mount
/home/py-kms/dbas a volume. - If
LOGFILE=STDOUT, source-IP startup backfill has no log files to parse. - GeoIP lookup uses an external provider by default (
ipapi.co), so public source IPs may be sent to that service. - On container startup, missing required runtime files are auto-created (touch), including db/blacklist/stats files and custom logfile paths.
- Docker self-update requires Docker socket access. Mounting
/var/run/docker.sockgives this container broad control over the host Docker daemon.
py-kms is released under The Unlicense.
