github.com/aavshr/aws-sdk-go@v1.41.3/example/aws/proxyWithTLSClientCert/main.go (about) 1 //go:build example && go1.15 2 // +build example,go1.15 3 4 package main 5 6 import ( 7 "crypto/tls" 8 "crypto/x509" 9 "flag" 10 "fmt" 11 "io/ioutil" 12 "log" 13 "net" 14 "net/http" 15 "time" 16 17 "github.com/aavshr/aws-sdk-go/aws" 18 "github.com/aavshr/aws-sdk-go/aws/session" 19 "github.com/aavshr/aws-sdk-go/service/s3" 20 "golang.org/x/net/http2" 21 ) 22 23 // Example of creating an HTTP Client configured with a client TLS 24 // certificates. Can be used with endpoints such as HTTPS_PROXY that require 25 // client certificates. 26 // 27 // Requires a cert and key flags, and optionally takes a CA file. 28 // 29 // To run: 30 // go run -cert <certfile> -key <keyfile> [-ca <cafile>] 31 // 32 // You can generate self signed cert and key pem files 33 // go run $(go env GOROOT)/src/crypto/tls/generate_cert.go -host <hostname> 34 func main() { 35 var clientCertFile, clientKeyFile, caFile string 36 flag.StringVar(&clientCertFile, "cert", "cert.pem", "The `certificate file` to load.") 37 flag.StringVar(&clientKeyFile, "key", "key.pem", "The `key file` to load.") 38 flag.StringVar(&caFile, "ca", "ca.pem", "The `root CA` to load.") 39 flag.Parse() 40 41 if len(clientCertFile) == 0 || len(clientKeyFile) == 0 { 42 flag.PrintDefaults() 43 log.Fatalf("client certificate and key required") 44 } 45 46 tlsCfg, err := tlsConfigWithClientCert(clientCertFile, clientKeyFile, caFile) 47 if err != nil { 48 log.Fatalf("failed to load client cert, %v", err) 49 } 50 51 // Copy of net/http.DefaultTransport with TLS config loaded 52 tr := defaultHTTPTransport() 53 tr.TLSClientConfig = tlsCfg 54 55 // re-enable HTTP/2 because modifing TLS config will prevent auto support 56 // for HTTP/2. 57 http2.ConfigureTransport(tr) 58 59 // Configure the SDK's session with the HTTP client with TLS client 60 // certificate support enabled. This session will be used to create all 61 // SDK's API clients. 62 sess, err := session.NewSession(&aws.Config{ 63 HTTPClient: &http.Client{ 64 Transport: tr, 65 }, 66 }) 67 68 // Create each API client will the session configured with the client TLS 69 // certificate. 70 svc := s3.New(sess) 71 72 resp, err := svc.ListBuckets(&s3.ListBucketsInput{}) 73 if err != nil { 74 log.Fatalf("failed to list buckets, %v", err) 75 } 76 77 fmt.Println("Buckets") 78 fmt.Println(resp) 79 } 80 81 func tlsConfigWithClientCert(clientCertFile, clientKeyFile, caFile string) (*tls.Config, error) { 82 clientCert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile) 83 if err != nil { 84 return nil, fmt.Errorf("unable to load certificat files, %s, %s, %v", 85 clientCertFile, clientKeyFile, err) 86 } 87 88 tlsCfg := &tls.Config{ 89 Certificates: []tls.Certificate{ 90 clientCert, 91 }, 92 } 93 94 if len(caFile) != 0 { 95 cert, err := ioutil.ReadFile(caFile) 96 if err != nil { 97 return nil, fmt.Errorf("unable to load root CA file, %s, %v", 98 caFile, err) 99 } 100 caCertPool := x509.NewCertPool() 101 caCertPool.AppendCertsFromPEM(cert) 102 tlsCfg.RootCAs = caCertPool 103 } 104 105 tlsCfg.BuildNameToCertificate() 106 107 return tlsCfg, nil 108 } 109 110 func defaultHTTPTransport() *http.Transport { 111 return &http.Transport{ 112 Proxy: http.ProxyFromEnvironment, 113 DialContext: (&net.Dialer{ 114 Timeout: 30 * time.Second, 115 KeepAlive: 30 * time.Second, 116 DualStack: true, 117 }).DialContext, 118 MaxIdleConns: 100, 119 MaxIdleConnsPerHost: 10, // Increased idle connections per host 120 IdleConnTimeout: 90 * time.Second, 121 TLSHandshakeTimeout: 10 * time.Second, 122 ExpectContinueTimeout: 1 * time.Second, 123 } 124 }