1
0
mirror of https://github.com/astaxie/beego.git synced 2024-06-16 11:43:32 +00:00

Merge pull request #2932 from lotus-wu/Branch_v1.9.0

1.Add Mutual HTTPS  Option!
This commit is contained in:
astaxie 2017-11-19 10:26:59 +08:00 committed by GitHub
commit 532eab8e1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 22 deletions

37
app.go
View File

@ -15,7 +15,10 @@
package beego package beego
import ( import (
"crypto/tls"
"crypto/x509"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"net/http/fcgi" "net/http/fcgi"
@ -110,7 +113,7 @@ func (app *App) Run(mws ...MiddleWare) {
if BConfig.Listen.Graceful { if BConfig.Listen.Graceful {
httpsAddr := BConfig.Listen.HTTPSAddr httpsAddr := BConfig.Listen.HTTPSAddr
app.Server.Addr = httpsAddr app.Server.Addr = httpsAddr
if BConfig.Listen.EnableHTTPS { if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
go func() { go func() {
time.Sleep(20 * time.Microsecond) time.Sleep(20 * time.Microsecond)
if BConfig.Listen.HTTPSPort != 0 { if BConfig.Listen.HTTPSPort != 0 {
@ -120,10 +123,19 @@ func (app *App) Run(mws ...MiddleWare) {
server := grace.NewServer(httpsAddr, app.Handlers) server := grace.NewServer(httpsAddr, app.Handlers)
server.Server.ReadTimeout = app.Server.ReadTimeout server.Server.ReadTimeout = app.Server.ReadTimeout
server.Server.WriteTimeout = app.Server.WriteTimeout server.Server.WriteTimeout = app.Server.WriteTimeout
if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { if BConfig.Listen.EnableMutualHTTPS {
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond) if err := server.ListenAndServeMutualTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile, BConfig.Listen.TrustCaFile); err != nil {
endRunning <- true logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
endRunning <- true
}
} else {
if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
time.Sleep(100 * time.Microsecond)
endRunning <- true
}
} }
}() }()
} }
@ -147,7 +159,7 @@ func (app *App) Run(mws ...MiddleWare) {
} }
// run normal mode // run normal mode
if BConfig.Listen.EnableHTTPS { if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
go func() { go func() {
time.Sleep(20 * time.Microsecond) time.Sleep(20 * time.Microsecond)
if BConfig.Listen.HTTPSPort != 0 { if BConfig.Listen.HTTPSPort != 0 {
@ -157,6 +169,19 @@ func (app *App) Run(mws ...MiddleWare) {
return return
} }
logs.Info("https server Running on https://%s", app.Server.Addr) logs.Info("https server Running on https://%s", app.Server.Addr)
if BConfig.Listen.EnableMutualHTTPS {
pool := x509.NewCertPool()
data, err := ioutil.ReadFile(BConfig.Listen.TrustCaFile)
if err != nil {
BeeLogger.Info("MutualHTTPS should provide TrustCaFile")
return
}
pool.AppendCertsFromPEM(data)
app.Server.TLSConfig = &tls.Config{
ClientCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
}
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil { if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
logs.Critical("ListenAndServeTLS: ", err) logs.Critical("ListenAndServeTLS: ", err)
time.Sleep(100 * time.Microsecond) time.Sleep(100 * time.Microsecond)

View File

@ -49,22 +49,24 @@ type Config struct {
// Listen holds for http and https related config // Listen holds for http and https related config
type Listen struct { type Listen struct {
Graceful bool // Graceful means use graceful module to start the server Graceful bool // Graceful means use graceful module to start the server
ServerTimeOut int64 ServerTimeOut int64
ListenTCP4 bool ListenTCP4 bool
EnableHTTP bool EnableHTTP bool
HTTPAddr string HTTPAddr string
HTTPPort int HTTPPort int
EnableHTTPS bool EnableHTTPS bool
HTTPSAddr string EnableMutualHTTPS bool
HTTPSPort int HTTPSAddr string
HTTPSCertFile string HTTPSPort int
HTTPSKeyFile string HTTPSCertFile string
EnableAdmin bool HTTPSKeyFile string
AdminAddr string TrustCaFile string
AdminPort int EnableAdmin bool
EnableFcgi bool AdminAddr string
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O AdminPort int
EnableFcgi bool
EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
} }
// WebConfig holds web related config // WebConfig holds web related config

View File

@ -2,7 +2,9 @@ package grace
import ( import (
"crypto/tls" "crypto/tls"
"crypto/x509"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -129,6 +131,61 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
return srv.Serve() return srv.Serve()
} }
//ListenAndServeMutualTLS
func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) (err error) {
addr := srv.Addr
if addr == "" {
addr = ":https"
}
if srv.TLSConfig == nil {
srv.TLSConfig = &tls.Config{}
}
if srv.TLSConfig.NextProtos == nil {
srv.TLSConfig.NextProtos = []string{"http/1.1"}
}
srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return
}
srv.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
pool := x509.NewCertPool()
data, err := ioutil.ReadFile(trustFile)
if err != nil {
log.Println(err)
return err
}
pool.AppendCertsFromPEM(data)
srv.TLSConfig.ClientCAs = pool
log.Println("Mutual HTTPS")
go srv.handleSignals()
l, err := srv.getListener(addr)
if err != nil {
log.Println(err)
return err
}
srv.tlsInnerListener = newGraceListener(l, srv)
srv.GraceListener = tls.NewListener(srv.tlsInnerListener, srv.TLSConfig)
if srv.isChild {
process, err := os.FindProcess(os.Getppid())
if err != nil {
log.Println(err)
return err
}
err = process.Kill()
if err != nil {
return err
}
}
log.Println(os.Getpid(), srv.Addr)
return srv.Serve()
}
// getListener either opens a new socket to listen on, or takes the acceptor socket // getListener either opens a new socket to listen on, or takes the acceptor socket
// it got passed when restarted. // it got passed when restarted.
func (srv *Server) getListener(laddr string) (l net.Listener, err error) { func (srv *Server) getListener(laddr string) (l net.Listener, err error) {