# SSH Infrastructure

Source-controlled SSH routing and configuration for multi-user jump infrastructure
(`is-jumper` gateway → J1/J2 company network → final hosts).

**⚠️ New to this project?** Start with [KEYS_AND_ACCESS.md](KEYS_AND_ACCESS.md) — it
explains which SSH key to use where, and how the access chain works.

## Quick Start

```bash
# 1. Access the local jump gateway
ssh is-jumper

# 2. From there, reach company network via J1 or J2
ssh j1              # or: ssh j2

# 3. From J1, reach final hosts
ssh porta-db        # automatic routing: local → is-jumper → J1 → porta-db
```

The `~/.ssh/config` is auto-generated from `inventory/hosts.yaml` — edit the
inventory, not the config file.

## File Structure

- **Project source**: `~/Documents/Workspaces/Bogdan/ssh-infrastructure`
- **OpenSSH runtime**: `~/.ssh` (do not commit)

Keep secrets and machine-local state out of version control:

- private keys: `~/.ssh/keys/` (not in git)
- `authorized_keys`, `known_hosts`, socket state (not in git)

Deploy the local runtime with:

```bash
# Regenerate ~/.ssh/config from inventory + install wrappers
tools/deploy-local.sh
```

## Version control

This directory is the git repository for source files only. Generated configs,
local state, keys, known hosts, and handoff notes stay out of version control.

Track source changes with:

```bash
git status
git add inventory schema scripts tools .doc README.md .gitignore
git commit
```

## SSH Key Management

Which key goes where? See [KEYS_AND_ACCESS.md](KEYS_AND_ACCESS.md) for the full matrix.

Migrate hosts from legacy RSA to modern ED25519:

```bash
# Migrate all legacy hosts
tools/migrate-modern-key.sh

# Migrate a specific host
tools/migrate-modern-key.sh is-baobab
```

Details: [docs/KEY_MIGRATION.md](docs/KEY_MIGRATION.md)

## Current client layout

```text
~/.ssh/config
~/.local/bin/ssh
~/.local/bin/scp
~/.local/bin/sftp
```

The wrapper sources stay versioned in `scripts/` inside the project; deploy
installs executable copies into `~/.local/bin` and removes the obsolete
`~/.ssh/scripts` runtime layout from older checkouts.

## Source of Truth

The structured source of truth starts in:

```text
inventory/hosts.yaml
schema/hosts.schema.json
tools/generate-configs.py
```

The `generated/*.conf` files are deploy artifacts. They are ignored by git and
can be recreated at any time with `tools/deploy-local.sh`.

## Inventory and Config Generation

The single source of truth:

```text
inventory/hosts.yaml         ← edit here to add/modify hosts
  ↓ (python3 tools/generate-configs.py)
generated/client.conf        ← deployed to ~/.ssh/config
generated/is-jumper.conf     ← deployed to is-jumper
generated/j1.conf            ← deployed to J1
generated/j2.conf            ← deployed to J2
```

### User and Port Defaults

| Context | User | Port | Notes |
| --- | --- | --- | --- |
| Jump hosts (J1, J2) | `bogdan.timofte` | `24` (standard) or `25904` (VPN) | override in inventory |
| Final hosts | `bogdan` | `22` | most systems; dotted usernames cause issues |
| Interactive auth (Cisco, OLTs) | varies | `22` | marked with `auth: password_interactive` |

### Deployment

```bash
# Option 1: Full deploy (recommended)
tools/deploy-local.sh

# Option 2: Manual steps
python3 tools/generate-configs.py           # Regenerate configs
cp generated/client.conf ~/.ssh/config      # Install client config
```

### Sync from Upstream

Pull latest `hosts.yaml` from nextgen and redeploy:

```bash
tools/sync-hosts-from-upstream.sh

# Customize:
DEPLOY_AFTER_SYNC=0 tools/sync-hosts-from-upstream.sh  # generate only
UPSTREAM_SSH_TARGET=user@host tools/sync-hosts-from-upstream.sh  # custom source
```
