- commit
- 4cbf498
- parent
- 7389d00
- author
- Antonio Mika
- date
- 2025-03-20 22:11:24 -0400 EDT
Use durable tunnel ids and fix logs
9 files changed,
+78,
-30
M
Makefile
+2,
-1
1@@ -127,10 +127,11 @@ migrate:
2 $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20241125_add_content_type_to_analytics.sql
3 $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20241202_add_more_idx_analytics.sql
4 $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20250319_add_tuns_event_logs_table.sql
5+ $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20250320_add_tunnel_id_to_tuns_event_logs_table.sql
6 .PHONY: migrate
7
8 latest:
9- $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20250319_add_tuns_event_logs_table.sql
10+ $(DOCKER_CMD) exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./sql/migrations/20250320_add_tunnel_id_to_tuns_event_logs_table.sql
11 .PHONY: latest
12
13 psql:
M
go.sum
+0,
-2
1@@ -31,8 +31,6 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4
2 git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
3 git.sr.ht/~delthas/senpai v0.3.1-0.20250311003540-18f699aaf9b0 h1:Knm2mHQwLsh1svD15lE27Cr6BMV2wH2t0OKUoSCNhuY=
4 git.sr.ht/~delthas/senpai v0.3.1-0.20250311003540-18f699aaf9b0/go.mod h1:RzVz1R7QRHGcRDnJTcr7AN/cD3rj9scdgvupkXTJLYk=
5-git.sr.ht/~rockorager/vaxis v0.12.1-0.20250312161844-81636f76af83 h1:9eVqJxJzMdnpfqfKKjvEvNDpVg6sIBvbI4FdTjhHqx8=
6-git.sr.ht/~rockorager/vaxis v0.12.1-0.20250312161844-81636f76af83/go.mod h1:h94aKek3frIV1hJbdXjqnBqaLkbWXvV+UxAsQHg9bns=
7 git.sr.ht/~rockorager/vaxis v0.13.0 h1:+F3ze1t4X5x87QEsyn/b9b9pWXw9MDqoHynoR/PHqKg=
8 git.sr.ht/~rockorager/vaxis v0.13.0/go.mod h1:h94aKek3frIV1hJbdXjqnBqaLkbWXvV+UxAsQHg9bns=
9 github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
+9,
-0
1@@ -748,6 +748,15 @@ func tunsEventLogDrainSub(ctx context.Context, dbpool db.DB, logger *slog.Logger
2 continue
3 }
4
5+ if log.TunnelType == "tcp" {
6+ newID, err := shared.ParseTunsTCP(log.TunnelID, log.ServerID)
7+ if err != nil {
8+ logger.Error("could not parse tunnel ID", "err", err)
9+ } else {
10+ log.TunnelID = newID
11+ }
12+ }
13+
14 logger.Info("inserting tuns event log", "log", log)
15 err = dbpool.InsertTunsEventLog(&log)
16 if err != nil {
+1,
-1
1@@ -331,9 +331,9 @@ type TunsEventLog struct {
2 UserId string `json:"user_id"`
3 RemoteAddr string `json:"remote_addr"`
4 EventType string `json:"event_type"`
5+ TunnelID string `json:"tunnel_id"`
6 TunnelType string `json:"tunnel_type"`
7 ConnectionType string `json:"connection_type"`
8- TunnelAddrs []string `json:"tunnel_addrs"`
9 CreatedAt *time.Time `json:"created_at"`
10 }
11
+8,
-8
1@@ -12,7 +12,7 @@ import (
2
3 "slices"
4
5- "github.com/lib/pq"
6+ _ "github.com/lib/pq"
7 "github.com/picosh/pico/pkg/db"
8 "github.com/picosh/utils"
9 )
10@@ -1799,11 +1799,11 @@ func (me *PsqlDB) findPagesStats(userID string) (*db.UserServiceStats, error) {
11 func (me *PsqlDB) InsertTunsEventLog(log *db.TunsEventLog) error {
12 _, err := me.Db.Exec(
13 `INSERT INTO tuns_event_logs
14- (user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_addrs)
15+ (user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_id)
16 VALUES
17 ($1, $2, $3, $4, $5, $6, $7)`,
18 log.UserId, log.ServerID, log.RemoteAddr, log.EventType, log.TunnelType,
19- log.ConnectionType, pq.Array(log.TunnelAddrs),
20+ log.ConnectionType, log.TunnelID,
21 )
22 return err
23 }
24@@ -1812,8 +1812,8 @@ func (me *PsqlDB) FindTunsEventLogsByAddr(userID, addr string) ([]*db.TunsEventL
25 logs := []*db.TunsEventLog{}
26 fmt.Println(addr)
27 rs, err := me.Db.Query(
28- `SELECT id, user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_addrs, created_at
29- FROM tuns_event_logs WHERE user_id=$1 AND tunnel_addrs @> ARRAY[$2] ORDER BY created_at DESC`, userID, addr)
30+ `SELECT id, user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_id, created_at
31+ FROM tuns_event_logs WHERE user_id=$1 AND tunnel_id=$2 ORDER BY created_at DESC`, userID, addr)
32 if err != nil {
33 return nil, err
34 }
35@@ -1823,7 +1823,7 @@ func (me *PsqlDB) FindTunsEventLogsByAddr(userID, addr string) ([]*db.TunsEventL
36 err := rs.Scan(
37 &log.ID, &log.UserId, &log.ServerID, &log.RemoteAddr,
38 &log.EventType, &log.TunnelType, &log.ConnectionType,
39- (*pq.StringArray)(&log.TunnelAddrs), &log.CreatedAt,
40+ &log.TunnelID, &log.CreatedAt,
41 )
42 if err != nil {
43 return nil, err
44@@ -1841,7 +1841,7 @@ func (me *PsqlDB) FindTunsEventLogsByAddr(userID, addr string) ([]*db.TunsEventL
45 func (me *PsqlDB) FindTunsEventLogs(userID string) ([]*db.TunsEventLog, error) {
46 logs := []*db.TunsEventLog{}
47 rs, err := me.Db.Query(
48- `SELECT id, user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_addrs, created_at
49+ `SELECT id, user_id, server_id, remote_addr, event_type, tunnel_type, connection_type, tunnel_id, created_at
50 FROM tuns_event_logs WHERE user_id=$1 ORDER BY created_at DESC`, userID)
51 if err != nil {
52 return nil, err
53@@ -1852,7 +1852,7 @@ func (me *PsqlDB) FindTunsEventLogs(userID string) ([]*db.TunsEventLog, error) {
54 err := rs.Scan(
55 &log.ID, &log.UserId, &log.ServerID, &log.RemoteAddr,
56 &log.EventType, &log.TunnelType, &log.ConnectionType,
57- (*pq.StringArray)(&log.TunnelAddrs), &log.CreatedAt,
58+ &log.TunnelID, &log.CreatedAt,
59 )
60 if err != nil {
61 return nil, err
1@@ -3,7 +3,6 @@ package shared
2 import (
3 "fmt"
4 "sort"
5- "strings"
6 "time"
7
8 "github.com/gorilla/feeds"
9@@ -137,16 +136,16 @@ Event type: %s<br />
10 Connection type: %s<br />
11 Remote addr: %s<br />
12 Tunnel type: %s<br />
13-Tunnel addrs: %s<br />
14+Tunnel ID: %s<br />
15 Server: %s`,
16 eventLog.CreatedAt.Format(time.RFC3339), eventLog.EventType, eventLog.ConnectionType,
17- eventLog.RemoteAddr, eventLog.TunnelType, eventLog.TunnelAddrs, eventLog.ServerID,
18+ eventLog.RemoteAddr, eventLog.TunnelType, eventLog.TunnelID, eventLog.ServerID,
19 )
20 logItem := &feeds.Item{
21 Id: fmt.Sprintf("%d", eventLog.CreatedAt.Unix()),
22 Title: fmt.Sprintf(
23 "%s tuns event for %s",
24- eventLog.EventType, strings.Join(eventLog.TunnelAddrs, ", "),
25+ eventLog.EventType, eventLog.TunnelID,
26 ),
27 Link: &feeds.Link{Href: "https://pico.sh"},
28 Content: content,
1@@ -0,0 +1,23 @@
2+package shared
3+
4+import (
5+ "fmt"
6+ "strings"
7+)
8+
9+// ParseTunsTCP parses the tunnelID and tunsInstance to return a user friendly address
10+func ParseTunsTCP(tunnelID string, tunsInstance string) (string, error) {
11+ // example string:
12+ // tcp://10.0.0.89:33652,tcp6://[2603:c020:400a:d000:bd71:c59f:720c:484b]:33652
13+ splitData := strings.Split(tunnelID, ":")
14+ if len(splitData) < 3 {
15+ return "", fmt.Errorf("invalid tunnelID: %s", tunnelID)
16+ }
17+
18+ port := splitData[len(splitData)-1]
19+ if port == "" {
20+ return "", fmt.Errorf("invalid tunnelID: %s", tunnelID)
21+ }
22+
23+ return fmt.Sprintf("%s:%s", tunsInstance, port), nil
24+}
+29,
-14
1@@ -67,9 +67,9 @@ type ResultLog struct {
2 ResponseBody string `json:"response_body"`
3 ResponseCode int `json:"response_code"`
4 ResponseStatus string `json:"response_status"`
5+ TunnelID string `json:"tunnel_id"`
6 TunnelType string `json:"tunnel_type"`
7 ConnectionType string `json:"connection_type"`
8- TunnelAddrs []string `json:"tunnel_addrs"`
9 // RequestURL string `json:"request_url"`
10 }
11
12@@ -141,6 +141,7 @@ func (m *TunsPage) getLogWidget(i uint, cursor uint) vxfw.Widget {
13 codestyle = vaxis.Style{Foreground: oj}
14 }
15 txt := richtext.New([]vaxis.Segment{
16+ {Text: log.CurrentTime + " "},
17 {Text: log.ResponseStatus + " ", Style: codestyle},
18 {Text: log.RequestTime + " "},
19 {Text: log.RequestIP + " "},
20@@ -192,10 +193,19 @@ func (m *TunsPage) connectToLogs() error {
21 continue
22 }
23
24+ if parsedData.TunnelType == "tcp" {
25+ newTunID, err := shared.ParseTunsTCP(parsedData.TunnelID, parsedData.ServerID)
26+ if err != nil {
27+ m.shared.Logger.Error("parse tun addr", "err", err)
28+ } else {
29+ parsedData.TunnelID = newTunID
30+ }
31+ }
32+
33 user := parsedData.User
34 userId := parsedData.UserId
35 isUser := user == m.shared.User.Name || userId == m.shared.User.ID
36- if m.isAdmin || isUser {
37+ if (m.isAdmin || isUser) && parsedData.TunnelID == m.selected {
38 m.shared.App.PostEvent(ResultLogLineLoaded{parsedData})
39 }
40 }
41@@ -419,14 +429,7 @@ func fetch(fqdn, auth string) (map[string]*TunsClient, error) {
42 }
43
44 func (m *TunsPage) fetchEventLogs() {
45- site := m.findSelected()
46- addr := m.selected
47- if site.TunType == "http" {
48- addr = "http://" + addr
49- } else if site.TunType == "https" {
50- addr = "https://" + addr
51- }
52- logs, err := m.shared.Dbpool.FindTunsEventLogsByAddr(m.shared.User.ID, addr)
53+ logs, err := m.shared.Dbpool.FindTunsEventLogsByAddr(m.shared.User.ID, m.selected)
54 if err != nil {
55 m.err = err
56 return
57@@ -464,7 +467,7 @@ func (m *TunsPage) fetchTuns() {
58
59 for k := range val.RouteListeners.TcpAliases {
60 ls = append(ls, TunsClientSimple{
61- TunType: "tcp-alias",
62+ TunType: "alias",
63 TunAddress: k,
64 RemoteAddr: val.RemoteAddr,
65 User: val.User,
66@@ -473,9 +476,15 @@ func (m *TunsPage) fetchTuns() {
67 }
68
69 for k := range val.RouteListeners.Listeners {
70+ tunAddr, err := shared.ParseTunsTCP(k, "tuns.sh")
71+ if err != nil {
72+ m.shared.Session.Logger.Info("parse tun addr", "err", err)
73+ tunAddr = k
74+ }
75+
76 ls = append(ls, TunsClientSimple{
77 TunType: "tcp",
78- TunAddress: k,
79+ TunAddress: tunAddr,
80 RemoteAddr: val.RemoteAddr,
81 User: val.User,
82 PubkeyFingerprint: val.PubkeyFingerprint,
83@@ -500,7 +509,7 @@ func (m *TunsPage) fetchTuns() {
84
85 for k := range val.RouteListeners.TcpAliases {
86 ls = append(ls, TunsClientSimple{
87- TunType: "tcp-alias",
88+ TunType: "alias",
89 TunAddress: k,
90 RemoteAddr: val.RemoteAddr,
91 User: val.User,
92@@ -509,9 +518,15 @@ func (m *TunsPage) fetchTuns() {
93 }
94
95 for k := range val.RouteListeners.Listeners {
96+ tunAddr, err := shared.ParseTunsTCP(k, "tuns.sh")
97+ if err != nil {
98+ m.shared.Session.Logger.Info("parse tun addr", "err", err)
99+ tunAddr = k
100+ }
101+
102 ls = append(ls, TunsClientSimple{
103 TunType: "tcp",
104- TunAddress: k,
105+ TunAddress: tunAddr,
106 RemoteAddr: val.RemoteAddr,
107 User: val.User,
108 PubkeyFingerprint: val.PubkeyFingerprint,
1@@ -0,0 +1,3 @@
2+DELETE FROM tuns_event_logs;
3+ALTER TABLE tuns_event_logs ADD COLUMN tunnel_id text NOT NULL;
4+ALTER TABLE tuns_event_logs DROP COLUMN tunnel_addrs;