From c2cf0f86598bb4e7cf600b97b6abd4c94928654d Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Mon, 26 Oct 2026 11:07:00 -0600 Subject: [PATCH 1/2] Revert PHP2Shell workaround (#222), fixed in DDEV v1.25.5 DDEV v1.25.5 ships ddev-webserver images with fixed PHP, and the v0.6 image installs it, so the per-start Dockerfile.php2shell upgrade step is no longer needed. This reverts commit cd5e8997f48aa92245bb96088946cc1d2d97a38f. Co-Authored-By: Claude Opus 5.5 --- drupal-contrib/template.tf | 18 ------------------ drupal-core/template.tf | 18 ------------------ freeform/template.tf | 22 ---------------------- image/scripts/.gitignore_global | 1 - 4 files changed, 59 deletions(-) diff --git a/drupal-contrib/template.tf b/drupal-contrib/template.tf index 11b2580..31c1656 100644 --- a/drupal-contrib/template.tf +++ b/drupal-contrib/template.tf @@ -335,13 +335,6 @@ resource "coder_agent" "main" { grep -qxF 'config.coder.yaml' "$HOME/.gitignore_global" || \ echo 'config.coder.yaml' >> "$HOME/.gitignore_global" fi - # PHP2Shell workaround (written into the project's .ddev/web-build below). - # Outside the if/elif so a fresh copy from an older image also gets it. - # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. - if [ -f "$HOME/.gitignore_global" ]; then - grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ - echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" - fi if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" fi @@ -629,17 +622,6 @@ hooks: - exec-host: 'echo "" && echo " Site: https://drupal-site--$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}.$CODER_DOMAIN" && echo " Mailpit: https://mailpit--$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}.$CODER_DOMAIN" && echo ""' CODER_YAML_EOF - # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in the web image - # until DDEV v1.25.5 ships a fixed ddev-webserver. Remove after that upgrade. - # https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ - mkdir -p .ddev/web-build - cat > .ddev/web-build/Dockerfile.php2shell << 'PHP2SHELL_EOF' -# Auto-generated by coder-ddev workspace startup -- do not edit. -# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. -RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' -PHP2SHELL_EOF - log_setup "✓ .ddev/web-build/Dockerfile.php2shell written (PHP2Shell fix)" - # For themes, set symlink target path via config.local.yaml if [ "$PROJECT_TYPE" = "theme" ]; then cat > .ddev/config.local.yaml << 'THEME_YAML_EOF' diff --git a/drupal-core/template.tf b/drupal-core/template.tf index 623a461..87cbe25 100644 --- a/drupal-core/template.tf +++ b/drupal-core/template.tf @@ -396,13 +396,6 @@ resource "coder_agent" "main" { grep -qxF 'config.zzz-coder-test-env.yaml' "$HOME/.gitignore_global" || \ echo 'config.zzz-coder-test-env.yaml' >> "$HOME/.gitignore_global" fi - # PHP2Shell workaround (written into the project's .ddev/web-build below). - # Outside the if/elif so a fresh copy from an older image also gets it. - # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. - if [ -f "$HOME/.gitignore_global" ]; then - grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ - echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" - fi if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" fi @@ -718,17 +711,6 @@ hooks: CODER_YAML_EOF log_setup "✓ .ddev/config.coder.yaml written" - # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in the web image - # until DDEV v1.25.5 ships a fixed ddev-webserver. Remove after that upgrade. - # https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ - mkdir -p .ddev/web-build - cat > .ddev/web-build/Dockerfile.php2shell << 'PHP2SHELL_EOF' -# Auto-generated by coder-ddev workspace startup -- do not edit. -# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. -RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' -PHP2SHELL_EOF - log_setup "✓ .ddev/web-build/Dockerfile.php2shell written (PHP2Shell fix)" - if ddev config --project-type="$DDEV_PROJECT_TYPE" $DDEV_DOCROOT_ARG --project-name="$${CODER_WORKSPACE_NAME}--$${CODER_WORKSPACE_OWNER_NAME}" >> "$SETUP_LOG" 2>&1; then log_setup "✓ DDEV configured (project-type=$DDEV_PROJECT_TYPE)" update_status "✓ DDEV config: Success" diff --git a/freeform/template.tf b/freeform/template.tf index 76bc52e..6efcd8b 100644 --- a/freeform/template.tf +++ b/freeform/template.tf @@ -247,13 +247,6 @@ resource "coder_agent" "main" { grep -qxF 'config.coder.yaml' "$HOME/.gitignore_global" || \ echo 'config.coder.yaml' >> "$HOME/.gitignore_global" fi - # PHP2Shell workaround (written into each project's .ddev/web-build below). - # Outside the if/elif so a fresh copy from an older image also gets it. - # Remove together with the Dockerfile.php2shell step after DDEV v1.25.5. - if [ -f "$HOME/.gitignore_global" ]; then - grep -qxF 'Dockerfile.php2shell' "$HOME/.gitignore_global" || \ - echo 'Dockerfile.php2shell' >> "$HOME/.gitignore_global" - fi mkdir -p ~/.ddev if [ -n "$CODER_WORKSPACE_OWNER_NAME" ]; then git config --global user.name "$CODER_WORKSPACE_OWNER_NAME" @@ -310,21 +303,6 @@ resource "coder_agent" "main" { tail -20 /tmp/ddev-download-images.log || true fi - # PHP2Shell (CVE-2026-109618/CVE-2026-109619): upgrade PHP in every known - # project's web image until DDEV v1.25.5 ships a fixed ddev-webserver. Takes - # effect on each project's next `ddev start`/`ddev restart`. Remove after - # that upgrade. https://ddev.com/blog/php2shell-what-ddev-users-need-to-know/ - ddev list -j 2>/dev/null | jq -r '.raw[]?.approot // empty' 2>/dev/null | while read -r _root; do - [ -d "$_root/.ddev" ] || continue - mkdir -p "$_root/.ddev/web-build" - cat > "$_root/.ddev/web-build/Dockerfile.php2shell" << 'PHP2SHELL_EOF' -# Auto-generated by coder-ddev workspace startup -- do not edit. -# PHP2Shell fix; safe to delete after upgrading to DDEV v1.25.5. -RUN (apt-get update || true) && apt-get install -y --only-upgrade 'php*' -PHP2SHELL_EOF - echo "✓ PHP2Shell fix written: $_root/.ddev/web-build/Dockerfile.php2shell" - done - # Ensure yq and linuxbrew are in PATH for this session export PATH="$PATH:/home/linuxbrew/.linuxbrew/bin" diff --git a/image/scripts/.gitignore_global b/image/scripts/.gitignore_global index 7bfafcb..1930893 100644 --- a/image/scripts/.gitignore_global +++ b/image/scripts/.gitignore_global @@ -1,7 +1,6 @@ # DDEV Coder integration config.coder.yaml config.zzz-coder-test-env.yaml -Dockerfile.php2shell # macOS .DS_Store From bc65c222f7df21b1d145de5499edba898b01d0db Mon Sep 17 00:00:00 2001 From: Randy Fay Date: Mon, 26 Oct 2026 11:12:36 -0600 Subject: [PATCH 2/2] feat: SSH agent relay for DDEV containers, Coder key in an agent, fixes #220, fixes #210 DDEV's containers couldn't use the Coder key or the user's forwarded agent, and a forwarded agent's socket dies on every VS Code reconnect. DDEV v1.25.5 adds ssh_agent_upstream and resolves symlinked sockets. - Image (v0.6, DDEV v1.25.5): add socat, fzf, zstd, and ship ssh-agent-relay/connect and bashrc.sh in /home/coder-files. - shared/ssh-agent-setup.sh (vendored by make sync-ssh-agent-setup, included in all three startup scripts): - loads the Coder key into ssh-agent at ~/.coder-ssh-agent/agent.sock - runs a socat relay at ~/.ssh-agent-relay/agent.sock that, per connection, uses the first live agent of: the most recent shell's forwarded agent (current), the newest /tmp/auth-agent*/listener.sock, the Coder-key agent - sets ddev ssh_agent_upstream to the relay socket - sources bashrc.sh from ~/.bashrc, which retargets current from shells with a live forwarded agent and points SSH_AUTH_SOCK at the relay - Liveness checks use timeout 2 ssh-add -l (exit 0/1 = live). - OpenSpec change add-ssh-agent-relay, user docs, template tests. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 +- Makefile | 9 +++- VERSION | 2 +- docs/user/using-workspaces.md | 22 +++++++++ drupal-contrib/ssh-agent-setup.sh | 49 +++++++++++++++++++ drupal-contrib/template.tf | 2 + drupal-contrib/tests/validate.tftest.hcl | 12 +++++ drupal-core/ssh-agent-setup.sh | 49 +++++++++++++++++++ drupal-core/template.tf | 2 + drupal-core/tests/validate.tftest.hcl | 15 ++++++ freeform/ssh-agent-setup.sh | 49 +++++++++++++++++++ freeform/template.tf | 2 + freeform/tests/validate.tftest.hcl | 12 +++++ image/Dockerfile | 9 +++- image/scripts/ssh-agent-relay/bashrc.sh | 28 +++++++++++ image/scripts/ssh-agent-relay/connect | 37 ++++++++++++++ .../changes/add-ssh-agent-relay/proposal.md | 23 +++++++++ .../specs/workspace-ssh-agent/spec.md | 31 ++++++++++++ openspec/changes/add-ssh-agent-relay/tasks.md | 12 +++++ shared/ssh-agent-setup.sh | 49 +++++++++++++++++++ 20 files changed, 411 insertions(+), 5 deletions(-) create mode 100644 drupal-contrib/ssh-agent-setup.sh create mode 100644 drupal-core/ssh-agent-setup.sh create mode 100644 freeform/ssh-agent-setup.sh create mode 100644 image/scripts/ssh-agent-relay/bashrc.sh create mode 100644 image/scripts/ssh-agent-relay/connect create mode 100644 openspec/changes/add-ssh-agent-relay/proposal.md create mode 100644 openspec/changes/add-ssh-agent-relay/specs/workspace-ssh-agent/spec.md create mode 100644 openspec/changes/add-ssh-agent-relay/tasks.md create mode 100644 shared/ssh-agent-setup.sh diff --git a/CLAUDE.md b/CLAUDE.md index dc0122f..4c3cff1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -79,7 +79,7 @@ make test-templates ## Shared Terraform Assets -Some Terraform config (currently `modules/claude-remote-control` and `shared/vscode-extensions.tf`) is shared across all three templates but must exist as a **physical copy inside each template directory** — `coder templates push` and CI's `terraform validate`/`test` only ever operate on a single template directory, so a relative `../modules` or `../shared` reference would not survive the push and would not be visible to CI. +Some Terraform config (currently `modules/claude-remote-control`, `modules/docker-daemon`, `shared/vscode-extensions.tf`, `shared/bashrc-symlink-guard.sh` and `shared/ssh-agent-setup.sh`) is shared across all three templates but must exist as a **physical copy inside each template directory** — `coder templates push` and CI's `terraform validate`/`test` only ever operate on a single template directory, so a relative `../modules` or `../shared` reference would not survive the push and would not be visible to CI. - **Edit only the canonical source**: `modules/claude-remote-control/` or `shared/vscode-extensions.tf` at the repo root. Never hand-edit the vendored copies (`