Skip to content

Commit 6283fad

Browse files
fix: remove ssh hardning
1 parent 9e50228 commit 6283fad

8 files changed

Lines changed: 36 additions & 271 deletions

File tree

.github/workflows/docker-rewind.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@ on:
1212
paths:
1313
- 'rewind/**'
1414
workflow_dispatch:
15-
inputs:
16-
api_url:
17-
description: 'API URL for web build'
18-
required: false
19-
default: 'https://10.0.70.70:8443'
2015

2116
env:
2217
REGISTRY: ghcr.io
@@ -109,7 +104,5 @@ jobs:
109104
push: ${{ github.event_name != 'pull_request' }}
110105
tags: ${{ steps.meta.outputs.tags }}
111106
labels: ${{ steps.meta.outputs.labels }}
112-
build-args: |
113-
VITE_API_URL=${{ github.event.inputs.api_url || 'https://10.0.70.70:8443' }}
114107
cache-from: type=gha,scope=rewind-web
115108
cache-to: type=gha,scope=rewind-web,mode=max

infra/claude-vms/configuration/group_vars/all.yml

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -23,65 +23,6 @@ os_security_kernel_module_loading: true
2323
os_auth_pw_max_age: 99999
2424
os_auth_pw_min_age: 0
2525

26-
# SSH Hardening Configuration (devsec.hardening.ssh_hardening)
27-
28-
# SSH authentication
29-
ssh_permit_root_login: "no"
30-
ssh_allow_users: "{{ dev_user }}"
31-
ssh_allow_agent_forwarding: true
32-
ssh_allow_tcp_forwarding: true
33-
34-
# Key-based auth only
35-
ssh_server_password_login: false
36-
ssh_challengeresponseauthentication: false
37-
38-
# Modern crypto settings for Ubuntu 24.04 / OpenSSH 9.x
39-
# Note: role uses ssh_kex, NOT ssh_kex_algorithms
40-
ssh_kex:
41-
- sntrup761x25519-sha512@openssh.com
42-
- curve25519-sha256
43-
- curve25519-sha256@libssh.org
44-
- diffie-hellman-group18-sha512
45-
- diffie-hellman-group16-sha512
46-
47-
ssh_ciphers:
48-
- chacha20-poly1305@openssh.com
49-
- aes256-gcm@openssh.com
50-
- aes128-gcm@openssh.com
51-
- aes256-ctr
52-
- aes192-ctr
53-
- aes128-ctr
54-
55-
ssh_macs:
56-
- hmac-sha2-512-etm@openssh.com
57-
- hmac-sha2-256-etm@openssh.com
58-
- umac-128-etm@openssh.com
59-
60-
# Host key algorithms for Ubuntu 24.04
61-
ssh_host_key_algorithms:
62-
- ssh-ed25519
63-
- rsa-sha2-512
64-
- rsa-sha2-256
65-
66-
# Client alive settings
67-
ssh_client_alive_interval: 300
68-
ssh_client_alive_count: 3
69-
70-
# Ubuntu 24.04 / OpenSSH 9.x compatibility settings
71-
ssh_use_pam: true # Required for proper auth on Ubuntu
72-
sftp_enabled: true # Enable SFTP (Ansible uses it by default)
73-
ssh_print_pam_motd: false # Disable duplicate MOTD
74-
ssh_print_last_log: true # Show last login info
75-
76-
# Don't regenerate host keys (can cause issues on Ubuntu 24.04)
77-
ssh_server_hardening: true
78-
sshd_moduli_minimum: 3072
79-
80-
# Disable the role's restart handler - we handle SSH reload manually in post_tasks
81-
# after validating the config. This prevents the handler failure on Ubuntu 24.04.
82-
# See: https://github.com/dev-sec/ansible-collection-hardening/issues/854
83-
ssh_server_enabled: false
84-
8526
# Development Environment Settings
8627

