@@ -8,18 +8,23 @@ import (
88 "strings"
99 "time"
1010
11+ "github.com/1Panel-dev/1Panel/core/app/repo"
1112 "github.com/1Panel-dev/1Panel/core/global"
13+ "github.com/1Panel-dev/1Panel/core/utils/encrypt"
1214 gossh "golang.org/x/crypto/ssh"
15+ "golang.org/x/net/proxy"
1316)
1417
1518type ConnInfo struct {
16- User string `json:"user"`
17- Addr string `json:"addr"`
18- Port int `json:"port"`
19- AuthMode string `json:"authMode"`
20- Password string `json:"password"`
21- PrivateKey []byte `json:"privateKey"`
22- PassPhrase []byte `json:"passPhrase"`
19+ User string `json:"user"`
20+ Addr string `json:"addr"`
21+ Port int `json:"port"`
22+ AuthMode string `json:"authMode"`
23+ Password string `json:"password"`
24+ PrivateKey []byte `json:"privateKey"`
25+ PassPhrase []byte `json:"passPhrase"`
26+
27+ UseProxy bool `json:"useProxy"`
2328 DialTimeOut time.Duration `json:"dialTimeOut"`
2429}
2530
@@ -52,7 +57,7 @@ func NewClient(c ConnInfo) (*SSHClient, error) {
5257 if strings .Contains (c .Addr , ":" ) {
5358 proto = "tcp6"
5459 }
55- client , err := DialWithTimeout (proto , addr , config )
60+ client , err := DialWithTimeout (proto , addr , c . UseProxy , config )
5661 if nil != err {
5762 return nil , err
5863 }
@@ -240,8 +245,14 @@ func (c *SSHClient) RunWithStreamOutput(command string, outputCallback func(stri
240245 return err
241246}
242247
243- func DialWithTimeout (network , addr string , config * gossh.ClientConfig ) (* gossh.Client , error ) {
244- conn , err := net .DialTimeout (network , addr , config .Timeout )
248+ func DialWithTimeout (network , addr string , useProxy bool , config * gossh.ClientConfig ) (* gossh.Client , error ) {
249+ var conn net.Conn
250+ var err error
251+ if useProxy {
252+ conn , err = loadSSHConnByProxy (network , addr , config .Timeout )
253+ } else {
254+ conn , err = net .DialTimeout (network , addr , config .Timeout )
255+ }
245256 if err != nil {
246257 return nil , err
247258 }
@@ -256,3 +267,55 @@ func DialWithTimeout(network, addr string, config *gossh.ClientConfig) (*gossh.C
256267 }
257268 return gossh .NewClient (c , chans , reqs ), nil
258269}
270+
271+ func loadSSHConnByProxy (network , addr string , timeout time.Duration ) (net.Conn , error ) {
272+ settingRepo := repo .NewISettingRepo ()
273+ proxyType , err := settingRepo .Get (repo .WithByKey ("ProxyType" ))
274+ if err != nil {
275+ return nil , fmt .Errorf ("get proxy type from db failed, err: %v" , err )
276+ }
277+ if len (proxyType .Value ) == 0 {
278+ return nil , fmt .Errorf ("get proxy type from db failed, err: %v" , err )
279+ }
280+ proxyUrl , _ := settingRepo .Get (repo .WithByKey ("ProxyUrl" ))
281+ port , _ := settingRepo .Get (repo .WithByKey ("ProxyPort" ))
282+ user , _ := settingRepo .Get (repo .WithByKey ("ProxyUser" ))
283+ passwd , _ := settingRepo .Get (repo .WithByKey ("ProxyPasswd" ))
284+
285+ pass , _ := encrypt .StringDecrypt (passwd .Value )
286+ proxyItem := fmt .Sprintf ("%s:%s" , proxyUrl .Value , port .Value )
287+ switch proxyType .Value {
288+ case "http" , "https" :
289+ item := HTTPProxyDialer {
290+ Type : proxyType .Value ,
291+ URL : proxyItem ,
292+ User : user .Value ,
293+ Password : pass ,
294+ }
295+ return HTTPDial (item , network , addr )
296+ case "socks5" :
297+ var auth * proxy.Auth
298+ if len (user .Value ) == 0 {
299+ auth = nil
300+ } else {
301+ auth = & proxy.Auth {
302+ User : user .Value ,
303+ Password : pass ,
304+ }
305+ }
306+ dialer , err := proxy .SOCKS5 ("tcp" , proxyItem , auth , & net.Dialer {
307+ Timeout : 30 * time .Second ,
308+ KeepAlive : 30 * time .Second ,
309+ })
310+ if err != nil {
311+ return nil , fmt .Errorf ("new socks5 proxy failed, err: %v" , err )
312+ }
313+ return dialer .Dial (network , addr )
314+ default :
315+ conn , err := net .DialTimeout (network , addr , timeout )
316+ if err != nil {
317+ return nil , err
318+ }
319+ return conn , nil
320+ }
321+ }
0 commit comments