@@ -9,6 +9,10 @@ class SSHServer {
9
9
{
10
10
hostKeys : [ require ( 'fs' ) . readFileSync ( config . getSSHConfig ( ) . hostKey . privateKeyPath ) ] ,
11
11
authMethods : [ 'publickey' , 'password' ] ,
12
+ // Add connection timeout and keepalive settings
13
+ keepaliveInterval : 10000 ,
14
+ keepaliveCountMax : 3 ,
15
+ readyTimeout : 10000 ,
12
16
// debug: (msg) => {
13
17
// console.debug('[SSH Debug]', msg);
14
18
// },
@@ -18,7 +22,24 @@ class SSHServer {
18
22
}
19
23
20
24
async handleClient ( client ) {
21
- console . log ( '[SSH] Client connected' , client ) ;
25
+ console . log ( '[SSH] Client connected' ) ;
26
+
27
+ // Set up client error handling
28
+ client . on ( 'error' , ( err ) => {
29
+ console . error ( '[SSH] Client error:' , err ) ;
30
+ // Don't end the connection on error, let it try to recover
31
+ } ) ;
32
+
33
+ // Handle client end
34
+ client . on ( 'end' , ( ) => {
35
+ console . log ( '[SSH] Client disconnected' ) ;
36
+ } ) ;
37
+
38
+ // Handle client close
39
+ client . on ( 'close' , ( ) => {
40
+ console . log ( '[SSH] Client connection closed' ) ;
41
+ } ) ;
42
+
22
43
client . on ( 'authentication' , async ( ctx ) => {
23
44
console . log ( `[SSH] Authentication attempt: ${ ctx . method } ` ) ;
24
45
@@ -89,10 +110,6 @@ class SSHServer {
89
110
console . log ( `[SSH] Client ready: ${ client . username } ` ) ;
90
111
client . on ( 'session' , this . handleSession . bind ( this ) ) ;
91
112
} ) ;
92
-
93
- client . on ( 'error' , ( err ) => {
94
- console . error ( '[SSH] Client error:' , err ) ;
95
- } ) ;
96
113
}
97
114
98
115
async handleSession ( accept , reject ) {
@@ -144,6 +161,36 @@ class SSHServer {
144
161
const githubSsh = new ssh2 . Client ( ) ;
145
162
146
163
console . log ( '[SSH] Creating SSH connection to GitHub' ) ;
164
+
165
+ // Add connection options
166
+ const connectionOptions = {
167
+ host : 'github.com' ,
168
+ port : 22 ,
169
+ username : 'git' ,
170
+ keepaliveInterval : 10000 , // Send keepalive every 10 seconds
171
+ keepaliveCountMax : 3 , // Allow 3 missed keepalives before disconnecting
172
+ readyTimeout : 10000 , // Connection timeout after 10 seconds
173
+ tryKeyboard : false , // Disable keyboard-interactive auth
174
+ debug : ( msg ) => {
175
+ console . debug ( '[GitHub SSH Debug]' , msg ) ;
176
+ } ,
177
+ } ;
178
+
179
+ // Get the client's SSH key that was used for authentication
180
+ const clientKey = session . _channel . _client . userPrivateKeyz ;
181
+ console . log ( '[SSH] Client key:' , clientKey ? 'Available' : 'Not available' ) ;
182
+
183
+ // Add the private key based on what's available
184
+ if ( clientKey ) {
185
+ console . log ( '[SSH] Using client key to connect to GitHub' ) ;
186
+ connectionOptions . privateKey = clientKey ;
187
+ } else {
188
+ console . log ( '[SSH] No client key available, using proxy key' ) ;
189
+ connectionOptions . privateKey = require ( 'fs' ) . readFileSync (
190
+ config . getSSHConfig ( ) . hostKey . privateKeyPath ,
191
+ ) ;
192
+ }
193
+
147
194
githubSsh . on ( 'ready' , ( ) => {
148
195
console . log ( '[SSH] Connected to GitHub' ) ;
149
196
@@ -156,6 +203,19 @@ class SSHServer {
156
203
return ;
157
204
}
158
205
206
+ // Handle stream errors
207
+ githubStream . on ( 'error' , ( err ) => {
208
+ console . error ( '[SSH] GitHub stream error:' , err ) ;
209
+ stream . write ( err . toString ( ) ) ;
210
+ stream . end ( ) ;
211
+ } ) ;
212
+
213
+ // Handle stream close
214
+ githubStream . on ( 'close' , ( ) => {
215
+ console . log ( '[SSH] GitHub stream closed' ) ;
216
+ githubSsh . end ( ) ;
217
+ } ) ;
218
+
159
219
// Pipe data between client and GitHub
160
220
stream . pipe ( githubStream ) . pipe ( stream ) ;
161
221
@@ -172,30 +232,8 @@ class SSHServer {
172
232
stream . end ( ) ;
173
233
} ) ;
174
234
175
- // Get the client's SSH key that was used for authentication
176
- // console.log('[SSH] Session:', session);
177
- const clientKey = session . _channel . _client . userPrivateKey ;
178
- console . log ( '[SSH] Client key:' , clientKey ? 'Available' : 'Not available' ) ;
179
-
180
- if ( clientKey ) {
181
- console . log ( '[SSH] Using client key to connect to GitHub' ) ;
182
- // Use the client's private key to connect to GitHub
183
- githubSsh . connect ( {
184
- host : 'github.com' ,
185
- port : 22 ,
186
- username : 'git' ,
187
- privateKey : clientKey ,
188
- } ) ;
189
- } else {
190
- console . log ( '[SSH] No client key available, using proxy key' ) ;
191
- // Fallback to proxy's SSH key if no client key is available
192
- githubSsh . connect ( {
193
- host : 'github.com' ,
194
- port : 22 ,
195
- username : 'git' ,
196
- privateKey : require ( 'fs' ) . readFileSync ( config . getSSHConfig ( ) . hostKey . privateKeyPath ) ,
197
- } ) ;
198
- }
235
+ // Connect to GitHub
236
+ githubSsh . connect ( connectionOptions ) ;
199
237
} catch ( error ) {
200
238
console . error ( '[SSH] Error during SSH connection:' , error ) ;
201
239
stream . write ( error . toString ( ) ) ;
0 commit comments