@@ -9,6 +9,10 @@ class SSHServer {
99 {
1010 hostKeys : [ require ( 'fs' ) . readFileSync ( config . getSSHConfig ( ) . hostKey . privateKeyPath ) ] ,
1111 authMethods : [ 'publickey' , 'password' ] ,
12+ // Add connection timeout and keepalive settings
13+ keepaliveInterval : 10000 ,
14+ keepaliveCountMax : 3 ,
15+ readyTimeout : 10000 ,
1216 // debug: (msg) => {
1317 // console.debug('[SSH Debug]', msg);
1418 // },
@@ -18,7 +22,24 @@ class SSHServer {
1822 }
1923
2024 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+
2243 client . on ( 'authentication' , async ( ctx ) => {
2344 console . log ( `[SSH] Authentication attempt: ${ ctx . method } ` ) ;
2445
@@ -89,10 +110,6 @@ class SSHServer {
89110 console . log ( `[SSH] Client ready: ${ client . username } ` ) ;
90111 client . on ( 'session' , this . handleSession . bind ( this ) ) ;
91112 } ) ;
92-
93- client . on ( 'error' , ( err ) => {
94- console . error ( '[SSH] Client error:' , err ) ;
95- } ) ;
96113 }
97114
98115 async handleSession ( accept , reject ) {
@@ -144,6 +161,36 @@ class SSHServer {
144161 const githubSsh = new ssh2 . Client ( ) ;
145162
146163 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+
147194 githubSsh . on ( 'ready' , ( ) => {
148195 console . log ( '[SSH] Connected to GitHub' ) ;
149196
@@ -156,6 +203,19 @@ class SSHServer {
156203 return ;
157204 }
158205
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+
159219 // Pipe data between client and GitHub
160220 stream . pipe ( githubStream ) . pipe ( stream ) ;
161221
@@ -172,30 +232,8 @@ class SSHServer {
172232 stream . end ( ) ;
173233 } ) ;
174234
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 ) ;
199237 } catch ( error ) {
200238 console . error ( '[SSH] Error during SSH connection:' , error ) ;
201239 stream . write ( error . toString ( ) ) ;
0 commit comments