-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Added S3 third party support #3057
Conversation
Can one of the admins verify this patch? |
I don't know if that counts, but I build the binaries from scratch to verify the functionality :-) The screenshot is from a S3 compatible storage backend: So I am able to record sessions and replay them. @klizhentas would be great if you could take a look here. |
ok to test |
@webvictim where do I get the read access for that jenkins job? Accessing results in a permission denied. |
@balpert89 Access to Jenkins is only for Gravitational staff I'm afraid. The failure was nothing to do with your code, however. |
@webvictim can you hold this back again, I have made some further tests when the endpoint is only an ip address (such as localhost), the patch does not work. I would like to extend it with that. Use case: we are further ecrypting the recorded sessions because the .tar is only a plain text. Depending on the logs there could be critical information found inside it. Has Teleport this functionality out of the box, encrypting the recorded sessions? |
I've changed the title of the PR to indicate that it's a work in progress to avoid merging for now. By default, Teleport will enable encryption for any S3 buckets that it creates on AWS. It doesn't include any encryption of its own - it relies on encryption at the storage level. If your third party S3-compatible provider also provides encryption at rest, it should be fairly easy to enable that too. |
9087b19
to
d4b5e3a
Compare
New iteration, I have used the same approach as the "region" param, as detecting if this is a hostname/ip with or without port is not trivial. Updated playground: https://play.golang.org/p/U-3e9Pr71Ah |
@webvictim @klizhentas checks are ok, is there anything I have to do? :) |
I'll leave this for @klizhentas to review and merge when ready. |
constants.go
Outdated
Endpoint = "endpoint" | ||
|
||
//DisableSSL is an optional switch to use http | ||
DisableSSL = "disablessl" |
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.
would it be possible to omit this flag?
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.
I will describe the use case for that.
In an above comment (#3057 (comment)) I've asked if Teleport is capable in encrypting the recorded session, however it relies on the s3 buckets functionality together with KMS to achieve that. Some cloud providers don't have that (MS Azure for example has another technology, Key Vault). Therefore we have developed our own encryption proxy that is deployed in the same pod as the auth server in a side container, it is targetted only over localhost: s3://bucket-name/path/to/dir?endpoint=127.0.0.1:8080
. As it is only using localhost
communication cannot be sniffed.
The flag also makes testing that much easier, its the same functionality you provide wit the etcd related insecure
flag (https://gravitational.com/teleport/docs/admin-guide/#using-etcd) or the overall --insecure
and --insecure-no-tls
flags. Maybe renaming that parameter to insecurehttp
or something like that would indicate to not use it in production environments?
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.
@klizhentas is this use case description sufficient for you? Can we proceed? :)
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.
There are a couple of other things we'd have to do before we proceed:
DisableSSL
->InsecureDisableTLS
SSL is a protocol that is no longer used, so this term is inaccurate.- Tests. This pull request should add appropriate tests
- Scheme. Adding query parameters to
s3://
scheme seems like a viable solution to me, however I wonder if we can come up with something more elegant here. Still scratching my head about this one though.
Thanks for your patience.
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.
Then I would opt for --insecure-no-tls
to be compliant with the other parameter flag. I will also add appropriate tests to the PR.
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.
The test suite also assumes a) running solely on AWS and b) there is only a TLS connection. Not sure how this test suite is set up, does it create an AWS bucket in the background? Seems like it.
I would suggest using https://github.com/johannesboyne/gofakes3 for a testing API but I would like to check with @klizhentas first :-).
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.
@klizhentas I have added the TestSuite for third party s3, please review it.
I've changed the title of the PR to indicate that it's a work in progress to avoid merging for now.
By default, Teleport will enable encryption for any S3 buckets that it creates on AWS. It doesn't include any encryption of its own - it relies on encryption at the storage level. If your third party S3-compatible provider also provides encryption at rest, it should be fairly easy to enable that too.
The commit also has a new switch to disable ServerSideEncryption, as there are some providers that do not support that. Also, I did not manage to have the tests for the 3rd party usage in the same s3handler_test.go file, so I opted to use a separate one.
Test Output:
=== RUN TestS3ThirdParty
2019/10/15 13:00:16 INFO HEAD BUCKET teleport-test-5358bf35-5497-4425-89ff-c69530e636c3
2019/10/15 13:00:16 INFO bucketname: teleport-test-5358bf35-5497-4425-89ff-c69530e636c3
2019/10/15 13:00:16 INFO CREATE BUCKET: teleport-test-5358bf35-5497-4425-89ff-c69530e636c3
2019/10/15 13:00:16 INFO PUT VERSIONING: Enabled
2019/10/15 13:00:16 INFO CREATE OBJECT: teleport-test-5358bf35-5497-4425-89ff-c69530e636c3 test/350e8284-161b-4fe4-82fd-0bb1d4be0a7a.tar
2019/10/15 13:00:16 INFO CREATED VERSION: teleport-test-5358bf35-5497-4425-89ff-c69530e636c3 test/350e8284-161b-4fe4-82fd-0bb1d4be0a7a.tar 3/60O30C1G60O30C1G60O30C1G60O30C1G60O30C1G60O30C1H00NOD62MJ6G7VI0=
2019/10/15 13:00:16 INFO GET OBJECT
2019/10/15 13:00:16 INFO Bucket: teleport-test-5358bf35-5497-4425-89ff-c69530e636c3
2019/10/15 13:00:16 INFO └── Object: test/350e8284-161b-4fe4-82fd-0bb1d4be0a7a.tar
OK: 2 passed
--- PASS: TestS3ThirdParty (0.01s)
PASS
Process finished with exit code 0
@kontsevoy @benarent this is a valid use case, however this implementation uses syntax should be improved: The problem with s3://example.com/path/to/dir
# example.com can be bucket name or endpoint The current solution proposes URL query parameters that is quite error prone: s3://bucket-name/path/to/dir?endpoint=127.0.0.1:8080&insecure=true Instead, I think we should use schemes: That denotes the S3 compatible storage # HTTPS enabled S3 compatible,
# first host is host, example.com is a bucket name
# and the rest is a path
s3compat://127.0.0.1:8080/example.com/path/to/dir Insecure version for cases with custom proxies that turns off security # HTTP enabled S3 compatible,
# first host is host, example.com is a bucket name
# and the rest is a path
s3insecure://127.0.0.1:8080/example.com/path/to/dir Let me know what you think so we can update the spec and ask for changes. |
@balpert89 per our design process, all changes affecting configuration should go through product team review. I have asked @benarent to get the opinion on the proposed design. |
I did a dive into this yesterday, and these are some of my findings. Since S3 can have a range of endpoints depending on your setup. I would suggest we provide this as an option to be provide a great range of AWS accounts setup, and provides a disableSSL/TLS e.g The one issue with the below proposal while some services provide offical docs with s3 refernces, their object store is called something else. I did find one other product using The second issue with below, is we'll need to be explicit for DynamoDB region & permissions. Proposal
For a S3 Setup in GovCloud
For a IBM Cloud
For a IBM Cloud Insecure
InsecureDisableTLS For IBM Cloud, this is how the recommend setting |
This won't allow scenarios of supporting 2 different URIs with different options applied to them, not sure if it's such a bad thing. Also our URI is a list, perhaps we can do something like this: audit_sessions_uri: ['stdout:///', {type: s3, bucket: , region:, all other optoins}, ] or less alien looking without yaml flow: audit_sessions_uri:
- 'stdout:///'
- type: s3
bucket:
region:
whatever: this will finally solve this attempts to put all this stuff in the string, and all prior cases will be supported. |
Yeah, that looks much better and more concise. The one consideration is how we treat 'endpoints', I would assume if not set it'll default to the AWS endpoint convention of |
@klizhentas will you pick this up or what exactly is the approach here? Should I introduce those changes to configuration? Not sure :) |
given the scope of changes, we will take your PR and introduce the changes on top of it. No actions is necessary from your side. Thanks! |
can you please squash your changes in one commit, so we can preserve the original attribution when building on top of your pull request. Thanks |
@klizhentas Should we add this into 4.2 or 4.3? |
@benarent I'd have to merge this one in 4.2 per our agreement with customer, forgot about this, sorry |
@balpert89 thanks for all the work you have done on this. Ultimately I ended up using your suggested flow. I have changed your commit a bit, but it's all largely unmodified and with preserved author name here: Thanks again, closing this PR in favor of the one above. |
This PR introduces the ability to support a third party (a.k.a. non-AWS) S3-compatible endpoint. It is analog to the gcshandler as it sets the config from URL, utilizing a new check for subdomain and program flow based on this check.
It introduces a check for sub domain ("com"/"org"/"io" etc.) and a parse func to determine bucket name and path portion
(s3.example.com/bucket-name/path/to/dir -> bucketName: "bucket-name", path: "/path/to/dir") which is then passed to the s3 session object.
An example for the relevant parts can be found here: https://play.golang.org/p/jfUmxpBp9Vl