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

Adding osctrl-api component #28

Merged
merged 5 commits into from
Nov 3, 2019
Merged

Adding osctrl-api component #28

merged 5 commits into from
Nov 3, 2019

Conversation

javuto
Copy link
Collaborator

@javuto javuto commented Oct 27, 2019

Overview

⚠️ This is still a Work In Progress PR ⚠️

  • Adding the osctrl-api component as a new service. It will listen locally in port 9002 and remotely in 8444, but those are default values and can be customized.

I will add more details once I am done, since there will be likely changes to this implementation.

cc @obelisk

@javuto javuto added the ✨ enhancement New feature or request label Oct 27, 2019
@javuto javuto added this to the v0.2.0 milestone Oct 27, 2019
@@ -3,18 +3,20 @@

VAGRANTFILE_API_VERSION = "2"

IP_ADDRESS = "10.10.10.6"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is hardcoding this ok or should we use hostnames (or configurable values)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the IP address for the vagrant machine. There is no way (that I know of) to configure this via a command and is better to have the IP set to something known. Since the flow is to run vagrant up this should be fine.

}

// Automigrate of tables
func automigrateDB() error {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this supposed to do?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The automigrateDB() function is used by the ORM to create the schema based on the data stored. It is not doing much now, but if we decide to store something in the DB, this will come handy. I am thinking keeping requests per token, so we can enable/enforce some rate limiting?

"github.com/jmpsec/osctrl/pkg/utils"
)

// GET Handler for single JSON environment
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean this API is used to validate if an environment exists in the backend?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, and returns all data for that environment. Does it make more sense to have a verb to check on a specific environment, passing the name, and return just a boolean?

incMetric(metricAPIOK)
}

// GET Handler for multiple JSON environments
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this returns all environments?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yessir.

incMetric(metricAPIErr)
if err.Error() == "record not found" {
log.Printf("node not found: %s", uuid)
apiHTTPResponse(w, JSONApplicationUTF8, http.StatusNotFound, ApiErrorResponse{Error: "node not found"})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is what this returns a similar JSON format to successful run? If so that'll make it easier to parse in prospective clients.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the requested node exists, it does return the structure for OsqueryNode{}, with all its fields in it. Does it make more sense to return always a JSON response with one field for message, and another for data?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No that should be fine, a client can easily check that the fields are empty :)

newQuery := queries.DistributedQuery{
Query: q.Query,
Name: queryName,
Creator: "API",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the username from the authorization mechanism, not API

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally, but this is just a placeholder until I get the actual tokens part finished.

Active: true,
Completed: false,
Deleted: false,
Repeat: 0,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this value should work. In my eyes a distributed query should run only once. If it runs anymore times than that, then when you fetch something by queryName what does that actually mean? Is it original data? The most recent data? Both?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some legacy stuff, that I thought about having distributed queries in a way that can be repeated, but then again, those queries should be scheduled. I can probably clean this up since it is dead code...

}
// Prepare and create new query
queryName := "query_" + generateQueryName()
newQuery := queries.DistributedQuery{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have an accelerate flag in here as well. We should set it if a query targets only a single host.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get that done!

for _, e := range q.Environments {
if (e != "") && envs.Exists(e) {
if err := queriesmgr.CreateTarget(queryName, queries.QueryTargetEnvironment, e); err != nil {
apiErrorResponse(w, "error creating query environment target", err)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question about sensitive errors getting passed to the client.

incMetric(metricAPIOK)
}

// GET Handler to return multiple queries in JSON
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a super powerful API and should probably be locked to a certain subset of users because that allows visibility into all queries, including ones that might relate to on going investigations.

@javuto javuto changed the title WIP: Adding osctrl-api component Adding osctrl-api component Nov 3, 2019
@javuto javuto merged commit e0f8551 into master Nov 3, 2019
@javuto javuto deleted the osctrl-api branch November 3, 2019 00:18
@javuto javuto mentioned this pull request Feb 25, 2020
CptOfEvilMinions added a commit that referenced this pull request Dec 28, 2021
CptOfEvilMinions added a commit that referenced this pull request Jun 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants