2019-04-24 21:52:08 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2022-04-04 23:57:47 +00:00
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
2022-06-14 07:20:13 +00:00
|
|
|
"fmt"
|
2020-07-16 06:36:37 +00:00
|
|
|
"net"
|
2019-04-24 21:52:08 +00:00
|
|
|
"os"
|
2020-06-21 13:40:37 +00:00
|
|
|
"strconv"
|
2019-04-24 21:52:08 +00:00
|
|
|
|
2020-04-05 12:37:21 +00:00
|
|
|
"github.com/valyala/fasthttp"
|
|
|
|
|
2021-08-11 01:04:35 +00:00
|
|
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
2022-04-05 21:57:23 +00:00
|
|
|
"github.com/authelia/authelia/v4/internal/logging"
|
2021-08-11 01:04:35 +00:00
|
|
|
"github.com/authelia/authelia/v4/internal/middlewares"
|
2019-04-24 21:52:08 +00:00
|
|
|
)
|
|
|
|
|
2022-06-14 07:20:13 +00:00
|
|
|
// CreateDefaultServer Create Authelia's internal webserver with the given configuration and providers.
|
|
|
|
func CreateDefaultServer(config schema.Configuration, providers middlewares.Providers) (server *fasthttp.Server, listener net.Listener, err error) {
|
|
|
|
server = &fasthttp.Server{
|
2022-06-11 23:26:28 +00:00
|
|
|
ErrorHandler: handleError(),
|
|
|
|
Handler: handleRouter(config, providers),
|
2020-04-30 03:16:41 +00:00
|
|
|
NoDefaultServerHeader: true,
|
2022-04-08 04:13:47 +00:00
|
|
|
ReadBufferSize: config.Server.ReadBufferSize,
|
|
|
|
WriteBufferSize: config.Server.WriteBufferSize,
|
2020-04-11 04:59:58 +00:00
|
|
|
}
|
2022-04-07 00:58:51 +00:00
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
address := net.JoinHostPort(config.Server.Host, strconv.Itoa(config.Server.Port))
|
2020-07-16 06:36:37 +00:00
|
|
|
|
2022-04-04 23:57:47 +00:00
|
|
|
var (
|
|
|
|
connectionType string
|
|
|
|
connectionScheme string
|
|
|
|
)
|
2019-04-24 21:52:08 +00:00
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
if config.Server.TLS.Certificate != "" && config.Server.TLS.Key != "" {
|
2022-04-04 23:57:47 +00:00
|
|
|
connectionType, connectionScheme = "TLS", schemeHTTPS
|
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
if err = server.AppendCert(config.Server.TLS.Certificate, config.Server.TLS.Key); err != nil {
|
2022-06-14 07:20:13 +00:00
|
|
|
return nil, nil, fmt.Errorf("unable to load tls server certificate '%s' or private key '%s': %w", config.Server.TLS.Certificate, config.Server.TLS.Key, err)
|
2021-08-05 04:02:07 +00:00
|
|
|
}
|
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
if len(config.Server.TLS.ClientCertificates) > 0 {
|
2022-04-04 23:57:47 +00:00
|
|
|
caCertPool := x509.NewCertPool()
|
|
|
|
|
2022-06-14 07:20:13 +00:00
|
|
|
var cert []byte
|
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
for _, path := range config.Server.TLS.ClientCertificates {
|
2022-06-14 07:20:13 +00:00
|
|
|
if cert, err = os.ReadFile(path); err != nil {
|
|
|
|
return nil, nil, fmt.Errorf("unable to load tls client certificate '%s': %w", path, err)
|
2022-04-04 23:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
caCertPool.AppendCertsFromPEM(cert)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ClientCAs should never be nil, otherwise the system cert pool is used for client authentication
|
|
|
|
// but we don't want everybody on the Internet to be able to authenticate.
|
|
|
|
server.TLSConfig.ClientCAs = caCertPool
|
|
|
|
server.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
2021-08-10 00:31:08 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 00:58:51 +00:00
|
|
|
if listener, err = tls.Listen("tcp", address, server.TLSConfig.Clone()); err != nil {
|
2022-06-14 07:20:13 +00:00
|
|
|
return nil, nil, fmt.Errorf("unable to initialize tcp listener: %w", err)
|
2022-04-04 23:57:47 +00:00
|
|
|
}
|
2020-03-03 07:18:25 +00:00
|
|
|
} else {
|
2022-04-04 23:57:47 +00:00
|
|
|
connectionType, connectionScheme = "non-TLS", schemeHTTP
|
2022-04-07 00:58:51 +00:00
|
|
|
|
|
|
|
if listener, err = net.Listen("tcp", address); err != nil {
|
2022-06-14 07:20:13 +00:00
|
|
|
return nil, nil, fmt.Errorf("unable to initialize tcp listener: %w", err)
|
2021-08-05 04:02:07 +00:00
|
|
|
}
|
2022-04-04 23:57:47 +00:00
|
|
|
}
|
2021-08-05 04:02:07 +00:00
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
if err = writeHealthCheckEnv(config.Server.DisableHealthcheck, connectionScheme, config.Server.Host,
|
|
|
|
config.Server.Path, config.Server.Port); err != nil {
|
2022-06-14 07:20:13 +00:00
|
|
|
return nil, nil, fmt.Errorf("unable to configure healthcheck: %w", err)
|
2020-03-03 07:18:25 +00:00
|
|
|
}
|
2022-04-04 23:57:47 +00:00
|
|
|
|
2022-06-14 07:20:13 +00:00
|
|
|
logger := logging.Logger()
|
|
|
|
|
2022-04-08 04:13:47 +00:00
|
|
|
if config.Server.Path == "" {
|
2022-04-07 00:58:51 +00:00
|
|
|
logger.Infof("Initializing server for %s connections on '%s' path '/'", connectionType, listener.Addr().String())
|
2022-04-04 23:57:47 +00:00
|
|
|
} else {
|
2022-04-08 04:13:47 +00:00
|
|
|
logger.Infof("Initializing server for %s connections on '%s' paths '/' and '%s'", connectionType, listener.Addr().String(), config.Server.Path)
|
2022-04-04 23:57:47 +00:00
|
|
|
}
|
|
|
|
|
2022-06-14 07:20:13 +00:00
|
|
|
return server, listener, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateMetricsServer creates a metrics server.
|
|
|
|
func CreateMetricsServer(config schema.TelemetryMetricsConfig) (server *fasthttp.Server, listener net.Listener, err error) {
|
|
|
|
if listener, err = config.Address.Listener(); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
server = &fasthttp.Server{
|
|
|
|
ErrorHandler: handleError(),
|
|
|
|
NoDefaultServerHeader: true,
|
|
|
|
Handler: handleMetrics(),
|
|
|
|
}
|
|
|
|
|
|
|
|
return server, listener, nil
|
2019-04-24 21:52:08 +00:00
|
|
|
}
|