8728
# User for development (can be overridden via -e cloud_init_user=xxx)
@@ -152,5 +93,7 @@ plane_workspace_slug: "{{ lookup('env', 'PLANE_WORKSPACE_SLUG') | default('', tr
15293
plane_api_key: "{{ lookup('env', 'PLANE_API_KEY') | default('', true) }}"
15394

15495
# Rewind Configuration
155-
rewind_api_port: 8443 # External HTTPS port (Caddy)
156-
rewind_api_url: "https://{{ core_services_ip }}:{{ rewind_api_port }}"
96+
# Use the web external port (8444) which proxies /api to the API container
97+
# This avoids cross-origin issues with self-signed certs on separate ports
98+
rewind_web_port: 8444 # External HTTPS port for web (Caddy) - also serves /api
99+
rewind_api_url: "https://{{ core_services_ip }}:{{ rewind_web_port }}"

infra/claude-vms/configuration/playbook.yml

Lines changed: 0 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -35,67 +35,6 @@
3535
name: rsyslog
3636
state: present
3737

38-
- name: Ensure /run/sshd exists (required for ssh_hardening on Ubuntu 24.04)
39-
ansible.builtin.file:
40-
path: /run/sshd
41-
state: directory
42-
mode: '0755'
43-
owner: root
44-
group: root
45-
46-
# Ensure OpenSSH is updated before hardening (fixes socket-activation issues)
47-
# Minimum recommended version: 1:9.6p1-3ubuntu13.8
48-
# See: https://github.com/dev-sec/ansible-collection-hardening/issues/854
49-
- name: Update OpenSSH to latest version
50-
ansible.builtin.apt:
51-
name:
52-
- openssh-server
53-
- openssh-client
54-
state: latest
55-
56-
# Ubuntu 24.04 uses socket activation by default which conflicts with ssh_hardening
57-
# See: https://github.com/dev-sec/ansible-collection-hardening/issues/854
58-
# See: https://discourse.ubuntu.com/t/sshd-now-uses-socket-based-activation-ubuntu-22-10-and-later/30189
59-
#
60-
# Best practice approach from DevSec hardening:
61-
# 1. Remove all socket-related config files
62-
# 2. Stop, disable, and MASK ssh.socket (mask prevents any re-activation)
63-
# 3. Reload systemd
64-
# 4. Enable and start ssh.service
65-
66-
- name: Remove socket activation configuration files
67-
ansible.builtin.file:
68-
path: "{{ item }}"
69-
state: absent
70-
loop:
71-
- /etc/systemd/system/ssh.service.d/00-socket.conf
72-
- /etc/systemd/system/ssh.socket.d/addresses.conf
73-
- /etc/systemd/system/ssh.service.requires/ssh.socket
74-
- /etc/systemd/system/sockets.target.wants/ssh.socket
75-
76-
- name: Stop, disable and mask ssh.socket
77-
ansible.builtin.systemd:
78-
name: ssh.socket
79-
state: stopped
80-
enabled: false
81-
masked: true
82-
register: ssh_socket_result
83-
failed_when: false
84-
85-
- name: Log ssh.socket status if unexpected
86-
ansible.builtin.debug:
87-
msg: "Note: ssh.socket operation returned: {{ ssh_socket_result.msg | default('OK') }}"
88-
when: ssh_socket_result is failed
89-
90-
- name: Reload systemd daemon after socket config removal
91-
ansible.builtin.systemd:
92-
daemon_reload: true
93-
94-
- name: Enable and start traditional SSH service
95-
ansible.builtin.systemd:
96-
name: ssh.service
97-
enabled: true
98-
state: started
9938

10039
roles:
10140
# OS-level hardening (file permissions, kernel params, etc.)
@@ -612,140 +551,3 @@
612551
# Claude Code will auto-enable plugins when it starts
613552

614553

