# Healthchecks This repository contains the operational wrapper for the headless login healthcheck. The underlying smoke client lives in `m2dev-server-src`. ## What Exists Source repository: - `tests/login_smoke.cpp` - binary target: `metin_login_smoke` Runtime repository: - `deploy/healthcheck/metin-login-healthcheck.sh` Installed on the VPS: - `/usr/local/sbin/metin-login-healthcheck` ## What The Headless Healthcheck Verifies The installed wrapper supports two modes: - `--mode ready` - `--mode full` The full mode performs two headless passes against the live server: 1. a select-screen create/delete pass 2. a full auth + channel + `ENTERGAME` + mall pass Together they perform the real two-step Metin login flow without a GUI client and cover both character lifecycle and in-game mall open behavior: 1. Connect to the auth socket. 2. Complete the secure handshake. 3. Send login credentials. 4. Receive `AUTH_SUCCESS` and the login key. 5. Open a second connection to the channel socket. 6. Complete the secure handshake again. 7. Send `LOGIN2` with `login` + `login_key`. 8. Verify `EMPIRE`. 9. Verify `LOGIN_SUCCESS4`. 10. Create a temporary character on an empty account. 11. Delete that temporary character on the select screen using the account private code path. 12. Create a fresh temporary character again. 13. Select a character slot. 14. Send `ENTERGAME`. 15. Verify `MAIN_CHARACTER`, `PHASE_GAME`, `TIME`, and `CHANNEL`. 16. Send `/mall_password 000000` through the encrypted chat path. 17. Verify `MALL_OPEN`. This is an end-to-end gameplay-path verification, not just a TCP port check. ## How The Wrapper Works `metin-login-healthcheck.sh --mode full` does the following: - creates two temporary accounts in MariaDB - runs `metin_login_smoke` once in create/delete mode on the select screen - runs `metin_login_smoke` again for the full auth + channel + `ENTERGAME` flow - uses separate temporary accounts because the server enforces a per-account character-create cooldown - verifies that the shared safebox/mall DB load bootstrap can open the mall with the default empty password - deletes both temporary accounts and any temporary character rows on exit - passes the configured client version expected by the server `metin-login-healthcheck.sh --mode ready` is intentionally lighter: - creates one temporary account in MariaDB - runs one headless login flow through auth + channel + character create + select + `ENTERGAME` - does not run the delete pass - does not open the mall This mode is the right readiness probe immediately after a service restart. It verifies that the server is login-ready without depending on the deeper post-login mall path. It is intended for manual admin use on the VPS. ## Usage On the VPS: ```bash ssh mt2 /usr/local/sbin/metin-login-healthcheck ``` Readiness-only mode: ```bash /usr/local/sbin/metin-login-healthcheck --mode ready ``` The smoke binary can also be run directly: ```bash sudo -iu mt2.jakubkadlec.dev \ /home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \ 173.249.9.66 11000 11011 ``` Or with password passed through the environment: ```bash sudo -iu mt2.jakubkadlec.dev env METIN_LOGIN_SMOKE_PASSWORD='' \ /home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \ 173.249.9.66 11000 11011 --password-env=METIN_LOGIN_SMOKE_PASSWORD ``` If you want the smoke client to create a temporary character when the account is empty: ```bash sudo -iu mt2.jakubkadlec.dev env METIN_LOGIN_SMOKE_PASSWORD='' \ /home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \ 173.249.9.66 11000 11011 --password-env=METIN_LOGIN_SMOKE_PASSWORD \ --create-character-name=smoketestchar \ --client-version=1215955205 \ --mall-password=000000 ``` Useful direct flags: - `--json` returns a machine-readable summary including timings and emitted events - `--expect-auth-failure=STATUS` treats an auth failure such as `NOID` or `WRONGPWD` as a successful negative test - `--expect-channel-failure=STATUS` treats a channel failure as a successful negative test - `--delete-private-code=CODE` creates or reuses a character slot, sends `CHARACTER_DELETE`, and verifies `PLAYER_DELETE_SUCCESS` - `--mall-password=PASSWORD` after `ENTERGAME`, opens the in-game mall via encrypted chat command and verifies `MALL_OPEN` Operational CLI: ```bash metinctl healthcheck --mode full metinctl healthcheck --mode ready metinctl wait-ready ``` `metinctl wait-ready` now uses the lighter `ready` mode on purpose. The deeper `full` mode remains available as an explicit admin healthcheck. Example negative auth test: ```bash sudo -iu mt2.jakubkadlec.dev env METIN_LOGIN_SMOKE_PASSWORD='wrongpass' \ /home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \ 173.249.9.66 11000 11011 someuser --password-env=METIN_LOGIN_SMOKE_PASSWORD \ --expect-auth-failure=WRONGPWD --json ``` ## Security Notes This does not open a new public network surface. It is a local operational tool. Current guardrails: - no new listening port - root-only installed wrapper (`/usr/local/sbin/metin-login-healthcheck`, mode `700`) - temporary credentials - cleanup trap removes the test account - wrapper passes the password through environment instead of command-line plaintext - secrets are not committed to git Remaining trust boundary: - anyone with effective root access can still inspect or run the check - therefore this tool assumes root is already trusted