Skip to content
Open
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
40 changes: 33 additions & 7 deletions cmd/boring/tunnels.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,27 +196,53 @@ func listTunnels() {
return
}

tbl := table.New("Status", "Name", "Local", "", "Remote", "Via")
// Group tunnels by their group field
groupedTunnels := make(map[string][]*tunnel.Desc)
visited := make(map[string]bool)

// Process configured tunnels
for _, t := range conf.Tunnels {
var tunnelToAdd *tunnel.Desc
if q, ok := ts[t.Name]; ok {
tbl.AddRow(status(q), q.Name, q.LocalAddress, q.Mode, q.RemoteAddress, q.Host)
tunnelToAdd = q
visited[q.Name] = true
continue
} else {
tunnelToAdd = &t
}
// TODO: case where tunnel is in resp but with different name
tbl.AddRow(status(&t), t.Name, t.LocalAddress, t.Mode, t.RemoteAddress, t.Host)

group := tunnelToAdd.Group
if group == "" {
group = "default"
}
groupedTunnels[group] = append(groupedTunnels[group], tunnelToAdd)
}

// Add tunnels that are in resp but not in the config
for _, q := range ts {
if !visited[q.Name] {
tbl.AddRow(status(q), q.Name, q.LocalAddress, q.Mode, q.RemoteAddress, q.Host)
group := q.Group
if group == "" {
group = "default"
}
groupedTunnels[group] = append(groupedTunnels[group], q)
}
}

log.Emitf("%v", tbl)
// Display tunnels grouped by group
first := true
for groupName, tunnels := range groupedTunnels {
if !first {
log.Emitf("\n")
}
first = false

log.Emitf("Group: %s\n", groupName)
tbl := table.New("Status", "Name", "Local", "", "Remote", "Via")
for _, t := range tunnels {
tbl.AddRow(status(t), t.Name, t.LocalAddress, t.Mode, t.RemoteAddress, t.Host)
}
log.Emitf("%v", tbl)
}
}

func transmitCmd(cmd daemon.Cmd, resp any) error {
Expand Down
6 changes: 6 additions & 0 deletions examples/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ name = "dev"
local = "9000"
remote = "localhost:9000"
host = "dev-server" # automatically matches host against SSH config
group = "development" # optional: group tunnels for organized display

# simple remote (-R) tunnel; note that we can also use IP{v4,v6} addresses
[[tunnels]]
Expand All @@ -12,6 +13,7 @@ local = "[::1]:9000"
remote = "9000"
host = "dev-server"
mode = "remote"
group = "development"

# example of an explicit host (doesn't use SSH config)
[[tunnels]]
Expand All @@ -21,6 +23,7 @@ remote = "localhost:5001"
host = "prod.example.com"
user = "root"
identity = "~/.ssh/id_prod" # will try default ones if not set
group = "production"

# example using Unix sockets, and remote (-R) mode;
# note that we can freely mix unix and TCP sockets
Expand All @@ -30,6 +33,7 @@ local = "/tmp/serve.sock"
remote = "/tmp/listen.sock"
host = "dev-server"
mode = "remote"
group = "development"

# example of a SOCKS5 proxy; this will setup a SOCKS5 server at
# port 9000 and forward all traffic through `dev-server`.
Expand All @@ -38,6 +42,7 @@ name = "dev-prox"
local = "9000"
host = "dev-server"
mode = "socks"
group = "proxies"

# reverse SOCKS5 proxy; this will setup a SOCKS5 server at
# port 9000 on `dev-server` and forward all traffic through
Expand All @@ -47,3 +52,4 @@ name = "dev-rev-prox"
remote = "9000"
host = "dev-server"
mode = "socks-remote"
group = "proxies"
1 change: 1 addition & 0 deletions internal/tunnel/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Desc struct {
Port int `toml:"port" json:"port"`
KeepAlive *int `toml:"keep_alive" json:"keep_alive"`
Mode Mode `toml:"mode" json:"mode"`
Group string `toml:"group" json:"group"`
Status Status `toml:"-" json:"status"`
LastConn time.Time `toml:"-" json:"last_conn"`
}
Expand Down