615-
# SSH hardening runs LAST to avoid connection issues blocking other tasks
616-
- name: Apply SSH hardening (final step)
617-
hosts: all
618-
become: true
619-
gather_facts: false
620-
tags: [hardening]
621-
622-
pre_tasks:
623-
- name: Ensure /run/sshd still exists
624-
ansible.builtin.file:
625-
path: /run/sshd
626-
state: directory
627-
mode: '0755'
628-
owner: root
629-
group: root
630-
631-
# Verify socket activation is still disabled before ssh_hardening runs
632-
- name: Verify ssh.socket is stopped, disabled and masked
633-
ansible.builtin.systemd:
634-
name: ssh.socket
635-
state: stopped
636-
enabled: false
637-
masked: true
638-
register: ssh_socket_verify_result
639-
failed_when: false
640-
641-
- name: Log ssh.socket verification status if unexpected
642-
ansible.builtin.debug:
643-
msg: "Note: ssh.socket verification returned: {{ ssh_socket_verify_result.msg | default('OK') }}"
644-
when: ssh_socket_verify_result is failed
645-
646-
# Remove any remaining socket activation config that may have been recreated
647-
- name: Remove socket activation configuration files (second pass)
648-
ansible.builtin.file:
649-
path: "{{ item }}"
650-
state: absent
651-
loop:
652-
- /etc/systemd/system/ssh.service.d/00-socket.conf
653-
- /etc/systemd/system/ssh.socket.d/addresses.conf
654-
- /etc/systemd/system/ssh.service.requires/ssh.socket
655-
656-
- name: Reload systemd daemon
657-
ansible.builtin.systemd:
658-
daemon_reload: true
659-
660-
# Check what's holding port 22 for debugging
661-
- name: Check what process is using port 22
662-
ansible.builtin.shell: ss -tlnp | grep ':22' || true
663-
register: port_22_check
664-
changed_when: false
665-
666-
- name: Display port 22 usage
667-
ansible.builtin.debug:
668-
msg: "Port 22 status: {{ port_22_check.stdout | default('Port 22 is free') }}"
669-
670-
# Test sshd config before attempting to start
671-
- name: Test sshd configuration validity before starting
672-
ansible.builtin.command: sshd -t
673-
register: sshd_pretest
674-
ignore_errors: true
675-
changed_when: false
676-
677-
- name: Display sshd config error if test failed
678-
ansible.builtin.debug:
679-
msg: "sshd -t failed: {{ sshd_pretest.stderr }}"
680-
when: sshd_pretest.rc != 0
681-
682-
- name: Fail if sshd config is invalid
683-
ansible.builtin.fail:
684-
msg: "sshd configuration is invalid. Check /etc/ssh/sshd_config. Error: {{ sshd_pretest.stderr }}"
685-
when: sshd_pretest.rc != 0
686-
687-
# Check if sshd is already running - if so, we don't need to start it
688-
- name: Check if sshd is already running
689-
ansible.builtin.shell: pgrep -x sshd > /dev/null && echo "running" || echo "stopped"
690-
register: sshd_running
691-
changed_when: false
692-
693-
- name: Display sshd status
694-
ansible.builtin.debug:
695-
msg: "sshd is {{ sshd_running.stdout }}"
696-
697-
# Only try to start if not already running
698-
- name: Start ssh.service if not running
699-
ansible.builtin.systemd:
700-
name: ssh.service
701-
state: started
702-
enabled: true
703-
when: sshd_running.stdout == "stopped"
704-
705-
roles:
706-
- role: devsec.hardening.ssh_hardening
707-
708-
post_tasks:
709-
# Test sshd config before attempting reload
710-
- name: Test sshd configuration validity
711-
ansible.builtin.command: sshd -t
712-
register: sshd_test
713-
ignore_errors: true
714-
changed_when: false
715-
716-
- name: Show sshd config test result
717-
ansible.builtin.debug:
718-
msg: "sshd -t output: {{ sshd_test.stderr | default('OK') }}"
719-
when: sshd_test.rc != 0
720-
721-
- name: Show generated sshd_config if test failed
722-
ansible.builtin.command: cat /etc/ssh/sshd_config
723-
register: sshd_config_content
724-
when: sshd_test.rc != 0
725-
changed_when: false
726-
727-
- name: Display sshd_config content
728-
ansible.builtin.debug:
729-
msg: "{{ sshd_config_content.stdout_lines }}"
730-
when: sshd_test.rc != 0 and sshd_config_content is defined
731-
732-
# Manually reload SSH since we disabled ssh_server_enabled to skip the role's handler
733-
# Try reload first, fall back to restart if reload fails (Ubuntu 24.04 quirk)
734-
- name: Reload SSH service to apply hardening config
735-
ansible.builtin.systemd:
736-
name: ssh
737-
state: reloaded
738-
when: sshd_test.rc == 0
739-
register: ssh_reload_result
740-
failed_when: false
741-
742-
- name: Restart SSH service if reload failed
743-
ansible.builtin.systemd:
744-
name: ssh
745-
state: restarted
746-
when: sshd_test.rc == 0 and ssh_reload_result is defined and ssh_reload_result.failed | default(false)
747-
748-
- name: Fail if sshd config is invalid
749-
ansible.builtin.fail:
750-
msg: "sshd configuration is invalid - SSH NOT reloaded. Fix config and retry."
751-
when: sshd_test.rc != 0

