diff --git a/.env b/.env deleted file mode 100644 index f45699d1d..000000000 --- a/.env +++ /dev/null @@ -1,12 +0,0 @@ -CTLOG="http://107.178.246.112" -SIGN_PERIOD="5s" -GOOGLE_APPLICATION_CREDENTIALS="service_key.json" -DOMAIN="example.com" -MAPID="0" -DB="genfiles/keytransparency-db.sqlite3" -LISTEN_IP="localhost" # To listen on all IPs, use empty string. -KEY="genfiles/server.key" -CERT="genfiles/server.crt" -VRF_PRIV="genfiles/vrf-key.pem" -VRF_PUB="genfiles/vrf-pubkey.pem" -SIGN_KEY="genfiles/p256-key.pem" diff --git a/.gitignore b/.gitignore index f75f858fb..741b774c2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,9 @@ *.swo *~ -keytransparency-server -keytransparency-signer -keytransparency-client +/keytransparency-server +/keytransparency-signer +/keytransparency-client infra*.etcd genfiles/* diff --git a/.keytransparency.yaml b/.keytransparency.yaml index 29ff4c1ee..81b1d11c7 100644 --- a/.keytransparency.yaml +++ b/.keytransparency.yaml @@ -1,9 +1,9 @@ -log-key: "../certificate-transparency/test/testdata/ct-server-key-public.pem" -vrf: "testdata/vrf-pubkey.pem" -kt-key: "testdata/server.crt" -kt-sig: "testdata/p256-pubkey.pem" +log-key: "../trillian/testdata/ct-http-server.pubkey.pem" +vrf: "genfiles/vrf-pubkey.pem" +kt-key: "genfiles/server.crt" +kt-sig: "genfiles/p256-pubkey.pem" domain: "example.com" -map-id: 0 +mapid: 0 kt-url: "104.199.112.76:5001" -client-secret: "client_secret.json" -service-key: "" +-client-secret: "client_secret.json" +-service-key: "" \ No newline at end of file diff --git a/Procfile b/Procfile deleted file mode 100644 index 648fbc91f..000000000 --- a/Procfile +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2016 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -frontend: ./keytransparency-server --addr=$LISTEN_IP:$PORT --key=$KEY --cert=$CERT --map-id=$MAPID --db=$DB --log-url=$CTLOG --vrf=$VRF_PRIV -backend: ./keytransparency-signer --domain=$DOMAIN --map-id=$MAPID --db=$DB --log-url=$CTLOG --period=$SIGN_PERIOD --key=$SIGN_KEY diff --git a/README.md b/README.md index 5433d25e9..eeeb6d2da 100644 --- a/README.md +++ b/README.md @@ -86,12 +86,15 @@ Set `$GOPATH` variable to point to your Go workspace directory and add `$GOPATH/ 1. Install - [Etcd v3.1.3](https://github.com/coreos/etcd/releases/tag/v3.1.3). - [OpenSSL](https://www.openssl.org/community/binaries.html) +- [Docker](https://docs.docker.com/engine/installation/) + - Docker Engine 1.13.0+ `docker version -f '{{.Server.APIVersion}}'` + - Docker Compose 1.11.0+ `docker-compose --version` 2. Install Key Transparency ```sh - go get -u github.com/mattn/goreman go get -u github.com/google/keytransparency/... + go get -u github.com/google/trillian/... ``` 4. Get a [service account key](https://console.developers.google.com/apis/credentials) and download the generated JSON file. @@ -101,7 +104,7 @@ Set `$GOPATH` variable to point to your Go workspace directory and add `$GOPATH/ 5. Run server setup ```sh - ./scripts/prepare_server.sh +./scripts/prepare_server.sh ``` The tool will build the server binaries, generate keys, and configure the server. @@ -111,8 +114,24 @@ Set `$GOPATH` variable to point to your Go workspace directory and add `$GOPATH/ - `genfiles/server.crt` - `genfile/p256-pubkey.pem` -6. Run the server and the signer using +6. Run the trillian-map server ```sh - goreman start +docker-compose up -d trillian-map ``` + +7. Provision a log and a map +```sh +MAP_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' keytransparency_trillian-map_1` +go run $GOPATH/src/github.com/google/trillian/cmd/createtree/main.go --admin_server=$MAP_IP:8090 --pem_key_path=testdata/log-rpc-server.privkey.pem --pem_key_password="towel" --signature_algorithm=ECDSA --tree_type=LOG +go run $GOPATH/src/github.com/google/trillian/cmd/createtree/main.go --admin_server=$MAP_IP:8090 --pem_key_path=testdata/log-rpc-server.privkey.pem --pem_key_password="towel" --signature_algorithm=ECDSA --tree_type=MAP +``` + +Set the `LOG_ID` and `MAP_ID` environment variables in `docker-compose.yml` with the output +of the respective commands. + +8. Launch the rest of the cluster and observe. +- `docker-compose up -d` +- `docker-compose logs --tail=0 --follow` +- [https://localhost:8080/v1/users/foo@bar.com](https://localhost:8080/v1/users/foo@bar.com) + diff --git a/cmd/keytransparency-server/Dockerfile b/cmd/keytransparency-server/Dockerfile new file mode 100644 index 000000000..c493724fe --- /dev/null +++ b/cmd/keytransparency-server/Dockerfile @@ -0,0 +1,41 @@ +FROM golang + +ENV DB_USER=test \ + DB_PASSWORD=zaphod \ + DB_DATABASE=test \ + DB_HOST=db:3306 + +ENV HOST=0.0.0.0 \ + RPC_PORT=8080 + +# TLS Certificate needs 0.0.0.0 to be in the SAN IP field. +ENV VRF_PRIV=genfiles/vrf-key.pem \ + TLS_KEY_PATH=genfiles/server.key \ + TLS_CRT_PATH=genfiles/server.crt + +ENV MAP_ID=0 \ + MAP_URL="" +ENV LOG_ID=0 \ + LOG_URL=localhost:8090 +ENV GOOGLE_APPLICATION_CREDENTIALS=genfiles/service_key.json +ENV VERBOSE=0 + +ADD . /go/src/github.com/google/keytransparency +WORKDIR /go/src/github.com/google/keytransparency + +RUN go get -tags="mysql" ./cmd/keytransparency-server + +ENTRYPOINT /go/bin/keytransparency-server \ + --addr="$HOST:$RPC_PORT" \ + --db="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST})/${DB_DATABASE}" \ + --vrf="$VRF_PRIV" \ + --key="$TLS_KEY_PATH" --cert="$TLS_CRT_PATH" \ + --log-id="$LOG_ID" --log-url="$LOG_URL" \ + --map-id="$MAP_ID" --map-url="$MAP_URL" \ + --alsologtostderr \ + --verbose="$VERBOSE" + +EXPOSE $RPC_PORT + +HEALTHCHECK --interval=5m --timeout=3s \ + CMD curl -f http://localhost:$RPC_PORT/debug/vars || exit 1 diff --git a/cmd/keytransparency-signer/Dockerfile b/cmd/keytransparency-signer/Dockerfile new file mode 100644 index 000000000..d864e6767 --- /dev/null +++ b/cmd/keytransparency-signer/Dockerfile @@ -0,0 +1,26 @@ +FROM golang + +ENV DB_USER=test \ + DB_PASSWORD=zaphod \ + DB_DATABASE=test \ + DB_HOST=127.0.0.0:3306 + +ENV MAP_ID=0 \ + MAP_URL="" +ENV LOG_ID=0 \ + LOG_URL=localhost:8090 \ + LOG_KEY=../trillian/testdata/log-rpc-server.pubkey.pem + +ENV SIGN_PERIOD=5s + +ADD . /go/src/github.com/google/keytransparency +WORKDIR /go/src/github.com/google/keytransparency + +RUN go get -tags="mysql" ./cmd/keytransparency-signer + +ENTRYPOINT /go/bin/keytransparency-signer \ + --db="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST})/${DB_DATABASE}" \ + --period="$SIGN_PERIOD" --key="$SIGN_KEY" --password="$SIGN_KEY_PW" \ + --log-id="$LOG_ID" --log-url="$LOG_URL" --log-key="$LOG_KEY" \ + --map-id="$MAP_ID" --map-url="$MAP_URL" \ + --alsologtostderr diff --git a/cmd/keytransparency-signer/backend.go b/cmd/keytransparency-signer/backend.go index 08fa2af9c..c00f8f94c 100644 --- a/cmd/keytransparency-signer/backend.go +++ b/cmd/keytransparency-signer/backend.go @@ -52,6 +52,7 @@ var ( // Info to replicate the Trillian Map Server locally. signingKey = flag.String("key", "", "Path to private key PEM for STH signing") + signingKeyPassword = flag.String("password", "", "Password of the private key PEM file for STH signing") // Info to send Signed Map Heads to a Trillian Log. logID = flag.Int64("log-id", 0, "Trillian Log ID") @@ -80,8 +81,7 @@ func newMapServer(ctx context.Context, sqldb *sql.DB, factory ctxn.Factory) (tri if err != nil { return nil, err } - - signer, err := keys.NewFromPrivatePEM(*signingKey, "") + signer, err := keys.NewFromPrivatePEMFile(*signingKey, *signingKeyPassword) if err != nil { return nil, err } diff --git a/core/signer/signer.go b/core/signer/signer.go index a8f01d19d..e4fe17f3c 100644 --- a/core/signer/signer.go +++ b/core/signer/signer.go @@ -67,7 +67,7 @@ func New(realm string, func (s *Signer) StartSigning(ctx context.Context, interval time.Duration) { for range time.NewTicker(interval).C { if err := s.CreateEpoch(ctx); err != nil { - glog.Fatalf("CreateEpoch failed: %v", err) + glog.Errorf("CreateEpoch failed: %v", err) } } } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..df227680f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,142 @@ +version: "3" +services: + db: + image: mysql + volumes: + - ../trillian/storage/mysql/storage.sql:/docker-entrypoint-initdb.d/storage.sql + restart: always + environment: + MYSQL_PASSWORD: zaphod + MYSQL_USER: test + MYSQL_DATABASE: test + MYSQL_RANDOM_ROOT_PASSWORD: "yes" + + trillian-log: + depends_on: + - db + image: trillian_log_server:latest + build: + context: ../trillian + dockerfile: server/trillian_log_server/Dockerfile + restart: always + ports: + - "8090:8090" # RPCs + - "8091:8091" # Metrics + environment: + DB_HOST: db:3306 + DB_DATABASE: test + DB_USER: test + DB_PASSWORD: zaphod + + trillian-log-signer: + depends_on: + - db + image: trillian_log_signer:latest + volumes: + - ../keytransparency/genfiles:/kt + build: + context: ../trillian + dockerfile: server/trillian_log_signer/Dockerfile + restart: always + ports: + - "8092:8091" # Metrics + environment: + DB_HOST: db:3306 + DB_DATABASE: test + DB_USER: test + DB_PASSWORD: zaphod + GOOGLE_APPLICATION_CREDENTIALS: /genfiles/service_key.json + KEY: /kt/server.key + CERT: /kt/server.crt + VRF_PRIV: /kt/vrf-key.pem + VRF_PUB: /kt/vrf-pubkey.pem + SIGN_KEY: /kt/p256-key.pem + SIGN_KEY_PW: "towel" + + + trillian-map: + depends_on: + - db + image: trillian_map_server:latest + build: + context: ../trillian + dockerfile: server/trillian_map_server/Dockerfile + restart: always + ports: + - "8093:8090" # RPCs + - "8094:8091" # Metrics + environment: + DB_HOST: db:3306 + DB_DATABASE: test + DB_USER: test + DB_PASSWORD: zaphod + + kt-server: + depends_on: + - db + - trillian-log + - trillian-map + build: + context: . + dockerfile: ./cmd/keytransparency-server/Dockerfile + image: keytransparency-server:latest + volumes: + - ./genfiles/:/kt/ + restart: always + ports: + - "8080:8080" # JSON & gRPC + environment: + LOG_ID: 4450861294505218766 # Update with trillian admin CLI. + LOG_URL: trillian-log:8090 + MAP_ID: 5698043027494814677 # Update with trillian admin CLI. + MAP_URL: trillian-map:8090 + DB_HOST: db:3306 + DB_DATABASE: test + DB_USER: test + DB_PASSWORD: zaphod + GOOGLE_APPLICATION_CREDENTIALS: /kt/service_key.json + KEY: /kt/server.key + CERT: /kt/server.crt + VRF_PRIV: /kt/vrf-key.pem + VRF_PUB: /kt/vrf-pubkey.pem + TLS_KEY_PATH: /kt/server.key + TLS_CRT_PATH: /kt/server.crt + + + + kt-signer: + depends_on: + - db + - trillian-log + - trillian-map + build: + context: . + dockerfile: ./cmd/keytransparency-signer/Dockerfile + image: keytransparency-signer:latest + volumes: + - ./genfiles/:/kt/ + - ../trillian/testdata/:/trillian/ + restart: always + environment: + LOG_ID: 4450861294505218766 # Update with trillian admin CLI. + LOG_URL: trillian-log:8090 + MAP_ID: 5698043027494814677 # Update with trillian admin CLI. + MAP_URL: trillian-map:8090 + DB_HOST: db:3306 + DB_DATABASE: test + DB_USER: test + DB_PASSWORD: zaphod + GOOGLE_APPLICATION_CREDENTIALS: /kt/service_key.json + KEY: /kt/server.key + LOG_KEY: /trillian/log-rpc-server.pubkey.pem + CERT: /kt/server.crt + VRF_PRIV: /kt/genfiles/vrf-key.pem + VRF_PUB: /kt/genfiles/vrf-pubkey.pem + SIGN_KEY: /trillian/log-rpc-server.privkey.pem + SIGN_KEY_PW: towel + +volumes: + kt: + + + diff --git a/impl/config/config.go b/impl/config/config.go index b3fc4770a..31c0a5f3e 100644 --- a/impl/config/config.go +++ b/impl/config/config.go @@ -17,20 +17,20 @@ package config import ( "fmt" - "log" "github.com/google/trillian" "github.com/google/trillian/client" "github.com/google/trillian/crypto/keys" "github.com/google/trillian/merkle/objhasher" "google.golang.org/grpc" + "github.com/golang/glog" ) // LogClient creates a log client. func LogClient(logID int64, logURL, pubKeyFile string) (client.VerifyingLogClient, error) { sthPubKey, err := keys.NewFromPublicPEMFile(pubKeyFile) if err != nil { - log.Fatalf("Failed to open public key %v: %v", pubKeyFile, err) + glog.Fatalf("Failed to open public key %v: %v", pubKeyFile, err) } // The log should be in a restricted access backend environment. cc, err := grpc.Dial(logURL, grpc.WithInsecure()) diff --git a/scripts/prepare_server.sh b/scripts/prepare_server.sh index 8eb71dfe0..098cea97d 100755 --- a/scripts/prepare_server.sh +++ b/scripts/prepare_server.sh @@ -32,7 +32,7 @@ IP3="127.0.0.1" SERVICEKEY="" LISTENADDR="" CERTDOMAIN="" -CERTIP="" +CERTIP="0.0.0.0" ################################## @@ -100,7 +100,11 @@ if ((FRONTEND == 1)); then # Read certificate related information. read -p "Frontend domain name (optional): " CERTDOMAIN - read -p "Frontend public IP address (optional): " CERTIP + read -p "Frontend public IP address (optional): " CERTIP_TEMP + if [[ -n "${CERTIP_TEMP}" ]]; then + CERTIP="${CERTIP_TEMP}" + fi + fi @@ -129,8 +133,7 @@ if ((BACKEND == 1)); then fi # Generating .env file -ENV="CTLOG=\"http://107.178.246.112\" -SIGN_PERIOD=5 +ENV="SIGN_PERIOD=5 GOOGLE_APPLICATION_CREDENTIALS=\"${SERVICEKEY}\"" if [[ -n "${CERTDOMAIN}" ]]; then