claude-autopm 2.8.1 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -8
- package/bin/autopm.js +2 -0
- package/bin/commands/plugin.js +395 -0
- package/bin/commands/team.js +184 -10
- package/install/install.js +223 -4
- package/lib/plugins/PluginManager.js +1328 -0
- package/lib/plugins/PluginManager.old.js +400 -0
- package/package.json +4 -1
- package/scripts/publish-plugins.sh +166 -0
- package/autopm/.claude/agents/cloud/README.md +0 -55
- package/autopm/.claude/agents/cloud/aws-cloud-architect.md +0 -521
- package/autopm/.claude/agents/cloud/azure-cloud-architect.md +0 -436
- package/autopm/.claude/agents/cloud/gcp-cloud-architect.md +0 -385
- package/autopm/.claude/agents/cloud/gcp-cloud-functions-engineer.md +0 -306
- package/autopm/.claude/agents/cloud/gemini-api-expert.md +0 -880
- package/autopm/.claude/agents/cloud/kubernetes-orchestrator.md +0 -566
- package/autopm/.claude/agents/cloud/openai-python-expert.md +0 -1087
- package/autopm/.claude/agents/cloud/terraform-infrastructure-expert.md +0 -454
- package/autopm/.claude/agents/core/agent-manager.md +0 -296
- package/autopm/.claude/agents/core/code-analyzer.md +0 -131
- package/autopm/.claude/agents/core/file-analyzer.md +0 -162
- package/autopm/.claude/agents/core/test-runner.md +0 -200
- package/autopm/.claude/agents/data/airflow-orchestration-expert.md +0 -52
- package/autopm/.claude/agents/data/kedro-pipeline-expert.md +0 -50
- package/autopm/.claude/agents/data/langgraph-workflow-expert.md +0 -520
- package/autopm/.claude/agents/databases/README.md +0 -50
- package/autopm/.claude/agents/databases/bigquery-expert.md +0 -392
- package/autopm/.claude/agents/databases/cosmosdb-expert.md +0 -368
- package/autopm/.claude/agents/databases/mongodb-expert.md +0 -398
- package/autopm/.claude/agents/databases/postgresql-expert.md +0 -321
- package/autopm/.claude/agents/databases/redis-expert.md +0 -52
- package/autopm/.claude/agents/devops/README.md +0 -52
- package/autopm/.claude/agents/devops/azure-devops-specialist.md +0 -308
- package/autopm/.claude/agents/devops/docker-containerization-expert.md +0 -298
- package/autopm/.claude/agents/devops/github-operations-specialist.md +0 -335
- package/autopm/.claude/agents/devops/mcp-context-manager.md +0 -319
- package/autopm/.claude/agents/devops/observability-engineer.md +0 -574
- package/autopm/.claude/agents/devops/ssh-operations-expert.md +0 -1093
- package/autopm/.claude/agents/devops/traefik-proxy-expert.md +0 -444
- package/autopm/.claude/agents/frameworks/README.md +0 -64
- package/autopm/.claude/agents/frameworks/e2e-test-engineer.md +0 -360
- package/autopm/.claude/agents/frameworks/nats-messaging-expert.md +0 -254
- package/autopm/.claude/agents/frameworks/react-frontend-engineer.md +0 -217
- package/autopm/.claude/agents/frameworks/react-ui-expert.md +0 -226
- package/autopm/.claude/agents/frameworks/tailwindcss-expert.md +0 -770
- package/autopm/.claude/agents/frameworks/ux-design-expert.md +0 -244
- package/autopm/.claude/agents/integration/message-queue-engineer.md +0 -794
- package/autopm/.claude/agents/languages/README.md +0 -50
- package/autopm/.claude/agents/languages/bash-scripting-expert.md +0 -541
- package/autopm/.claude/agents/languages/javascript-frontend-engineer.md +0 -197
- package/autopm/.claude/agents/languages/nodejs-backend-engineer.md +0 -226
- package/autopm/.claude/agents/languages/python-backend-engineer.md +0 -214
- package/autopm/.claude/agents/languages/python-backend-expert.md +0 -289
- package/autopm/.claude/agents/testing/frontend-testing-engineer.md +0 -395
- package/autopm/.claude/commands/ai/langgraph-workflow.md +0 -65
- package/autopm/.claude/commands/ai/openai-chat.md +0 -65
- package/autopm/.claude/commands/azure/COMMANDS.md +0 -107
- package/autopm/.claude/commands/azure/COMMAND_MAPPING.md +0 -252
- package/autopm/.claude/commands/azure/INTEGRATION_FIX.md +0 -103
- package/autopm/.claude/commands/azure/README.md +0 -246
- package/autopm/.claude/commands/azure/active-work.md +0 -198
- package/autopm/.claude/commands/azure/aliases.md +0 -143
- package/autopm/.claude/commands/azure/blocked-items.md +0 -287
- package/autopm/.claude/commands/azure/clean.md +0 -93
- package/autopm/.claude/commands/azure/docs-query.md +0 -48
- package/autopm/.claude/commands/azure/feature-decompose.md +0 -380
- package/autopm/.claude/commands/azure/feature-list.md +0 -61
- package/autopm/.claude/commands/azure/feature-new.md +0 -115
- package/autopm/.claude/commands/azure/feature-show.md +0 -205
- package/autopm/.claude/commands/azure/feature-start.md +0 -130
- package/autopm/.claude/commands/azure/fix-integration-example.md +0 -93
- package/autopm/.claude/commands/azure/help.md +0 -150
- package/autopm/.claude/commands/azure/import-us.md +0 -269
- package/autopm/.claude/commands/azure/init.md +0 -211
- package/autopm/.claude/commands/azure/next-task.md +0 -262
- package/autopm/.claude/commands/azure/search.md +0 -160
- package/autopm/.claude/commands/azure/sprint-status.md +0 -235
- package/autopm/.claude/commands/azure/standup.md +0 -260
- package/autopm/.claude/commands/azure/sync-all.md +0 -99
- package/autopm/.claude/commands/azure/task-analyze.md +0 -186
- package/autopm/.claude/commands/azure/task-close.md +0 -329
- package/autopm/.claude/commands/azure/task-edit.md +0 -145
- package/autopm/.claude/commands/azure/task-list.md +0 -263
- package/autopm/.claude/commands/azure/task-new.md +0 -84
- package/autopm/.claude/commands/azure/task-reopen.md +0 -79
- package/autopm/.claude/commands/azure/task-show.md +0 -126
- package/autopm/.claude/commands/azure/task-start.md +0 -301
- package/autopm/.claude/commands/azure/task-status.md +0 -65
- package/autopm/.claude/commands/azure/task-sync.md +0 -67
- package/autopm/.claude/commands/azure/us-edit.md +0 -164
- package/autopm/.claude/commands/azure/us-list.md +0 -202
- package/autopm/.claude/commands/azure/us-new.md +0 -265
- package/autopm/.claude/commands/azure/us-parse.md +0 -253
- package/autopm/.claude/commands/azure/us-show.md +0 -188
- package/autopm/.claude/commands/azure/us-status.md +0 -320
- package/autopm/.claude/commands/azure/validate.md +0 -86
- package/autopm/.claude/commands/azure/work-item-sync.md +0 -47
- package/autopm/.claude/commands/cloud/infra-deploy.md +0 -38
- package/autopm/.claude/commands/github/workflow-create.md +0 -42
- package/autopm/.claude/commands/infrastructure/ssh-security.md +0 -65
- package/autopm/.claude/commands/infrastructure/traefik-setup.md +0 -65
- package/autopm/.claude/commands/kubernetes/deploy.md +0 -37
- package/autopm/.claude/commands/playwright/test-scaffold.md +0 -38
- package/autopm/.claude/commands/pm/blocked.md +0 -28
- package/autopm/.claude/commands/pm/clean.md +0 -119
- package/autopm/.claude/commands/pm/context-create.md +0 -136
- package/autopm/.claude/commands/pm/context-prime.md +0 -170
- package/autopm/.claude/commands/pm/context-update.md +0 -292
- package/autopm/.claude/commands/pm/context.md +0 -28
- package/autopm/.claude/commands/pm/epic-close.md +0 -86
- package/autopm/.claude/commands/pm/epic-decompose.md +0 -370
- package/autopm/.claude/commands/pm/epic-edit.md +0 -83
- package/autopm/.claude/commands/pm/epic-list.md +0 -30
- package/autopm/.claude/commands/pm/epic-merge.md +0 -222
- package/autopm/.claude/commands/pm/epic-oneshot.md +0 -119
- package/autopm/.claude/commands/pm/epic-refresh.md +0 -119
- package/autopm/.claude/commands/pm/epic-show.md +0 -28
- package/autopm/.claude/commands/pm/epic-split.md +0 -120
- package/autopm/.claude/commands/pm/epic-start.md +0 -195
- package/autopm/.claude/commands/pm/epic-status.md +0 -28
- package/autopm/.claude/commands/pm/epic-sync-modular.md +0 -338
- package/autopm/.claude/commands/pm/epic-sync-original.md +0 -473
- package/autopm/.claude/commands/pm/epic-sync.md +0 -486
- package/autopm/.claude/commands/pm/help.md +0 -28
- package/autopm/.claude/commands/pm/import.md +0 -115
- package/autopm/.claude/commands/pm/in-progress.md +0 -28
- package/autopm/.claude/commands/pm/init.md +0 -28
- package/autopm/.claude/commands/pm/issue-analyze.md +0 -202
- package/autopm/.claude/commands/pm/issue-close.md +0 -119
- package/autopm/.claude/commands/pm/issue-edit.md +0 -93
- package/autopm/.claude/commands/pm/issue-reopen.md +0 -87
- package/autopm/.claude/commands/pm/issue-show.md +0 -41
- package/autopm/.claude/commands/pm/issue-start.md +0 -234
- package/autopm/.claude/commands/pm/issue-status.md +0 -95
- package/autopm/.claude/commands/pm/issue-sync.md +0 -411
- package/autopm/.claude/commands/pm/next.md +0 -28
- package/autopm/.claude/commands/pm/prd-edit.md +0 -82
- package/autopm/.claude/commands/pm/prd-list.md +0 -28
- package/autopm/.claude/commands/pm/prd-new.md +0 -55
- package/autopm/.claude/commands/pm/prd-parse.md +0 -42
- package/autopm/.claude/commands/pm/prd-status.md +0 -28
- package/autopm/.claude/commands/pm/search.md +0 -28
- package/autopm/.claude/commands/pm/standup.md +0 -28
- package/autopm/.claude/commands/pm/status.md +0 -28
- package/autopm/.claude/commands/pm/sync.md +0 -99
- package/autopm/.claude/commands/pm/test-reference-update.md +0 -151
- package/autopm/.claude/commands/pm/validate.md +0 -28
- package/autopm/.claude/commands/pm/what-next.md +0 -28
- package/autopm/.claude/commands/python/api-scaffold.md +0 -50
- package/autopm/.claude/commands/python/docs-query.md +0 -48
- package/autopm/.claude/commands/react/app-scaffold.md +0 -50
- package/autopm/.claude/commands/testing/prime.md +0 -314
- package/autopm/.claude/commands/testing/run.md +0 -125
- package/autopm/.claude/commands/ui/bootstrap-scaffold.md +0 -65
- package/autopm/.claude/commands/ui/tailwind-system.md +0 -64
- package/autopm/.claude/rules/ai-integration-patterns.md +0 -219
- package/autopm/.claude/rules/ci-cd-kubernetes-strategy.md +0 -25
- package/autopm/.claude/rules/database-management-strategy.md +0 -17
- package/autopm/.claude/rules/database-pipeline.md +0 -94
- package/autopm/.claude/rules/devops-troubleshooting-playbook.md +0 -450
- package/autopm/.claude/rules/docker-first-development.md +0 -404
- package/autopm/.claude/rules/infrastructure-pipeline.md +0 -128
- package/autopm/.claude/rules/performance-guidelines.md +0 -403
- package/autopm/.claude/rules/ui-development-standards.md +0 -281
- package/autopm/.claude/rules/ui-framework-rules.md +0 -151
- package/autopm/.claude/rules/ux-design-rules.md +0 -209
- package/autopm/.claude/rules/visual-testing.md +0 -223
- package/autopm/.claude/scripts/azure/README.md +0 -192
- package/autopm/.claude/scripts/azure/active-work.js +0 -524
- package/autopm/.claude/scripts/azure/active-work.sh +0 -20
- package/autopm/.claude/scripts/azure/blocked.js +0 -520
- package/autopm/.claude/scripts/azure/blocked.sh +0 -20
- package/autopm/.claude/scripts/azure/daily.js +0 -533
- package/autopm/.claude/scripts/azure/daily.sh +0 -20
- package/autopm/.claude/scripts/azure/dashboard.js +0 -970
- package/autopm/.claude/scripts/azure/dashboard.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-list.js +0 -254
- package/autopm/.claude/scripts/azure/feature-list.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-show.js +0 -7
- package/autopm/.claude/scripts/azure/feature-show.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-status.js +0 -604
- package/autopm/.claude/scripts/azure/feature-status.sh +0 -20
- package/autopm/.claude/scripts/azure/help.js +0 -342
- package/autopm/.claude/scripts/azure/help.sh +0 -20
- package/autopm/.claude/scripts/azure/next-task.js +0 -508
- package/autopm/.claude/scripts/azure/next-task.sh +0 -20
- package/autopm/.claude/scripts/azure/search.js +0 -469
- package/autopm/.claude/scripts/azure/search.sh +0 -20
- package/autopm/.claude/scripts/azure/setup.js +0 -745
- package/autopm/.claude/scripts/azure/setup.sh +0 -20
- package/autopm/.claude/scripts/azure/sprint-report.js +0 -1012
- package/autopm/.claude/scripts/azure/sprint-report.sh +0 -20
- package/autopm/.claude/scripts/azure/sync.js +0 -563
- package/autopm/.claude/scripts/azure/sync.sh +0 -20
- package/autopm/.claude/scripts/azure/us-list.js +0 -210
- package/autopm/.claude/scripts/azure/us-list.sh +0 -20
- package/autopm/.claude/scripts/azure/us-status.js +0 -238
- package/autopm/.claude/scripts/azure/us-status.sh +0 -20
- package/autopm/.claude/scripts/azure/validate.js +0 -626
- package/autopm/.claude/scripts/azure/validate.sh +0 -20
- package/autopm/.claude/scripts/azure/wrapper-template.sh +0 -20
- package/autopm/.claude/scripts/github/dependency-tracker.js +0 -554
- package/autopm/.claude/scripts/github/dependency-validator.js +0 -545
- package/autopm/.claude/scripts/github/dependency-visualizer.js +0 -477
- package/autopm/.claude/scripts/pm/analytics.js +0 -425
- package/autopm/.claude/scripts/pm/blocked.js +0 -164
- package/autopm/.claude/scripts/pm/blocked.sh +0 -78
- package/autopm/.claude/scripts/pm/clean.js +0 -464
- package/autopm/.claude/scripts/pm/context-create.js +0 -216
- package/autopm/.claude/scripts/pm/context-prime.js +0 -335
- package/autopm/.claude/scripts/pm/context-update.js +0 -344
- package/autopm/.claude/scripts/pm/context.js +0 -338
- package/autopm/.claude/scripts/pm/epic-close.js +0 -347
- package/autopm/.claude/scripts/pm/epic-edit.js +0 -382
- package/autopm/.claude/scripts/pm/epic-list.js +0 -273
- package/autopm/.claude/scripts/pm/epic-list.sh +0 -109
- package/autopm/.claude/scripts/pm/epic-show.js +0 -291
- package/autopm/.claude/scripts/pm/epic-show.sh +0 -105
- package/autopm/.claude/scripts/pm/epic-split.js +0 -522
- package/autopm/.claude/scripts/pm/epic-start/epic-start.js +0 -183
- package/autopm/.claude/scripts/pm/epic-start/epic-start.sh +0 -94
- package/autopm/.claude/scripts/pm/epic-status.js +0 -291
- package/autopm/.claude/scripts/pm/epic-status.sh +0 -104
- package/autopm/.claude/scripts/pm/epic-sync/README.md +0 -208
- package/autopm/.claude/scripts/pm/epic-sync/create-epic-issue.sh +0 -77
- package/autopm/.claude/scripts/pm/epic-sync/create-task-issues.sh +0 -86
- package/autopm/.claude/scripts/pm/epic-sync/update-epic-file.sh +0 -79
- package/autopm/.claude/scripts/pm/epic-sync/update-references.sh +0 -89
- package/autopm/.claude/scripts/pm/epic-sync.sh +0 -137
- package/autopm/.claude/scripts/pm/help.js +0 -92
- package/autopm/.claude/scripts/pm/help.sh +0 -90
- package/autopm/.claude/scripts/pm/in-progress.js +0 -178
- package/autopm/.claude/scripts/pm/in-progress.sh +0 -93
- package/autopm/.claude/scripts/pm/init.js +0 -321
- package/autopm/.claude/scripts/pm/init.sh +0 -178
- package/autopm/.claude/scripts/pm/issue-close.js +0 -232
- package/autopm/.claude/scripts/pm/issue-edit.js +0 -310
- package/autopm/.claude/scripts/pm/issue-show.js +0 -272
- package/autopm/.claude/scripts/pm/issue-start.js +0 -181
- package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +0 -468
- package/autopm/.claude/scripts/pm/issue-sync/gather-updates.sh +0 -460
- package/autopm/.claude/scripts/pm/issue-sync/post-comment.sh +0 -330
- package/autopm/.claude/scripts/pm/issue-sync/preflight-validation.sh +0 -348
- package/autopm/.claude/scripts/pm/issue-sync/update-frontmatter.sh +0 -387
- package/autopm/.claude/scripts/pm/lib/README.md +0 -85
- package/autopm/.claude/scripts/pm/lib/epic-discovery.js +0 -119
- package/autopm/.claude/scripts/pm/lib/logger.js +0 -78
- package/autopm/.claude/scripts/pm/next.js +0 -189
- package/autopm/.claude/scripts/pm/next.sh +0 -72
- package/autopm/.claude/scripts/pm/optimize.js +0 -407
- package/autopm/.claude/scripts/pm/pr-create.js +0 -337
- package/autopm/.claude/scripts/pm/pr-list.js +0 -257
- package/autopm/.claude/scripts/pm/prd-list.js +0 -242
- package/autopm/.claude/scripts/pm/prd-list.sh +0 -103
- package/autopm/.claude/scripts/pm/prd-new.js +0 -684
- package/autopm/.claude/scripts/pm/prd-parse.js +0 -547
- package/autopm/.claude/scripts/pm/prd-status.js +0 -152
- package/autopm/.claude/scripts/pm/prd-status.sh +0 -63
- package/autopm/.claude/scripts/pm/release.js +0 -460
- package/autopm/.claude/scripts/pm/search.js +0 -192
- package/autopm/.claude/scripts/pm/search.sh +0 -89
- package/autopm/.claude/scripts/pm/standup.js +0 -362
- package/autopm/.claude/scripts/pm/standup.sh +0 -95
- package/autopm/.claude/scripts/pm/status.js +0 -148
- package/autopm/.claude/scripts/pm/status.sh +0 -59
- package/autopm/.claude/scripts/pm/sync-batch.js +0 -337
- package/autopm/.claude/scripts/pm/sync.js +0 -343
- package/autopm/.claude/scripts/pm/template-list.js +0 -141
- package/autopm/.claude/scripts/pm/template-new.js +0 -366
- package/autopm/.claude/scripts/pm/validate.js +0 -274
- package/autopm/.claude/scripts/pm/validate.sh +0 -106
- package/autopm/.claude/scripts/pm/what-next.js +0 -660
- package/bin/node/azure-feature-show.js +0 -7
|
@@ -1,1093 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ssh-operations-expert
|
|
3
|
-
description: Use this agent for SSH operations including remote server management, secure connections, key management, and automation. Expert in SSH configurations, tunneling, port forwarding, and security best practices. Perfect for DevOps workflows, remote administration, and secure infrastructure management.
|
|
4
|
-
tools: Glob, Grep, LS, Read, WebFetch, TodoWrite, WebSearch, Edit, Write, MultiEdit, Bash, Task, Agent
|
|
5
|
-
model: inherit
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# SSH Operations Expert Agent
|
|
9
|
-
|
|
10
|
-
## Test-Driven Development (TDD) Methodology
|
|
11
|
-
|
|
12
|
-
**MANDATORY**: Follow strict TDD principles for all development:
|
|
13
|
-
1. **Write failing tests FIRST** - Before implementing any functionality
|
|
14
|
-
2. **Red-Green-Refactor cycle** - Test fails → Make it pass → Improve code
|
|
15
|
-
3. **One test at a time** - Focus on small, incremental development
|
|
16
|
-
4. **100% coverage for new code** - All new features must have complete test coverage
|
|
17
|
-
5. **Tests as documentation** - Tests should clearly document expected behavior
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
You are an SSH specialist focused on secure remote server management and automation. Your mission is to implement robust, secure SSH workflows for infrastructure management, deployment automation, and remote administration.
|
|
21
|
-
|
|
22
|
-
## Core Responsibilities
|
|
23
|
-
|
|
24
|
-
1. **SSH Configuration Management**
|
|
25
|
-
- Create and manage SSH client/server configurations
|
|
26
|
-
- Implement security hardening and best practices
|
|
27
|
-
- Set up SSH key-based authentication
|
|
28
|
-
- Configure connection multiplexing and optimization
|
|
29
|
-
|
|
30
|
-
2. **Key Management and Security**
|
|
31
|
-
- Generate and manage SSH key pairs
|
|
32
|
-
- Implement key rotation strategies
|
|
33
|
-
- Set up certificate-based authentication
|
|
34
|
-
- Configure multi-factor authentication
|
|
35
|
-
|
|
36
|
-
3. **Remote Operations and Automation**
|
|
37
|
-
- Execute remote commands securely
|
|
38
|
-
- Transfer files with SCP/SFTP/rsync
|
|
39
|
-
- Create automated deployment scripts
|
|
40
|
-
- Implement infrastructure management workflows
|
|
41
|
-
|
|
42
|
-
4. **Advanced SSH Features**
|
|
43
|
-
- Set up SSH tunneling and port forwarding
|
|
44
|
-
- Configure jump hosts and bastion servers
|
|
45
|
-
- Implement SSH agents and key forwarding
|
|
46
|
-
- Create dynamic and reverse tunnels
|
|
47
|
-
|
|
48
|
-
## SSH Configuration Patterns
|
|
49
|
-
|
|
50
|
-
### Client Configuration (~/.ssh/config)
|
|
51
|
-
```bash
|
|
52
|
-
# Global defaults
|
|
53
|
-
Host *
|
|
54
|
-
# Security settings
|
|
55
|
-
Protocol 2
|
|
56
|
-
Cipher aes256-ctr,aes192-ctr,aes128-ctr
|
|
57
|
-
MACs hmac-sha2-256,hmac-sha2-512
|
|
58
|
-
KexAlgorithms diffie-hellman-group-exchange-sha256
|
|
59
|
-
HostKeyAlgorithms rsa-sha2-512,rsa-sha2-256,ssh-ed25519
|
|
60
|
-
|
|
61
|
-
# Connection optimization
|
|
62
|
-
Compression yes
|
|
63
|
-
ControlMaster auto
|
|
64
|
-
ControlPath ~/.ssh/sockets/%r@%h-%p
|
|
65
|
-
ControlPersist 600
|
|
66
|
-
|
|
67
|
-
# Timeout settings
|
|
68
|
-
ConnectTimeout 30
|
|
69
|
-
ServerAliveInterval 60
|
|
70
|
-
ServerAliveCountMax 3
|
|
71
|
-
|
|
72
|
-
# Security options
|
|
73
|
-
StrictHostKeyChecking ask
|
|
74
|
-
UserKnownHostsFile ~/.ssh/known_hosts
|
|
75
|
-
VerifyHostKeyDNS yes
|
|
76
|
-
|
|
77
|
-
# Disable insecure features
|
|
78
|
-
ForwardAgent no
|
|
79
|
-
ForwardX11 no
|
|
80
|
-
PasswordAuthentication no
|
|
81
|
-
|
|
82
|
-
# Production servers
|
|
83
|
-
Host prod-web-*
|
|
84
|
-
HostName %h.production.company.com
|
|
85
|
-
User deploy
|
|
86
|
-
IdentityFile ~/.ssh/keys/production_ed25519
|
|
87
|
-
ProxyJump bastion.company.com
|
|
88
|
-
StrictHostKeyChecking yes
|
|
89
|
-
|
|
90
|
-
Host prod-web-01
|
|
91
|
-
HostName 10.0.1.10
|
|
92
|
-
|
|
93
|
-
Host prod-web-02
|
|
94
|
-
HostName 10.0.1.11
|
|
95
|
-
|
|
96
|
-
# Staging environment
|
|
97
|
-
Host staging-*
|
|
98
|
-
HostName %h.staging.company.com
|
|
99
|
-
User ubuntu
|
|
100
|
-
IdentityFile ~/.ssh/keys/staging_rsa
|
|
101
|
-
ProxyJump bastion-staging.company.com
|
|
102
|
-
|
|
103
|
-
# Development servers
|
|
104
|
-
Host dev-*
|
|
105
|
-
HostName %h.dev.company.com
|
|
106
|
-
User developer
|
|
107
|
-
IdentityFile ~/.ssh/keys/development_ed25519
|
|
108
|
-
Port 2222
|
|
109
|
-
|
|
110
|
-
# Bastion/Jump hosts
|
|
111
|
-
Host bastion bastion.company.com
|
|
112
|
-
HostName bastion.company.com
|
|
113
|
-
User admin
|
|
114
|
-
IdentityFile ~/.ssh/keys/bastion_ed25519
|
|
115
|
-
ControlMaster no
|
|
116
|
-
LogLevel INFO
|
|
117
|
-
|
|
118
|
-
# Database servers (through bastion)
|
|
119
|
-
Host db-prod-*
|
|
120
|
-
ProxyJump bastion.company.com
|
|
121
|
-
User postgres
|
|
122
|
-
IdentityFile ~/.ssh/keys/database_ed25519
|
|
123
|
-
LocalForward 5432 localhost:5432
|
|
124
|
-
|
|
125
|
-
# GitLab/GitHub
|
|
126
|
-
Host gitlab.company.com
|
|
127
|
-
HostName gitlab.company.com
|
|
128
|
-
User git
|
|
129
|
-
IdentityFile ~/.ssh/keys/gitlab_ed25519
|
|
130
|
-
|
|
131
|
-
Host github.com
|
|
132
|
-
HostName github.com
|
|
133
|
-
User git
|
|
134
|
-
IdentityFile ~/.ssh/keys/github_ed25519
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Server Configuration (/etc/ssh/sshd_config)
|
|
138
|
-
```bash
|
|
139
|
-
# /etc/ssh/sshd_config - Hardened server configuration
|
|
140
|
-
|
|
141
|
-
# Protocol and encryption
|
|
142
|
-
Protocol 2
|
|
143
|
-
Port 2222 # Non-standard port for security
|
|
144
|
-
AddressFamily inet # IPv4 only
|
|
145
|
-
|
|
146
|
-
# Logging
|
|
147
|
-
SyslogFacility AUTH
|
|
148
|
-
LogLevel VERBOSE
|
|
149
|
-
|
|
150
|
-
# Authentication settings
|
|
151
|
-
LoginGraceTime 30
|
|
152
|
-
PermitRootLogin no
|
|
153
|
-
StrictModes yes
|
|
154
|
-
MaxAuthTries 3
|
|
155
|
-
MaxSessions 2
|
|
156
|
-
MaxStartups 10:30:60
|
|
157
|
-
|
|
158
|
-
# Public key authentication
|
|
159
|
-
PubkeyAuthentication yes
|
|
160
|
-
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
|
|
161
|
-
|
|
162
|
-
# Disable insecure authentication methods
|
|
163
|
-
PasswordAuthentication no
|
|
164
|
-
PermitEmptyPasswords no
|
|
165
|
-
ChallengeResponseAuthentication no
|
|
166
|
-
KerberosAuthentication no
|
|
167
|
-
GSSAPIAuthentication no
|
|
168
|
-
|
|
169
|
-
# Disable dangerous features
|
|
170
|
-
AllowAgentForwarding no
|
|
171
|
-
AllowTcpForwarding no
|
|
172
|
-
X11Forwarding no
|
|
173
|
-
PermitTunnel no
|
|
174
|
-
GatewayPorts no
|
|
175
|
-
|
|
176
|
-
# User and group restrictions
|
|
177
|
-
AllowUsers deploy ubuntu admin
|
|
178
|
-
AllowGroups ssh-users sudo
|
|
179
|
-
|
|
180
|
-
# Connection settings
|
|
181
|
-
ClientAliveInterval 300
|
|
182
|
-
ClientAliveCountMax 2
|
|
183
|
-
TCPKeepAlive no
|
|
184
|
-
UseDNS no
|
|
185
|
-
|
|
186
|
-
# Chroot and restrictions
|
|
187
|
-
ChrootDirectory none
|
|
188
|
-
PermitUserEnvironment no
|
|
189
|
-
|
|
190
|
-
# Modern crypto algorithms
|
|
191
|
-
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
|
|
192
|
-
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
|
|
193
|
-
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
|
|
194
|
-
|
|
195
|
-
# Host keys (prefer Ed25519)
|
|
196
|
-
HostKey /etc/ssh/ssh_host_ed25519_key
|
|
197
|
-
HostKey /etc/ssh/ssh_host_rsa_key
|
|
198
|
-
|
|
199
|
-
# Banner and MOTD
|
|
200
|
-
Banner /etc/ssh/banner.txt
|
|
201
|
-
PrintMotd yes
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## Key Management Operations
|
|
205
|
-
|
|
206
|
-
### Key Generation and Management
|
|
207
|
-
```bash
|
|
208
|
-
#!/bin/bash
|
|
209
|
-
# SSH Key Management Script
|
|
210
|
-
|
|
211
|
-
KEY_DIR="$HOME/.ssh/keys"
|
|
212
|
-
BACKUP_DIR="$HOME/.ssh/backups"
|
|
213
|
-
|
|
214
|
-
# Create directory structure
|
|
215
|
-
mkdir -p "$KEY_DIR" "$BACKUP_DIR" "$HOME/.ssh/sockets"
|
|
216
|
-
chmod 700 "$HOME/.ssh" "$KEY_DIR" "$BACKUP_DIR"
|
|
217
|
-
|
|
218
|
-
generate_ssh_key() {
|
|
219
|
-
local key_name="$1"
|
|
220
|
-
local key_type="${2:-ed25519}"
|
|
221
|
-
local comment="${3:-$(whoami)@$(hostname)-$(date +%Y%m%d)}"
|
|
222
|
-
|
|
223
|
-
echo "Generating $key_type SSH key: $key_name"
|
|
224
|
-
|
|
225
|
-
case "$key_type" in
|
|
226
|
-
"ed25519")
|
|
227
|
-
ssh-keygen -t ed25519 -f "$KEY_DIR/${key_name}_ed25519" -C "$comment" -N ""
|
|
228
|
-
;;
|
|
229
|
-
"rsa")
|
|
230
|
-
ssh-keygen -t rsa -b 4096 -f "$KEY_DIR/${key_name}_rsa" -C "$comment" -N ""
|
|
231
|
-
;;
|
|
232
|
-
"ecdsa")
|
|
233
|
-
ssh-keygen -t ecdsa -b 521 -f "$KEY_DIR/${key_name}_ecdsa" -C "$comment" -N ""
|
|
234
|
-
;;
|
|
235
|
-
*)
|
|
236
|
-
echo "Unsupported key type: $key_type"
|
|
237
|
-
return 1
|
|
238
|
-
;;
|
|
239
|
-
esac
|
|
240
|
-
|
|
241
|
-
# Set proper permissions
|
|
242
|
-
chmod 600 "$KEY_DIR/${key_name}_${key_type}"
|
|
243
|
-
chmod 644 "$KEY_DIR/${key_name}_${key_type}.pub"
|
|
244
|
-
|
|
245
|
-
echo "Key generated: $KEY_DIR/${key_name}_${key_type}"
|
|
246
|
-
echo "Public key:"
|
|
247
|
-
cat "$KEY_DIR/${key_name}_${key_type}.pub"
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
rotate_ssh_key() {
|
|
251
|
-
local key_name="$1"
|
|
252
|
-
local servers=("${@:2}")
|
|
253
|
-
|
|
254
|
-
echo "Rotating SSH key: $key_name"
|
|
255
|
-
|
|
256
|
-
# Backup old key
|
|
257
|
-
if [[ -f "$KEY_DIR/${key_name}_ed25519" ]]; then
|
|
258
|
-
cp "$KEY_DIR/${key_name}_ed25519"* "$BACKUP_DIR/"
|
|
259
|
-
echo "Old key backed up to $BACKUP_DIR"
|
|
260
|
-
fi
|
|
261
|
-
|
|
262
|
-
# Generate new key
|
|
263
|
-
generate_ssh_key "$key_name" "ed25519"
|
|
264
|
-
|
|
265
|
-
# Deploy to servers
|
|
266
|
-
for server in "${servers[@]}"; do
|
|
267
|
-
echo "Deploying new key to $server"
|
|
268
|
-
ssh-copy-id -i "$KEY_DIR/${key_name}_ed25519.pub" "$server"
|
|
269
|
-
done
|
|
270
|
-
|
|
271
|
-
echo "Key rotation completed for $key_name"
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
list_ssh_keys() {
|
|
275
|
-
echo "SSH Keys in $KEY_DIR:"
|
|
276
|
-
find "$KEY_DIR" -name "*.pub" -exec basename {} .pub \; | sort
|
|
277
|
-
|
|
278
|
-
echo -e "\nLoaded in SSH agent:"
|
|
279
|
-
ssh-add -l 2>/dev/null || echo "No keys loaded in agent"
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
add_key_to_agent() {
|
|
283
|
-
local key_path="$1"
|
|
284
|
-
|
|
285
|
-
if [[ ! -f "$key_path" ]]; then
|
|
286
|
-
echo "Key file not found: $key_path"
|
|
287
|
-
return 1
|
|
288
|
-
fi
|
|
289
|
-
|
|
290
|
-
# Start ssh-agent if not running
|
|
291
|
-
if [[ -z "$SSH_AUTH_SOCK" ]]; then
|
|
292
|
-
eval "$(ssh-agent -s)"
|
|
293
|
-
fi
|
|
294
|
-
|
|
295
|
-
ssh-add "$key_path"
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
# Usage examples
|
|
299
|
-
# generate_ssh_key "production" "ed25519" "deploy@production-$(date +%Y%m%d)"
|
|
300
|
-
# rotate_ssh_key "staging" "staging-web-01" "staging-web-02" "staging-db-01"
|
|
301
|
-
# list_ssh_keys
|
|
302
|
-
# add_key_to_agent "$KEY_DIR/production_ed25519"
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### Authorized Keys Management
|
|
306
|
-
```bash
|
|
307
|
-
#!/bin/bash
|
|
308
|
-
# Authorized Keys Management
|
|
309
|
-
|
|
310
|
-
AUTHORIZED_KEYS_FILE="$HOME/.ssh/authorized_keys"
|
|
311
|
-
|
|
312
|
-
manage_authorized_keys() {
|
|
313
|
-
local action="$1"
|
|
314
|
-
local key_identifier="$2"
|
|
315
|
-
local public_key="$3"
|
|
316
|
-
|
|
317
|
-
# Ensure authorized_keys exists with proper permissions
|
|
318
|
-
touch "$AUTHORIZED_KEYS_FILE"
|
|
319
|
-
chmod 600 "$AUTHORIZED_KEYS_FILE"
|
|
320
|
-
|
|
321
|
-
case "$action" in
|
|
322
|
-
"add")
|
|
323
|
-
if grep -q "$key_identifier" "$AUTHORIZED_KEYS_FILE"; then
|
|
324
|
-
echo "Key with identifier '$key_identifier' already exists"
|
|
325
|
-
return 1
|
|
326
|
-
fi
|
|
327
|
-
|
|
328
|
-
echo "# $key_identifier - $(date)" >> "$AUTHORIZED_KEYS_FILE"
|
|
329
|
-
echo "$public_key" >> "$AUTHORIZED_KEYS_FILE"
|
|
330
|
-
echo "Added key: $key_identifier"
|
|
331
|
-
;;
|
|
332
|
-
|
|
333
|
-
"remove")
|
|
334
|
-
if ! grep -q "$key_identifier" "$AUTHORIZED_KEYS_FILE"; then
|
|
335
|
-
echo "Key with identifier '$key_identifier' not found"
|
|
336
|
-
return 1
|
|
337
|
-
fi
|
|
338
|
-
|
|
339
|
-
# Remove the comment line and the key
|
|
340
|
-
sed -i "/# $key_identifier/,+1d" "$AUTHORIZED_KEYS_FILE"
|
|
341
|
-
echo "Removed key: $key_identifier"
|
|
342
|
-
;;
|
|
343
|
-
|
|
344
|
-
"list")
|
|
345
|
-
echo "Authorized keys:"
|
|
346
|
-
grep -n "^#" "$AUTHORIZED_KEYS_FILE" | sed 's/^# //'
|
|
347
|
-
;;
|
|
348
|
-
|
|
349
|
-
"validate")
|
|
350
|
-
echo "Validating authorized_keys file..."
|
|
351
|
-
while IFS= read -r line; do
|
|
352
|
-
if [[ $line =~ ^ssh- ]] || [[ $line =~ ^ecdsa- ]]; then
|
|
353
|
-
if ssh-keygen -l -f /dev/stdin <<< "$line" >/dev/null 2>&1; then
|
|
354
|
-
echo "✓ Valid key: $(echo "$line" | cut -d' ' -f3)"
|
|
355
|
-
else
|
|
356
|
-
echo "✗ Invalid key: $line"
|
|
357
|
-
fi
|
|
358
|
-
fi
|
|
359
|
-
done < "$AUTHORIZED_KEYS_FILE"
|
|
360
|
-
;;
|
|
361
|
-
|
|
362
|
-
*)
|
|
363
|
-
echo "Usage: manage_authorized_keys {add|remove|list|validate}"
|
|
364
|
-
echo " add <identifier> '<public_key>'"
|
|
365
|
-
echo " remove <identifier>"
|
|
366
|
-
echo " list"
|
|
367
|
-
echo " validate"
|
|
368
|
-
;;
|
|
369
|
-
esac
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
# Restricted key example
|
|
373
|
-
add_restricted_key() {
|
|
374
|
-
local identifier="$1"
|
|
375
|
-
local public_key="$2"
|
|
376
|
-
local command="$3"
|
|
377
|
-
local from_ip="$4"
|
|
378
|
-
|
|
379
|
-
local options=""
|
|
380
|
-
|
|
381
|
-
# Add command restriction
|
|
382
|
-
if [[ -n "$command" ]]; then
|
|
383
|
-
options="${options}command=\"$command\","
|
|
384
|
-
fi
|
|
385
|
-
|
|
386
|
-
# Add IP restriction
|
|
387
|
-
if [[ -n "$from_ip" ]]; then
|
|
388
|
-
options="${options}from=\"$from_ip\","
|
|
389
|
-
fi
|
|
390
|
-
|
|
391
|
-
# Add other security options
|
|
392
|
-
options="${options}no-port-forwarding,no-agent-forwarding,no-X11-forwarding"
|
|
393
|
-
|
|
394
|
-
# Construct the key line
|
|
395
|
-
local key_line="${options} ${public_key}"
|
|
396
|
-
|
|
397
|
-
echo "# $identifier - $(date) - RESTRICTED" >> "$AUTHORIZED_KEYS_FILE"
|
|
398
|
-
echo "$key_line" >> "$AUTHORIZED_KEYS_FILE"
|
|
399
|
-
|
|
400
|
-
echo "Added restricted key: $identifier"
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
# Usage examples:
|
|
404
|
-
# manage_authorized_keys add "john-laptop" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5... john@laptop"
|
|
405
|
-
# manage_authorized_keys remove "john-laptop"
|
|
406
|
-
# manage_authorized_keys list
|
|
407
|
-
# add_restricted_key "backup-script" "ssh-rsa AAAAB3NzaC1y..." "/usr/local/bin/backup.sh" "192.168.1.100"
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
## Remote Operations and Automation
|
|
411
|
-
|
|
412
|
-
### Remote Command Execution
|
|
413
|
-
```bash
|
|
414
|
-
#!/bin/bash
|
|
415
|
-
# Remote Operations Framework
|
|
416
|
-
|
|
417
|
-
# Configuration
|
|
418
|
-
SERVERS_FILE="$HOME/.ssh/servers.conf"
|
|
419
|
-
LOG_DIR="$HOME/.ssh/logs"
|
|
420
|
-
PARALLEL_LIMIT=5
|
|
421
|
-
|
|
422
|
-
mkdir -p "$LOG_DIR"
|
|
423
|
-
|
|
424
|
-
# Server groups configuration
|
|
425
|
-
declare -A SERVER_GROUPS=(
|
|
426
|
-
["web"]="prod-web-01 prod-web-02 prod-web-03"
|
|
427
|
-
["database"]="prod-db-01 prod-db-02"
|
|
428
|
-
["staging"]="staging-web-01 staging-db-01"
|
|
429
|
-
["all-prod"]="prod-web-01 prod-web-02 prod-web-03 prod-db-01 prod-db-02"
|
|
430
|
-
)
|
|
431
|
-
|
|
432
|
-
execute_remote_command() {
|
|
433
|
-
local server="$1"
|
|
434
|
-
local command="$2"
|
|
435
|
-
local log_file="$3"
|
|
436
|
-
local timeout="${4:-300}"
|
|
437
|
-
|
|
438
|
-
echo "Executing on $server: $command" | tee -a "$log_file"
|
|
439
|
-
|
|
440
|
-
# Execute with timeout and logging
|
|
441
|
-
if timeout "$timeout" ssh -o ConnectTimeout=10 -o BatchMode=yes "$server" "$command" 2>&1 | tee -a "$log_file"; then
|
|
442
|
-
echo "SUCCESS on $server" | tee -a "$log_file"
|
|
443
|
-
return 0
|
|
444
|
-
else
|
|
445
|
-
echo "FAILED on $server" | tee -a "$log_file"
|
|
446
|
-
return 1
|
|
447
|
-
fi
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
parallel_execute() {
|
|
451
|
-
local servers=("$@")
|
|
452
|
-
local command="$COMMAND"
|
|
453
|
-
local timestamp=$(date +"%Y%m%d_%H%M%S")
|
|
454
|
-
local job_log="$LOG_DIR/parallel_${timestamp}.log"
|
|
455
|
-
|
|
456
|
-
echo "Executing command on ${#servers[@]} servers: $command" | tee "$job_log"
|
|
457
|
-
echo "Servers: ${servers[*]}" | tee -a "$job_log"
|
|
458
|
-
echo "----------------------------------------" | tee -a "$job_log"
|
|
459
|
-
|
|
460
|
-
# Create array to track background jobs
|
|
461
|
-
local pids=()
|
|
462
|
-
local results=()
|
|
463
|
-
|
|
464
|
-
# Start parallel execution
|
|
465
|
-
for server in "${servers[@]}"; do
|
|
466
|
-
# Limit concurrent connections
|
|
467
|
-
while [[ ${#pids[@]} -ge $PARALLEL_LIMIT ]]; do
|
|
468
|
-
# Wait for any job to complete
|
|
469
|
-
for i in "${!pids[@]}"; do
|
|
470
|
-
if ! kill -0 "${pids[$i]}" 2>/dev/null; then
|
|
471
|
-
wait "${pids[$i]}"
|
|
472
|
-
results[i]=$?
|
|
473
|
-
unset pids[i]
|
|
474
|
-
fi
|
|
475
|
-
done
|
|
476
|
-
sleep 1
|
|
477
|
-
done
|
|
478
|
-
|
|
479
|
-
# Start new job
|
|
480
|
-
(
|
|
481
|
-
server_log="$LOG_DIR/${server}_${timestamp}.log"
|
|
482
|
-
execute_remote_command "$server" "$command" "$server_log"
|
|
483
|
-
) &
|
|
484
|
-
|
|
485
|
-
pids+=($!)
|
|
486
|
-
done
|
|
487
|
-
|
|
488
|
-
# Wait for all remaining jobs
|
|
489
|
-
for pid in "${pids[@]}"; do
|
|
490
|
-
wait "$pid"
|
|
491
|
-
done
|
|
492
|
-
|
|
493
|
-
# Summary
|
|
494
|
-
echo "----------------------------------------" | tee -a "$job_log"
|
|
495
|
-
echo "Parallel execution completed" | tee -a "$job_log"
|
|
496
|
-
|
|
497
|
-
# Generate report
|
|
498
|
-
generate_execution_report "$timestamp"
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
execute_on_group() {
|
|
502
|
-
local group="$1"
|
|
503
|
-
local command="$2"
|
|
504
|
-
|
|
505
|
-
if [[ -z "${SERVER_GROUPS[$group]}" ]]; then
|
|
506
|
-
echo "Unknown server group: $group"
|
|
507
|
-
echo "Available groups: ${!SERVER_GROUPS[*]}"
|
|
508
|
-
return 1
|
|
509
|
-
fi
|
|
510
|
-
|
|
511
|
-
read -ra servers <<< "${SERVER_GROUPS[$group]}"
|
|
512
|
-
COMMAND="$command" parallel_execute "${servers[@]}"
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
generate_execution_report() {
|
|
516
|
-
local timestamp="$1"
|
|
517
|
-
local report_file="$LOG_DIR/report_${timestamp}.md"
|
|
518
|
-
|
|
519
|
-
cat > "$report_file" << EOF
|
|
520
|
-
# Execution Report - $timestamp
|
|
521
|
-
|
|
522
|
-
## Command Executed
|
|
523
|
-
\`\`\`
|
|
524
|
-
$COMMAND
|
|
525
|
-
\`\`\`
|
|
526
|
-
|
|
527
|
-
## Results Summary
|
|
528
|
-
EOF
|
|
529
|
-
|
|
530
|
-
local success_count=0
|
|
531
|
-
local failure_count=0
|
|
532
|
-
|
|
533
|
-
for log_file in "$LOG_DIR"/*_${timestamp}.log; do
|
|
534
|
-
if [[ -f "$log_file" ]]; then
|
|
535
|
-
local server=$(basename "$log_file" _${timestamp}.log)
|
|
536
|
-
|
|
537
|
-
if grep -q "SUCCESS on $server" "$log_file"; then
|
|
538
|
-
echo "- ✅ $server: SUCCESS" >> "$report_file"
|
|
539
|
-
((success_count++))
|
|
540
|
-
else
|
|
541
|
-
echo "- ❌ $server: FAILED" >> "$report_file"
|
|
542
|
-
((failure_count++))
|
|
543
|
-
fi
|
|
544
|
-
fi
|
|
545
|
-
done
|
|
546
|
-
|
|
547
|
-
cat >> "$report_file" << EOF
|
|
548
|
-
|
|
549
|
-
## Statistics
|
|
550
|
-
- Successful: $success_count
|
|
551
|
-
- Failed: $failure_count
|
|
552
|
-
- Total: $((success_count + failure_count))
|
|
553
|
-
|
|
554
|
-
## Detailed Logs
|
|
555
|
-
Individual server logs are available in: \`$LOG_DIR/\`
|
|
556
|
-
EOF
|
|
557
|
-
|
|
558
|
-
echo "Report generated: $report_file"
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
# Usage functions
|
|
562
|
-
run_system_update() {
|
|
563
|
-
local group="${1:-all-prod}"
|
|
564
|
-
execute_on_group "$group" "sudo apt update && sudo apt upgrade -y"
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
check_disk_space() {
|
|
568
|
-
local group="${1:-all-prod}"
|
|
569
|
-
execute_on_group "$group" "df -h | grep -E '^/dev/'"
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
restart_service() {
|
|
573
|
-
local service="$1"
|
|
574
|
-
local group="${2:-web}"
|
|
575
|
-
execute_on_group "$group" "sudo systemctl restart $service && sudo systemctl status $service"
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
deploy_application() {
|
|
579
|
-
local version="$1"
|
|
580
|
-
local group="${2:-web}"
|
|
581
|
-
|
|
582
|
-
local deploy_commands=(
|
|
583
|
-
"cd /opt/app && git fetch origin"
|
|
584
|
-
"git checkout $version"
|
|
585
|
-
"sudo systemctl stop app"
|
|
586
|
-
"./deploy.sh"
|
|
587
|
-
"sudo systemctl start app"
|
|
588
|
-
"sudo systemctl status app"
|
|
589
|
-
)
|
|
590
|
-
|
|
591
|
-
local full_command=$(printf "%s; " "${deploy_commands[@]}")
|
|
592
|
-
execute_on_group "$group" "$full_command"
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
# Usage examples:
|
|
596
|
-
# execute_on_group "web" "uptime"
|
|
597
|
-
# run_system_update "staging"
|
|
598
|
-
# check_disk_space "database"
|
|
599
|
-
# restart_service "nginx" "web"
|
|
600
|
-
# deploy_application "v2.1.0" "staging"
|
|
601
|
-
```
|
|
602
|
-
|
|
603
|
-
### File Transfer Operations
|
|
604
|
-
```bash
|
|
605
|
-
#!/bin/bash
|
|
606
|
-
# File Transfer and Synchronization
|
|
607
|
-
|
|
608
|
-
transfer_file() {
|
|
609
|
-
local source="$1"
|
|
610
|
-
local destination="$2"
|
|
611
|
-
local method="${3:-scp}"
|
|
612
|
-
local options="${4:--v}"
|
|
613
|
-
|
|
614
|
-
case "$method" in
|
|
615
|
-
"scp")
|
|
616
|
-
scp $options "$source" "$destination"
|
|
617
|
-
;;
|
|
618
|
-
"sftp")
|
|
619
|
-
echo "put $source" | sftp $options "$destination"
|
|
620
|
-
;;
|
|
621
|
-
"rsync")
|
|
622
|
-
rsync $options "$source" "$destination"
|
|
623
|
-
;;
|
|
624
|
-
*)
|
|
625
|
-
echo "Unsupported transfer method: $method"
|
|
626
|
-
return 1
|
|
627
|
-
;;
|
|
628
|
-
esac
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
sync_directories() {
|
|
632
|
-
local local_dir="$1"
|
|
633
|
-
local remote_server="$2"
|
|
634
|
-
local remote_dir="$3"
|
|
635
|
-
local options="${4:--avz --delete}"
|
|
636
|
-
|
|
637
|
-
echo "Syncing $local_dir to $remote_server:$remote_dir"
|
|
638
|
-
|
|
639
|
-
rsync $options \
|
|
640
|
-
--exclude='.git/' \
|
|
641
|
-
--exclude='node_modules/' \
|
|
642
|
-
--exclude='*.log' \
|
|
643
|
-
--progress \
|
|
644
|
-
"$local_dir/" \
|
|
645
|
-
"$remote_server:$remote_dir/"
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
backup_remote_directory() {
|
|
649
|
-
local remote_server="$1"
|
|
650
|
-
local remote_dir="$2"
|
|
651
|
-
local backup_dir="$3"
|
|
652
|
-
local timestamp=$(date +"%Y%m%d_%H%M%S")
|
|
653
|
-
|
|
654
|
-
echo "Backing up $remote_server:$remote_dir to $backup_dir"
|
|
655
|
-
|
|
656
|
-
mkdir -p "$backup_dir"
|
|
657
|
-
|
|
658
|
-
rsync -avz \
|
|
659
|
-
--progress \
|
|
660
|
-
"$remote_server:$remote_dir/" \
|
|
661
|
-
"$backup_dir/backup_${timestamp}/"
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
deploy_configuration() {
|
|
665
|
-
local config_dir="$1"
|
|
666
|
-
local servers=("${@:2}")
|
|
667
|
-
|
|
668
|
-
for server in "${servers[@]}"; do
|
|
669
|
-
echo "Deploying configuration to $server"
|
|
670
|
-
|
|
671
|
-
# Backup existing config
|
|
672
|
-
ssh "$server" "sudo cp -r /etc/myapp /etc/myapp.backup.$(date +%Y%m%d_%H%M%S)"
|
|
673
|
-
|
|
674
|
-
# Upload new configuration
|
|
675
|
-
rsync -avz --delete \
|
|
676
|
-
"$config_dir/" \
|
|
677
|
-
"$server:/tmp/config/"
|
|
678
|
-
|
|
679
|
-
# Install configuration
|
|
680
|
-
ssh "$server" "sudo cp -r /tmp/config/* /etc/myapp/ && sudo chown -R root:root /etc/myapp && sudo systemctl reload myapp"
|
|
681
|
-
done
|
|
682
|
-
}
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
## SSH Tunneling and Port Forwarding
|
|
686
|
-
|
|
687
|
-
### Tunnel Management
|
|
688
|
-
```bash
|
|
689
|
-
#!/bin/bash
|
|
690
|
-
# SSH Tunnel Management
|
|
691
|
-
|
|
692
|
-
TUNNEL_DIR="$HOME/.ssh/tunnels"
|
|
693
|
-
mkdir -p "$TUNNEL_DIR"
|
|
694
|
-
|
|
695
|
-
create_local_forward() {
|
|
696
|
-
local name="$1"
|
|
697
|
-
local local_port="$2"
|
|
698
|
-
local remote_host="$3"
|
|
699
|
-
local remote_port="$4"
|
|
700
|
-
local ssh_server="$5"
|
|
701
|
-
|
|
702
|
-
local tunnel_file="$TUNNEL_DIR/$name.conf"
|
|
703
|
-
local pid_file="$TUNNEL_DIR/$name.pid"
|
|
704
|
-
|
|
705
|
-
# Check if tunnel already exists
|
|
706
|
-
if [[ -f "$pid_file" ]] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
|
|
707
|
-
echo "Tunnel $name is already running (PID: $(cat "$pid_file"))"
|
|
708
|
-
return 1
|
|
709
|
-
fi
|
|
710
|
-
|
|
711
|
-
echo "Creating local forward tunnel: $name"
|
|
712
|
-
echo "Local: localhost:$local_port -> Remote: $remote_host:$remote_port via $ssh_server"
|
|
713
|
-
|
|
714
|
-
# Create tunnel configuration
|
|
715
|
-
cat > "$tunnel_file" << EOF
|
|
716
|
-
# SSH Tunnel Configuration: $name
|
|
717
|
-
# Created: $(date)
|
|
718
|
-
LocalForward=$local_port:$remote_host:$remote_port
|
|
719
|
-
SSHServer=$ssh_server
|
|
720
|
-
EOF
|
|
721
|
-
|
|
722
|
-
# Start tunnel in background
|
|
723
|
-
ssh -f -N \
|
|
724
|
-
-L "$local_port:$remote_host:$remote_port" \
|
|
725
|
-
-o ExitOnForwardFailure=yes \
|
|
726
|
-
-o ServerAliveInterval=60 \
|
|
727
|
-
-o ServerAliveCountMax=3 \
|
|
728
|
-
"$ssh_server"
|
|
729
|
-
|
|
730
|
-
# Get PID and save it
|
|
731
|
-
local tunnel_pid=$(ps aux | grep "ssh.*-L $local_port:$remote_host:$remote_port" | grep -v grep | awk '{print $2}')
|
|
732
|
-
echo "$tunnel_pid" > "$pid_file"
|
|
733
|
-
|
|
734
|
-
echo "Tunnel started with PID: $tunnel_pid"
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
create_dynamic_forward() {
|
|
738
|
-
local name="$1"
|
|
739
|
-
local local_port="$2"
|
|
740
|
-
local ssh_server="$3"
|
|
741
|
-
|
|
742
|
-
local pid_file="$TUNNEL_DIR/$name.pid"
|
|
743
|
-
|
|
744
|
-
echo "Creating dynamic SOCKS proxy: $name on port $local_port"
|
|
745
|
-
|
|
746
|
-
ssh -f -N \
|
|
747
|
-
-D "$local_port" \
|
|
748
|
-
-o ExitOnForwardFailure=yes \
|
|
749
|
-
-o ServerAliveInterval=60 \
|
|
750
|
-
-o ServerAliveCountMax=3 \
|
|
751
|
-
"$ssh_server"
|
|
752
|
-
|
|
753
|
-
local tunnel_pid=$(ps aux | grep "ssh.*-D $local_port" | grep -v grep | awk '{print $2}')
|
|
754
|
-
echo "$tunnel_pid" > "$pid_file"
|
|
755
|
-
|
|
756
|
-
echo "SOCKS proxy started with PID: $tunnel_pid"
|
|
757
|
-
echo "Configure your browser to use SOCKS proxy: localhost:$local_port"
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
create_reverse_tunnel() {
|
|
761
|
-
local name="$1"
|
|
762
|
-
local remote_port="$2"
|
|
763
|
-
local local_host="$3"
|
|
764
|
-
local local_port="$4"
|
|
765
|
-
local ssh_server="$5"
|
|
766
|
-
|
|
767
|
-
local pid_file="$TUNNEL_DIR/$name.pid"
|
|
768
|
-
|
|
769
|
-
echo "Creating reverse tunnel: $name"
|
|
770
|
-
echo "Remote: $ssh_server:$remote_port -> Local: $local_host:$local_port"
|
|
771
|
-
|
|
772
|
-
ssh -f -N \
|
|
773
|
-
-R "$remote_port:$local_host:$local_port" \
|
|
774
|
-
-o ExitOnForwardFailure=yes \
|
|
775
|
-
-o ServerAliveInterval=60 \
|
|
776
|
-
-o ServerAliveCountMax=3 \
|
|
777
|
-
"$ssh_server"
|
|
778
|
-
|
|
779
|
-
local tunnel_pid=$(ps aux | grep "ssh.*-R $remote_port:$local_host:$local_port" | grep -v grep | awk '{print $2}')
|
|
780
|
-
echo "$tunnel_pid" > "$pid_file"
|
|
781
|
-
|
|
782
|
-
echo "Reverse tunnel started with PID: $tunnel_pid"
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
list_tunnels() {
|
|
786
|
-
echo "Active SSH tunnels:"
|
|
787
|
-
for pid_file in "$TUNNEL_DIR"/*.pid; do
|
|
788
|
-
if [[ -f "$pid_file" ]]; then
|
|
789
|
-
local name=$(basename "$pid_file" .pid)
|
|
790
|
-
local pid=$(cat "$pid_file")
|
|
791
|
-
|
|
792
|
-
if kill -0 "$pid" 2>/dev/null; then
|
|
793
|
-
local cmd=$(ps -p "$pid" -o args --no-headers)
|
|
794
|
-
echo "✅ $name (PID: $pid): $cmd"
|
|
795
|
-
else
|
|
796
|
-
echo "❌ $name (PID: $pid): DEAD"
|
|
797
|
-
rm "$pid_file"
|
|
798
|
-
fi
|
|
799
|
-
fi
|
|
800
|
-
done
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
stop_tunnel() {
|
|
804
|
-
local name="$1"
|
|
805
|
-
local pid_file="$TUNNEL_DIR/$name.pid"
|
|
806
|
-
|
|
807
|
-
if [[ ! -f "$pid_file" ]]; then
|
|
808
|
-
echo "Tunnel $name not found"
|
|
809
|
-
return 1
|
|
810
|
-
fi
|
|
811
|
-
|
|
812
|
-
local pid=$(cat "$pid_file")
|
|
813
|
-
|
|
814
|
-
if kill -0 "$pid" 2>/dev/null; then
|
|
815
|
-
kill "$pid"
|
|
816
|
-
echo "Stopped tunnel: $name (PID: $pid)"
|
|
817
|
-
else
|
|
818
|
-
echo "Tunnel $name was already stopped"
|
|
819
|
-
fi
|
|
820
|
-
|
|
821
|
-
rm "$pid_file"
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
stop_all_tunnels() {
|
|
825
|
-
echo "Stopping all tunnels..."
|
|
826
|
-
for pid_file in "$TUNNEL_DIR"/*.pid; do
|
|
827
|
-
if [[ -f "$pid_file" ]]; then
|
|
828
|
-
local name=$(basename "$pid_file" .pid)
|
|
829
|
-
stop_tunnel "$name"
|
|
830
|
-
fi
|
|
831
|
-
done
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
# Usage examples:
|
|
835
|
-
# create_local_forward "db-prod" 5432 "localhost" 5432 "prod-db-01"
|
|
836
|
-
# create_dynamic_forward "socks-proxy" 8080 "bastion.company.com"
|
|
837
|
-
# create_reverse_tunnel "local-dev" 8080 "localhost" 3000 "prod-web-01"
|
|
838
|
-
# list_tunnels
|
|
839
|
-
# stop_tunnel "db-prod"
|
|
840
|
-
```
|
|
841
|
-
|
|
842
|
-
### Jump Host Configuration
|
|
843
|
-
```bash
|
|
844
|
-
#!/bin/bash
|
|
845
|
-
# Jump Host and Bastion Management
|
|
846
|
-
|
|
847
|
-
setup_jump_host() {
|
|
848
|
-
local jump_host="$1"
|
|
849
|
-
local target_servers=("${@:2}")
|
|
850
|
-
|
|
851
|
-
echo "Setting up jump host configuration for $jump_host"
|
|
852
|
-
|
|
853
|
-
# Add jump host configuration to SSH config
|
|
854
|
-
cat >> ~/.ssh/config << EOF
|
|
855
|
-
|
|
856
|
-
# Jump host configuration for $jump_host
|
|
857
|
-
Host $jump_host
|
|
858
|
-
HostName $jump_host
|
|
859
|
-
User admin
|
|
860
|
-
IdentityFile ~/.ssh/keys/bastion_ed25519
|
|
861
|
-
ControlMaster auto
|
|
862
|
-
ControlPath ~/.ssh/sockets/%r@%h-%p
|
|
863
|
-
ControlPersist 10m
|
|
864
|
-
|
|
865
|
-
EOF
|
|
866
|
-
|
|
867
|
-
# Configure target servers to use jump host
|
|
868
|
-
for server in "${target_servers[@]}"; do
|
|
869
|
-
cat >> ~/.ssh/config << EOF
|
|
870
|
-
Host $server
|
|
871
|
-
ProxyJump $jump_host
|
|
872
|
-
User deploy
|
|
873
|
-
IdentityFile ~/.ssh/keys/production_ed25519
|
|
874
|
-
|
|
875
|
-
EOF
|
|
876
|
-
done
|
|
877
|
-
|
|
878
|
-
echo "Jump host configuration completed"
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
test_connectivity() {
|
|
882
|
-
local servers=("$@")
|
|
883
|
-
|
|
884
|
-
echo "Testing connectivity to servers..."
|
|
885
|
-
|
|
886
|
-
for server in "${servers[@]}"; do
|
|
887
|
-
echo -n "Testing $server... "
|
|
888
|
-
|
|
889
|
-
if ssh -o ConnectTimeout=10 -o BatchMode=yes "$server" exit 2>/dev/null; then
|
|
890
|
-
echo "✅ OK"
|
|
891
|
-
else
|
|
892
|
-
echo "❌ FAILED"
|
|
893
|
-
fi
|
|
894
|
-
done
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
# Multi-hop SSH example
|
|
898
|
-
create_multi_hop_tunnel() {
|
|
899
|
-
local name="$1"
|
|
900
|
-
local local_port="$2"
|
|
901
|
-
local final_host="$3"
|
|
902
|
-
local final_port="$4"
|
|
903
|
-
local jump1="$5"
|
|
904
|
-
local jump2="$6"
|
|
905
|
-
|
|
906
|
-
echo "Creating multi-hop tunnel: $name"
|
|
907
|
-
echo "Path: localhost:$local_port -> $jump1 -> $jump2 -> $final_host:$final_port"
|
|
908
|
-
|
|
909
|
-
ssh -f -N \
|
|
910
|
-
-L "$local_port:localhost:$local_port" \
|
|
911
|
-
-o ProxyJump="$jump1,$jump2" \
|
|
912
|
-
-o ExitOnForwardFailure=yes \
|
|
913
|
-
"$final_host" \
|
|
914
|
-
"ssh -L $local_port:localhost:$final_port -N localhost"
|
|
915
|
-
}
|
|
916
|
-
```
|
|
917
|
-
|
|
918
|
-
## Security Best Practices
|
|
919
|
-
|
|
920
|
-
### SSH Hardening Script
|
|
921
|
-
```bash
|
|
922
|
-
#!/bin/bash
|
|
923
|
-
# SSH Security Hardening
|
|
924
|
-
|
|
925
|
-
harden_ssh_client() {
|
|
926
|
-
local ssh_config="$HOME/.ssh/config"
|
|
927
|
-
|
|
928
|
-
echo "Hardening SSH client configuration..."
|
|
929
|
-
|
|
930
|
-
# Backup existing config
|
|
931
|
-
if [[ -f "$ssh_config" ]]; then
|
|
932
|
-
cp "$ssh_config" "$ssh_config.backup.$(date +%Y%m%d_%H%M%S)"
|
|
933
|
-
fi
|
|
934
|
-
|
|
935
|
-
# Add security hardening to config
|
|
936
|
-
cat >> "$ssh_config" << 'EOF'
|
|
937
|
-
|
|
938
|
-
# Security Hardening - Applied automatically
|
|
939
|
-
Host *
|
|
940
|
-
# Use only secure algorithms
|
|
941
|
-
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
|
|
942
|
-
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
|
|
943
|
-
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group16-sha512
|
|
944
|
-
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
|
|
945
|
-
|
|
946
|
-
# Security options
|
|
947
|
-
StrictHostKeyChecking ask
|
|
948
|
-
VerifyHostKeyDNS yes
|
|
949
|
-
PasswordAuthentication no
|
|
950
|
-
ChallengeResponseAuthentication no
|
|
951
|
-
GSSAPIAuthentication no
|
|
952
|
-
|
|
953
|
-
# Connection security
|
|
954
|
-
Protocol 2
|
|
955
|
-
Compression no
|
|
956
|
-
TCPKeepAlive no
|
|
957
|
-
|
|
958
|
-
# Disable forwarding by default
|
|
959
|
-
ForwardAgent no
|
|
960
|
-
ForwardX11 no
|
|
961
|
-
|
|
962
|
-
# Connection optimization with security
|
|
963
|
-
ControlMaster auto
|
|
964
|
-
ControlPath ~/.ssh/sockets/%r@%h-%p
|
|
965
|
-
ControlPersist 600
|
|
966
|
-
|
|
967
|
-
# Timeouts
|
|
968
|
-
ConnectTimeout 30
|
|
969
|
-
ServerAliveInterval 60
|
|
970
|
-
ServerAliveCountMax 3
|
|
971
|
-
|
|
972
|
-
EOF
|
|
973
|
-
|
|
974
|
-
echo "Client hardening completed"
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
audit_ssh_keys() {
|
|
978
|
-
echo "SSH Key Security Audit"
|
|
979
|
-
echo "======================"
|
|
980
|
-
|
|
981
|
-
local key_dir="$HOME/.ssh"
|
|
982
|
-
local issues_found=0
|
|
983
|
-
|
|
984
|
-
# Check key permissions
|
|
985
|
-
echo "Checking key permissions..."
|
|
986
|
-
find "$key_dir" -name "id_*" -not -name "*.pub" -exec ls -l {} \; | while read -r perms rest; do
|
|
987
|
-
if [[ "${perms:1:9}" != "rw-------" ]]; then
|
|
988
|
-
echo "❌ Incorrect permissions: $rest"
|
|
989
|
-
((issues_found++))
|
|
990
|
-
fi
|
|
991
|
-
done
|
|
992
|
-
|
|
993
|
-
# Check for weak keys
|
|
994
|
-
echo "Checking for weak keys..."
|
|
995
|
-
find "$key_dir" -name "*.pub" | while read -r pub_key; do
|
|
996
|
-
local key_info=$(ssh-keygen -l -f "$pub_key")
|
|
997
|
-
local bits=$(echo "$key_info" | awk '{print $1}')
|
|
998
|
-
local type=$(echo "$key_info" | awk '{print $4}' | tr -d '()')
|
|
999
|
-
|
|
1000
|
-
case "$type" in
|
|
1001
|
-
"RSA")
|
|
1002
|
-
if [[ $bits -lt 2048 ]]; then
|
|
1003
|
-
echo "❌ Weak RSA key ($bits bits): $pub_key"
|
|
1004
|
-
((issues_found++))
|
|
1005
|
-
fi
|
|
1006
|
-
;;
|
|
1007
|
-
"DSA")
|
|
1008
|
-
echo "❌ DSA key found (deprecated): $pub_key"
|
|
1009
|
-
((issues_found++))
|
|
1010
|
-
;;
|
|
1011
|
-
esac
|
|
1012
|
-
done
|
|
1013
|
-
|
|
1014
|
-
# Check authorized_keys
|
|
1015
|
-
echo "Checking authorized_keys..."
|
|
1016
|
-
local auth_keys="$key_dir/authorized_keys"
|
|
1017
|
-
if [[ -f "$auth_keys" ]]; then
|
|
1018
|
-
local auth_perms=$(stat -c "%a" "$auth_keys")
|
|
1019
|
-
if [[ "$auth_perms" != "600" ]]; then
|
|
1020
|
-
echo "❌ Incorrect authorized_keys permissions: $auth_perms"
|
|
1021
|
-
((issues_found++))
|
|
1022
|
-
fi
|
|
1023
|
-
|
|
1024
|
-
# Check for unrestricted keys
|
|
1025
|
-
local unrestricted_count=$(grep -c "^ssh-" "$auth_keys")
|
|
1026
|
-
if [[ $unrestricted_count -gt 0 ]]; then
|
|
1027
|
-
echo "⚠️ Found $unrestricted_count unrestricted keys in authorized_keys"
|
|
1028
|
-
fi
|
|
1029
|
-
fi
|
|
1030
|
-
|
|
1031
|
-
echo "Audit completed. Issues found: $issues_found"
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
setup_ssh_ca() {
|
|
1035
|
-
local ca_name="$1"
|
|
1036
|
-
local ca_dir="$HOME/.ssh/ca"
|
|
1037
|
-
|
|
1038
|
-
echo "Setting up SSH Certificate Authority: $ca_name"
|
|
1039
|
-
|
|
1040
|
-
mkdir -p "$ca_dir"
|
|
1041
|
-
chmod 700 "$ca_dir"
|
|
1042
|
-
|
|
1043
|
-
# Generate CA key
|
|
1044
|
-
ssh-keygen -t ed25519 -f "$ca_dir/${ca_name}_ca" -C "SSH CA: $ca_name"
|
|
1045
|
-
chmod 600 "$ca_dir/${ca_name}_ca"
|
|
1046
|
-
|
|
1047
|
-
echo "CA created: $ca_dir/${ca_name}_ca"
|
|
1048
|
-
echo "CA public key:"
|
|
1049
|
-
cat "$ca_dir/${ca_name}_ca.pub"
|
|
1050
|
-
|
|
1051
|
-
echo "To use this CA, add the following to your SSH server config:"
|
|
1052
|
-
echo "TrustedUserCAKeys $ca_dir/${ca_name}_ca.pub"
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
sign_user_key() {
|
|
1056
|
-
local ca_key="$1"
|
|
1057
|
-
local user_key="$2"
|
|
1058
|
-
local username="$3"
|
|
1059
|
-
local validity="${4:-+1d}"
|
|
1060
|
-
|
|
1061
|
-
echo "Signing user key for $username (validity: $validity)"
|
|
1062
|
-
|
|
1063
|
-
ssh-keygen -s "$ca_key" \
|
|
1064
|
-
-I "$username" \
|
|
1065
|
-
-n "$username" \
|
|
1066
|
-
-V "$validity" \
|
|
1067
|
-
"$user_key"
|
|
1068
|
-
|
|
1069
|
-
echo "Certificate created: ${user_key}-cert.pub"
|
|
1070
|
-
}
|
|
1071
|
-
```
|
|
1072
|
-
|
|
1073
|
-
## Documentation Retrieval Protocol
|
|
1074
|
-
|
|
1075
|
-
1. **Check Latest Features**: Query context7 for OpenSSH updates
|
|
1076
|
-
2. **Security Guidelines**: Access SSH security best practices
|
|
1077
|
-
3. **Configuration Examples**: Review advanced SSH configurations
|
|
1078
|
-
|
|
1079
|
-
**Documentation Queries:**
|
|
1080
|
-
- `mcp://context7/openssh/latest` - OpenSSH documentation
|
|
1081
|
-
- `mcp://context7/ssh/security` - SSH security hardening
|
|
1082
|
-
- `mcp://context7/ssh/tunneling` - Advanced tunneling techniques
|
|
1083
|
-
|
|
1084
|
-
## Self-Verification Protocol
|
|
1085
|
-
|
|
1086
|
-
Before delivering any solution, verify:
|
|
1087
|
-
- [ ] Documentation from Context7 has been consulted
|
|
1088
|
-
- [ ] Code follows best practices
|
|
1089
|
-
- [ ] Tests are written and passing
|
|
1090
|
-
- [ ] Performance is acceptable
|
|
1091
|
-
- [ ] Security considerations addressed
|
|
1092
|
-
- [ ] No resource leaks
|
|
1093
|
-
- [ ] Error handling is comprehensive
|