diff --git a/Gopkg.lock b/Gopkg.lock index a2e3b6f..e792b6d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -5,7 +5,7 @@ branch = "master" name = "github.com/aclindsa/gorp" packages = ["."] - revision = "d53dbb52439a458ae75f574d9420f66b6489441d" + revision = "4735379e1f46302b58b985d8172a53988aad93b4" [[projects]] name = "github.com/aclindsa/ofxgo" @@ -25,11 +25,17 @@ revision = "a0583e0143b1624142adab07e0e97fe106d99561" version = "v1.3" +[[projects]] + branch = "master" + name = "github.com/kabukky/httpscerts" + packages = ["."] + revision = "617593d7dcb39c9ed617bb62c5e2056244d02184" + [[projects]] branch = "master" name = "github.com/lib/pq" packages = [".","oid"] - revision = "8c6ee72f3e6bcb1542298dd5f76cb74af9742cec" + revision = "83612a56d3dd153a94a629cd64925371c9adad78" [[projects]] name = "github.com/mattn/go-sqlite3" @@ -47,13 +53,13 @@ branch = "master" name = "golang.org/x/net" packages = ["context"] - revision = "9dfe39835686865bff950a07b394c12a98ddc811" + revision = "a8b9294777976932365dabb6640cf1468d95c70f" [[projects]] branch = "master" name = "golang.org/x/text" packages = ["currency","internal","internal/format","internal/gen","internal/tag","language","unicode/cldr"] - revision = "88f656faf3f37f690df1a32515b479415e1a6769" + revision = "57961680700a5336d15015c8c50686ca5ba362a4" [[projects]] name = "gopkg.in/gcfg.v1" @@ -70,6 +76,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "de6a009267b8a81e29fc30f4bb7431c32ca42650d6cfd458324324f3f63abbff" + inputs-digest = "ad90bfdaa27132d84af5979b27d0960663bd13d57510566071056e1d4bb0d503" solver-name = "gps-cdcl" solver-version = 1 diff --git a/README.md b/README.md index f15e709..47bb548 100644 --- a/README.md +++ b/README.md @@ -63,15 +63,21 @@ cusip_list.csv file and re-run the `go generate ...` command. ## Running -Assuming you're in the same directory you ran the above installation commands -from, running MoneyGo is then as easy as: +MoneyGo requires HTTPS or FCGI (no HTTP). Before starting the server, you will +want to edit the example configuration file +(src/github.com/aclindsa/moneygo/example_config.ini) to point to your own SSL +certificate/key OR set 'generate-certs-if-absent = true' in the '[http]' section +of the config file. + +Then, assuming you're in the same directory you ran the above installation +commands from, running MoneyGo is as easy as: $ ./bin/moneygo -config src/github.com/aclindsa/moneygo/example_config.ini -You should then be able to explore MoneyGo by visiting http://localhost:8080 in +You should then be able to explore MoneyGo by visiting https://localhost:8443 in your browser. Editing the configuration file supplied will allow you to modify -several settings including the port used and whether to serve via FastCGI -instead of HTTP (the default). +several settings including the port used, SSL certificate locations, and whether +to serve via FastCGI instead of HTTPS (the default). ## Missing Features diff --git a/example_config.ini b/example_config.ini index 861fdea..1c6dddf 100644 --- a/example_config.ini +++ b/example_config.ini @@ -1,10 +1,10 @@ [moneygo] -# Whether to serve as FastCGI (default is false, for HTTP) +# Whether to serve as FastCGI (default is false, for HTTPS) fcgi = false -# Port to serve FCGI or HTTP on -port = 8080 +# Port on which to serve HTTPS or FCGI +port = 8443 # Base directory for serving files out of. This should point to the root of the # moneygo source directory @@ -25,3 +25,18 @@ db-type = sqlite3 # Postgres documentation: https://godoc.org/github.com/lib/pq # example DSN: "postgres://user:password@localhost/dbname" db-dsn = file:moneygo.sqlite?cache=shared&mode=rwc + + +[https] +# If 'fcgi = false', the following paths to a SSL certificate and the paired +# private key are used when serving HTTPS +cert-file = ./cert.pem +key-file = ./key.pem + +# Attempt to generate self-signed certificates if the certificate files +# specified above are missing or invalid. This should *never* be set to 'true' +# for any environment where security is important (including but not limited to +# production systems) +generate-certs-if-absent = false +# A CSV list of hostnames to generate the above certs for +generate-certs-hosts = localhost,127.0.0.1 diff --git a/internal/config/config.go b/internal/config/config.go index 5d71d7c..ecfb1cd 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -55,8 +55,16 @@ type MoneyGo struct { DSN string `gcfg:"db-dsn"` // 'Data Source Name' for database connection } +type Https struct { + CertFile string `gcfg:"cert-file"` + KeyFile string `gcfg:"key-file"` + GenerateCerts bool `gcfg:"generate-certs-if-absent"` // Generate certificates if missing + GenerateCertsHosts string `gcfg:"generate-certs-hosts"` // Hostnames to generate certificates for if missing and GenerateCerts==true +} + type Config struct { MoneyGo MoneyGo + Https Https } func ReadConfig(filename string) (*Config, error) { @@ -68,6 +76,12 @@ func ReadConfig(filename string) (*Config, error) { DBType: SQLite, DSN: "file:moneygo.sqlite?cache=shared&mode=rwc", }, + Https: Https{ + CertFile: "./cert.pem", + KeyFile: "./key.pem", + GenerateCerts: false, + GenerateCertsHosts: "localhost", + }, } err := gcfg.ReadFileInto(&cfg, filename) diff --git a/main.go b/main.go index 1a78a62..2baf7c0 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "github.com/aclindsa/moneygo/internal/config" "github.com/aclindsa/moneygo/internal/db" "github.com/aclindsa/moneygo/internal/handlers" + "github.com/kabukky/httpscerts" "log" "net" "net/http" @@ -89,10 +90,24 @@ func main() { log.Fatal(err) } - log.Printf("Serving on port %d out of directory: %s", cfg.MoneyGo.Port, cfg.MoneyGo.Basedir) if cfg.MoneyGo.Fcgi { + log.Printf("Serving via FCGI on port %d out of directory: %s", cfg.MoneyGo.Port, cfg.MoneyGo.Basedir) fcgi.Serve(listener, servemux) } else { - http.Serve(listener, servemux) + cert := cfg.Https.CertFile + key := cfg.Https.KeyFile + + if err := httpscerts.Check(cert, key); err != nil { + if !cfg.Https.GenerateCerts { + log.Fatalf("HTTPS certficates not found at '%s' and '%s'. If you would like for them to be auto-generated for you, specify 'generate-certs-if-absent = true' in your config file at '%s'", cert, key, configFile) + } + + err = httpscerts.Generate(cert, key, cfg.Https.GenerateCertsHosts) + if err != nil { + log.Fatalf("Error: Generating HTTPS cert/key at '%s' and '%s' failed: %s", cert, key, err) + } + } + log.Printf("Serving via HTTPS on port %d out of directory: %s", cfg.MoneyGo.Port, cfg.MoneyGo.Basedir) + http.ServeTLS(listener, servemux, cert, key) } }