diff --git a/go.mod b/go.mod index ff77f9e..0ca7932 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.19 require ( cloud.google.com/go/compute/metadata v0.2.3 - github.com/aws/aws-sdk-go-v2/config v1.18.3 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 github.com/cilium/cilium v1.13.0 github.com/cilium/ebpf v0.9.4-0.20221102092914-a9cf21df64c2 github.com/containerd/cgroups v1.0.1 @@ -30,6 +28,7 @@ require ( golang.org/x/mod v0.7.0 golang.org/x/net v0.7.0 golang.org/x/sys v0.6.0 + golang.org/x/time v0.3.0 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/yaml.v2 v2.4.0 inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e @@ -43,16 +42,6 @@ require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/aws/aws-sdk-go-v2 v1.17.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.17.5 // indirect - github.com/aws/smithy-go v1.13.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -138,7 +127,6 @@ require ( golang.org/x/exp v0.0.0-20221106115401-f9659909a136 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/text v0.7.0 // indirect - golang.org/x/time v0.3.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.53.0 // indirect google.golang.org/protobuf v1.28.1 // indirect diff --git a/go.sum b/go.sum index 8ba8a27..1672a5f 100644 --- a/go.sum +++ b/go.sum @@ -95,30 +95,6 @@ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:W github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk= -github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw= -github.com/aws/aws-sdk-go-v2/config v1.18.3 h1:3kfBKcX3votFX84dm00U8RGA1sCCh3eRMOGzg5dCWfU= -github.com/aws/aws-sdk-go-v2/config v1.18.3/go.mod h1:BYdrbeCse3ZnOD5+2/VE/nATOK8fEUpBtmPMdKSyhMU= -github.com/aws/aws-sdk-go-v2/credentials v1.13.3 h1:ur+FHdp4NbVIv/49bUjBW+FE7e57HOo03ELodttmagk= -github.com/aws/aws-sdk-go-v2/credentials v1.13.3/go.mod h1:/rOMmqYBcFfNbRPU0iN9IgGqD5+V2yp3iWNmIlz0wI4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTIfvp425HHhwKsFvmzBwHgs= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 h1:nBO/RFxeq/IS5G9Of+ZrgucRciie2qpLy++3UGZ+q2E= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 h1:oRHDrwCTVT8ZXi4sr9Ld+EXk7N/KGssOr2ygNeojEhw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19/go.mod h1:6Q0546uHDp421okhmmGfbxzq2hBqbXFNpi4k+Q1JnQA= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 h1:Mza+vlnZr+fPKFKRq/lKGVvM6B/8ZZmNdEopOwSQLms= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26/go.mod h1:Y2OJ+P+MC1u1VKnavT+PshiEuGPyh/7DqxoDNij4/bg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 h1:GE25AWCdNUPh9AOJzI9KIJnja7IwUc1WyUqz/JTyJ/I= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19/go.mod h1:02CP6iuYP+IVnBX5HULVdSAku/85eHB2Y9EsFhrkEwU= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 h1:GFZitO48N/7EsFDt8fMa5iYdmWqkUDDB3Eje6z3kbG0= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.25/go.mod h1:IARHuzTXmj1C0KS35vboR0FeJ89OkEy1M9mWbK2ifCI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 h1:jcw6kKZrtNfBPJkaHrscDOZoe5gvi9wjudnxvozYFJo= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8/go.mod h1:er2JHN+kBY6FcMfcBBKNGCT3CarImmdFzishsqBmSRI= -github.com/aws/aws-sdk-go-v2/service/sts v1.17.5 h1:60SJ4lhvn///8ygCzYy2l53bFW/Q15bVfyjyAWo6zuw= -github.com/aws/aws-sdk-go-v2/service/sts v1.17.5/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4= -github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk= -github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -487,7 +463,6 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -552,8 +527,6 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -1209,8 +1182,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= -golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/node/metadata/aws.go b/node/metadata/aws.go index 4ab837a..1b3fc97 100644 --- a/node/metadata/aws.go +++ b/node/metadata/aws.go @@ -3,33 +3,76 @@ package metadata import ( "context" "encoding/json" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" + "errors" + "github.com/coroot/coroot-node-agent/proc" "io" "k8s.io/klog/v2" + "net" + "net/http" ) +const awsInstanceMetadataURL = "http://169.254.169.254/latest" + +func getAwsToken() (string, error) { + // a token must be retrieved using the host net NS because the metadata service sets IP TTL to 1 on all response packets + hostNetNs, err := proc.GetHostNetNs() + if err != nil { + return "", err + } + defer hostNetNs.Close() + agentNetNs, err := proc.GetSelfNetNs() + if err != nil { + return "", err + } + defer agentNetNs.Close() + + r, _ := http.NewRequest(http.MethodPut, awsInstanceMetadataURL+"/api/token", nil) + r.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "21600") + + client := http.Client{ + Transport: &http.Transport{ + DisableKeepAlives: true, + DialContext: func(ctx context.Context, network, addr string) (conn net.Conn, err error) { + err = proc.ExecuteInNetNs(hostNetNs, agentNetNs, func() error { + conn, err = net.DialTimeout(network, addr, metadataServiceTimeout) + return err + }) + return conn, err + }, + }, + } + resp, err := client.Do(r) + if err != nil { + return "", err + } + if resp.StatusCode != 200 { + return "", errors.New(resp.Status) + } + defer resp.Body.Close() + token, err := io.ReadAll(resp.Body) + return string(token), err +} + func getAwsMetadata() *CloudMetadata { - ctx, cancel := context.WithTimeout(context.Background(), metadataServiceTimeout) - defer cancel() - cfg, err := config.LoadDefaultConfig(ctx) + md := &CloudMetadata{Provider: CloudProviderAWS} + token, err := getAwsToken() if err != nil { - klog.Errorln(err) - return nil + klog.Errorln("failed to get token:", err) + return md } - c := imds.NewFromConfig(cfg) - md := &CloudMetadata{ + + md = &CloudMetadata{ Provider: CloudProviderAWS, - InstanceId: getAwsMetadataVariable(ctx, c, "instance-id"), - LifeCycle: getAwsMetadataVariable(ctx, c, "instance-life-cycle"), - InstanceType: getAwsMetadataVariable(ctx, c, "instance-type"), - Region: getAwsMetadataVariable(ctx, c, "placement/region"), - AvailabilityZone: getAwsMetadataVariable(ctx, c, "placement/availability-zone"), - AvailabilityZoneId: getAwsMetadataVariable(ctx, c, "placement/availability-zone-id"), - LocalIPv4: getAwsMetadataVariable(ctx, c, "local-ipv4"), - PublicIPv4: getAwsMetadataVariable(ctx, c, "public-ipv4"), - } - if infoJson := getAwsMetadataVariable(ctx, c, "identity-credentials/ec2/info"); infoJson != "" { + InstanceId: getAwsMetadataVariable(token, "instance-id"), + LifeCycle: getAwsMetadataVariable(token, "instance-life-cycle"), + InstanceType: getAwsMetadataVariable(token, "instance-type"), + Region: getAwsMetadataVariable(token, "placement/region"), + AvailabilityZone: getAwsMetadataVariable(token, "placement/availability-zone"), + AvailabilityZoneId: getAwsMetadataVariable(token, "placement/availability-zone-id"), + LocalIPv4: getAwsMetadataVariable(token, "local-ipv4"), + PublicIPv4: getAwsMetadataVariable(token, "public-ipv4"), + } + if infoJson := getAwsMetadataVariable(token, "identity-credentials/ec2/info"); infoJson != "" { m := map[string]string{} if err := json.Unmarshal([]byte(infoJson), &m); err != nil { klog.Errorln(err) @@ -40,14 +83,16 @@ func getAwsMetadata() *CloudMetadata { return md } -func getAwsMetadataVariable(ctx context.Context, client *imds.Client, path string) string { - res, err := client.GetMetadata(ctx, &imds.GetMetadataInput{Path: path}) +func getAwsMetadataVariable(token string, path string) string { + r, _ := http.NewRequest(http.MethodGet, awsInstanceMetadataURL+"/meta-data/"+path, nil) + r.Header.Set("X-aws-ec2-metadata-token", string(token)) + resp, err := httpCallWithTimeout(r) if err != nil { - klog.Errorln(path, err) + klog.Errorln(err) return "" } - defer res.Content.Close() - payload, err := io.ReadAll(res.Content) + defer resp.Body.Close() + payload, err := io.ReadAll(resp.Body) if err != nil { klog.Errorln(path, err) return "" diff --git a/node/metadata/azure.go b/node/metadata/azure.go index 1bb4c58..5037c81 100644 --- a/node/metadata/azure.go +++ b/node/metadata/azure.go @@ -42,7 +42,7 @@ func getAzureMetadata() *CloudMetadata { q.Add("api-version", "2021-05-01") r.URL.RawQuery = q.Encode() - resp, err := httpGetWithTimeout(r) + resp, err := httpCallWithTimeout(r) if err != nil { klog.Errorln(err) return nil diff --git a/node/metadata/digital_ocean.go b/node/metadata/digital_ocean.go index fa7dec3..9be0279 100644 --- a/node/metadata/digital_ocean.go +++ b/node/metadata/digital_ocean.go @@ -12,7 +12,7 @@ func getDigitalOceanMetadata() *CloudMetadata { var lastErr error getVar := func(path string) string { r, _ := http.NewRequest(http.MethodGet, doInstanceMetadataURL+path, nil) - resp, err := httpGetWithTimeout(r) + resp, err := httpCallWithTimeout(r) if err != nil { lastErr = err return "" diff --git a/node/metadata/hetzner.go b/node/metadata/hetzner.go index 7d30047..de2fb5a 100644 --- a/node/metadata/hetzner.go +++ b/node/metadata/hetzner.go @@ -18,7 +18,7 @@ type hetznerInstanceMetadata struct { func getHetznerMetadata() *CloudMetadata { r, _ := http.NewRequest(http.MethodGet, hetznerInstanceMetadataURL, nil) - resp, err := httpGetWithTimeout(r) + resp, err := httpCallWithTimeout(r) if err != nil { klog.Errorln(err) return nil diff --git a/node/metadata/metadata.go b/node/metadata/metadata.go index 0e88fda..d864a78 100644 --- a/node/metadata/metadata.go +++ b/node/metadata/metadata.go @@ -79,7 +79,7 @@ func GetInstanceMetadata() *CloudMetadata { return nil } -func httpGetWithTimeout(r *http.Request) (*http.Response, error) { +func httpCallWithTimeout(r *http.Request) (*http.Response, error) { client := http.DefaultClient client.Timeout = metadataServiceTimeout resp, err := client.Do(r) @@ -87,7 +87,6 @@ func httpGetWithTimeout(r *http.Request) (*http.Response, error) { return nil, err } if resp.StatusCode != 200 { - klog.Errorln() return nil, fmt.Errorf("metadata service response: %s", resp.Status) } return resp, nil