ec2metaproxy

package module
v0.0.0-...-e6fb53f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2015 License: MIT Imports: 10 Imported by: 0

README

Credits

First off. This is a repackaging of this repo: dump247/docker-ec2-metadata I didn't write this code. It works great though. Hopefully this will enable you to adopt it even quicker.

What is this?

A service that runs on an EC2 instance that proxies the EC2 instance metadata service for docker containers. The proxy overrides metadata endpoints for individual docker containers.

At this point, the only endpoint overridden is the security credentials. This allows for different containers to have different IAM permissions and not just use the permissions provided by the instance profile. However, this same technique could be used to override any other endpoints where appropriate.

Build

Requires:

  • golang 1.2+

The dependencies are managed with Godep.

Go

Clone this repo into your Golang workspace, move into the repo, and then maybe run things like this:

go test ./...
go install ./...

Docker

Clone this repo and do something like this:

docker build -t ec2metaproxy .

Setup

What is needed is an EC2 instance with assume role permissions and one or more roles defined that it can assume. The roles will be used by the containers to acquire their own permissions.

Permissions

The EC2 instance must have permission to assume the roles required by the docker containers.

Note that assuming a role is two way: the permission to assume roles has to be granted to the instance profile and the role has to allow the instance profile to assume it.

There must be at least one role to use as the default role if the container has not specified one. The default role can have empty permissions (zero access) or some set of standard permissions.

