Initial commit

This commit is contained in:
Jiayu Yi 2018-08-17 00:39:01 +08:00
commit 704cba197d
No known key found for this signature in database
GPG key ID: 84B60878E8AEAD6C
2 changed files with 115 additions and 0 deletions

42
README.md Normal file
View file

@ -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

73
main.go Normal file
View file

@ -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)
}
}