From 704cba197de27bc8c9cba44f5ec1a05f6f003db6 Mon Sep 17 00:00:00 2001 From: Jiayu Yi Date: Fri, 17 Aug 2018 00:39:01 +0800 Subject: [PATCH] Initial commit --- README.md | 42 ++++++++++++++++++++++++++++++++ main.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 README.md create mode 100644 main.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..569620a --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# secure +Super simple HTTPS reverse proxy + +## Overview +TODO + +## Motivation +I wanted HTTPS for `godoc -http :6060`. + +## Usage +``` +secure -key-file path/to/key/file -cert-file path/to/cert/file -upstream http://localhost:6060 -addr :443 +``` + +## Demo +*nix: +``` +# generate cert +openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 365 -out cert.pem -subj "/CN=localhost" + +# start godoc +godoc -http localhost:6060 & + +# secure it +go run main.go -key-file key.pem -cert-file cert.pem -upstream http://localhost:6060 -addr :443 +``` + +Windows (PowerShell) +``` +# somehow obtain key.pem and cert.pem + +# start godoc +# cmd: start godoc -http localhost:6060 +Start-Process godoc "-http localhost:6060" + +# secure it +go run main.go -key-file key.pem -cert-file cert.pem -upstream http://localhost:6060 -addr :443 +``` + +## Features +- [x] TLS termination proxy +- [ ] Redirect HTTP to HTTPS diff --git a/main.go b/main.go new file mode 100644 index 0000000..7659487 --- /dev/null +++ b/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "flag" + "net/http/httputil" + "net/url" + "fmt" + "net/http" + "os/signal" + "os" + "context" + "syscall" +) + +var ( + certFile string + keyFile string + upstream string + addr string +) + +func init() { + flag.StringVar(&certFile, "cert-file", "", "path to cert file") + flag.StringVar(&keyFile, "key-file", "", "path to key file") + flag.StringVar(&upstream, "upstream", "", "upstream address") + flag.StringVar(&addr, "addr", ":443", "listen address") +} + +func _main() error { + flag.Parse() + + u, err := url.Parse(upstream) + if err != nil { + return fmt.Errorf("invalid upstream address: %v", err) + } + + rp := httputil.NewSingleHostReverseProxy(u) + srv := http.Server{ + Handler: rp, + Addr: addr, + } + + idleConnsClosed := make(chan struct{}) + go func() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGTERM) + fmt.Println(<-sig) + + // We received an interrupt signal, shut down. + if err := srv.Shutdown(context.Background()); err != nil { + // Error from closing listeners, or context timeout: + fmt.Printf("HTTP server Shutdown: %v", err) + } + close(idleConnsClosed) + }() + + if err := srv.ListenAndServeTLS(certFile, keyFile); err != http.ErrServerClosed { + // Error starting or closing listener: + return fmt.Errorf("ListenAndServeTLS: %v", err) + } + + <-idleConnsClosed + + return nil +} + +func main() { + err := _main() + if err != nil { + fmt.Println(err) + os.Exit(1) + } +}