Skip to content

Commit e099cfd

Browse files
Fixed nocolor, headerlen spamming, updated README.md
1 parent 3f10ff1 commit e099cfd

File tree

7 files changed

+59
-31
lines changed

7 files changed

+59
-31
lines changed

README.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
![GitHub Release](https://img.shields.io/github/v/release/shadowy-pycoder/go-http-proxy-to-socks)
88
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/shadowy-pycoder/go-http-proxy-to-socks/total)
99

10+
![GoHPTS - Colors example](resources/sniffing_color.png)
11+
1012
## Table of contents
1113

1214
- [Introduction](#introduction)
@@ -19,6 +21,8 @@
1921
- [redirect (via NAT and SO_ORIGINAL_DST)](#redirect-via-nat-and-so_original_dst)
2022
- [tproxy (via MANGLE and IP_TRANSPARENT)](#tproxy-via-mangle-and-ip_transparent)
2123
- [Traffic sniffing](#traffic-sniffing)
24+
- [JSON format](#json-format)
25+
- [Colored format](#colored-format)
2226
- [Links](#links)
2327
- [Contributing](#contributing)
2428
- [License](#license)
@@ -93,7 +97,7 @@ You can download the binary for your platform from [Releases](https://github.com
9397
Example:
9498

9599
```shell
96-
HPTS_RELEASE=v1.7.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
100+
HPTS_RELEASE=v1.8.0; 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
97101
```
98102

99103
Alternatively, you can install it using `go install` command (requires Go [1.24](https://go.dev/doc/install) or later):
@@ -154,7 +158,7 @@ Options:
154158
-logfile string
155159
Log file path (Default: stdout)
156160
-nocolor
157-
Disable colored output for logs in stdout (no effect if log file provided or -j flag specified)
161+
Disable colored output for logs (no effect if -j flag specified)
158162
-s string
159163
Address of SOCKS5 proxy server (default "127.0.0.1:1080")
160164
-sniff
@@ -432,6 +436,8 @@ ip link del veth1
432436
433437
`GoHPTS` proxy allows one to capture and monitor traffic that goes through the service. This procces is known as `traffic sniffing`, `packet sniffing` or just `sniffing`. In particular, proxy tries to identify whether it is a plain text (HTTP) or TLS traffic, and after identification is done, it parses request/response metadata and writes it to the file or console. In the case of `GoHTPS` proxy a parsed metadata looks like the following (TLS Handshake):
434438
439+
### JSON format
440+
435441
```json
436442
[
437443
{
@@ -553,13 +559,35 @@ And HTTP request with curl:
553559
Usage as simple as specifying `-sniff` flag along with regular flags
554560
555561
```shell
556-
gohpts -d -t 8888 -M redirect -sniff
562+
gohpts -d -t 8888 -M redirect -sniff -j
557563
```
558564
559565
You can also specify a file to which write sniffed traffic:
560566
561567
```shell
562-
gohpts -d -sniff -snifflog ~/sniff.log
568+
gohpts -sniff -snifflog ~/sniff.log -j
569+
```
570+
571+
### Colored format
572+
573+
You can see the example of colored output in the picture at the very top. In this mode, `GoHPTS` tries to highlight import information such as TLS Handshake, HTTP metadata, something that looks line login/passwords or different types of auth and secret tokens. The output is limited comparing to JSON but way easier to read for humans.
574+
575+
To run `GoHPTS` in this mode you use the following flags:
576+
577+
```shell
578+
gohpts -sniff -body
579+
```
580+
581+
You can combine sniffing with transparent mode:
582+
583+
```shell
584+
./gohpts -T 8888 -M redirect -sniff -body
585+
```
586+
587+
To disable colors add `-nocolor`:
588+
589+
```shell
590+
gohpts -sniff -body -nocolor
563591
```
564592
565593
## Links

cmd/gohpts/cli.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func root(args []string) error {
6161
flags.BoolVar(&conf.Json, "j", false, "Show logs in JSON format")
6262
flags.BoolVar(&conf.Sniff, "sniff", false, "Enable traffic sniffing for HTTP and TLS")
6363
flags.StringVar(&conf.SniffLogFile, "snifflog", "", "Sniffed traffic log file path (Default: the same as -logfile)")
64-
flags.BoolVar(&conf.NoColor, "nocolor", false, "Disable colored output for logs in stdout (no effect if log file provided or -j flag specified)")
64+
flags.BoolVar(&conf.NoColor, "nocolor", false, "Disable colored output for logs (no effect if -j flag specified)")
6565
flags.BoolVar(&conf.Body, "body", false, "Collect request and response body for HTTP sniffing")
6666
flags.BoolFunc("v", "print version", func(flagValue string) error {
6767
fmt.Printf("%s (built for %s %s with %s)\n", gohpts.Version, runtime.GOOS, runtime.GOARCH, runtime.Version())
@@ -84,7 +84,7 @@ func root(args []string) error {
8484
}
8585
if seen["t"] {
8686
if !seen["M"] {
87-
return fmt.Errorf("Transparent proxy mode is not provided: -M flag")
87+
return fmt.Errorf("transparent proxy mode is not provided: -M flag")
8888
}
8989
}
9090
if seen["T"] {
@@ -94,12 +94,12 @@ func root(args []string) error {
9494
}
9595
}
9696
if !seen["M"] {
97-
return fmt.Errorf("Transparent proxy mode is not provided: -M flag")
97+
return fmt.Errorf("transparent proxy mode is not provided: -M flag")
9898
}
9999
}
100100
if seen["M"] {
101101
if !seen["t"] && !seen["T"] {
102-
return fmt.Errorf("Transparent proxy mode requires -t or -T flag")
102+
return fmt.Errorf("transparent proxy mode requires -t or -T flag")
103103
}
104104
}
105105
if seen["f"] {

gohpts.go

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ type proxyapp struct {
115115
rrIndexReset uint32
116116
sniff bool
117117
nocolor bool
118-
sniffnocolor bool
119118
body bool
120119
json bool
121120

@@ -150,7 +149,7 @@ func randColor() func(string) *colors.Color {
150149

151150
func (p *proxyapp) getId() string {
152151
id := uuid.New()
153-
if p.sniffnocolor {
152+
if p.nocolor {
154153
return fmt.Sprintf("%s", colors.WrapBrackets(id.String()))
155154
}
156155
return randColor()(fmt.Sprintf("%s", colors.WrapBrackets(id.String()))).String()
@@ -182,7 +181,7 @@ func (p *proxyapp) colorizeHTTP(req *http.Request, resp *http.Response, reqBodyS
182181
if ts {
183182
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
184183
}
185-
if p.sniffnocolor {
184+
if p.nocolor {
186185
sb.WriteString(id)
187186
sb.WriteString(fmt.Sprintf(" %s %s %s ", req.Method, req.URL, req.Proto))
188187
if req.UserAgent() != "" {
@@ -237,7 +236,7 @@ func (p *proxyapp) colorizeHTTP(req *http.Request, resp *http.Response, reqBodyS
237236
sb.WriteString("\n")
238237
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
239238
sb.WriteString(id)
240-
sb.WriteString(colors.GreenBg(" req_body: ").String())
239+
sb.WriteString(colors.RedBgDark(" req_body: ").String())
241240
sb.WriteString(b)
242241
}
243242
}
@@ -247,7 +246,7 @@ func (p *proxyapp) colorizeHTTP(req *http.Request, resp *http.Response, reqBodyS
247246
sb.WriteString("\n")
248247
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
249248
sb.WriteString(id)
250-
sb.WriteString(colors.GreenBg(" resp_body: ").String())
249+
sb.WriteString(colors.RedBgDark(" resp_body: ").String())
251250
sb.WriteString(b)
252251
}
253252
}
@@ -257,10 +256,10 @@ func (p *proxyapp) colorizeHTTP(req *http.Request, resp *http.Response, reqBodyS
257256

258257
func (p *proxyapp) colorizeTLS(req *layers.TLSClientHello, resp *layers.TLSServerHello, id string) string {
259258
var sb strings.Builder
260-
if p.sniffnocolor {
259+
if p.nocolor {
261260
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
262261
sb.WriteString(id)
263-
sb.WriteString(fmt.Sprintf(" %s:", req.TypeDesc))
262+
sb.WriteString(fmt.Sprintf(" %s ", req.TypeDesc))
264263
if req.Length > 0 {
265264
sb.WriteString(fmt.Sprintf(" Len: %d", req.Length))
266265
}
@@ -277,7 +276,7 @@ func (p *proxyapp) colorizeTLS(req *layers.TLSClientHello, resp *layers.TLSServe
277276
sb.WriteString(fmt.Sprintf(" ALPN: %v", req.ALPN))
278277
}
279278
sb.WriteString(" -> ")
280-
sb.WriteString(fmt.Sprintf("%s:", resp.TypeDesc))
279+
sb.WriteString(fmt.Sprintf("%s ", resp.TypeDesc))
281280
if resp.Length > 0 {
282281
sb.WriteString(fmt.Sprintf(" Len: %d", resp.Length))
283282
}
@@ -293,7 +292,7 @@ func (p *proxyapp) colorizeTLS(req *layers.TLSClientHello, resp *layers.TLSServe
293292
} else {
294293
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
295294
sb.WriteString(id)
296-
sb.WriteString(colors.Magenta(fmt.Sprintf(" %s:", req.TypeDesc)).Bold())
295+
sb.WriteString(colors.Magenta(fmt.Sprintf(" %s ", req.TypeDesc)).Bold())
297296
if req.Length > 0 {
298297
sb.WriteString(colors.BeigeBg(fmt.Sprintf(" Len: %d", req.Length)).String())
299298
}
@@ -310,7 +309,7 @@ func (p *proxyapp) colorizeTLS(req *layers.TLSClientHello, resp *layers.TLSServe
310309
sb.WriteString(colors.BlueBg(fmt.Sprintf(" ALPN: %v", req.ALPN)).String())
311310
}
312311
sb.WriteString(colors.MagentaBg(" -> ").String())
313-
sb.WriteString(colors.LightBlue(fmt.Sprintf("%s:", resp.TypeDesc)).Bold())
312+
sb.WriteString(colors.LightBlue(fmt.Sprintf("%s ", resp.TypeDesc)).Bold())
314313
if resp.Length > 0 {
315314
sb.WriteString(colors.BeigeBg(fmt.Sprintf(" Len: %d", resp.Length)).String())
316315
}
@@ -343,7 +342,7 @@ func (p *proxyapp) highlightPatterns(line string) (string, bool) {
343342
func (p *proxyapp) replace(line string, re *regexp.Regexp, color func(string) *colors.Color, matched bool) (string, bool) {
344343
if re.MatchString(line) {
345344
matched = true
346-
if !p.sniffnocolor {
345+
if !p.nocolor {
347346
line = re.ReplaceAllStringFunc(line, func(s string) string {
348347
return color(s).String()
349348
})
@@ -366,10 +365,10 @@ func (p *proxyapp) colorizeBody(b *[]byte) string {
366365

367366
func (p *proxyapp) colorizeTimestamp() string {
368367
ts := time.Now()
369-
if p.sniffnocolor {
368+
if p.nocolor {
370369
return colors.WrapBrackets(ts.Format(time.TimeOnly))
371370
}
372-
return colors.GrayBg(colors.WrapBrackets(ts.Format(time.TimeOnly))).String()
371+
return colors.Gray(colors.WrapBrackets(ts.Format(time.TimeOnly))).String()
373372
}
374373

375374
func (p *proxyapp) colorizeTunnel(req, resp layers.Layer, sniffheader *[]string, id string) error {
@@ -936,13 +935,13 @@ func (p *proxyapp) handleTunnel(w http.ResponseWriter, r *http.Request) {
936935
}
937936
} else {
938937
var sb strings.Builder
939-
if p.sniffnocolor {
938+
if p.nocolor {
940939
sb.WriteString(id)
941940
sb.WriteString(fmt.Sprintf(" Src: %s->%s -> Dst: %s->%s", srcConn.LocalAddr(), srcConn.RemoteAddr(), dstConn.LocalAddr(), dstConn.RemoteAddr()))
942941
sb.WriteString("\n")
943942
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
944943
sb.WriteString(id)
945-
sb.WriteString(fmt.Sprintf(" %s %s %s ", r.Method, r.URL, r.Proto))
944+
sb.WriteString(fmt.Sprintf(" %s %s %s ", r.Method, r.Host, r.Proto))
946945
} else {
947946
sb.WriteString(id)
948947
sb.WriteString(colors.Green(fmt.Sprintf(" Src: %s->%s", srcConn.LocalAddr(), srcConn.RemoteAddr())).String())
@@ -952,7 +951,7 @@ func (p *proxyapp) handleTunnel(w http.ResponseWriter, r *http.Request) {
952951
sb.WriteString(fmt.Sprintf("%s ", p.colorizeTimestamp()))
953952
sb.WriteString(id)
954953
sb.WriteString(colors.Gray(fmt.Sprintf(" %s ", r.Method)).String())
955-
sb.WriteString(colors.YellowBg(fmt.Sprintf("%s ", r.URL)).String())
954+
sb.WriteString(colors.YellowBg(fmt.Sprintf("%s ", r.Host)).String())
956955
sb.WriteString(colors.BlueBg(fmt.Sprintf("%s ", r.Proto)).String())
957956
}
958957
sniffheader = append(sniffheader, sb.String())
@@ -988,7 +987,7 @@ func (p *proxyapp) sniffreporter(wg *sync.WaitGroup, sniffheader *[]string, reqC
988987
respQueue = respQueue[1:]
989988

990989
err := p.colorizeTunnel(req, resp, sniffheader, id)
991-
if err == nil {
990+
if err == nil && len(*sniffheader) > sniffheaderlen {
992991
if p.json {
993992
p.snifflogger.Log().Msg(fmt.Sprintf("[%s]", strings.Join(*sniffheader, ",")))
994993
} else {
@@ -1304,8 +1303,7 @@ func New(conf *Config) *proxyapp {
13041303
} else {
13051304
snifflog = logfile
13061305
}
1307-
p.nocolor = conf.Json || (conf.NoColor && logfile == os.Stdout)
1308-
p.sniffnocolor = conf.Json || (conf.NoColor && logfile == os.Stdout)
1306+
p.nocolor = conf.Json || conf.NoColor
13091307
if conf.Json {
13101308
log.SetFlags(0)
13111309
jsonWriter := jsonLogWriter{file: logfile}
@@ -1361,13 +1359,13 @@ func New(conf *Config) *proxyapp {
13611359

13621360
}
13631361
logger = zerolog.New(output).With().Timestamp().Logger()
1364-
sniffoutput := zerolog.ConsoleWriter{Out: snifflog, TimeFormat: time.RFC3339, NoColor: p.sniffnocolor, PartsExclude: []string{"level"}}
1362+
sniffoutput := zerolog.ConsoleWriter{Out: snifflog, TimeFormat: time.RFC3339, NoColor: p.nocolor, PartsExclude: []string{"level"}}
13651363
sniffoutput.FormatTimestamp = func(i any) string {
13661364
ts, _ := time.Parse(time.RFC3339, i.(string))
13671365
if p.nocolor {
13681366
return colors.WrapBrackets(ts.Format(time.TimeOnly))
13691367
}
1370-
return colors.GrayBg(colors.WrapBrackets(ts.Format(time.TimeOnly))).String()
1368+
return colors.Gray(colors.WrapBrackets(ts.Format(time.TimeOnly))).String()
13711369
}
13721370
sniffoutput.FormatMessage = func(i any) string {
13731371
if i == nil || i == "" {

resources/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
*
12
!example_gohpts.yaml
3+
!sniffing_color.png

resources/sniffing_color.png

259 KB
Loading

tproxy_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func (ts *tproxyServer) handleConnection(srcConn net.Conn) {
187187
ts.pa.tproxyMode, srcConn.LocalAddr(), srcConn.RemoteAddr(), dstConn.LocalAddr(), dstConn.RemoteAddr(), dst))
188188
} else {
189189
var sb strings.Builder
190-
if ts.pa.sniffnocolor {
190+
if ts.pa.nocolor {
191191
sb.WriteString(id)
192192
sb.WriteString(fmt.Sprintf(" Src: %s->%s -> Dst: %s->%s Orig: %s", srcConn.LocalAddr(), srcConn.RemoteAddr(), dstConn.LocalAddr(), dstConn.RemoteAddr(), dst))
193193
} else {

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package gohpts
22

3-
const Version string = "gohpts v1.7.3"
3+
const Version string = "gohpts v1.8.0"

0 commit comments

Comments
 (0)