Example CloudFormation:

  • DockerContainerRole1 is the set of permissions for a docker container
  • InstanceRole is the role used by the EC2 instance profile and needs permission to assume DockerContainerRole1
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "DockerContainerRole1": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": [ {"Fn::GetAtt" : ["InstanceRole", "Arn"]} ]
              },
              "Action": [ "sts:AssumeRole" ]
            }
          ]
        },
        "Path": "/docker/",
        "Policies": []
      }
    },

    "InstanceRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
           {
             "Effect": "Allow",
             "Principal": {
                "Service": [ "ec2.amazonaws.com" ]
              },
              "Action": [ "sts:AssumeRole" ]
            }
          ]
        },
        "Path": "/",
        "Policies": [
          {
            "PolicyName": "AssumeRoles",
            "PolicyDocument": {
              "Statement": [
                {
                  "Effect": "Allow",
                  "Resource": {"Fn::Join": ["", ["arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":role/docker/*"]]},
                  "Action": [ "sts:AssumeRole" ]
                }
              ]
            }
          }
        ]
      }
    },

    "InstanceProfile": {
      "Type": "AWS::IAM::InstanceProfile",
      "Properties": {
        "Path": "/",
        "Roles": [{"Ref": "InstanceRole"}]
      }
    }
  }
}

Instance Setup

Install docker and run with the standard unix domain socket (/var/run/docker.sock).

Run this command to setup iptables to reroute metadata service calls from docker0 to our little docker instance:

Note: NIC_NAME should be the name of the nic that is in use on the machine.

curl -sSL https://raw.githubusercontent.com/flyinprogrammer/ec2metaproxy/master/firewall_setup.sh | NIC_NAME=eth0 bash

Run the Service

Run this to pull and start the container:

curl -sSL https://raw.githubusercontent.com/flyinprogrammer/ec2metaproxy/master/start_ec2metaproxy.sh | bash

Container Role

If the container does not specify a role, the default role is used. A container can specify a specific role to use by setting the IAM_ROLE environment variable.

Example: IAM_ROLE=arn:aws:iam::123456789012:role/CONTAINER_ROLE_NAME

Note that the host machine’s instance profile must have permission to assume the given role. If not, the container will receive an error when requesting the credentials.

Docker Test

docker-machine create \
    --driver amazonec2 \
    --amazonec2-region "us-west-2" \
    --amazonec2-access-key <key> \
    --amazonec2-secret-key <secret> \
    --amazonec2-vpc-id <vpc id> \
    --amazonec2-instance-type "t2.medium" \
    --amazonec2-iam-instance-profile <InstanceProfile> \
    docker-ec2
eval $(docker-machine env docker-ec2)

docker-machine ssh docker-ec2
sudo su -
curl -sSL https://raw.githubusercontent.com/flyinprogrammer/ec2metaproxy/master/firewall_setup.sh | NIC_NAME=eth0 bash
curl -sSL https://raw.githubusercontent.com/flyinprogrammer/ec2metaproxy/master/start_ec2metaproxy.sh | bash -s -- --verbose
exit
exit

docker run -it -e IAM_ROLE=arn:aws:iam::<account number>:role/docker/<DockerContainerRole1> ubuntu:14.04 /bin/bash
--> apt-get install curl
--> curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ && echo

License

The MIT License (MIT) Copyright (c) 2014 Cory Thomas

See LICENSE

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ContainerInfo

type ContainerInfo struct {
	ContainerID      string
	ShortContainerID string
	SessionName      string
	LastUpdated      time.Time
	Error            error
	RoleArn          RoleArn
	Credentials      *RoleCredentials
}

func (*ContainerInfo) RequiresRefresh

func (t *ContainerInfo) RequiresRefresh() bool

type ContainerRole

type ContainerRole struct {
	LastUpdated time.Time
	Arn         RoleArn
	Credentials *RoleCredentials
}

type ContainerService

type ContainerService struct {
	// contains filtered or unexported fields
}

func NewContainerService

func NewContainerService(docker *docker.Client, defaultRoleArn RoleArn, auth aws.Auth) *ContainerService

func (*ContainerService) RoleForIP

func (t *ContainerService) RoleForIP(containerIP string) (*ContainerRole, error)

type RoleArn

type RoleArn struct {
	// contains filtered or unexported fields
}

func NewRoleArn

func NewRoleArn(value string) (RoleArn, error)

func (RoleArn) AccountID

func (t RoleArn) AccountID() string

func (RoleArn) Empty

func (t RoleArn) Empty() bool

func (RoleArn) Path

func (t RoleArn) Path() string

func (RoleArn) RoleName

func (t RoleArn) RoleName() string

func (RoleArn) String

func (t RoleArn) String() string

type RoleCredentials

type RoleCredentials struct {
	AccessKey  string
	SecretKey  string
	Token      string
	Expiration time.Time
}

func AssumeRole

func AssumeRole(auth aws.Auth, roleArn, sessionName string) (*RoleCredentials, error)

func (*RoleCredentials) ExpiredAt

func (t *RoleCredentials) ExpiredAt(at time.Time) bool

func (*RoleCredentials) ExpiredNow

func (t *RoleCredentials) ExpiredNow() bool

Directories

Path Synopsis
Godeps
_workspace/src/github.com/alecthomas/kingpin
Package kingpin provides command line interfaces like this: $ chat usage: chat [<flags>] <command> [<flags>] [<args> ...] Flags: --debug enable debug mode --help Show help.
Package kingpin provides command line interfaces like this: $ chat usage: chat [<flags>] <command> [<flags>] [<args> ...] Flags: --debug enable debug mode --help Show help.
_workspace/src/github.com/alecthomas/kingpin/examples/curl
A curl-like HTTP command-line client.
A curl-like HTTP command-line client.
_workspace/src/github.com/alecthomas/units
Package units provides helpful unit multipliers and functions for Go.
Package units provides helpful unit multipliers and functions for Go.
_workspace/src/github.com/cihub/seelog
Package seelog implements logging functionality with flexible dispatching, filtering, and formatting.
Package seelog implements logging functionality with flexible dispatching, filtering, and formatting.
_workspace/src/github.com/fsouza/go-dockerclient
Package docker provides a client for the Docker remote API.
Package docker provides a client for the Docker remote API.
_workspace/src/github.com/fsouza/go-dockerclient/testing
Package testing provides a fake implementation of the Docker API, useful for testing purpose.
Package testing provides a fake implementation of the Docker API, useful for testing purpose.
_workspace/src/github.com/goamz/goamz/aws
goamz - Go packages to interact with the Amazon Web Services.
goamz - Go packages to interact with the Amazon Web Services.
_workspace/src/github.com/stretchr/testify/assert
A set of comprehensive testing tools for use with the normal Go testing system.
A set of comprehensive testing tools for use with the normal Go testing system.
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL