Verify the GL.iNet Slate 7 Pro (GL-BE10000) JSON-RPC API against the assumptions built into hydraneck pkg/glinet (shipped in v0.12.0, issue #516 Phase A). This task needs LAN access to the device. Run it from a machine on the router's network. The hydraneck server cannot reach the device.
hydraneck v0.12.0 added a glinet router backend. It was built from the archived GL.iNet 4.x API description (dev.gl-inet.com is offline), not against real firmware. Two wire-format assumptions need confirmation on the real device. The full findings go back to issue #516.
You need:
192.168.8.1. Set IP to it.PW to it.curl, openssl, md5sum, python3 (only for pretty printing).Do not change the router's WAN, Wi-Fi, or firewall settings. Steps 1 to 5 are read only. Step 6 writes one scratch WireGuard group and removes it again.
curl -s -o /dev/null -w '%{http_code}\n' http://$IP/rpc -d '{}'
Expect an HTTP 200 (with a JSON-RPC error body). Record the code.
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":1,"method":"challenge","params":{"username":"root"}}'
Record the raw JSON. Confirm the result contains alg, salt, and nonce. Record whether alg is a number or a string, its value, and whether a hash-method field is present (expected on firmware 4.8+).
hydraneck computes: cipher = unix crypt(3) of the password with alg and salt, then hash = md5 hex of root:<cipher>:<nonce> (or sha256/sha512 hex when hash-method says so).
# Use the alg from step 2: -1 for alg 1, -5 for alg 5, -6 for alg 6.
CIPHER=$(openssl passwd -6 -salt <salt-from-step-2> "$PW")
HASH=$(echo -n "root:$CIPHER:<nonce-from-step-2>" | md5sum | cut -d' ' -f1)
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":2,"method":"login","params":{"username":"root","hash":"'$HASH'"}}'
Fetch a fresh challenge immediately before the login. Nonces expire. Expect a result that contains sid. Record the exact shape of the result. If login fails with error -32000, record the full error and try the sha256/sha512 digest per the hash-method field. Export SID for the next steps.
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":3,"method":"call","params":["'$SID'","system","get_info",{}]}'
Record firmware_version, model, and board_info.model. hydraneck renders the version as <firmware_version> (<board_info.model>).
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":4,"method":"call","params":["'$SID'","clients","get_list",{}]}'
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":5,"method":"call","params":["'$SID'","wg-client","get_group_list",{}]}'
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":6,"method":"call","params":["'$SID'","wg-client","get_status",{}]}'
Record one full client entry (field names matter: mac, ip, name, online, tx, rx). Record the group list and status shapes. Confirm the module name wg-client (with hyphen) works.
This settles the open assumption: add_config may want allowed_ips as a CSV string (what hydraneck sends) or as an array.
# Create a scratch group.
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":7,"method":"call","params":["'$SID'","wg-client","add_group",{"group_name":"hydratest"}]}'
# Find its group_id.
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":8,"method":"call","params":["'$SID'","wg-client","get_group_list",{}]}'
# Try add_config with allowed_ips as a CSV STRING (hydraneck's format). Use throwaway keys:
KEYS=$(curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":9,"method":"call","params":["'$SID'","wg-server","generate_key",{}]}')
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":10,"method":"call","params":["'$SID'","wg-client","add_config",{"group_id":<GID>,"name":"hydratest-peer","address_v4":"10.99.99.2/32","private_key":"<PRIV>","public_key":"<PUB>","end_point":"203.0.113.1:51820","allowed_ips":"10.99.0.0/16","persistent_keepalive":25,"presharedkey_enable":false}]}'
Record whether the string form is accepted (result with peer_id) or rejected (record the exact error). If rejected, retry with "allowed_ips":["10.99.0.0/16"] and record the outcome. Do NOT start this tunnel. Clean up:
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":11,"method":"call","params":["'$SID'","wg-client","remove_config",{"group_id":<GID>,"peer_id":<PEER_ID>}]}'
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":12,"method":"call","params":["'$SID'","wg-client","remove_group",{"group_id":<GID>}]}'
curl -s http://$IP/rpc -d '{"jsonrpc":"2.0","id":13,"method":"logout","params":["'$SID'"]}'
Verify with get_group_list that the scratch group is gone.
Collect for issue #516:
Redact the password and the sid from the report. Hand the findings to Cederik, or PATCH them into issue #516 on issues.experiencenet.com if you have the API token. If any step contradicts the pkg/glinet implementation, say exactly which call and which field.
Runbook executed on the LAN 2026-08-19. All six steps completed; scratch group removed; findings posted to issue #516. Key results: challenge/login/system/clients assumptions confirmed; allowed_ips CSV string ACCEPTED by add_config; but wg-client get_status is Method not found (-32601) on firmware 4.8.4.