Skip to content

Commit

Permalink
Add support for additional HTTP listener
Browse files Browse the repository at this point in the history
Fixes #289
  • Loading branch information
tsandall committed Mar 12, 2017
1 parent 7d7d291 commit 6cdcb31
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 15 deletions.
1 change: 1 addition & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ to delete policies will remove the definition file.
runCommand.Flags().StringVarP(&params.HistoryPath, "history", "H", historyPath(), "set path of history file")
runCommand.Flags().StringVarP(&params.PolicyDir, "policy-dir", "p", "", "set directory to store policy definitions")
runCommand.Flags().StringVarP(&params.Addr, "addr", "a", defaultAddr, "set listening address of the server")
runCommand.Flags().StringVarP(&params.InsecureAddr, "insecure-addr", "", "", "set insecure listening address of the server")
runCommand.Flags().StringVarP(&params.OutputFormat, "format", "f", "pretty", "set shell output format, i.e, pretty, json")
runCommand.Flags().BoolVarP(&params.Watch, "watch", "w", false, "watch command line files for changes")
runCommand.Flags().StringVarP(&tlsCertFile, "tls-cert-file", "", "", "set path of TLS certificate file")
Expand Down
19 changes: 17 additions & 2 deletions runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ type Params struct {
// Addr is the listening address that the OPA server will bind to.
Addr string

// InsecureAddr is the listening address that the OPA server will bind to
// in addition to Addr if TLS is enabled.
InsecureAddr string

// Authentication is the type of authentication scheme to use.
Authentication server.AuthenticationScheme

Expand Down Expand Up @@ -164,14 +168,16 @@ func (rt *Runtime) startServer(ctx context.Context, params *Params) {
setupLogging(params.Logging)

logrus.WithFields(logrus.Fields{
"addr": params.Addr,
"addr": params.Addr,
"insecure_addr": params.InsecureAddr,
}).Infof("First line of log stream.")

persist := len(params.PolicyDir) > 0

s, err := server.New().
WithStorage(rt.Store).
WithAddress(params.Addr).
WithInsecureAddress(params.InsecureAddr).
WithPersist(persist).
WithCertificate(params.Certificate).
WithAuthentication(params.Authentication).
Expand All @@ -184,7 +190,16 @@ func (rt *Runtime) startServer(ctx context.Context, params *Params) {

s.Handler = NewLoggingHandler(s.Handler)

if err := s.Loop(); err != nil {
loop1, loop2 := s.Listeners()
if loop2 != nil {
go func() {
if err := loop2(); err != nil {
logrus.WithField("err", err).Fatalf("Server exiting.")
}
}()
}

if err := loop1(); err != nil {
logrus.WithField("err", err).Fatalf("Server exiting.")
}
}
Expand Down
40 changes: 29 additions & 11 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Server struct {
Handler http.Handler

addr string
insecureAddr string
authentication AuthenticationScheme
authorization AuthorizationScheme
cert *tls.Certificate
Expand Down Expand Up @@ -133,6 +134,12 @@ func (s *Server) WithAddress(addr string) *Server {
return s
}

// WithInsecureAddress sets the listening address that the server will bind to.
func (s *Server) WithInsecureAddress(addr string) *Server {
s.insecureAddr = addr
return s
}

// WithAuthentication sets authentication scheme to use on the server.
func (s *Server) WithAuthentication(scheme AuthenticationScheme) *Server {
s.authentication = scheme
Expand Down Expand Up @@ -175,26 +182,37 @@ func (s *Server) Compiler() *ast.Compiler {
return s.compiler
}

// Loop starts the server. This function does not return.
func (s *Server) Loop() error {
httpServer := http.Server{
// Listeners returns functions that listen and serve connections.
func (s *Server) Listeners() (func() error, func() error) {

server1 := http.Server{
Addr: s.addr,
Handler: s.Handler,
}

if s.cert != nil {
httpServer.TLSConfig = &tls.Config{
loop1 := func() error { return server1.ListenAndServe() }

if s.cert == nil {
return loop1, nil
}

server2 := http.Server{
Addr: s.addr,
Handler: s.Handler,
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{*s.cert},
}
},
}

if httpServer.TLSConfig == nil {
return httpServer.ListenAndServe()
loop2 := func() error { return server2.ListenAndServeTLS("", "") }

if s.insecureAddr == "" {
return loop2, nil
}

// http.Server will ignore the cert and key file params if the
// TLSConfig.Certificates field is set.
return httpServer.ListenAndServeTLS("", "")
server1.Addr = s.insecureAddr

return loop2, loop1
}

func (s *Server) execQuery(ctx context.Context, compiler *ast.Compiler, txn storage.Transaction, query ast.Body, explainMode types.ExplainModeV1) (types.QueryResponseV1, error) {
Expand Down
5 changes: 3 additions & 2 deletions site/documentation/references/security/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ startup:
OPA will exit immediately with a non-zero status code if only one of these flags
is specified.

When TLS credentials are provided, OPA will ignore normal/insecure incoming HTTP
connections.
By default, OPA ignores insecure HTTP connections when TLS is enabled. To allow
insecure HTTP connections in addition to HTTPS connections, provide another
listening address with `--insecure-addr`.

#### 1. Generate the TLS credentials for OPA (Example)

Expand Down

0 comments on commit 6cdcb31

Please sign in to comment.