|
|
@ -11,6 +11,7 @@ |
|
|
|
package writefreely |
|
|
|
package writefreely |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"crypto/tls" |
|
|
|
"database/sql" |
|
|
|
"database/sql" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"html/template" |
|
|
|
"html/template" |
|
|
@ -39,6 +40,7 @@ import ( |
|
|
|
"github.com/writeas/writefreely/key" |
|
|
|
"github.com/writeas/writefreely/key" |
|
|
|
"github.com/writeas/writefreely/migrations" |
|
|
|
"github.com/writeas/writefreely/migrations" |
|
|
|
"github.com/writeas/writefreely/page" |
|
|
|
"github.com/writeas/writefreely/page" |
|
|
|
|
|
|
|
"golang.org/x/crypto/acme/autocert" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
const ( |
|
|
@ -380,19 +382,55 @@ func Serve(app *App, r *mux.Router) { |
|
|
|
} |
|
|
|
} |
|
|
|
var err error |
|
|
|
var err error |
|
|
|
if app.cfg.IsSecureStandalone() { |
|
|
|
if app.cfg.IsSecureStandalone() { |
|
|
|
log.Info("Serving redirects on http://%s:80", bindAddress) |
|
|
|
if app.cfg.Server.Autocert { |
|
|
|
go func() { |
|
|
|
m := &autocert.Manager{ |
|
|
|
err = http.ListenAndServe( |
|
|
|
Prompt: autocert.AcceptTOS, |
|
|
|
fmt.Sprintf("%s:80", bindAddress), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
|
|
Cache: autocert.DirCache(app.cfg.Server.TLSCertPath), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
host, err := url.Parse(app.cfg.App.Host) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
log.Error("[WARNING] Unable to parse configured host! %s", err) |
|
|
|
|
|
|
|
log.Error(`[WARNING] ALL hosts are allowed, which can open you to an attack where |
|
|
|
|
|
|
|
clients connect to a server by IP address and pretend to be asking for an |
|
|
|
|
|
|
|
incorrect host name, and cause you to reach the CA's rate limit for certificate |
|
|
|
|
|
|
|
requests. We recommend supplying a valid host name.`) |
|
|
|
|
|
|
|
log.Info("Using autocert on ANY host") |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
log.Info("Using autocert on host %s", host.Host) |
|
|
|
|
|
|
|
m.HostPolicy = autocert.HostWhitelist(host.Host) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s := &http.Server{ |
|
|
|
|
|
|
|
Addr: ":https", |
|
|
|
|
|
|
|
Handler: r, |
|
|
|
|
|
|
|
TLSConfig: &tls.Config{ |
|
|
|
|
|
|
|
GetCertificate: m.GetCertificate, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
s.SetKeepAlivesEnabled(false) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
log.Info("Serving redirects on http://%s:80", bindAddress) |
|
|
|
|
|
|
|
err = http.ListenAndServe(":80", m.HTTPHandler(nil)) |
|
|
|
|
|
|
|
log.Error("Unable to start redirect server: %v", err) |
|
|
|
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log.Info("Serving on https://%s:443", bindAddress) |
|
|
|
|
|
|
|
log.Info("---") |
|
|
|
|
|
|
|
err = s.ListenAndServeTLS("", "") |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
log.Info("Serving redirects on http://%s:80", bindAddress) |
|
|
|
|
|
|
|
err = http.ListenAndServe(fmt.Sprintf("%s:80", bindAddress), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|
|
|
http.Redirect(w, r, app.cfg.App.Host, http.StatusMovedPermanently) |
|
|
|
http.Redirect(w, r, app.cfg.App.Host, http.StatusMovedPermanently) |
|
|
|
})) |
|
|
|
})) |
|
|
|
log.Error("Unable to start redirect server: %v", err) |
|
|
|
log.Error("Unable to start redirect server: %v", err) |
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
log.Info("Serving on https://%s:443", bindAddress) |
|
|
|
log.Info("Serving on https://%s:443", bindAddress) |
|
|
|
log.Info("---") |
|
|
|
log.Info("Using manual certificates") |
|
|
|
err = http.ListenAndServeTLS( |
|
|
|
log.Info("---") |
|
|
|
fmt.Sprintf("%s:443", bindAddress), app.cfg.Server.TLSCertPath, app.cfg.Server.TLSKeyPath, r) |
|
|
|
err = http.ListenAndServeTLS(fmt.Sprintf("%s:443", bindAddress), app.cfg.Server.TLSCertPath, app.cfg.Server.TLSKeyPath, r) |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
log.Info("Serving on http://%s:%d\n", bindAddress, app.cfg.Server.Port) |
|
|
|
log.Info("Serving on http://%s:%d\n", bindAddress, app.cfg.Server.Port) |
|
|
|
log.Info("---") |
|
|
|
log.Info("---") |
|
|
|