Codex リモートログイン手順(最新版・実戦対応フルガイド)
Codex リモートログイン手順(最新版・実戦対応フルガイド)
目的:ヘッドレスなリモートサーバー(例:golgi)上で
codex loginを安定して成功させる。
本書は仕組み・標準手順・エラーの切り分け・掃除コマンド・応用例まで現場でそのまま使える形でまとめています。
0. TL;DR(最短経路)
前提:手元にブラウザあり。リモートは golgi。JumpHost は ~/.ssh/config で設定済み。
別ターミナルA(ローカル)
ssh -fN -o ExitOnForwardFailure=yes \
-L 127.0.0.1:1455:127.0.0.1:1455 golgi
別ターミナルB(リモート)
ssh golgi
codex login
ターミナルに出る URL をローカルのブラウザで開く。
ダメなときは URL 中の localhost を 127.0.0.1 に置換して開き直す。
これで終わるのが通常。詰まったら以下の切り分けへ。
1. 仕組み(なぜトンネルが要るのか)
-
codex loginはhttp://localhost:1455で一時的な認証受け口(小さなHTTPサーバ)を立てる。 -
ブラウザは手元(ローカル)、
codexはリモートで動くため、そのままだとコールバックがローカルに落ちて終わり。リモートのcodexには届かない。 -
そこで SSH ローカルフォワード(
ssh -L) を使って、-
ローカルの
127.0.0.1:1455へのアクセス ⇒ トンネル経由 ⇒ リモートの127.0.0.1:1455に橋渡しする。
-
ローカルの
-
こうすると、ローカルのブラウザでコールバックを開くだけで、リモートの
codexに到達してログイン完了。
localhostだと環境により::1(IPv6)へ行くことがある。127.0.0.1(IPv4)を強制すると安定。
2. 役割と用語
-
ローカル:あなたのPC(例:
yt@yt-Z490-S01)。ブラウザがある側。SSHクライアント側。 -
リモート:サーバ(例:
golgi)。codex loginを実行して1455で待つ側。 -
トンネル:
ssh -L 127.0.0.1:1455:127.0.0.1:1455 <host>によるローカル→リモートの転送路。
3. 標準手順(再現性重視)
3.1 前提の確認
-
sshでgolgiに入れること(JumpHost は~/.ssh/configでProxyJump設定済みでOK)。 - ブラウザはローカルにある。
3.2 実行順序
(1) トンネルを張る(ローカル)
ssh -fN -o ExitOnForwardFailure=yes \
-L 127.0.0.1:1455:127.0.0.1:1455 golgi
-
-fN:バックグラウンド・コマンド実行なし。 -
ExitOnForwardFailure=yes:ポート競合などで即失敗してくれる(成功/失敗が分かりやすい)。
(2) 1455 の LISTEN を確認(ローカル)
ss -lptn 'sport = :1455'
# 例) users:(('ssh',pid=12345,fd=4)) と出ればOK(ローカルの ssh が LISTEN)
(3) リモートで codex login を実行
ssh golgi
codex login
# 端末に出た長い URL をローカルのブラウザで開く
# うまくいかなければ URL の localhost → 127.0.0.1 に置換
(4) 完了後
- 使い終えたらトンネルを閉じる:
pkill -f 'ssh -N -L .*1455:127.0.0.1:1455' || true
4. エラーの「場所」を即断する(一次切り分け)
| どこで出た? | エラーメッセージ例 | よくある原因 | 見るべき場所 |
|---|---|---|---|
ローカルで ssh -L |
bind [127.0.0.1]:1455: Address already in use / cannot listen to port: 1455
|
ローカル1455が既に誰かに占有(既存の ssh -L、ローカル codex 等) |
ローカルで ss/lsof
|
リモートで codex login |
Error logging in: Port 127.0.0.1:1455 is already in use |
リモート1455を codex/sshd -R/残骸が占有 |
リモートで ss/lsof
|
| ブラウザ認証後も終わらない | (無反応) | コールバックがリモートに届いていない(トンネル未張り/宛先違い/IPv6) | トンネル確認、URLの 127.0.0.1 強制 |
まず どちら側の 1455 が詰まってるかを切り分けると、対処は一瞬で決まります。
5. トラブルシュート(実コマンド集)
5.1 ローカル側 1455 が埋まっている
症状:ssh -L 実行時に Address already in use など。
ローカルで実行
# だれが掴んでいる?
ss -lptn 'sport = :1455' || true
lsof -iTCP:1455 -sTCP:LISTEN -n -P || true
pgrep -af 'ssh -N -L .*1455:127.0.0.1:1455|codex' || true
# 掴んでいる ssh/codex を落とす
pkill -f 'ssh -N -L .*1455:127.0.0.1:1455' || true
pkill -f '^codex .*login' || true
# root が掴んでいそうなら確認して PID 指定で kill
sudo lsof -iTCP:1455 -sTCP:LISTEN -n -P
# → 表示された PID を sudo kill <PID>
再試行
ssh -fN -o ExitOnForwardFailure=yes \
-L 127.0.0.1:1455:127.0.0.1:1455 golgi
ss -lptn 'sport = :1455'
既存トンネルが目的のホスト向けなら、わざわざ落とさず“そのまま使う”のも手です。例:
ps -p <PID> -o pid,etimes,cmdで宛先がgolgiか確認。
5.2 リモート側 1455 が埋まっている
症状:codex login 側で Port 127.0.0.1:1455 is already in use。
リモート(golgi)で実行
ss -lptn 'sport = :1455'
sudo lsof -iTCP:1455 -sTCP:LISTEN -n -P
ps -ef | egrep 'ssh.* -R .*1455|codex|app-server' | grep -v egrep
# 安全速攻で掃除(誰が掴んでいても落とす)
sudo fuser -k 1455/tcp
for p in $(sudo lsof -tiTCP:1455 -sTCP:LISTEN); do
sudo kill -TERM "$p" || true; sleep 1; sudo kill -KILL "$p" || true
done
# 解放確認
ss -lptn 'sport = :1455' || true
sudo lsof -iTCP:1455 -sTCP:LISTEN -n -P || true
# 改めて
codex login
よくある犯人
- 以前の
codex loginが停止(Stopped)状態でポート保持。 - 昔打った **
ssh -R 127.0.0.1:1455:...(リバースフォワード)**の残骸。
5.3 宛先ホストの取り違え(ケーススタディ)
現象:ローカル 1455 は既に ssh が LISTEN しているが、そのトンネルの宛先が gvelox。本来は golgi に通したい。
対処(ローカル)
# どこ向きのトンネル?
ps -p <PID> -o pid,etimes,cmd --cols=200
cat /proc/<PID>/cmdline | tr '\0' ' '
# 宛先が違うなら落として作り直し
kill <PID> || true; sleep 1; kill -9 <PID> || true
ssh -fN -o ExitOnForwardFailure=yes -L 127.0.0.1:1455:127.0.0.1:1455 golgi
5.4 localhost でこける
現象:ブラウザで認証したのに codex が完了しない。
原因:localhost が ::1(IPv6)へ解決されトンネルに乗らないことがある。
対処:認証URLの localhost を 127.0.0.1 に置換して開く。
5.5 二重起動の罠
- 既にローカルにトンネルがあるのに、さらに
ssh -Lを起動すると**Address already in use**。 - 解決:既存トンネルを使うか、一旦落としてから張り直す。
5.6 JumpHost / 多段 SSH(必要なとき)
# 一発指定(ローカルで)
ssh -fN -o ExitOnForwardFailure=yes \
-J bastion \
-L 127.0.0.1:1455:127.0.0.1:1455 golgi
※ ~/.ssh/config に ProxyJump bastion を書いておけば -J 省略可。
5.7 tmux/screen や systemd/autossh の影響
- バックグラウンド化されたトンネルが無自覚に生き続けることがある。
pkill -f 'ssh -N -L .*1455:127.0.0.1:1455'で掃除。 -
autosshや systemd ユーザーサービスで自動復活していると、落としても再起動する。ps -o pid,ppid,cmd --forest -p <PID>で親プロセスを確認。
6. 疎通確認&デバッグ
ローカル
ss -lptn 'sport = :1455'
リモート(golgi)
ss -lptn 'sport = :1455'
トンネル越しの到達可否(ローカルから)
# リモートに 1455 のHTTPサーバ(codex)が立っていれば 200/302/404 等が返る
curl -i http://127.0.0.1:1455/ || true
7. 応用編
7.1 逆方向(リモートにブラウザ、ローカルに callback)
# ローカルで実行:リバースフォワード
ssh -N -R 127.0.0.1:1455:127.0.0.1:1455 golgi
7.2 ブラウザ→コピー→curl(GUIなしでも完了させる)
- リモートで
codex loginを実行し、URL を取得。 - ローカルで URL を開いて認証。
- ブラウザが開こうとする
http://localhost:1455/auth/callback?...を丸ごとコピー。 - リモートで:
curl -iL "http://localhost:1455/auth/callback?code=...&state=..."
これでトンネルなしでも完了できる(非常用)。
8. ワンライナー&エイリアス
一撃ログイン(標準)
# ターミナルA(ローカル)
ssh -fN -o ExitOnForwardFailure=yes -L 127.0.0.1:1455:127.0.0.1:1455 golgi
# ターミナルB(リモート)
ssh golgi && codex login
残骸掃除(ローカル)
( ss -lptn 'sport = :1455' || true ); \
( lsof -iTCP:1455 -sTCP:LISTEN -n -P || true ); \
( pkill -f 'ssh -N -L .*1455:127.0.0.1:1455' || true ); \
( pkill -f '^codex .*login' || true )
残骸掃除(リモート)
sudo fuser -k 1455/tcp; \
for p in $(sudo lsof -tiTCP:1455 -sTCP:LISTEN); do
sudo kill -TERM "$p" || true; sleep 1; sudo kill -KILL "$p" || true;
done
9. セキュリティ注意
-
バインドは 127.0.0.1 限定(
0.0.0.0で外部に晒さない)。 - 認可URL(
code,state等を含む)は第三者と共有しない。 - 終了後はトンネルを閉じる(
pkill -f ...)。
10. エラー辞典(クイックリファレンス)
| エラー | 原因 | 対処 |
|---|---|---|
bind [127.0.0.1]:1455: Address already in use |
ローカル 1455 が埋まっている | ローカルで ss/lsof → 掴んでる ssh/codex を kill → 再トンネル |
cannot listen to port: 1455 |
同上 | 同上 |
Error logging in: Port 127.0.0.1:1455 is already in use |
リモート 1455 が埋まっている | リモートで fuser -k 1455/tcp → codex login 再実行 |
| 認証後も完了しない | コールバックがリモートに届かない / IPv6 に流れている | トンネル確認、URL を 127.0.0.1 に、または 7.2 の curl 手法 |
| どのホストにトンネル張ってるか不明 | 宛先取り違え |
ps -p <PID> -o pid,etimes,cmd / /proc/<PID>/cmdline で確認 → 作り直し |
11. まとめ
- 原理:ブラウザの callback を SSH ローカルフォワードでローカル→リモートへ橋渡し。
-
実践:
ssh -L 127.0.0.1:1455:127.0.0.1:1455 golgi→ リモートでcodex login→ ローカルのブラウザで URL を開く。 -
詰まりポイント:1455 の占有(ローカル or リモート)、宛先ホスト取り違え、
localhostvs127.0.0.1、二重トンネル。 - 困ったら:本書 5章の掃除コマンドとチェックリストで5分以内に復旧できます。
Discussion