osquery / osquery-go

Go bindings for osquery
MIT License
386 stars 78 forks source link

Extension cannot connect on first try when loaded automatically #80

Open 0xpaulbenoit opened 4 years ago

0xpaulbenoit commented 4 years ago

Context

osquery 4.2
Windows 10 Pro 64bit

Test extension

package main

import (
    "context"
    "flag"
    "log"

    "github.com/kolide/osquery-go"
    "github.com/kolide/osquery-go/plugin/table"
)

func main() {
    flSocket := flag.String("socket", "", "")
    flag.Int("timeout", 0, "")
    flag.Int("interval", 0, "")
    flag.Bool("verbose", false, "")
    flag.Parse()

    if *flSocket == "" {
        log.Fatalln("--socket flag cannot be empty")
    }

    server, err := osquery.NewExtensionManagerServer("dev_extension", *flSocket)
    if err != nil {
        log.Fatalf("Error creating osquery extension server: %s\n", err)
    }

    server.RegisterPlugin(
        table.NewPlugin(
            "test_table",
            []table.ColumnDefinition{
                table.TextColumn("foo"),
            },
            func(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
                return []map[string]string{
                    map[string]string{
                        "foo": "bar",
                    },
                }, nil
            },
        ),
    )

    if err := server.Run(); err != nil {
        log.Fatal(err)
    }
}

Running the above test extension with .\osqueryi.exe --allow_unsafe --extension=.\extension.exe will throw an error registering extension: i/o timeout. Then about a minute later the extension will connect successfully.
Adding a time.Sleep(1 * time.Second) to the beginning of the extension will make it connect on the first try instead.
Similar behavior happens when the extension is run via the extensions.load file.

directionless commented 4 years ago

In our code, we do similar.

launcher itself use a rate limiter and retry logic (embarassingly we have two different rate limiter implementations)

Our extension, which as no content, but is there to keep the socket open, uses a simple sleep. launcher-extension.go

I'm not sure this is a bug, per se, but how windows is. I'm not sure that the sleep and retry belongs in the sdk. Feels like it might be better to keep it in the callers. But I'm interested in discussing that

zwass commented 2 years ago

I think osquery-go should try to make it as easy as possible for users to get extensions connected up to osquery. If this kind of retry logic is a necessary (or even often necessary) part of connecting on Windows, I'd argue that it deserves inclusion directly.

directionless commented 2 years ago

I think osquery-go should try to make it as easy as possible for users to get extensions connected up to osquery. If this kind of retry logic is a necessary (or even often necessary) part of connecting on Windows, I'd argue that it deserves inclusion directly.

I think I agree, though we should probably understand if this is a bug in osquery first.