-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
example/aws/proxyWithTLSClientCert: Add HTTPS_PROXY client cert examp…
…le (#2664) Adds an example for using the SDK with an HTTPS_PROXY that requires the client include a TLS certificate to the HTTPS proxy.
- Loading branch information
Showing
2 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Example | ||
|
||
Example of using the AWS SDK for Go with an HTTPS_PROXY that requires client | ||
TLS certificates. The example will use the proxy configured via the environment | ||
variable `HTTPS_PROXY` proxy a request for the Amazon S3 `ListBuckets` API | ||
operation call. | ||
|
||
The example assumes credentials are provided in the environment, or shared | ||
credentials file `~/.aws/credentials`. The `certificate` and `key` files paths | ||
are required to be specified when the example is run. An certificate authority | ||
(CA) file path can also be optionally specified. | ||
|
||
Refer to [httpproxy.FromEnvironment](https://godoc.org/golang.org/x/net/http/httpproxy#FromEnvironment) | ||
for details using `HTTPS_PROXY` with the Go HTTP client. | ||
|
||
## Usage: | ||
|
||
```sh | ||
export HTTPS_PROXY=https://127.0.0.1:8443 | ||
export AWS_REGION=us-west-2 | ||
go run -cert <certfile> -key <keyfile> [-ca <cafile>] | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// +build example | ||
|
||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"crypto/x509" | ||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"net" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/s3" | ||
"golang.org/x/net/http2" | ||
) | ||
|
||
// Example of creating an HTTP Client configured with a client TLS | ||
// certificates. Can be used with endpoints such as HTTPS_PROXY that require | ||
// client certificates. | ||
// | ||
// Requires a cert and key flags, and optionally takes a CA file. | ||
// | ||
// To run: | ||
// go run -cert <certfile> -key <keyfile> [-ca <cafile>] | ||
// | ||
// You can generate self signed cert and key pem files | ||
// go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -host <hostname> | ||
func main() { | ||
var clientCertFile, clientKeyFile, caFile string | ||
flag.StringVar(&clientCertFile, "cert", "cert.pem", "The `certificate file` to load.") | ||
flag.StringVar(&clientKeyFile, "key", "key.pem", "The `key file` to load.") | ||
flag.StringVar(&caFile, "ca", "ca.pem", "The `root CA` to load.") | ||
flag.Parse() | ||
|
||
if len(clientCertFile) == 0 || len(clientKeyFile) == 0 { | ||
flag.PrintDefaults() | ||
log.Fatalf("client certificate and key required") | ||
} | ||
|
||
tlsCfg, err := tlsConfigWithClientCert(clientCertFile, clientKeyFile, caFile) | ||
if err != nil { | ||
log.Fatalf("failed to load client cert, %v", err) | ||
} | ||
|
||
// Copy of net/http.DefaultTransport with TLS config loaded | ||
tr := defaultHTTPTransport() | ||
tr.TLSClientConfig = tlsCfg | ||
|
||
// re-enable HTTP/2 because modifing TLS config will prevent auto support | ||
// for HTTP/2. | ||
http2.ConfigureTransport(tr) | ||
|
||
// Configure the SDK's session with the HTTP client with TLS client | ||
// certificate support enabled. This session will be used to create all | ||
// SDK's API clients. | ||
sess, err := session.NewSession(&aws.Config{ | ||
HTTPClient: &http.Client{ | ||
Transport: tr, | ||
}, | ||
}) | ||
|
||
// Create each API client will the session configured with the client TLS | ||
// certificate. | ||
svc := s3.New(sess) | ||
|
||
resp, err := svc.ListBuckets(&s3.ListBucketsInput{}) | ||
if err != nil { | ||
log.Fatalf("failed to list buckets, %v", err) | ||
} | ||
|
||
fmt.Println("Buckets") | ||
fmt.Println(resp) | ||
} | ||
|
||
func tlsConfigWithClientCert(clientCertFile, clientKeyFile, caFile string) (*tls.Config, error) { | ||
clientCert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to load certificat files, %s, %s, %v", | ||
clientCertFile, clientKeyFile, err) | ||
} | ||
|
||
tlsCfg := &tls.Config{ | ||
Certificates: []tls.Certificate{ | ||
clientCert, | ||
}, | ||
} | ||
|
||
if len(caFile) != 0 { | ||
cert, err := ioutil.ReadFile(caFile) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to load root CA file, %s, %v", | ||
caFile, err) | ||
} | ||
caCertPool := x509.NewCertPool() | ||
caCertPool.AppendCertsFromPEM(cert) | ||
tlsCfg.RootCAs = caCertPool | ||
} | ||
|
||
tlsCfg.BuildNameToCertificate() | ||
|
||
return tlsCfg, nil | ||
} | ||
|
||
func defaultHTTPTransport() *http.Transport { | ||
return &http.Transport{ | ||
Proxy: http.ProxyFromEnvironment, | ||
DialContext: (&net.Dialer{ | ||
Timeout: 30 * time.Second, | ||
KeepAlive: 30 * time.Second, | ||
DualStack: true, | ||
}).DialContext, | ||
MaxIdleConns: 100, | ||
MaxIdleConnsPerHost: 10, // Increased idle connections per host | ||
IdleConnTimeout: 90 * time.Second, | ||
TLSHandshakeTimeout: 10 * time.Second, | ||
ExpectContinueTimeout: 1 * time.Second, | ||
} | ||
} |