168 lines
5.4 KiB
Markdown
168 lines
5.4 KiB
Markdown
# 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 <login> <password>
|
|
```
|
|
|
|
Or with password passed through the environment:
|
|
|
|
```bash
|
|
sudo -iu mt2.jakubkadlec.dev env METIN_LOGIN_SMOKE_PASSWORD='<password>' \
|
|
/home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \
|
|
173.249.9.66 11000 11011 <login> --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='<password>' \
|
|
/home/mt2.jakubkadlec.dev/metin/build/server-src/bin/metin_login_smoke \
|
|
173.249.9.66 11000 11011 <login> --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
|