Skip to content

Commit

Permalink
make it possible to bind to an interface on unix
Browse files Browse the repository at this point in the history
  • Loading branch information
arriven committed May 3, 2022
1 parent 49ec298 commit a7edd00
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 19 deletions.
24 changes: 11 additions & 13 deletions src/core/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"go.uber.org/zap"

"github.com/Arriven/db1000n/src/utils"
"github.com/Arriven/db1000n/src/utils/templates"
)

// RequestConfig is a struct representing the config of a single request
Expand Down Expand Up @@ -102,6 +101,7 @@ type ClientConfig struct {
MaxIdleConns *int
ProxyURLs string
LocalAddr string
Interface string
}

// NewClient creates a fasthttp client based on the config.
Expand All @@ -112,17 +112,15 @@ func NewClient(ctx context.Context, clientConfig ClientConfig, logger *zap.Logge
)

timeout := utils.NonNilOrDefault(clientConfig.Timeout, defaultTimeout)

tlsConfig := &tls.Config{
tlsConfig := utils.NonNilOrDefault(clientConfig.TLSClientConfig, tls.Config{
InsecureSkipVerify: true, //nolint:gosec // This is intentional
}
if clientConfig.TLSClientConfig != nil {
tlsConfig = clientConfig.TLSClientConfig
}

proxyURLs := templates.ParseAndExecute(logger, clientConfig.ProxyURLs, ctx)
localAddr := utils.ResolveAddr("tcp", clientConfig.LocalAddr)
proxyFunc := utils.GetProxyFunc(proxyURLs, localAddr, timeout, true)
})
proxyFunc := utils.GetProxyFunc(utils.ProxyParams{
URLs: clientConfig.ProxyURLs,
LocalAddr: utils.ResolveAddr("tcp", clientConfig.LocalAddr),
Timeout: timeout,
Interface: clientConfig.Interface,
}, true)

