-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Changes from 4 commits
0ec9307
f437eeb
d894bfd
86be05b
5106c05
fc33e85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -18,12 +18,87 @@ | |||||||||||||||||
package add_cloud_metadata | ||||||||||||||||||
|
||||||||||||||||||
import ( | ||||||||||||||||||
"fmt" | ||||||||||||||||||
"io" | ||||||||||||||||||
"io/ioutil" | ||||||||||||||||||
"net" | ||||||||||||||||||
"net/http" | ||||||||||||||||||
|
||||||||||||||||||
"github.com/elastic/beats/v7/libbeat/logp" | ||||||||||||||||||
|
||||||||||||||||||
"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" | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
// 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) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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{ | ||||||||||||||||||
|
@@ -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 | ||||||||||||||||||
}, | ||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the empty space