Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for healtcheck #173

Merged
merged 1 commit into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ OUTPUT:
-nc, -no-color disable colors in cli output
-v, -verbose display verbose output
-version display project version

DEBUG:
-health-check, -hc run diagnostic check up
```

## Using tlsx as library
Expand Down
9 changes: 9 additions & 0 deletions cmd/tlsx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,19 @@ func readFlags() error {
flagSet.BoolVar(&options.Version, "version", false, "display project version"),
)

flagSet.CreateGroup("debug", "Debug",
flagSet.BoolVarP(&options.HealthCheck, "hc", "health-check", false, "run diagnostic check up"),
)

if err := flagSet.Parse(); err != nil {
return errorutils.NewWithErr(err).Msgf("could not parse flags")
}

if options.HealthCheck {
gologger.Print().Msgf("%s\n", runner.DoHealthCheck(flagSet))
os.Exit(0)
}

if cfgFile != "" {
if err := flagSet.MergeConfigFile(cfgFile); err != nil {
return errorutils.NewWithErr(err).Msgf("could not read config file")
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/miekg/dns v1.1.50
github.com/projectdiscovery/dnsx v1.1.1
github.com/projectdiscovery/fastdialer v0.0.22
github.com/projectdiscovery/fileutil v0.0.3
github.com/projectdiscovery/goflags v0.1.6
github.com/projectdiscovery/gologger v1.1.7
github.com/projectdiscovery/mapcidr v1.0.3
Expand Down Expand Up @@ -60,7 +61,6 @@ require (
github.com/projectdiscovery/asnmap v0.0.1 // indirect
github.com/projectdiscovery/blackrock v0.0.0-20220628111055-35616c71b2dc // indirect
github.com/projectdiscovery/cdncheck v0.0.3 // indirect
github.com/projectdiscovery/fileutil v0.0.3 // indirect
github.com/projectdiscovery/hmap v0.0.2 // indirect
github.com/projectdiscovery/iputil v0.0.2 // indirect
github.com/projectdiscovery/networkpolicy v0.0.3 // indirect
Expand Down
81 changes: 81 additions & 0 deletions internal/runner/healthcheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package runner

import (
"fmt"
"net"
"runtime"
"strings"

"github.com/projectdiscovery/fileutil"
"github.com/projectdiscovery/goflags"
"github.com/projectdiscovery/tlsx/pkg/tlsx/openssl"
"github.com/projectdiscovery/tlsx/pkg/tlsx/tls"
"github.com/projectdiscovery/tlsx/pkg/tlsx/ztls"
)

func DoHealthCheck(flagSet *goflags.FlagSet) string {
// RW permissions on config file
cfgFilePath, _ := flagSet.GetConfigFilePath()
var test strings.Builder
test.WriteString(fmt.Sprintf("Version: %s\n", version))
test.WriteString(fmt.Sprintf("Operative System: %s\n", runtime.GOOS))
test.WriteString(fmt.Sprintf("Architecture: %s\n", runtime.GOARCH))
test.WriteString(fmt.Sprintf("Go Version: %s\n", runtime.Version()))
test.WriteString(fmt.Sprintf("Compiler: %s\n", runtime.Compiler))

var testResult string
ok, err := fileutil.IsReadable(cfgFilePath)
if ok {
testResult = "Ok"
} else {
testResult = "Ko"
}
if err != nil {
testResult += fmt.Sprintf(" (%s)", err)
}
test.WriteString(fmt.Sprintf("Config file \"%s\" Read => %s\n", cfgFilePath, testResult))
ok, err = fileutil.IsWriteable(cfgFilePath)
if ok {
testResult = "Ok"
} else {
testResult = "Ko"
}
if err != nil {
testResult += fmt.Sprintf(" (%s)", err)
}
test.WriteString(fmt.Sprintf("Config file \"%s\" Write => %s\n", cfgFilePath, testResult))
c4, err := net.Dial("tcp4", "scanme.sh:80")
if err == nil && c4 != nil {
c4.Close()
}
testResult = "Ok"
if err != nil {
testResult = fmt.Sprintf("Ko (%s)", err)
}
test.WriteString(fmt.Sprintf("IPv4 connectivity to scanme.sh:80 => %s\n", testResult))
c6, err := net.Dial("tcp6", "scanme.sh:80")
if err == nil && c6 != nil {
c6.Close()
}
testResult = "Ok"
if err != nil {
testResult = fmt.Sprintf("Ko (%s)", err)
}
test.WriteString(fmt.Sprintf("IPv6 connectivity to scanme.sh:80 => %s\n", testResult))

test.WriteString("Supported Engines\n")
test.WriteString("ctls\n")
test.WriteString(fmt.Sprintf("TLS: %s\n", strings.Join(tls.SupportedTlsVersions, ", ")))
test.WriteString(fmt.Sprintf("Ciphers: %s\n", strings.Join(tls.AllCiphersNames, ", ")))

test.WriteString("ztls\n")
test.WriteString(fmt.Sprintf("TLS: %s\n", strings.Join(ztls.SupportedTlsVersions, ", ")))
test.WriteString(fmt.Sprintf("Ciphers: %s\n", strings.Join(ztls.AllCiphersNames, ", ")))

if openssl.IsAvailable() {
test.WriteString("openssl\n")
test.WriteString(fmt.Sprintf("location: %s\n", openssl.BinaryPath))
}

return test.String()
}
2 changes: 2 additions & 0 deletions pkg/tlsx/clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ type Options struct {
ClientHello bool
// ServerHello include server hello (only ztls)
ServerHello bool
// HealthCheck performs a capabilities healthcheck
HealthCheck bool

// Fastdialer is a fastdialer dialer instance
Fastdialer *fastdialer.Dialer
Expand Down
12 changes: 6 additions & 6 deletions pkg/tlsx/openssl/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var (
)

var (
binaryPath = ""
BinaryPath = ""
OPENSSL_CONF = ""
IsLibreSSL = false
PkgTag = "" // Header or Tag value that will be reflected in all errors (include openssl(libressl) and version)
Expand All @@ -45,11 +45,11 @@ CipherString = DEFAULT:@SECLEVEL=1

func init() {
if runtime.GOOS == "windows" {
binaryPath, _ = exec.LookPath("openssl.exe")
BinaryPath, _ = exec.LookPath("openssl.exe")
} else {
binaryPath, _ = exec.LookPath("openssl")
BinaryPath, _ = exec.LookPath("openssl")
}
if binaryPath == "" {
if BinaryPath == "" {
// not available or failed to get return
gologger.Debug().Label("openssl").Msgf("openssl binary not found skipping")
return
Expand Down Expand Up @@ -94,12 +94,12 @@ func openSSLSetup() errorutils.Error {

// check if openssl if available for use
func IsAvailable() bool {
return binaryPath != ""
return BinaryPath != ""
}

// UseOpenSSLBinary From Path
func UseOpenSSLBinary(binpath string) {
binaryPath = binpath
BinaryPath = binpath
if err := openSSLSetup(); err != nil {
// do not fallback
gologger.Fatal().Label("openssl").Msgf(err.Error())
Expand Down
4 changes: 2 additions & 2 deletions pkg/tlsx/openssl/openssl_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func execOpenSSL(ctx context.Context, args []string) (*CMDOUT, error) {
3. error purely realted to I/O and command execution
*/
var outbuff, inbuff, errbuff bytes.Buffer
cmd := exec.CommandContext(ctx, binaryPath)
cmd := exec.CommandContext(ctx, BinaryPath)
if !IsLibreSSL {
newenv := "OPENSSL_CONF=" + OPENSSL_CONF
cmd.Env = append(os.Environ(), newenv)
Expand Down Expand Up @@ -74,7 +74,7 @@ func getResponse(ctx context.Context, opts *Options) (*Response, errorutils.Erro
}
result, err := execOpenSSL(ctx, args)
if err != nil {
return nil, errorutils.NewWithErr(err).WithTag(PkgTag, binaryPath).Msgf("failed to execute openssl got %v", result.Stderr).Msgf(commadFormat, result.Command)
return nil, errorutils.NewWithErr(err).WithTag(PkgTag, BinaryPath).Msgf("failed to execute openssl got %v", result.Stderr).Msgf(commadFormat, result.Command)
}
response := &Response{}
if !strings.Contains(result.Stdout, "CONNECTED") {
Expand Down