1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2024-10-30 07:40:05 -04:00

Only serve over HTTPS, optionally auto-generating certificates

Because MoneyGo requires sending passwords and session cookies, we
should never serve over HTTP. While we're at it, make it more convenient
for folks to test this out by adding a config option to auto-generate
self-signed certificates.
This commit is contained in:
Aaron Lindsay 2017-12-05 20:56:57 -05:00
parent 1dc57dc761
commit 147a00e429
5 changed files with 71 additions and 15 deletions

16
Gopkg.lock generated
View File

@ -5,7 +5,7 @@
branch = "master" branch = "master"
name = "github.com/aclindsa/gorp" name = "github.com/aclindsa/gorp"
packages = ["."] packages = ["."]
revision = "d53dbb52439a458ae75f574d9420f66b6489441d" revision = "4735379e1f46302b58b985d8172a53988aad93b4"
[[projects]] [[projects]]
name = "github.com/aclindsa/ofxgo" name = "github.com/aclindsa/ofxgo"
@ -25,11 +25,17 @@
revision = "a0583e0143b1624142adab07e0e97fe106d99561" revision = "a0583e0143b1624142adab07e0e97fe106d99561"
version = "v1.3" version = "v1.3"
[[projects]]
branch = "master"
name = "github.com/kabukky/httpscerts"
packages = ["."]
revision = "617593d7dcb39c9ed617bb62c5e2056244d02184"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/lib/pq" name = "github.com/lib/pq"
packages = [".","oid"] packages = [".","oid"]
revision = "8c6ee72f3e6bcb1542298dd5f76cb74af9742cec" revision = "83612a56d3dd153a94a629cd64925371c9adad78"
[[projects]] [[projects]]
name = "github.com/mattn/go-sqlite3" name = "github.com/mattn/go-sqlite3"
@ -47,13 +53,13 @@
branch = "master" branch = "master"
name = "golang.org/x/net" name = "golang.org/x/net"
packages = ["context"] packages = ["context"]
revision = "9dfe39835686865bff950a07b394c12a98ddc811" revision = "a8b9294777976932365dabb6640cf1468d95c70f"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/text" name = "golang.org/x/text"
packages = ["currency","internal","internal/format","internal/gen","internal/tag","language","unicode/cldr"] packages = ["currency","internal","internal/format","internal/gen","internal/tag","language","unicode/cldr"]
revision = "88f656faf3f37f690df1a32515b479415e1a6769" revision = "57961680700a5336d15015c8c50686ca5ba362a4"
[[projects]] [[projects]]
name = "gopkg.in/gcfg.v1" name = "gopkg.in/gcfg.v1"
@ -70,6 +76,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "de6a009267b8a81e29fc30f4bb7431c32ca42650d6cfd458324324f3f63abbff" inputs-digest = "ad90bfdaa27132d84af5979b27d0960663bd13d57510566071056e1d4bb0d503"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -63,15 +63,21 @@ cusip_list.csv file and re-run the `go generate ...` command.
## Running ## Running
Assuming you're in the same directory you ran the above installation commands MoneyGo requires HTTPS or FCGI (no HTTP). Before starting the server, you will
from, running MoneyGo is then as easy as: 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 $ ./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 your browser. Editing the configuration file supplied will allow you to modify
several settings including the port used and whether to serve via FastCGI several settings including the port used, SSL certificate locations, and whether
instead of HTTP (the default). to serve via FastCGI instead of HTTPS (the default).
## Missing Features ## Missing Features

View File

@ -1,10 +1,10 @@
[moneygo] [moneygo]
# Whether to serve as FastCGI (default is false, for HTTP) # Whether to serve as FastCGI (default is false, for HTTPS)
fcgi = false fcgi = false
# Port to serve FCGI or HTTP on # Port on which to serve HTTPS or FCGI
port = 8080 port = 8443
# Base directory for serving files out of. This should point to the root of the # Base directory for serving files out of. This should point to the root of the
# moneygo source directory # moneygo source directory
@ -25,3 +25,18 @@ db-type = sqlite3
# Postgres documentation: https://godoc.org/github.com/lib/pq # Postgres documentation: https://godoc.org/github.com/lib/pq
# example DSN: "postgres://user:password@localhost/dbname" # example DSN: "postgres://user:password@localhost/dbname"
db-dsn = file:moneygo.sqlite?cache=shared&mode=rwc 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

View File

@ -55,8 +55,16 @@ type MoneyGo struct {
DSN string `gcfg:"db-dsn"` // 'Data Source Name' for database connection 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 { type Config struct {
MoneyGo MoneyGo MoneyGo MoneyGo
Https Https
} }
func ReadConfig(filename string) (*Config, error) { func ReadConfig(filename string) (*Config, error) {
@ -68,6 +76,12 @@ func ReadConfig(filename string) (*Config, error) {
DBType: SQLite, DBType: SQLite,
DSN: "file:moneygo.sqlite?cache=shared&mode=rwc", 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) err := gcfg.ReadFileInto(&cfg, filename)

19
main.go
View File

@ -8,6 +8,7 @@ import (
"github.com/aclindsa/moneygo/internal/config" "github.com/aclindsa/moneygo/internal/config"
"github.com/aclindsa/moneygo/internal/db" "github.com/aclindsa/moneygo/internal/db"
"github.com/aclindsa/moneygo/internal/handlers" "github.com/aclindsa/moneygo/internal/handlers"
"github.com/kabukky/httpscerts"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -89,10 +90,24 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
log.Printf("Serving on port %d out of directory: %s", cfg.MoneyGo.Port, cfg.MoneyGo.Basedir)
if cfg.MoneyGo.Fcgi { 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) fcgi.Serve(listener, servemux)
} else { } 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)
} }
} }