Skip to content

Commit

Permalink
https
Browse files Browse the repository at this point in the history
  • Loading branch information
metachris committed Sep 20, 2024
1 parent 3958cd4 commit c2a0813
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 93 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@

# Builds
/build
/cert.pem
/key.pem
64 changes: 15 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,23 @@
# go-template
# builder-tools

[![Goreport status](https://goreportcard.com/badge/github.com/flashbots/go-template)](https://goreportcard.com/report/github.com/flashbots/go-template)
[![Test status](https://github.com/flashbots/go-template/workflows/Checks/badge.svg?branch=main)](https://github.com/flashbots/go-template/actions?query=workflow%3A%22Checks%22)
WIP Toolbox

Toolbox and building blocks for new Go projects, to get started quickly and right-footed!
- [Create ECDSA keypair](cmd/ecdsa-gen/main.go)
- [Create TLS certificate + key (PEM format)](cmd/tls-gen/main.go)
- [Server using custom TLS certificate](cmd/https-server/main.go)
- [Client allowing only server using the custom TLS certificate](cmd/https-client/main.go)

* [`Makefile`](https://github.com/flashbots/go-template/blob/main/Makefile) with `lint`, `test`, `build`, `fmt` and more
* Linting with `gofmt`, `gofumpt`, `go vet`, `staticcheck` and `golangci-lint`
* Logging setup using the [slog logger](https://pkg.go.dev/golang.org/x/exp/slog) (with debug and json logging options)
* [GitHub Workflows](.github/workflows/) for linting and testing, as well as releasing and publishing Docker images
* Entry files for [CLI](/cmd/cli/main.go) and [HTTP server](/cmd/httpserver/main.go)
* Webserver with
* Graceful shutdown, implementing `livez`, `readyz` and draining API handlers
* Prometheus metrics
* Using https://pkg.go.dev/github.com/go-chi/chi/v5 for routing
* [Urfave](https://cli.urfave.org/) for cli args
* https://github.com/uber-go/nilaway
* See also:
* Public project setup: https://github.com/flashbots/flashbots-repository-template
* Repository for common Go utilities: https://github.com/flashbots/go-utils

Pick and choose whatever is useful to you! Don't feel the need to use everything, or even to follow this structure.

---

## Getting started

**Build CLI**

```bash
make build-cli
```

**Build HTTP server**

```bash
make build-httpserver
```
# create the TLS cert
$ go run cmd/tls-gen/main.go --host foo.com,0.0.0.0,127.0.0.1

**Install dev dependencies**
# run the server (serving the created TLS cert)
$ go run cmd/https-server/main.go

```bash
go install mvdan.cc/[email protected]
go install honnef.co/go/tools/cmd/[email protected]
go install github.com/golangci/golangci-lint/cmd/[email protected]
go install go.uber.org/nilaway/cmd/[email protected]
go install github.com/daixiang0/[email protected]
```
# check with curl
$ curl --insecure https://localhost:8080

**Lint, test, format**

```bash
make lint
make test
make fmt
```
# run the client (allowing only server with that specific TLS cert)
$ go run cmd/https-client/main.go
```
21 changes: 0 additions & 21 deletions cli.dockerfile

This file was deleted.

81 changes: 81 additions & 0 deletions cmd/https-client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package main

import (
"crypto/tls"
"crypto/x509"
"errors"
"io"
"log"
"net/http"
"os"

"github.com/flashbots/go-template/common"
"github.com/urfave/cli/v2" // imports as package "cli"
)

var flags []cli.Flag = []cli.Flag{
&cli.StringFlag{
Name: "server-addr",
Value: "https://0.0.0.0:8080",
Usage: "address to serve certificate on",
},
}

func main() {
app := &cli.App{
Name: "https-client",
Usage: "Client to allow only specific self-signed server cert",
Flags: flags,
Action: runCli,
}

if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}

func runCli(cCtx *cli.Context) error {
log := common.SetupLogger(&common.LoggingOpts{})

serverAddr := cCtx.String("server-addr")

certFile := "cert.pem"

certData, err := os.ReadFile(certFile)
if err != nil {
log.Error("could not read cert data", "err", err)
return err
}

roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(certData)
if !ok {
log.Error("invalid certificate received", "cert", string(certData))
return errors.New("invalid certificate")
}

client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: roots,
},
},
}

resp, err := client.Get(serverAddr)
if err != nil {
log.Error("http request error", "err", err)
return err
}
defer resp.Body.Close()

respBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Error("could not read proxied service body", "err", err)
return err
}

log.Info("Received", "resp", string(respBody))

return nil
}
66 changes: 66 additions & 0 deletions cmd/https-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"crypto/tls"
"io"
"log"
"net/http"
"os"
"time"

"github.com/flashbots/go-template/common"
"github.com/urfave/cli/v2" // imports as package "cli"
)

var flags []cli.Flag = []cli.Flag{
&cli.StringFlag{
Name: "listen-addr",
Value: "0.0.0.0:8080",
Usage: "address to serve certificate on",
},
}

func main() {
app := &cli.App{
Name: "https-server",
Usage: "Server with custom cert",
Flags: flags,
Action: runCli,
}

if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}

func runCli(cCtx *cli.Context) error {
listenAddr := cCtx.String("listen-addr")
certFile := "cert.pem"
keyFile := "key.pem"

log := common.SetupLogger(&common.LoggingOpts{})

mux := http.NewServeMux()
mux.HandleFunc("/", getRoot)

srv := &http.Server{
Addr: listenAddr,
Handler: mux,
ReadHeaderTimeout: time.Second,
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS13,
PreferServerCipherSuites: true,
},
}

log.Info("Starting HTTPS server", "addr", listenAddr)
if err := srv.ListenAndServeTLS(certFile, keyFile); err != nil {
log.Error("proxy exited", "err", err)
return err
}
return nil
}

func getRoot(w http.ResponseWriter, r *http.Request) {
_, _ = io.WriteString(w, "checkcheck\n")
}
23 changes: 0 additions & 23 deletions httpserver.dockerfile

This file was deleted.

0 comments on commit c2a0813

Please sign in to comment.