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

[Libbeat] Security - fetch IMDSv2 token for add_cloud_metadata suppor… #28285

Merged
merged 6 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Remove deprecated/undocumented IncludeCreatorMetadata setting from kubernetes metadata config options {pull}28006[28006]
- Remove deprecated fields from kubernetes module {pull}28046[28046]
- Remove deprecated config option aws_partition. {pull}28120[28120]
- Enable IMDSv2 support for `add_cloud_metadata` processor on AWS. {issue}22101[22101] {pull}28285[28285]
- Update kubernetes.namespace from keyword to group field and add name, labels, annotations, uuid as its fields {pull}27917[27917]

*Auditbeat*
Expand Down
83 changes: 82 additions & 1 deletion libbeat/processors/add_cloud_metadata/provider_aws_ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,87 @@
package add_cloud_metadata

import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"

"github.com/elastic/beats/v7/libbeat/logp"

Copy link
Contributor

Choose a reason for hiding this comment

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

remove the empty space

"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"

"github.com/elastic/beats/v7/libbeat/common"
s "github.com/elastic/beats/v7/libbeat/common/schema"
c "github.com/elastic/beats/v7/libbeat/common/schema/mapstriface"
)

const ec2InstanceIdentityURI = "/2014-02-25/dynamic/instance-identity/document"
const ec2InstanceIMDSv2TokenValueHeader = "X-aws-ec2-metadata-token"
const ec2InstanceIMDSv2TokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"
const ec2InstanceIMDSv2TokenTTLValue = "21600"
const ec2InstanceIMDSv2TokenURI = "/latest/api/token"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const ec2InstanceIMDSv2TokenURI = "/latest/api/token"
const (
ec2InstanceIdentityURI = "/2014-02-25/dynamic/instance-identity/document"
ec2InstanceIMDSv2TokenURI = "/latest/api/token"
ec2InstanceIMDSv2TokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"
ec2InstanceIMDSv2TokenTTLValue = "21600"
ec2InstanceIMDSv2TokenURI = "/latest/api/token"
)


// fetches IMDSv2 token, returns empty one on errors
func getIMDSv2Token(c *common.Config) string {
logger := logp.NewLogger("add_cloud_metadata")

config := defaultConfig()
if err := c.Unpack(&config); err != nil {
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
return ""
}

tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS)
if err != nil {
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
logger.Warnf("error when load TLS config for getting IMDSv2 token: %s. No token in the metadata request will be used.", err)

Copy link
Contributor

Choose a reason for hiding this comment

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

All the warning log messages are the same in the function. What do you think about adding more detail in the warning messages?

return ""
}

client := http.Client{
Timeout: config.Timeout,
Transport: &http.Transport{
DisableKeepAlives: true,
DialContext: (&net.Dialer{
Timeout: config.Timeout,
KeepAlive: 0,
}).DialContext,
TLSClientConfig: tlsConfig.ToConfig(),
},
}

tokenReq, err := http.NewRequest("PUT", fmt.Sprintf("http://%s%s", metadataHost, ec2InstanceIMDSv2TokenURI), nil)
if err != nil {
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
return ""
}

tokenReq.Header.Add(ec2InstanceIMDSv2TokenTTLHeader, ec2InstanceIMDSv2TokenTTLValue)
rsp, err := client.Do(tokenReq)
defer func(body io.ReadCloser) {
if body != nil {
body.Close()
}
}(rsp.Body)

if err != nil {
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
return ""
}

if rsp.StatusCode != http.StatusOK {
logger.Warnf("error while getting IMDSv2 token: http request status %d. No token in the metadata request will be used.", rsp.StatusCode)
return ""
}

all, err := ioutil.ReadAll(rsp.Body)
if err != nil {
logger.Warnf("error while getting IMDSv2 token: %s. No token in the metadata request will be used.", err)
return ""
}

return string(all)
}

// AWS EC2 Metadata Service
var ec2MetadataFetcher = provider{
Expand All @@ -48,7 +123,13 @@ var ec2MetadataFetcher = provider{
return common.MapStr{"cloud": out}
}

fetcher, err := newMetadataFetcher(config, "aws", nil, metadataHost, ec2Schema, ec2InstanceIdentityURI)
headers := make(map[string]string, 1)
token := getIMDSv2Token(config)
if len(token) > 0 {
headers[ec2InstanceIMDSv2TokenValueHeader] = token
}

fetcher, err := newMetadataFetcher(config, "aws", headers, metadataHost, ec2Schema, ec2InstanceIdentityURI)
return fetcher, err
},
}