# instinct: noVNC/VNCのbind公開範囲を変える前に、systemd unit定義でなく実際にポートを握る稼働プロセスのbindを確認する

サービスのbind/認証設定を変更する前に、**systemd unit定義ではなく「実際にポートを握っている稼働プロセス」のbindを `ss -tlnp` で確認する**。unit定義が正しくても、過去に手動起動されたプロセスが居座り、unitが起動できずにドリフトしていることがある。

**Why:** shadowのnoVNCで実証(2026-06-07)。`novnc.service` の定義は `--listen $(tailscale ip -4):6080`(Tailscale限定)で正しかったが、実際は5/24に手動起動された別のwebsockify(`session-N.scope` 配下)が `0.0.0.0:6080` で全公開bindして居座り、unitは inactive のまま。**定義を読むだけでは「Tailscale限定で安全」と誤判断する**。同じ構造でXtigervncも手動起動が5901を握り `vncserver@1.service` が activating のまま起動できずにいた。

**How to apply:**
1. 設定変更前に必ず `ss -tlnp | grep :` で**実bindと保持pid**を見る。`0.0.0.0` なら全公開(公開IPからも到達)。Tailscale IPやlocalhostなら内部限定
2. 保持pidの素性を確認: `ps -o lstart=,args= -p ` / `cat /proc//cgroup`。`session-N.scope` 配下なら手動ログインセッション起動=unit管理外のドリフト
3. ドリフト解消手順: 手動プロセスを `kill` してポート解放 → `systemctl start ` でunit管理下に正常化 → `ss` で実bindが意図通りか再確認
4. 変更後は必ず**実挙動をcurlで検証**([[instinct-config-file-not-served-drift]]と同じ原則): Tailscale IP経由=到達可・localhost経由=到達不可、で内部限定が効いたと確認できる
5. パスワード撤廃(fail-open化)は、bind内部限定が**curlで確実に検証できてから**行う。順序を逆にすると一瞬でも無認証で全公開になる

**今回の最終構成(参考):** noVNC `100.115.94.5:6080`(Tailscale限定bind・`novnc.service` enabled)+ VNC `127.0.0.1:5901`(localhost限定・`~/.vnc/config` に `securitytypes=none`+`localhost`・`vncserver@1.service` 経由)。Tailscale内に居る端末のブラウザから `http://100.115.94.5:6080/vnc.html` でパスワードなしアクセス可。関連 [[instinct-ai-dev-failopen-tailscale-bind]]

---
(migrated from local memory/instinct_novnc_unit_vs_manual_process_drift.md)