infra/core-services/configuration/files/Caddyfile.j2

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@
3737
{% if rewind_enabled | default(true) %}
3838
# Rewind API - external HTTPS port {{ rewind_api_external_port }} proxies to internal port {{ rewind_api_port }}
3939
{{ core_services_ip }}:{{ rewind_api_external_port }} {
40+
# Handle CORS preflight requests
41+
@cors_preflight method OPTIONS
42+
handle @cors_preflight {
43+
header Access-Control-Allow-Origin "{header.Origin}"
44+
header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
45+
header Access-Control-Allow-Headers "Content-Type, Authorization"
46+
header Access-Control-Allow-Credentials "true"
47+
header Access-Control-Max-Age "86400"
48+
respond "" 204
49+
}
50+
4051
reverse_proxy localhost:{{ rewind_api_port }}
4152

4253
encode gzip zstd
@@ -49,9 +60,10 @@
4960
header {
5061
Strict-Transport-Security "max-age=31536000; includeSubDomains"
5162
X-Content-Type-Options "nosniff"
52-
Access-Control-Allow-Origin "*"
53-
Access-Control-Allow-Methods "GET, POST, OPTIONS"
63+
Access-Control-Allow-Origin "{header.Origin}"
64+
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
5465
Access-Control-Allow-Headers "Content-Type, Authorization"
66+
Access-Control-Allow-Credentials "true"
5567
}
5668

5769
tls internal

marketplace

rewind/packages/web/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ FROM base AS builder
88
WORKDIR /app
99

1010
# Accept build arguments
11-
ARG VITE_API_URL=http://localhost:8429
11+
# Default to empty string - nginx proxies /api to the API container
12+
ARG VITE_API_URL=
1213

1314
# Copy workspace files
1415
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./

rewind/packages/web/app/lib/api-client.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type { Project, Conversation } from './types';
22

3-
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8429';
3+
// Use relative URL by default - nginx proxies /api to the API container
4+
// This eliminates cross-origin issues in production
5+
// VITE_API_URL can override for development or external API access
6+
const API_URL = import.meta.env.VITE_API_URL || '';
47

58
async function handleResponse<T>(response: Response, errorMessage: string): Promise<T> {
69
if (!response.ok) {

rewind/packages/web/nginx.conf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ server {
1010
gzip_min_length 1000;
1111
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json;
1212

13+
# API proxy - forward /api requests to the API container
14+
# This eliminates cross-origin issues when web and API are on different ports
15+
location /api/ {
16+
proxy_pass http://api:8429/api/;
17+
proxy_http_version 1.1;
18+
proxy_set_header Host $host;
19+
proxy_set_header X-Real-IP $remote_addr;
20+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
21+
proxy_set_header X-Forwarded-Proto $scheme;
22+
}
23+
1324
# SPA routing - serve index.html for all routes
1425
location / {
1526
try_files $uri $uri/ /index.html;

0 commit comments

Comments
 (0)