Skip to content
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
109 changes: 69 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ You can download the binary for your platform from [Releases](https://github.com
Example:

```shell
HPTS_RELEASE=v1.8.2; wget -v https://github.com/shadowy-pycoder/go-http-proxy-to-socks/releases/download/$HPTS_RELEASE/gohpts-$HPTS_RELEASE-linux-amd64.tar.gz -O gohpts && tar xvzf gohpts && mv -f gohpts-$HPTS_RELEASE-linux-amd64 gohpts && ./gohpts -h
HPTS_RELEASE=v1.8.3; wget -v https://github.com/shadowy-pycoder/go-http-proxy-to-socks/releases/download/$HPTS_RELEASE/gohpts-$HPTS_RELEASE-linux-amd64.tar.gz -O gohpts && tar xvzf gohpts && mv -f gohpts-$HPTS_RELEASE-linux-amd64 gohpts && ./gohpts -h
```

Alternatively, you can install it using `go install` command (requires Go [1.24](https://go.dev/doc/install) or later):
Expand Down Expand Up @@ -135,45 +135,36 @@ GitHub: https://github.com/shadowy-pycoder/go-http-proxy-to-socks

Usage: gohpts [OPTIONS]
Options:
-h Show this help message and exit.
-D Run as a daemon (provide -logfile to see logs)
-M value
Transparent proxy mode: [redirect tproxy]
-T string
Address of transparent proxy server (no HTTP)
-U string
User for HTTP proxy (basic auth). This flag invokes prompt for password (not echoed to terminal)
-auto
Automatically setup iptables for transparent proxy (requires elevated privileges)
-body
Collect request and response body for HTTP sniffing
-c string
Path to certificate PEM encoded file
-d Show logs in DEBUG mode
-f string
Path to server configuration file in YAML format
-j Show logs in JSON format
-k string
Path to private key PEM encoded file
-l string
Address of HTTP proxy server (default "127.0.0.1:8080")
-logfile string
Log file path (Default: stdout)
-mark uint
Set the mark for each packet sent through transparent proxy
-nocolor
Disable colored output for logs (no effect if -j flag specified)
-s string
Address of SOCKS5 proxy server (default "127.0.0.1:1080")
-sniff
Enable traffic sniffing for HTTP and TLS
-snifflog string
Sniffed traffic log file path (Default: the same as -logfile)
-t string
Address of transparent proxy server (it starts along with HTTP proxy server)
-u string
User for SOCKS5 proxy authentication. This flag invokes prompt for password (not echoed to terminal)
-v print version
-h Show this help message and exit
-v Show version and build information
-D Run as a daemon (provide -logfile to see logs)

Proxy:
-l Address of HTTP proxy server (default "127.0.0.1:8080")
-s Address of SOCKS5 proxy server (default "127.0.0.1:1080")
-c Path to certificate PEM encoded file
-k Path to private key PEM encoded file
-U User for HTTP proxy (basic auth). This flag invokes prompt for password (not echoed to terminal)
-u User for SOCKS5 proxy authentication. This flag invokes prompt for password (not echoed to terminal)
-f Path to server configuration file in YAML format (overrides other proxy flags)

Logs:
-d Show logs in DEBUG mode
-j Show logs in JSON format
-logfile Log file path (Default: stdout)
-nocolor Disable colored output for logs (no effect if -j flag specified)

Sniffing:
-sniff Enable traffic sniffing for HTTP and TLS
-snifflog Sniffed traffic log file path (Default: the same as -logfile)
-body Collect request and response body for HTTP traffic (credentials, tokens, etc)

TProxy:
-t Address of transparent proxy server (it starts along with HTTP proxy server)
-T Address of transparent proxy server (no HTTP)
-M Transparent proxy mode: (redirect, tproxy)
-auto Automatically setup iptables for transparent proxy (requires elevated privileges)
-mark Set mark for each packet sent through transparent proxy (Default: redirect 0, tproxy 100)
```

### Configuration via CLI flags
Expand Down Expand Up @@ -450,6 +441,44 @@ ip netns del ns-client
ip link del veth1
```

### Auto configuration for `tproxy` mode

To configure your system automatically, run the following command (for example, on a separate VM):

```shell
ssh remote -D 1080 -Nf
sudo env PATH=$PATH gohpts -d -T 8888 -M tproxy -auto -mark 100
```

Run the following on your host:

```shell
ip route show default > /tmp/default-route.txt

ip route add 0.0.0.0/1 via 192.168.0.1 # change with ip of your VM
ip route add 128.0.0.0/1 via 192.168.0.1
```

Test connection:

```shell
curl http://example.com #check logs on your VM
```

Undo everything:

```shell
ip route del 0.0.0.0/1 via 192.168.0.1 2>/dev/null || true
ip route del 128.0.0.0/1 via 192.168.0.1 2>/dev/null || true

if [[ -f /tmp/default-route.txt ]]; then
eval $(awk '{print "ip route add "$0}' /tmp/default-route.txt)
rm -f /tmp/default-route.txt
else
echo "Something went wrong"
fi
```

## Traffic sniffing

[[Back]](#table-of-contents)
Expand Down
47 changes: 38 additions & 9 deletions cmd/gohpts/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,37 @@ GitHub: https://github.com/shadowy-pycoder/go-http-proxy-to-socks

Usage: gohpts [OPTIONS]
Options:
-h Show this help message and exit.
-h Show this help message and exit
-v Show version and build information
-D Run as a daemon (provide -logfile to see logs)

Proxy:
-l Address of HTTP proxy server (default "127.0.0.1:8080")
-s Address of SOCKS5 proxy server (default "127.0.0.1:1080")
-c Path to certificate PEM encoded file
-k Path to private key PEM encoded file
-U User for HTTP proxy (basic auth). This flag invokes prompt for password (not echoed to terminal)
-u User for SOCKS5 proxy authentication. This flag invokes prompt for password (not echoed to terminal)
-f Path to server configuration file in YAML format (overrides other proxy flags)

Logs:
-d Show logs in DEBUG mode
-j Show logs in JSON format
-logfile Log file path (Default: stdout)
-nocolor Disable colored output for logs (no effect if -j flag specified)

Sniffing:
-sniff Enable traffic sniffing for HTTP and TLS
-snifflog Sniffed traffic log file path (Default: the same as -logfile)
-body Collect request and response body for HTTP traffic (credentials, tokens, etc)
`
const usageTproxy string = `
TProxy:
-t Address of transparent proxy server (it starts along with HTTP proxy server)
-T Address of transparent proxy server (no HTTP)
-M Transparent proxy mode: (redirect, tproxy)
-auto Automatically setup iptables for transparent proxy (requires elevated privileges)
-mark Set mark for each packet sent through transparent proxy (Default: redirect 0, tproxy 100)
`

func root(args []string) error {
Expand All @@ -41,7 +71,7 @@ func root(args []string) error {
flags.StringVar(&conf.ServerUser, "U", "", "User for HTTP proxy (basic auth). This flag invokes prompt for password (not echoed to terminal)")
flags.StringVar(&conf.CertFile, "c", "", "Path to certificate PEM encoded file")
flags.StringVar(&conf.KeyFile, "k", "", "Path to private key PEM encoded file")
flags.StringVar(&conf.ServerConfPath, "f", "", "Path to server configuration file in YAML format")
flags.StringVar(&conf.ServerConfPath, "f", "", "Path to server configuration file in YAML format (overrides other proxy flags)")
daemon := flags.Bool("D", false, "Run as a daemon (provide -logfile to see logs)")
if runtime.GOOS == tproxyOS {
flags.StringVar(&conf.TProxy, "t", "", "Address of transparent proxy server (it starts along with HTTP proxy server)")
Expand All @@ -55,24 +85,26 @@ func root(args []string) error {
return nil
})
flags.BoolVar(&conf.Auto, "auto", false, "Automatically setup iptables for transparent proxy (requires elevated privileges)")
flags.UintVar(&conf.Mark, "mark", 0, "Set the mark for each packet sent through transparent proxy")
flags.UintVar(&conf.Mark, "mark", 0, "Set mark for each packet sent through transparent proxy (Default: redirect 0, tproxy 100)")
}
flags.StringVar(&conf.LogFilePath, "logfile", "", "Log file path (Default: stdout)")
flags.BoolVar(&conf.Debug, "d", false, "Show logs in DEBUG mode")
flags.BoolVar(&conf.Json, "j", false, "Show logs in JSON format")
flags.BoolVar(&conf.Sniff, "sniff", false, "Enable traffic sniffing for HTTP and TLS")
flags.StringVar(&conf.SniffLogFile, "snifflog", "", "Sniffed traffic log file path (Default: the same as -logfile)")
flags.BoolVar(&conf.NoColor, "nocolor", false, "Disable colored output for logs (no effect if -j flag specified)")
flags.BoolVar(&conf.Body, "body", false, "Collect request and response body for HTTP sniffing")
flags.BoolFunc("v", "print version", func(flagValue string) error {
flags.BoolVar(&conf.Body, "body", false, "Collect request and response body for HTTP traffic (credentials, tokens, etc)")
flags.BoolFunc("v", "Show version and build information", func(flagValue string) error {
fmt.Printf("%s (built for %s %s with %s)\n", gohpts.Version, runtime.GOOS, runtime.GOARCH, runtime.Version())
os.Exit(0)
return nil
})

flags.Usage = func() {
fmt.Print(usagePrefix)
flags.PrintDefaults()
if runtime.GOOS == tproxyOS {
fmt.Print(usageTproxy)
}
}

if err := flags.Parse(args); err != nil {
Expand Down Expand Up @@ -107,9 +139,6 @@ func root(args []string) error {
if !seen["t"] && !seen["T"] {
return fmt.Errorf("-auto requires -t or -T flag")
}
if conf.TProxyMode != "redirect" {
return fmt.Errorf("-auto is available only for -M redirect")
}
}
if seen["mark"] {
if !seen["t"] && !seen["T"] {
Expand Down
Loading