if clientConfig.StaticHost != nil {
makeHostClient := func(tls bool) *fasthttp.HostClient {
Expand All @@ -137,7 +135,7 @@ func NewClient(ctx context.Context, clientConfig ClientConfig, logger *zap.Logge
NoDefaultUserAgentHeader: true, // Don't send: User-Agent: fasthttp
DisableHeaderNamesNormalizing: true, // If you set the case on your headers correctly you can enable this
DisablePathNormalizing: true,
TLSConfig: tlsConfig,
TLSConfig: &tlsConfig,
Dial: dialViaProxyFunc(proxyFunc, "tcp"),
}
}
Expand All @@ -161,7 +159,7 @@ func NewClient(ctx context.Context, clientConfig ClientConfig, logger *zap.Logge
NoDefaultUserAgentHeader: true, // Don't send: User-Agent: fasthttp
DisableHeaderNamesNormalizing: true, // If you set the case on your headers correctly you can enable this
DisablePathNormalizing: true,
TLSConfig: tlsConfig,
TLSConfig: &tlsConfig,
Dial: dialViaProxyFunc(proxyFunc, "tcp"),
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/core/packetgen/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type netConnConfig struct {
Timeout time.Duration
ProxyURLs string
LocalAddr string
Interface string
Reader *netReaderConfig
TLSClientConfig *tls.Config
}
Expand Down Expand Up @@ -150,7 +151,13 @@ func readStub(ctx context.Context, conn net.Conn, c *netReaderConfig) {
}

func openNetConn(ctx context.Context, c netConnConfig) (*netConn, error) {
conn, err := utils.GetProxyFunc(c.ProxyURLs, utils.ResolveAddr(c.Protocol, c.LocalAddr), c.Timeout, false)(c.Protocol, c.Address)
proxyParams := utils.ProxyParams{
URLs: c.ProxyURLs,
LocalAddr: utils.ResolveAddr(c.Protocol, c.LocalAddr),
Interface: c.Interface,
Timeout: c.Timeout,
}
conn, err := utils.GetProxyFunc(proxyParams, false)(c.Protocol, c.Address)

switch {
case err != nil:
Expand Down
3 changes: 3 additions & 0 deletions src/job/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type GlobalConfig struct {

ProxyURLs string
LocalAddr string
Interface string
SkipEncrypted bool
EnablePrimitiveJobs bool
ScaleFactor int
Expand All @@ -59,6 +60,8 @@ func NewGlobalConfigWithFlags() *GlobalConfig {
"system proxy to set by default (can be a comma-separated list or a template)")
flag.StringVar(&res.LocalAddr, "local-address", utils.GetEnvStringDefault("LOCAL_ADDRESS", ""),
"specify ip address of local interface to use")
flag.StringVar(&res.Interface, "interface", utils.GetEnvStringDefault("NETWORK_INTERFACE", ""),
"specify which interface to bind to for attacks (ignored on windows)")
flag.BoolVar(&res.SkipEncrypted, "skip-encrypted", utils.GetEnvBoolDefault("SKIP_ENCRYPTED", false),
"set to true if you want to only run plaintext jobs from the config for security considerations")
flag.BoolVar(&res.EnablePrimitiveJobs, "enable-primitive", utils.GetEnvBoolDefault("ENABLE_PRIMITIVE", true),
Expand Down
4 changes: 4 additions & 0 deletions src/job/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ func getHTTPJobConfigs(ctx context.Context, args config.Args, global GlobalConfi
clientConfig.LocalAddr = templates.ParseAndExecute(logger, global.LocalAddr, ctx)
}

if global.Interface != "" {
clientConfig.Interface = templates.ParseAndExecute(logger, global.Interface, ctx)
}

requestTpl, err = templates.ParseMapStruct(jobConfig.Request)
if err != nil {
return nil, nil, nil, fmt.Errorf("error parsing request config: %w", err)
Expand Down
4 changes: 4 additions & 0 deletions src/job/packetgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ func parsePacketgenArgs(ctx context.Context, args config.Args, globalConfig *Glo
jobConfig.Connection.Args["local_addr"] = templates.ParseAndExecute(logger, globalConfig.LocalAddr, ctx)
}

if globalConfig.Interface != "" {
jobConfig.Connection.Args["interface"] = templates.ParseAndExecute(logger, globalConfig.Interface, ctx)
}

return &packetgenJobConfig{
BasicJobConfig: jobConfig.BasicJobConfig,
StaticPacket: jobConfig.StaticPacket,
Expand Down
17 changes: 12 additions & 5 deletions src/utils/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ import (

type ProxyFunc func(network, addr string) (net.Conn, error)

func GetProxyFunc(proxyURLs string, localAddr net.Addr, timeout time.Duration, httpEnabled bool) ProxyFunc {
direct := &net.Dialer{Timeout: timeout, LocalAddr: localAddr}
if proxyURLs == "" {
type ProxyParams struct {
URLs string
LocalAddr net.Addr
Interface string
Timeout time.Duration
}

func GetProxyFunc(params ProxyParams, httpEnabled bool) ProxyFunc {
direct := &net.Dialer{Timeout: params.Timeout, LocalAddr: params.LocalAddr, Control: BindToInterface(params.Interface)}
if params.URLs == "" {
return proxy.FromEnvironmentUsing(direct).Dial
}

proxies := strings.Split(proxyURLs, ",")
proxies := strings.Split(params.URLs, ",")

// We need to dial new proxy on each call
return func(network, addr string) (net.Conn, error) {
Expand All @@ -42,7 +49,7 @@ func GetProxyFunc(proxyURLs string, localAddr net.Addr, timeout time.Duration, h
return socks.Dial(u.String())(network, addr)
default:
if httpEnabled {
return fasthttpproxy.FasthttpHTTPDialerTimeout(u.Host, timeout)(addr)
return fasthttpproxy.FasthttpHTTPDialerTimeout(u.Host, params.Timeout)(addr)
}

return nil, fmt.Errorf("unsupported proxy scheme %v", u.Scheme)
Expand Down
16 changes: 16 additions & 0 deletions src/utils/utils_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package utils

import (
"syscall"

"go.uber.org/zap"
sys "golang.org/x/sys/unix"
)
Expand All @@ -20,3 +22,17 @@ func UpdateRLimit(logger *zap.Logger) error {

return sys.Setrlimit(sys.RLIMIT_NOFILE, &rLimit)
}

func BindToInterface(name string) func(network, address string, conn syscall.RawConn) error {
return func(network, address string, conn syscall.RawConn) error {
var operr error

if err := conn.Control(func(fd uintptr) {
operr = syscall.BindToDevice(int(fd), name)
}); err != nil {
return err
}

return operr
}
}
6 changes: 6 additions & 0 deletions src/utils/utils_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ import (
func UpdateRLimit(logger *zap.Logger) error {
return nil
}

func BindToInterface(name string) func(network, address string, conn syscall.RawConn) error {
return func(network, address string, conn syscall.RawConn) error {
return nil
}
}

0 comments on commit a7edd00

Please sign in to comment.