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  }