Browse Source

http2/h2demo: enable HTTP ACME challenges, move from CoreOS to Kubernetes

This makes HTTP challenges work on https://http2.golang.org/ since
LetsEncrypted disabled the TLS-SNI challenges.

Also, move it from a systemd unit on CoreOS to GKE.

Updates golang/go#23627
Fixes golang/go#23034

Change-Id: Id8348e9e56ab43e277f1e12d563fd8fc490d6211
Reviewed-on: https://go-review.googlesource.com/91495
Reviewed-by: Andrew Bonventre <andybons@golang.org>
Brad Fitzpatrick 8 years ago
parent
commit
d19327ad09

+ 1 - 0
http2/h2demo/.gitignore

@@ -3,3 +3,4 @@ h2demo.linux
 client-id.dat
 client-id.dat
 client-secret.dat
 client-secret.dat
 token.dat
 token.dat
+ca-certificates.crt

+ 11 - 0
http2/h2demo/Dockerfile

@@ -0,0 +1,11 @@
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+FROM scratch
+LABEL maintainer "golang-dev@googlegroups.com"
+
+COPY ca-certificates.crt /etc/ssl/certs/
+COPY h2demo /
+ENTRYPOINT ["/h2demo", "-prod"]
+

+ 134 - 0
http2/h2demo/Dockerfile.0

