🐕

Codex リモートログイン手順(仕組みと対処集)

に公開

Codex リモートログイン手順(仕組みと対処集)

このドキュメントは、ヘッドレスなリモートサーバー上で codex login を安定して成功させるための「仕組みの解説」と「再現性の高い手順集」をまとめたものです。必要に応じてコピー&ペーストで使えるコマンドを掲載しています。


1. 何が起きていたか(メカニズム)

  • codex loginhttp://localhost:1455 に小さな一時サーバーを立て、ブラウザ認証(OAuth)の**リダイレクト(callback)**を受け取って完了します。

  • しかし 認証用のブラウザは“手元(ローカルPC)”codex login を動かすのは “リモートサーバー”。このままだと ブラウザ → localhost:1455(ローカル) に返るだけで、リモートの codex が待っている localhost:1455(リモート) には届きません。

  • 解決策は SSH ローカルポートフォワーディング

    • ローカルの 127.0.0.1:1455 へのアクセスを トンネルでリモートの 127.0.0.1:1455 に中継します(ssh -L)。
    • こうすると、ローカルのブラウザで callback を開くだけで、その HTTP リクエストがトンネルを通って リモートの codex に到達し、ログインが完了します。
  • なお、^Zcodex を止めると 停止(Stopped)状態のままポートを掴み続けることがあり、再ログイン時に Port 127.0.0.1:1455 is already in use が発生します。


2. いちばん確実な基本手順(再現性重視)

前提

  • リモートホスト名:gvelox(ProxyJump 等は ~/.ssh/config で設定済み)
  • ローカル環境にブラウザあり

手順

  1. 停止ジョブの後始末(ローカル or リモートで必要に応じて)

    jobs -l                    # 停止ジョブ確認(シェルが同一なら)
    kill %1 %2 %3 2>/dev/null # 必要な番号だけでOK
    jobs -p | xargs -r kill -TERM; sleep 1
    jobs -p | xargs -r kill -KILL
    ss -lptn 'sport = :1455' || true
    lsof -i :1455 || true
    
  2. ローカル→gvelox へトンネルを張る(別ターミナルで実行・張りっぱなし)

    ssh -N -L 127.0.0.1:1455:127.0.0.1:1455 gvelox
    # バックグラウンド化するなら: ssh -fN -L 127.0.0.1:1455:127.0.0.1:1455 gvelox
    
  3. リモートで codex login を実行

    ssh gvelox
    codex login
    
    • 端末に長い URL(例:https://auth.openai.com/...)が表示されます。
    • その URL をローカルのブラウザで開くだけでOK。
    • 認証後のリダイレクト http://localhost:1455/auth/callback?... はトンネル経由でリモートの codex に届き、ログイン完了。
    • うまくいかない場合は URL の localhost127.0.0.1 に置き換えて再試行。

3. 代替手段(環境や制約に応じて)

A. コールバック URL を手動で叩く方法(ブラウザ→コピー→curl)

  1. リモートで codex login を起動して URL を表示。

  2. ローカルでその URL を開いて認証。

  3. 認証後にブラウザが遷移しようとする http://localhost:1455/auth/callback?... を丸ごとコピー

  4. リモートシェルで以下を実行:

    curl -iL "http://localhost:1455/auth/callback?code=...&state=..."
    

    これでリモートの codex にトークンが渡りログイン完了。

B. API キーで非対話ログイン(CI/GUI なし環境向け)

printenv OPENAI_API_KEY | codex login --with-api-key
# あるいは
codex login --with-api-key <<<"$OPENAI_API_KEY"
  • GUI 不要・最短で確実。~/.codex/ 配下に認証情報が保存されます。

C. 逆方向(必要なら)

  • もしブラウザがリモート、callback サーバーがローカルという特殊パターンなら、ssh -R(リバースフォワード)で反転させます。

    # ローカルで実行(ローカル:1455 → リモート:1455 の逆向き中継)
    ssh -N -R 127.0.0.1:1455:127.0.0.1:1455 gvelox
    

4. よくあるエラーと対処

症状 原因 対処
Port 127.0.0.1:1455 is already in use 停止ジョブや残骸プロセスがポートを占有 jobs -lkill %nss/lsof で PID を特定して kill
ブラウザで認証後も codex が終わらない callback がリモートに届いていない ssh -L トンネルを張る/localhost127.0.0.1 に変更/A手法(curl)
--device-auth が 403 デバイスコードフローが無効/制限中 代わりに SSH トンネル or API キー方式
認証 URL を開けない 企業プロキシ/ファイアウォール 別ネットワークで試す/モバイルテザリング一時利用

5. 疎通確認・デバッグ用コマンド

# 1455番ポートの待受確認(リモート側)
ss -lptn 'sport = :1455'

# ローカル→リモートのトンネル疎通チェック(ローカル側で実行)
curl -i http://127.0.0.1:1455/health || true   # ヘルスエンドポイントが無い場合は 404 でもOK、到達可否だけ見る

# プロセス確認
ps aux | grep -E 'codex|ssh -.*1455' | grep -v grep

6. すぐ使えるテンプレ(コピペ用)

6.1 一撃ログイン(標準)

別ターミナルA:

ssh -fN -L 127.0.0.1:1455:127.0.0.1:1455 gvelox

ターミナルB(リモート):

ssh gvelox
codex login

ローカルで URL を開く → 完了。

6.2 残骸掃除ワンライナー

( jobs -p || true ) | xargs -r kill -TERM; sleep 1; \
( jobs -p || true ) | xargs -r kill -KILL; \
ss -lptn 'sport = :1455' || true; lsof -i :1455 || true

6.3 API キー方式

printenv OPENAI_API_KEY | codex login --with-api-key

7. セキュリティ注意

  • ssh -L 127.0.0.1:1455:127.0.0.1:1455 のように バインドは 127.0.0.1 に限定0.0.0.0 で外部に晒さない)。
  • 認可 URL(code, state などを含む)は 第三者に共有しない
  • 使い終えたトンネルは pkill -f "ssh -N -L .*1455:127.0.0.1:1455" 等で閉じる。

8. FAQ

  • Q. localhost でダメだけど 127.0.0.1 だと通るのはなぜ?

    • A. 名前解決/IPv6優先などの挙動差で ::1(IPv6)に行ってしまう環境があるため。IPv4 を強制すると安定します。
  • Q. ポート番号 1455 は固定?

    • A. codex login がそのポートで待受する想定。競合する場合は、該当プロセスを終了してから再試行。
  • Q. プロキシ下でもいける?

    • A. 認証サイト(auth.openai.com)に到達できればOK。社内プロキシでブロックされる場合は一時的に別ネットワークを使用。

9. まとめ(運用メモ)

  • 原理:ブラウザの callback を SSH トンネルで“ローカル→リモート”に橋渡しする。
  • 実践ssh -L 127.0.0.1:1455:127.0.0.1:1455 gvelox → リモートで codex login → ローカルで URL を開く。
  • 代替:curl で callback を叩く/API キー方式。
  • 落とし穴:停止ジョブがポートを掴む、localhost127.0.0.1 の違い、--device-auth は使わない。

Discussion