Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tetra: transparently handle unix or tcp gRPC socket #967

Merged
merged 3 commits into from
May 4, 2023
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
60 changes: 58 additions & 2 deletions cmd/tetra/common/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,83 @@ package common

import (
"context"
"encoding/json"
"os"
"os/signal"
"syscall"
"time"

"github.com/sirupsen/logrus"

"github.com/cilium/tetragon/api/v1/tetragon"
"github.com/cilium/tetragon/pkg/defaults"
"github.com/cilium/tetragon/pkg/logger"
"github.com/spf13/viper"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

type daemonInfo struct {
ServerAddr string `json:"server_address"`
}

func getActiveServAddr(fname string) (string, error) {
f, err := os.Open(fname)
if err != nil {
return "", err
}
defer f.Close()

var info daemonInfo
if err := json.NewDecoder(f).Decode(&info); err != nil {
return "", err
}

return info.ServerAddr, nil
}

func CliRunErr(fn func(ctx context.Context, cli tetragon.FineGuidanceSensorsClient), fnErr func(err error)) {
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

connCtx, connCancel := context.WithTimeout(ctx, 10*time.Second)
defer connCancel()
conn, err := grpc.DialContext(connCtx, viper.GetString(KeyServerAddress), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())

var conn *grpc.ClientConn
var serverAddr string
var err error

// The client cli can run remotely so to support most cases transparently
// Check if the server address was set
// - If yes: use it directly, users know better
// - If no: then try the default tetragon-info.json file to find the best
// address if possible (could be unix socket). This also covers the
// case that default address is localhost so we are operating in localhost
// context anyway.
// If that address is set try it, if it fails for any reason then retry
// last time with the server address.
if viper.IsSet(KeyServerAddress) == false {
tixxdz marked this conversation as resolved.
Show resolved Hide resolved
// server-address was not set by user, try the tetragon-info.json file
serverAddr, err = getActiveServAddr(defaults.InitInfoFile)
if err == nil && serverAddr != "" {
conn, err = grpc.DialContext(connCtx, serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
}
// Handle both errors
if err != nil {
logger.GetLogger().WithFields(logrus.Fields{
"InitInfoFile": defaults.InitInfoFile,
"server-address": serverAddr,
}).WithError(err).Debugf("Failed to connect to server")
}
tixxdz marked this conversation as resolved.
Show resolved Hide resolved
}
if conn == nil {
// Try the server-address prameter
serverAddr = viper.GetString(KeyServerAddress)
conn, err = grpc.DialContext(connCtx, serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
}
if err != nil {
fnErr(err)
logger.GetLogger().WithError(err).Fatal("Failed to connect")
logger.GetLogger().WithField("server-address", serverAddr).WithError(err).Fatal("Failed to connect to server")
}
defer conn.Close()
client := tetragon.NewFineGuidanceSensorsClient(conn)
Expand Down
4 changes: 3 additions & 1 deletion cmd/tetragon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ func getFieldFilters() ([]*tetragon.FieldFilter, error) {
return filters, nil
}

// Save daemon information so it is used by client cli but
// also by bugtool
func saveInitInfo() error {
info := bugtool.InitInfo{
ExportFname: option.Config.ExportFilename,
Expand Down Expand Up @@ -591,7 +593,7 @@ func execute() error {
flags.Bool(keyEnableCiliumAPI, false, "Access Cilium API to associate Tetragon events with Cilium endpoints and DNS cache")
flags.Bool(keyEnableProcessAncestors, true, "Include ancestors in process exec events")
flags.String(keyMetricsServer, "", "Metrics server address (e.g. ':2112'). Disabled by default")
flags.String(keyServerAddress, "localhost:54321", "gRPC server address")
flags.String(keyServerAddress, "localhost:54321", "gRPC server address (e.g. 'localhost:54321' or 'unix:///var/run/tetragon/tetragon.sock'")
flags.String(keyGopsAddr, "", "gops server address (e.g. 'localhost:8118'). Disabled by default")
flags.String(keyCiliumBPF, "", "Cilium BPF directory")
flags.Bool(keyEnableProcessCred, false, "Enable process_cred events")
Expand Down
36 changes: 36 additions & 0 deletions docs/content/en/docs/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,39 @@ directory into the `/etc/tetragon/tetragon.conf.d/` subdirectory. The latter is
generally recommended. Defaults can be restored by simply deleting this file
and all drop-ins.


### Restrict gRPC API access

The gRPC API supports unix sockets, it can be set using one of the following methods:

- Use the `--server-address` flag:

```
--server-address unix:///var/run/tetragon/tetragon.sock
```

- Or use the drop-in configuration file `/etc/tetragon/tetragon.conf.d/server-address` containing:

```
unix:///var/run/tetragon/tetragon.sock
```

{{< note >}}
Tetragon tarball by default listens to `unix:///var/run/tetragon/tetragon.sock`
{{< /note >}}

Then to access the gRPC API with `tetra` client, set `--server-address` to point to the corresponding address:

```
sudo tetra --server-address unix:///var/run/tetragon/tetragon.sock getevents
```

{{< note >}}
When reading events with the `tetra` client, if `--server-address` is not specified,
it will try to detect if Tetragon daemon is running on the same host and use its
`server-address` configuration.
{{< /note >}}

{{< caution >}}
Ensure that you have enough privileges to open the gRPC unix socket since it is restricted to privileged users only.
{{< /caution >}}
10 changes: 2 additions & 8 deletions pkg/bugtool/bugtool.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ import (
"github.com/vishvananda/netlink"
)

const (
// initInfoFile is the file location for the info file.
// After initialization, initInfoFname will contain a json representation of InitInfo
initInfoFname = defaults.DefaultRunDir + "tetragon-info.json"
)

// InitInfo contains information about how Tetragon was initialized.
type InitInfo struct {
ExportFname string `json:"export_fname"`
Expand All @@ -47,12 +41,12 @@ type InitInfo struct {

// LoadInitInfo returns the InitInfo by reading the info file from its default location
func LoadInitInfo() (*InitInfo, error) {
return doLoadInitInfo(initInfoFname)
return doLoadInitInfo(defaults.InitInfoFile)
}

// SaveInitInfo saves InitInfo to the info file
func SaveInitInfo(info *InitInfo) error {
return doSaveInitInfo(initInfoFname, info)
return doSaveInitInfo(defaults.InitInfoFile, info)
}

func doLoadInitInfo(fname string) (*InitInfo, error) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const (

// Default location for BPF programs and BTF files
DefaultTetragonLib = "/var/lib/tetragon/"

// InitInfoFile is the file location for the info file.
// After initialization, InitInfoFile will contain a json representation of InitInfo
// Used by both client cli to guess unix socket address and by bugtool
InitInfoFile = DefaultRunDir + "tetragon-info.json"
tixxdz marked this conversation as resolved.
Show resolved Hide resolved
)

var (
Expand Down