@@ -0,0 +1,134 @@
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+FROM golang:1.9
+LABEL maintainer "golang-dev@googlegroups.com"
+
+ENV CGO_ENABLED=0
+
+# BEGIN deps (run `make update-deps` to update)
+
+# Repo cloud.google.com/go at 1d0c2da (2018-01-30)
+ENV REV=1d0c2da40456a9b47f5376165f275424acc15c09
+RUN go get -d cloud.google.com/go/compute/metadata `#and 6 other pkgs` &&\
+    (cd /go/src/cloud.google.com/go && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo github.com/golang/protobuf at 9255415 (2018-01-25)
+ENV REV=925541529c1fa6821df4e44ce2723319eb2be768
+RUN go get -d github.com/golang/protobuf/proto `#and 6 other pkgs` &&\
+    (cd /go/src/github.com/golang/protobuf && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo github.com/googleapis/gax-go at 317e000 (2017-09-15)
+ENV REV=317e0006254c44a0ac427cc52a0e083ff0b9622f
+RUN go get -d github.com/googleapis/gax-go &&\
+    (cd /go/src/github.com/googleapis/gax-go && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo go4.org at 034d17a (2017-05-25)
+ENV REV=034d17a462f7b2dcd1a4a73553ec5357ff6e6c6e
+RUN go get -d go4.org/syncutil/singleflight &&\
+    (cd /go/src/go4.org && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/build at 8aa9ee0 (2018-02-01)
+ENV REV=8aa9ee0e557fd49c14113e5ba106e13a5b455460
+RUN go get -d golang.org/x/build/autocertcache &&\
+    (cd /go/src/golang.org/x/build && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/crypto at 1875d0a (2018-01-27)
+ENV REV=1875d0a70c90e57f11972aefd42276df65e895b9
+RUN go get -d golang.org/x/crypto/acme `#and 2 other pkgs` &&\
+    (cd /go/src/golang.org/x/crypto && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/oauth2 at 30785a2 (2018-01-04)
+ENV REV=30785a2c434e431ef7c507b54617d6a951d5f2b4
+RUN go get -d golang.org/x/oauth2 `#and 5 other pkgs` &&\
+    (cd /go/src/golang.org/x/oauth2 && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo golang.org/x/text at e19ae14 (2017-12-27)
+ENV REV=e19ae1496984b1c655b8044a65c0300a3c878dd3
+RUN go get -d golang.org/x/text/secure/bidirule `#and 4 other pkgs` &&\
+    (cd /go/src/golang.org/x/text && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/api at 7d0e2d3 (2018-01-30)
+ENV REV=7d0e2d350555821bef5a5b8aecf0d12cc1def633
+RUN go get -d google.golang.org/api/gensupport `#and 9 other pkgs` &&\
+    (cd /go/src/google.golang.org/api && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/genproto at 4eb30f4 (2018-01-25)
+ENV REV=4eb30f4778eed4c258ba66527a0d4f9ec8a36c45
+RUN go get -d google.golang.org/genproto/googleapis/api/annotations `#and 3 other pkgs` &&\
+    (cd /go/src/google.golang.org/genproto && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Repo google.golang.org/grpc at 0bd008f (2018-01-25)
+ENV REV=0bd008f5fadb62d228f12b18d016709e8139a7af
+RUN go get -d google.golang.org/grpc `#and 23 other pkgs` &&\
+    (cd /go/src/google.golang.org/grpc && (git cat-file -t $REV 2>/dev/null || git fetch -q origin $REV) && git reset --hard $REV)
+
+# Optimization to speed up iterative development, not necessary for correctness:
+RUN go install cloud.google.com/go/compute/metadata \
+	cloud.google.com/go/iam \
+	cloud.google.com/go/internal \
+	cloud.google.com/go/internal/optional \
+	cloud.google.com/go/internal/version \
+	cloud.google.com/go/storage \
+	github.com/golang/protobuf/proto \
+	github.com/golang/protobuf/protoc-gen-go/descriptor \
+	github.com/golang/protobuf/ptypes \
+	github.com/golang/protobuf/ptypes/any \
+	github.com/golang/protobuf/ptypes/duration \
+	github.com/golang/protobuf/ptypes/timestamp \
+	github.com/googleapis/gax-go \
+	go4.org/syncutil/singleflight \
+	golang.org/x/build/autocertcache \
+	golang.org/x/crypto/acme \
+	golang.org/x/crypto/acme/autocert \
+	golang.org/x/oauth2 \
+	golang.org/x/oauth2/google \
+	golang.org/x/oauth2/internal \
+	golang.org/x/oauth2/jws \
+	golang.org/x/oauth2/jwt \
+	golang.org/x/text/secure/bidirule \
+	golang.org/x/text/transform \
+	golang.org/x/text/unicode/bidi \
+	golang.org/x/text/unicode/norm \
+	google.golang.org/api/gensupport \
+	google.golang.org/api/googleapi \
+	google.golang.org/api/googleapi/internal/uritemplates \
+	google.golang.org/api/googleapi/transport \
+	google.golang.org/api/internal \
+	google.golang.org/api/iterator \
+	google.golang.org/api/option \
+	google.golang.org/api/storage/v1 \
+	google.golang.org/api/transport/http \
+	google.golang.org/genproto/googleapis/api/annotations \
+	google.golang.org/genproto/googleapis/iam/v1 \
+	google.golang.org/genproto/googleapis/rpc/status \
+	google.golang.org/grpc \
+	google.golang.org/grpc/balancer \
+	google.golang.org/grpc/balancer/base \
+	google.golang.org/grpc/balancer/roundrobin \
+	google.golang.org/grpc/codes \
+	google.golang.org/grpc/connectivity \
+	google.golang.org/grpc/credentials \
+	google.golang.org/grpc/encoding \
+	google.golang.org/grpc/encoding/proto \
+	google.golang.org/grpc/grpclb/grpc_lb_v1/messages \
+	google.golang.org/grpc/grpclog \
+	google.golang.org/grpc/internal \
+	google.golang.org/grpc/keepalive \
+	google.golang.org/grpc/metadata \
+	google.golang.org/grpc/naming \
+	google.golang.org/grpc/peer \
+	google.golang.org/grpc/resolver \
+	google.golang.org/grpc/resolver/dns \
+	google.golang.org/grpc/resolver/passthrough \
+	google.golang.org/grpc/stats \
+	google.golang.org/grpc/status \
+	google.golang.org/grpc/tap \
+	google.golang.org/grpc/transport
+# END deps
+
+COPY . /go/src/golang.org/x/net/
+
+RUN go install -tags "h2demo netgo" -ldflags "-linkmode=external -extldflags '-static -pthread'" golang.org/x/net/http2/h2demo
+

+ 53 - 6
http2/h2demo/Makefile

@@ -1,8 +1,55 @@
-h2demo.linux: h2demo.go
-	GOOS=linux go build --tags=h2demo -o h2demo.linux .
+# Copyright 2018 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
 
 
-FORCE:
+MUTABLE_VERSION ?= latest
+VERSION ?= $(shell git rev-parse --short HEAD)
+
+IMAGE_STAGING := gcr.io/go-dashboard-dev/h2demo
+IMAGE_PROD := gcr.io/symbolic-datum-552/h2demo
+
+DOCKER_IMAGE_build0=build0/h2demo:latest
+DOCKER_CTR_build0=h2demo-build0
+
+build0: *.go Dockerfile.0
+	docker build --force-rm -f Dockerfile.0 --tag=$(DOCKER_IMAGE_build0) ../..
+
+h2demo: build0
+	docker create --name $(DOCKER_CTR_build0) $(DOCKER_IMAGE_build0)
+	docker cp $(DOCKER_CTR_build0):/go/bin/$@ $@
+	docker rm $(DOCKER_CTR_build0)
+
+ca-certificates.crt:
+	docker create --name $(DOCKER_CTR_build0) $(DOCKER_IMAGE_build0)
+	docker cp $(DOCKER_CTR_build0):/etc/ssl/certs/$@ $@
+	docker rm $(DOCKER_CTR_build0)
 
 
-upload: FORCE
-	go install golang.org/x/build/cmd/upload
-	upload --verbose --osarch=linux-amd64 --tags=h2demo --file=go:golang.org/x/net/http2/h2demo --public http2-demo-server-tls/h2demo
+update-deps:
+	go install golang.org/x/build/cmd/gitlock
+	gitlock --update=Dockerfile.0 --ignore=golang.org/x/net golang.org/x/net/http2/h2demo
+
+docker-prod: Dockerfile h2demo ca-certificates.crt
+	docker build --force-rm --tag=$(IMAGE_PROD):$(VERSION) .
+	docker tag $(IMAGE_PROD):$(VERSION) $(IMAGE_PROD):$(MUTABLE_VERSION)
+docker-staging: Dockerfile h2demo ca-certificates.crt
+	docker build --force-rm --tag=$(IMAGE_STAGING):$(VERSION) .
+	docker tag $(IMAGE_STAGING):$(VERSION) $(IMAGE_STAGING):$(MUTABLE_VERSION)
+
+push-prod: docker-prod
+	gcloud docker -- push $(IMAGE_PROD):$(MUTABLE_VERSION)
+	gcloud docker -- push $(IMAGE_PROD):$(VERSION)
+push-staging: docker-staging
+	gcloud docker -- push $(IMAGE_STAGING):$(MUTABLE_VERSION)
+	gcloud docker -- push $(IMAGE_STAGING):$(VERSION)
+
+deploy-prod: push-prod
+	kubectl set image deployment/h2demo-deployment h2demo=$(IMAGE_PROD):$(VERSION)
+deploy-staging: push-staging
+	kubectl set image deployment/h2demo-deployment h2demo=$(IMAGE_STAGING):$(VERSION)
+
+.PHONY: clean
+clean:
+	$(RM) h2demo
+	$(RM) ca-certificates.crt
+
+FORCE:

+ 28 - 0
http2/h2demo/deployment-prod.yaml

@@ -0,0 +1,28 @@
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+  name: h2demo-deployment
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: h2demo
+      annotations:
+        container.seccomp.security.alpha.kubernetes.io/h2demo: docker/default
+        container.apparmor.security.beta.kubernetes.io/h2demo: runtime/default
+    spec:
+      containers:
+      - name: h2demo
+        image: gcr.io/symbolic-datum-552/h2demo:latest
+        imagePullPolicy: Always
+        command: ["/h2demo", "-prod"]
+        ports:
+        - containerPort: 80
+        - containerPort: 443
+        resources:
+          requests:
+            cpu: "1"
+            memory: "1Gi"
+          limits:
+            memory: "2Gi"

+ 19 - 14
http2/h2demo/h2demo.go

@@ -8,6 +8,7 @@ package main
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"context"
 	"crypto/tls"
 	"crypto/tls"
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
@@ -19,7 +20,6 @@ import (
 	"log"
 	"log"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
-	"os"
 	"path"
 	"path"
 	"regexp"
 	"regexp"
 	"runtime"
 	"runtime"
@@ -28,7 +28,9 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
+	"cloud.google.com/go/storage"
 	"go4.org/syncutil/singleflight"
 	"go4.org/syncutil/singleflight"
+	"golang.org/x/build/autocertcache"
 	"golang.org/x/crypto/acme/autocert"
 	"golang.org/x/crypto/acme/autocert"
 	"golang.org/x/net/http2"
 	"golang.org/x/net/http2"
 )
 )
@@ -426,19 +428,10 @@ func httpHost() string {
 	}
 	}
 }
 }
 
 
-func serveProdTLS() error {
-	const cacheDir = "/var/cache/autocert"
-	if err := os.MkdirAll(cacheDir, 0700); err != nil {
-		return err
-	}
-	m := autocert.Manager{
-		Cache:      autocert.DirCache(cacheDir),
-		Prompt:     autocert.AcceptTOS,
-		HostPolicy: autocert.HostWhitelist("http2.golang.org"),
-	}
+func serveProdTLS(autocertManager *autocert.Manager) error {
 	srv := &http.Server{
 	srv := &http.Server{
 		TLSConfig: &tls.Config{
 		TLSConfig: &tls.Config{
-			GetCertificate: m.GetCertificate,
+			GetCertificate: autocertManager.GetCertificate,
 		},
 		},
 	}
 	}
 	http2.ConfigureServer(srv, &http2.Server{
 	http2.ConfigureServer(srv, &http2.Server{
@@ -468,9 +461,21 @@ func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
 }
 }
 
 
 func serveProd() error {
 func serveProd() error {
+	log.Printf("running in production mode")
+
+	storageClient, err := storage.NewClient(context.Background())
+	if err != nil {
+		log.Fatalf("storage.NewClient: %v", err)
+	}
+	autocertManager := &autocert.Manager{
+		Prompt:     autocert.AcceptTOS,
+		HostPolicy: autocert.HostWhitelist("http2.golang.org"),
+		Cache:      autocertcache.NewGoogleCloudStorageCache(storageClient, "golang-h2demo-autocert"),
+	}
+
 	errc := make(chan error, 2)
 	errc := make(chan error, 2)
-	go func() { errc <- http.ListenAndServe(":80", nil) }()
-	go func() { errc <- serveProdTLS() }()
+	go func() { errc <- http.ListenAndServe(":80", autocertManager.HTTPHandler(http.DefaultServeMux)) }()
+	go func() { errc <- serveProdTLS(autocertManager) }()
 	return <-errc
 	return <-errc
 }
 }
 
 

+ 16 - 0
http2/h2demo/service.yaml

@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: h2demo
+spec:
+  ports:
+    - port: 80
+      targetPort: 80
+      name: http
+    - port: 443
+      targetPort: 443
+      name: https
+  selector:
+    app: h2demo
+  type: LoadBalancer
+  loadBalancerIP: 130.211.116.44