-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add CMD protocol that SSH's and execs the command
- Loading branch information
1 parent
368e74d
commit c880392
Showing
5 changed files
with
102 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package checkers | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"golang.org/x/crypto/ssh" | ||
"golang.org/x/crypto/ssh/agent" | ||
) | ||
|
||
type CMDChecker struct { | ||
sshKeyPath string | ||
} | ||
|
||
func NewCMDChecker() *CMDChecker { | ||
return &CMDChecker{ | ||
sshKeyPath: os.Getenv("SSH_KEY_PATH"), | ||
} | ||
} | ||
|
||
func (c *CMDChecker) Protocol() Protocol { | ||
return CMD | ||
} | ||
|
||
func (c *CMDChecker) Check(ctx context.Context, address string) CheckResult { | ||
start := time.Now() | ||
|
||
config, err := c.getSSHConfig() | ||
if err != nil { | ||
return newFailedResult(time.Since(start), fmt.Errorf("ssh config error: %w", err)) | ||
} | ||
|
||
client, err := ssh.Dial("tcp", address, config) | ||
if err != nil { | ||
return newFailedResult(time.Since(start), fmt.Errorf("ssh dial error: %w", err)) | ||
} | ||
defer client.Close() | ||
|
||
session, err := client.NewSession() | ||
if err != nil { | ||
return newFailedResult(time.Since(start), fmt.Errorf("session error: %w", err)) | ||
} | ||
defer session.Close() | ||
|
||
if err := session.Run(ctx.Value("cmd").(string)); err != nil { | ||
return newFailedResult(time.Since(start), fmt.Errorf("command error: %w", err)) | ||
} | ||
|
||
return newSuccessResult(time.Since(start)) | ||
} | ||
|
||
func (c *CMDChecker) getSSHConfig() (*ssh.ClientConfig, error) { | ||
var auth []ssh.AuthMethod | ||
|
||
if c.sshKeyPath != "" { | ||
key, err := os.ReadFile(filepath.Clean(c.sshKeyPath)) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to read SSH key: %w", err) | ||
} | ||
|
||
signer, err := ssh.ParsePrivateKey(key) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to parse SSH key: %w", err) | ||
} | ||
auth = append(auth, ssh.PublicKeys(signer)) | ||
} else { | ||
socket := os.Getenv("SSH_AUTH_SOCK") | ||
if socket != "" { | ||
conn, err := net.Dial("unix", socket) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to connect to SSH agent: %w", err) | ||
} | ||
|
||
agentClient := agent.NewClient(conn) | ||
auth = append(auth, ssh.PublicKeysCallback(agentClient.Signers)) | ||
} | ||
} | ||
|
||
if len(auth) == 0 { | ||
return nil, fmt.Errorf("no SSH authentication methods available") | ||
} | ||
|
||
return &ssh.ClientConfig{ | ||
User: os.Getenv("SSH_USER"), | ||
Auth: auth, | ||
HostKeyCallback: ssh.InsecureIgnoreHostKey(), | ||
Check failure Code scanning / CodeQL Use of insecure HostKeyCallback implementation High
Configuring SSH ClientConfig with insecure HostKeyCallback implementation from
this source Error loading related location Loading |
||
Timeout: 10 * time.Second, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters