Skip to content

ChatGPT iOS Codex SSH connection works on linux, but the bootstrap/proxy flow is fragile and hardcoded #23102

@92645417d9e5c763259dbebc306e3e

Description

What version of Codex CLI is running?

0.131.0-alpha.22, (iOS 1.2026.125)

What subscription do you have?

Plus

Which model were you using?

No response

What platform is your computer?

Linux 6.12.65-gentoo x86_64 AMD Ryzen 9 5950X 16-Core Processor

What terminal emulator and version are you using (if applicable)?

byobu

What issue are you seeing?

This is not a generic "cannot connect" report. I was able to get the ChatGPT iOS SSH-based Codex connection working against a Linux host, but only after working around several assumptions in the SSH bootstrap/proxy flow. The current flow appears usable, but fragile.

From server-side SSH logging, the iOS client appears to:

  1. Open a non-TTY SSH command and run a shell probe that discovers codex with command -v codex, checks codex --version, and prints uname -s.
  2. Try to use codex app-server proxy, or start codex app-server --listen "unix://" if no app server is available.
  3. For the final proxy step, connect directly to:
control_socket="${CODEX_HOME:-$HOME/.codex}/app-server-control/app-server-control.sock"
exec nc -U "$control_socket"

The connection can fail or hang for reasons that are hard to diagnose from the iOS UI:

  • Some Linux distributions ship a traditional nc that does not support -U. In that case the iOS app quickly reports a lost network connection, even though SSH and Codex are otherwise working.
  • The final proxy step hardcodes the default Unix socket path instead of using codex app-server proxy or a configured socket path. This makes non-default CODEX_HOME, low-privilege relay users, containers, jump hosts, and custom socket locations difficult.
  • The bootstrap probe uses an interactive/login shell path. User shell startup files that launch byobu/tmux, run clear, print menus, or emit other interactive output can corrupt the protocol or make the app spin forever.
  • Noninteractive SSH PATH may not include the user-installed codex, even when normal terminal SSH sessions work.
  • iOS currently reports broad messages such as waiting for Codex app / network connection lost, without exposing which bootstrap step failed.

What steps can reproduce the bug?

One reproducible failure mode on Linux:

  1. Install or use a Linux environment where nc exists but does not support Unix sockets via nc -U.
  2. Start or allow the iOS SSH connection flow to start a Codex app server on the Linux host.
  3. Connect from ChatGPT iOS using the Codex SSH connection flow.
  4. The SSH connection succeeds and the host can run codex, but the final proxy step fails when nc -U "$control_socket" is executed.

Another reproducible failure mode:

  1. Configure the SSH user shell startup to launch byobu/tmux, run clear, or print an interactive menu.
  2. Connect from ChatGPT iOS using the Codex SSH connection flow.
  3. The app may hang or fail because the command protocol receives unrelated shell output before the expected Codex probe/proxy output.

Workarounds that made the Linux connection usable:

  • Put codex somewhere visible to noninteractive SSH commands.
  • Suppress all shell startup output when SSH_ORIGINAL_COMMAND is set and no TTY is allocated.
  • Install an nc implementation with Unix socket support, such as OpenBSD netcat.
  • Use the same Unix user that owns the Codex app-server socket, because the default socket directory/file are user-private.

What is the expected behavior?

The SSH connection flow should be robust against common Linux environments and should report actionable bootstrap errors.

Specifically:

  • Prefer codex app-server proxy for the final proxy step, instead of directly requiring nc -U against a hardcoded socket path.
  • If a fallback is needed, detect support for nc -U explicitly, or support common alternatives such as ncat -U / socat.
  • Avoid requiring an interactive shell for command probing, or document/enforce that startup files must not emit output for the non-TTY command path.
  • Respect a configured or discoverable app-server socket path, rather than assuming ${CODEX_HOME:-$HOME/.codex}/app-server-control/app-server-control.sock in the iOS SSH script.
  • Surface the failing stage and stderr in the iOS UI, for example: codex not found, nc does not support -U, socket not found, permission denied, or unexpected shell output.

Additional information

This also affects safer deployment models. The iOS SSH UI currently appears to support username/password, but some users will want safer or more flexible options:

  • SSH private key support, including paste/import or system keychain integration.
  • Jump host / ProxyJump style support.
  • A way to set the command, CODEX_HOME, or app-server socket path explicitly.

The direct cloud remote-control path is separate from this SSH route. The SSH route is useful because it can work over a user's private network/VPN, but the current hardcoded final proxy step makes it hard to run through a restricted relay user or container without matching the default per-user socket path.

  • All of the above was accomplished with the help of the Codex CLI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    app-serverIssues involving app server protocol or interfacesbugSomething isn't workingconnectivityIssues involving networking or endpoint connectivity problems (disconnections)iOSIssues related to the Codex iOS appremote

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions