From a874e6e05dd6e0bc4465d4abadec208033498b0a Mon Sep 17 00:00:00 2001 From: Aaron Turner Date: Tue, 9 Jul 2024 08:52:43 -0700 Subject: [PATCH] continue ecs cleanup --- cmd/aws-sso/ecs_client_cmd.go | 46 +++++++++++++++++------------------ cmd/aws-sso/ecs_cmd.go | 2 +- cmd/aws-sso/ecs_server_cmd.go | 9 +++++-- docs/commands-ecs.md | 21 +++++++++------- docs/ecs-server.md | 28 ++++++++++++++++----- docs/remote-ssh.md | 23 +++++++++++++----- 6 files changed, 82 insertions(+), 47 deletions(-) diff --git a/cmd/aws-sso/ecs_client_cmd.go b/cmd/aws-sso/ecs_client_cmd.go index 974c16ac..a12f265b 100644 --- a/cmd/aws-sso/ecs_client_cmd.go +++ b/cmd/aws-sso/ecs_client_cmd.go @@ -32,31 +32,18 @@ import ( "github.com/synfinatic/gotable" ) -type EcsListCmd struct { - Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` -} - type EcsLoadCmd struct { // AWS Params - Arn string `kong:"short='a',help='ARN of role to assume',env='AWS_SSO_ROLE_ARN',predictor='arn'"` - AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to assume',env='AWS_SSO_ACCOUNT_ID',predictor='accountId',xor='account'"` - Role string `kong:"short='R',help='Name of AWS Role to assume',env='AWS_SSO_ROLE_NAME',predictor='role',xor='role'"` - Profile string `kong:"short='p',help='Name of AWS Profile to assume',predictor='profile',xor='account,role'"` + Arn string `kong:"short='a',help='ARN of role to load',env='AWS_SSO_ROLE_ARN',predictor='arn'"` + AccountId int64 `kong:"name='account',short='A',help='AWS AccountID of role to load',env='AWS_SSO_ACCOUNT_ID',predictor='accountId',xor='account'"` + Role string `kong:"short='R',help='Name of AWS Role to load',env='AWS_SSO_ROLE_NAME',predictor='role',xor='role'"` + Profile string `kong:"short='p',help='Name of AWS Profile to load',predictor='profile',xor='account,role'"` // Other params Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` Slotted bool `kong:"short='s',help='Load credentials in a unique slot using the ProfileName as the key'"` } -type EcsProfileCmd struct { - Server string `kong:"help='URL endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` -} - -type EcsUnloadCmd struct { - Profile string `kong:"short='p',help='Name of AWS Profile to unload',predictor='profile'"` - Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` -} - func (cc *EcsLoadCmd) Run(ctx *RunContext) error { sci := NewSelectCliArgs(ctx.Cli.Ecs.Load.Arn, ctx.Cli.Ecs.Load.AccountId, ctx.Cli.Ecs.Load.Role, ctx.Cli.Ecs.Load.Profile) if awssso, err := sci.Update(ctx); err == nil { @@ -70,6 +57,10 @@ func (cc *EcsLoadCmd) Run(ctx *RunContext) error { return ctx.PromptExec(ecsLoadCmd) } +type EcsProfileCmd struct { + Server string `kong:"help='URL endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` +} + func (cc *EcsProfileCmd) Run(ctx *RunContext) error { c := newClient(ctx.Cli.Ecs.Profile.Server, ctx) @@ -88,12 +79,6 @@ func (cc *EcsProfileCmd) Run(ctx *RunContext) error { return listProfiles(profiles) } -func (cc *EcsUnloadCmd) Run(ctx *RunContext) error { - c := newClient(ctx.Cli.Ecs.Unload.Server, ctx) - - return c.Delete(ctx.Cli.Ecs.Unload.Profile) -} - // Loads our AWS API creds into the ECS Server func ecsLoadCmd(ctx *RunContext, awssso *sso.AWSSSO, accountId int64, role string) error { c := newClient(ctx.Cli.Ecs.Load.Server, ctx) @@ -122,6 +107,10 @@ func ecsLoadCmd(ctx *RunContext, awssso *sso.AWSSSO, accountId int64, role strin return c.SubmitCreds(creds, rFlat.Profile, ctx.Cli.Ecs.Load.Slotted) } +type EcsListCmd struct { + Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` +} + func (cc *EcsListCmd) Run(ctx *RunContext) error { c := newClient(ctx.Cli.Ecs.Profile.Server, ctx) @@ -137,6 +126,17 @@ func (cc *EcsListCmd) Run(ctx *RunContext) error { return listProfiles(profiles) } +type EcsUnloadCmd struct { + Profile string `kong:"short='p',help='Slot of AWS Profile to unload',predictor='profile'"` + Server string `kong:"help='Endpoint of aws-sso ECS Server',env='AWS_SSO_ECS_SERVER',default='localhost:4144'"` +} + +func (cc *EcsUnloadCmd) Run(ctx *RunContext) error { + c := newClient(ctx.Cli.Ecs.Unload.Server, ctx) + + return c.Delete(ctx.Cli.Ecs.Unload.Profile) +} + func listProfiles(profiles []ecs.ListProfilesResponse) error { // sort our results sort.Slice(profiles, func(i, j int) bool { diff --git a/cmd/aws-sso/ecs_cmd.go b/cmd/aws-sso/ecs_cmd.go index 6ed40a65..fef92983 100644 --- a/cmd/aws-sso/ecs_cmd.go +++ b/cmd/aws-sso/ecs_cmd.go @@ -62,9 +62,9 @@ func (cc *EcsAuthCmd) Run(ctx *RunContext) error { } type EcsSSLCmd struct { - Save EcsSSLSaveCmd `kong:"cmd,help='Save a new SSL certificate/private key'"` Delete EcsSSLDeleteCmd `kong:"cmd,help='Delete the current SSL certificate/private key'"` Print EcsSSLPrintCmd `kong:"cmd,help='Print the current SSL certificate'"` + Save EcsSSLSaveCmd `kong:"cmd,help='Save a new SSL certificate/private key'"` } type EcsSSLSaveCmd struct { diff --git a/cmd/aws-sso/ecs_server_cmd.go b/cmd/aws-sso/ecs_server_cmd.go index 1535943d..3096da5c 100644 --- a/cmd/aws-sso/ecs_server_cmd.go +++ b/cmd/aws-sso/ecs_server_cmd.go @@ -32,8 +32,9 @@ type EcsServerCmd struct { BindIP string `kong:"help='Bind address for ECS Server',default='127.0.0.1'"` Port int `kong:"help='TCP port to listen on',default=4144"` // hidden flags are for internal use only when running in a docker container - Docker bool `kong:"hidden"` - DisableSSL bool `kong:"help='Disable SSL/TLS for the ECS Server'"` + Docker bool `kong:"hidden"` + DisableAuth bool `kong:"help='Disable HTTP Auth for the ECS Server'"` + DisableSSL bool `kong:"help='Disable SSL/TLS for the ECS Server'"` } func (cc *EcsServerCmd) Run(ctx *RunContext) error { @@ -88,6 +89,10 @@ func (cc *EcsServerCmd) Run(ctx *RunContext) error { certChain = "" } + if ctx.Cli.Ecs.Server.DisableAuth { + bearerToken = "" + } + if bearerToken == "" { log.Warnf("HTTP Auth: disabled. Use 'aws-sso ecs bearer-token' to enable") } else { diff --git a/docs/commands-ecs.md b/docs/commands-ecs.md index e9300304..a9298350 100644 --- a/docs/commands-ecs.md +++ b/docs/commands-ecs.md @@ -44,7 +44,7 @@ SSL/TLS for the ECS Server. ### ecs ssl print -Prints the SSL certificate stored in the SecureStore. +Prints the SSL public certificate stored in the SecureStore. --- @@ -54,7 +54,8 @@ Starts the ECS Server in the foreground. Flags: - * `--disable-ssl` -- Disables SSL/TLS, even if a certificate and private key are available. + * `--disable-auth` -- Disables HTTP Authentication, even if a Bearer Token is available + * `--disable-ssl` -- Disables SSL/TLS, even if a certificate and private key are available --- @@ -97,10 +98,14 @@ Flags: * `--account `, `-A` -- AWS AccountID of role to assume (`$AWS_SSO_ACCOUNT_ID`) * `--role `, `-R` -- Name of AWS Role to assume (requires `--account`) (`$AWS_SSO_ROLE_NAME`) * `--profile `, `-p` -- Name of AWS Profile to assume - * `--account` -- AWS AccountID of the IAM Role to load. * `--server` -- host:port of the ECS Server (default `localhost:4144`) * `--slotted` -- Load the IAM credentials into a unique slot using the ProfileName as the key +You can provide `--profile` or `--arn` or (`--account` and `--role`) to specify the IAM role to load. + +If you do not specify `--slotted`, the role will be loaded into the default URL path at `/`. If you +would like to load multiple roles, specify `--slotted` and the role will be loaded into `/slot/` + --- ### ecs unload @@ -109,13 +114,11 @@ Removes the AWS IAM Role credentials from the ECS Server and makes them unavaila Flags: - * `--arn `, `-a` -- ARN of role to assume (`$AWS_SSO_ROLE_ARN`) - * `--account `, `-A` -- AWS AccountID of role to assume (`$AWS_SSO_ACCOUNT_ID`) - * `--role `, `-R` -- Name of AWS Role to assume (requires `--account`) (`$AWS_SSO_ROLE_NAME`) - * `--profile `, `-p` -- Name of AWS Profile to assume - * `--account` -- AWS AccountID of the IAM Role to load. + * `--profile `, `-p` -- Slot of AWS Profile to unload * `--server` -- host:port of the ECS Server (default `localhost:4144`) - * `--slotted` -- Load the IAM credentials into a unique slot using the ProfileName as the key + +By default, this will unload the IAM credentials for the default role. Passing in +`--profile ` will unload the credentials in the named slot. --- diff --git a/docs/ecs-server.md b/docs/ecs-server.md index 64dfd5dc..43bf78af 100644 --- a/docs/ecs-server.md +++ b/docs/ecs-server.md @@ -40,7 +40,7 @@ an alternative IP/port via the `--bind-ip` and `--port` flags. ### Running the ECS Server in the background The recommended way to run the ECS server in the background is via the -[aws-sso-cli-ecs-server](https://hub.docker.com/repository/docker/synfinatic/xb8-docsis-stats/general) +[aws-sso-cli-ecs-server](https://hub.docker.com/repository/docker/synfinatic/aws-sso-cli-ecs-server/general) Docker image and the `aws-sso ecs docker [start|stop]` commands as this will automatically configure your SSL key pair and bearer token from the secure store in the most secure means possible. @@ -61,12 +61,16 @@ AWS IAM authentication tokens. #### ECS Server SSL Certificate -**Important:** Due to a [bug in the AWS Boto3 SDK](https://github.com/synfinatic/aws-sso-cli/issues/936) -you can not enable SSL at this time. I'm currently unsure if other AWS SDKs -(like the Go SDK used by Terraform) also experience this issue. __I'd greatly +**Important:** Due to a [bug in the AWS SDK](https://github.com/aws/aws-sdk/issues/774) +you can not easily enable SSL at this time. __I'd greatly appreciate people to upvote my ticket with AWS and help get it greater visibility at AWS and hopefully addressed sooner rather than later.__ +You will need to create an SSL certificate which is _signed by a well trusted CA_ +such as DigiCert, Let's Encrypt, Thwate, etc. Currently, the AWS SDK does __NOT__ +support self-signed certificates or private CA's for this endpoint. + + + Once you have your certificate and private key, you will need to save them into the `aws-sso` secure store: @@ -109,6 +115,7 @@ $ aws-sso ecs ssl print **Note:** At this time, there is no way to extract the SSL Private Key from the Secure Store. + + +##### Using self-signed certificates + +In theory, you can add your self-signed certificate or custom CA into the AWS SDK certificate bundle. +However, this file is SDK specific (the Boto3 SDK ships with it's own `cacert.pem` while the Go v2 SDK uses +the system default bundle). Managing this is not just language specific, but likely to be site-specific +so getting this to work is left as an exercise to the reader. + #### ECS Server HTTP Authentication The way to configure HTTP Authentication is with a @@ -176,9 +192,9 @@ for all AWS Client SDKs using it. Ensure you have exported the following shell ENV variable: -`export AWS_CONTAINER_CREDENTIALS_FULL_URI=http://localhost:4144/creds` +`export AWS_CONTAINER_CREDENTIALS_FULL_URI=http://localhost:4144/` -**Note:** If you have configured an SSL certificate as described above, use `https://localhost:4144/creds`. +**Note:** If you have configured an SSL certificate as described above, use `https://localhost:4144/`. Then just: diff --git a/docs/remote-ssh.md b/docs/remote-ssh.md index 3a6bc34f..b62c14b7 100644 --- a/docs/remote-ssh.md +++ b/docs/remote-ssh.md @@ -29,7 +29,7 @@ and/or any IAM Credentials stored in the ECS Server if you have not [enabled SSL or [tmux](https://hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/) session: `aws-sso ecs run` 1. Load your selected IAM credentials into the ECS Server:
-`aws-sso ecs load --profile=` +`aws-sso ecs load --profile=` 1. SSH to the remote system using the [-R flag to forward tcp/4144](https://man.openbsd.org/ssh#R):
`ssh -R 4144:localhost:4144 ` @@ -38,11 +38,22 @@ or [tmux](https://hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/) session: **Note:** The following commands assume you are using `bash`. You may have to tweak for other shells. 1. Tell the AWS SDK how to talk to the ECS Server over SSH:
-`export AWS_CONTAINER_CREDENTIALS_FULL_URI=https://localhost:4144/` (or `http` if you did not enable SSL) + `export AWS_CONTAINER_CREDENTIALS_FULL_URI=https://localhost:4144/` (or `http` if you did not enable SSL) 1. Tell the AWS SDK the bearer token secret from the first step on your local system:
-`export AWS_CONTAINER_AUTHORIZATION_TOKEN='Bearer '` -1. Verify everything works: -`aws sts get-caller-identity` + `export AWS_CONTAINER_AUTHORIZATION_TOKEN='Bearer '` +1. Verify everything works: `aws sts get-caller-identity` See the [ECS Server documentation](ecs-server.md) for more information about the ECS server and -how to use multiple IAM role credentials simultaneously. \ No newline at end of file +how to use multiple IAM role credentials simultaneously. + +## Advanced Usage + +The above instructions grant any host you ssh to, access to the same AWS IAM Role. But what if +you want to access multiple roles? + +For each role you'd like to access you will need to do two things: + + 1. On your local host, load that role into an individual slot in the ECS Server:
+ `aws-sso ecs load --slotted --profile ` + 2. On the remote host, specify the correct URL:
+ `export AWS_CONTAINER_CREDENTIALS_FULL=https://localhost:4144/slot/` \ No newline at end of file