Skip to content

Commit 6667d15

Browse files
committed
feat: adds ssh support for git operations
1 parent 72d43e4 commit 6667d15

File tree

28 files changed

+1811
-26
lines changed

28 files changed

+1811
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ dist
246246

247247
# testing
248248
/coverage
249+
.temp
249250

250251
# production
251252
/build

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ customize for your environment, see the [project's documentation](https://git-pr
9191
- [Quickstart](https://git-proxy.finos.org/docs/category/quickstart/)
9292
- [Installation](https://git-proxy.finos.org/docs/installation)
9393
- [Configuration](https://git-proxy.finos.org/docs/category/configuration)
94+
- [SSH Support](docs/SSH.md) - Documentation for SSH feature and configuration
9495

9596
## Contributing
9697

config.schema.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,36 @@
110110
"$ref": "#/definitions/authentication"
111111
}
112112
},
113+
"ssh": {
114+
"description": "SSH server configuration for secure Git operations",
115+
"type": "object",
116+
"properties": {
117+
"enabled": {
118+
"type": "boolean",
119+
"description": "Enable or disable SSH server"
120+
},
121+
"port": {
122+
"type": "number",
123+
"description": "Port number for the SSH server to listen on"
124+
},
125+
"hostKey": {
126+
"type": "object",
127+
"description": "SSH host key configuration",
128+
"properties": {
129+
"privateKeyPath": {
130+
"type": "string",
131+
"description": "Path to the private key file"
132+
},
133+
"publicKeyPath": {
134+
"type": "string",
135+
"description": "Path to the public key file"
136+
}
137+
},
138+
"required": ["privateKeyPath", "publicKeyPath"]
139+
}
140+
},
141+
"required": ["enabled", "port", "hostKey"]
142+
},
113143
"tls": {
114144
"description": "TLS configuration for secure connections",
115145
"type": "object",

docs/SSH.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# SSH Feature Documentation
2+
3+
## Overview
4+
5+
The SSH feature enables secure Git operations over SSH protocol, providing an alternative to HTTPS for repository access. This implementation acts as a proxy between Git clients and the remote Git server (e.g., GitHub), with additional security and control capabilities.
6+
7+
## Configuration
8+
9+
The SSH feature can be configured in the main configuration file with the following options:
10+
11+
```json
12+
{
13+
"ssh": {
14+
"enabled": true,
15+
"port": 22,
16+
"hostKey": {
17+
"privateKeyPath": "./.ssh/host_key",
18+
"publicKeyPath": "./.ssh/host_key.pub"
19+
}
20+
}
21+
}
22+
```
23+
24+
### Configuration Options
25+
26+
- `enabled`: Boolean flag to enable/disable SSH support
27+
- `port`: Port number for the SSH server to listen on (default is 22)
28+
- `hostKey`: Configuration for the server's SSH host key
29+
- `privateKeyPath`: Path to the private key file
30+
- `publicKeyPath`: Path to the public key file
31+
32+
## Authentication Methods
33+
34+
The SSH server supports two authentication methods:
35+
36+
1. **Public Key Authentication**
37+
38+
- Users can authenticate using their SSH public keys
39+
- Keys are stored in the database and associated with user accounts
40+
- Supports various key types (RSA, ED25519, etc.)
41+
42+
2. **Password Authentication**
43+
- Users can authenticate using their username and password
44+
- Passwords are stored securely using bcrypt hashing
45+
- Only available if no public key is provided
46+
47+
## Connection Handling
48+
49+
The SSH server implements several features to ensure reliable connections:
50+
51+
- **Keepalive Mechanism**
52+
53+
- Regular keepalive packets (every 15 seconds)
54+
- Configurable keepalive interval and maximum attempts
55+
- Helps prevent connection timeouts
56+
57+
- **Error Recovery**
58+
59+
- Graceful handling of connection errors
60+
- Automatic recovery from temporary disconnections
61+
- Fallback mechanisms for authentication failures
62+
63+
- **Connection Timeouts**
64+
- 5-minute timeout for large repository operations
65+
- Configurable ready timeout (30 seconds by default)
66+
67+
## Git Protocol Support
68+
69+
The SSH server fully supports Git protocol operations:
70+
71+
- **Git Protocol Version 2**
72+
73+
- Enabled by default for all connections
74+
- Improved performance and security
75+
76+
- **Command Execution**
77+
- Supports all standard Git commands
78+
- Proper handling of Git protocol streams
79+
- Efficient data transfer between client and server
80+
81+
## Security Features
82+
83+
1. **Host Key Verification**
84+
85+
- Server uses a dedicated host key pair for the initial handshake between git proxy and user
86+
- Keys are stored securely in the filesystem
87+
- This key pair is used to establish the secure SSH connection and verify the server's identity to the client
88+
89+
2. **Authentication Chain**
90+
91+
- Integrates with the existing authentication chain
92+
- Supports custom authentication plugins
93+
- Enforces access control policies
94+
95+
3. **Connection Security**
96+
- Secure key exchange
97+
- Encrypted data transmission
98+
- Protection against common SSH attacks
99+
100+
## Implementation Details
101+
102+
The SSH server is implemented using the `ssh2` library and includes:
103+
104+
- Custom SSH server class (`SSHServer`)
105+
- Comprehensive error handling
106+
- Detailed logging for debugging
107+
- Support for large file transfers
108+
- Efficient stream handling
109+
110+
## Usage
111+
112+
To use the SSH feature:
113+
114+
1. Ensure SSH is enabled in the configuration
115+
2. Generate and configure the host key pair
116+
3. Add user SSH keys to the database
117+
4. Connect using standard Git SSH commands:
118+
119+
```bash
120+
git clone git@your-proxy:username/repo.git
121+
```
122+
123+
If other than default (22) port is used, git command will look like this:
124+
125+
```bash
126+
git clone ssh://git@your-proxy:2222/username/repo.git
127+
```
128+
129+
## Troubleshooting
130+
131+
Common issues and solutions:
132+
133+
1. **Connection Timeouts**
134+
135+
- Check keepalive settings
136+
- Verify network connectivity
137+
- Ensure proper firewall configuration
138+
139+
2. **Authentication Failures**
140+
141+
- Verify SSH key format
142+
- Check key association in database
143+
- Ensure proper permissions
144+
145+
3. **Performance Issues**
146+
- Adjust window size and packet size
147+
- Monitor connection timeouts
148+
- Check server resources
149+
150+
## Development
151+
152+
The SSH implementation includes comprehensive tests in `test/ssh/sshServer.test.js`. To run the tests:
153+
154+
```bash
155+
npm test
156+
```
157+
158+
## Future Improvements
159+
160+
Planned enhancements:
161+
162+
1. Move SSH configuration options (keep alive, timeouts, and other params) to config file
163+
2. Enhance actions for SSH functionality
164+
3. Improved error reporting
165+
4. Additional security features

package-lock.json

Lines changed: 76 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"test-coverage": "nyc npm run test",
1818
"test-coverage-ci": "nyc --reporter=lcovonly --reporter=text npm run test",
1919
"prepare": "node ./scripts/prepare.js",
20-
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx,json}\" \"test/**/*.{js,jsx,ts,tsx,json}\"",
20+
"lint": "eslint --quiet --ignore-pattern \"**/*.d.ts\" \"src/**/*.{js,jsx,ts,tsx,json}\" \"test/**/*.{js,jsx,ts,tsx,json}\"",
2121
"lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx,json}\" \"test/**/*.{js,jsx,ts,tsx,json}\"",
2222
"format": "prettier --write src/**/*.{js,jsx,ts,tsx,css,md,json,scss} test/**/*.{js,jsx,ts,tsx,json} packages/git-proxy-cli/test/**/*.{js,jsx,ts,tsx,json} packages/git-proxy-cli/index.js --config ./.prettierrc",
2323
"gen-schema-doc": "node ./scripts/doc-schema.js",
@@ -78,6 +78,7 @@
7878
"react-html-parser": "^2.0.2",
7979
"react-router-dom": "6.28.2",
8080
"simple-git": "^3.25.0",
81+
"ssh2": "^1.16.0",
8182
"uuid": "^11.0.0",
8283
"yargs": "^17.7.2"
8384
},
@@ -92,6 +93,7 @@
9293
"@types/lodash": "^4.17.15",
9394
"@types/mocha": "^10.0.10",
9495
"@types/node": "^22.13.5",
96+
"@types/ssh2": "^1.15.5",
9597
"@types/yargs": "^17.0.33",
9698
"@typescript-eslint/eslint-plugin": "^8.26.1",
9799
"@typescript-eslint/parser": "^8.26.1",

0 commit comments

Comments
 (0)