feature: allow preloaded certs with prefork (#2351)

* allow preloaded certs with prefork

* add to documentation

* add comments for ListenMutualTLSWithCertificate

* add test for WithCertificate

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

---------

Co-authored-by: RW <rene@gofiber.io>
pull/2354/head
lublak 2023-03-06 12:03:41 +01:00 committed by GitHub
parent e2da8540be
commit 2e7e879d6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 159 additions and 1 deletions

View File

@ -38,5 +38,7 @@ jobs:
github-token: ${{ secrets.BENCHMARK_TOKEN }} github-token: ${{ secrets.BENCHMARK_TOKEN }}
benchmark-data-dir-path: 'benchmarks' benchmark-data-dir-path: 'benchmarks'
fail-on-alert: true fail-on-alert: true
comment-on-alert: true comment-on-alert: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
# Enable Job Summary for PRs
#summary-always: ${{ github.event_name != 'push' && github.event_name != 'workflow_dispatch' }}
auto-push: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} auto-push: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}

View File

@ -525,6 +525,27 @@ Using `ListenTLS` defaults to the following config \( use `Listener` to provide
} }
``` ```
## ListenTLSWithCertificate
```go title="Signature"
func (app *App) ListenTLS(addr string, cert tls.Certificate) error
```
```go title="Examples"
app.ListenTLSWithCertificate(":443", cert);
```
Using `ListenTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
```go title="Default \*tls.Config"
&tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{
cert,
},
}
```
## ListenMutualTLS ## ListenMutualTLS
ListenMutualTLS serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file ListenMutualTLS serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
@ -550,6 +571,31 @@ Using `ListenMutualTLS` defaults to the following config \( use `Listener` to pr
} }
``` ```
## ListenMutualTLSWithCertificate
ListenMutualTLSWithCertificate serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
```go title="Signature"
func (app *App) ListenMutualTLSWithCertificate(addr string, cert tls.Certificate, clientCertPool *x509.CertPool) error
```
```go title="Examples"
app.ListenMutualTLSWithCertificate(":443", cert, clientCertPool);
```
Using `ListenMutualTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
```go title="Default \*tls.Config"
&tls.Config{
MinVersion: tls.VersionTLS12,
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientCertPool,
Certificates: []tls.Certificate{
cert,
},
}
```
## Listener ## Listener
You can pass your own [`net.Listener`](https://pkg.go.dev/net/#Listener) using the `Listener` method. This method can be used to enable **TLS/HTTPS** with a custom tls.Config. You can pass your own [`net.Listener`](https://pkg.go.dev/net/#Listener) using the `Listener` method. This method can be used to enable **TLS/HTTPS** with a custom tls.Config.

View File

@ -98,6 +98,14 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error {
return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %w", certFile, keyFile, err) return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %w", certFile, keyFile, err)
} }
return app.ListenTLSWithCertificate(addr, cert)
}
// ListenTLS serves HTTPS requests from the given addr.
// cert is a tls.Certificate
//
// app.ListenTLSWithCertificate(":8080", cert)
func (app *App) ListenTLSWithCertificate(addr string, cert tls.Certificate) error {
tlsHandler := &TLSHandler{} tlsHandler := &TLSHandler{}
config := &tls.Config{ config := &tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
@ -161,6 +169,14 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string)
clientCertPool := x509.NewCertPool() clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert) clientCertPool.AppendCertsFromPEM(clientCACert)
return app.ListenMutualTLSWithCertificate(addr, cert, clientCertPool)
}
// ListenMutualTLSWithCertificate serves HTTPS requests from the given addr.
// cert is a tls.Certificate and clientCertPool is a *x509.CertPool:
//
// app.ListenMutualTLS(":8080", cert, clientCertPool)
func (app *App) ListenMutualTLSWithCertificate(addr string, cert tls.Certificate, clientCertPool *x509.CertPool) error {
tlsHandler := &TLSHandler{} tlsHandler := &TLSHandler{}
config := &tls.Config{ config := &tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,

View File

@ -7,9 +7,11 @@ package fiber
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"crypto/x509"
"io" "io"
"log" "log"
"os" "os"
"path/filepath"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@ -142,6 +144,98 @@ func Test_App_Listener_TLS_Listener(t *testing.T) {
utils.AssertEqual(t, nil, app.Listener(ln)) utils.AssertEqual(t, nil, app.Listener(ln))
} }
// go test -run Test_App_ListenTLSWithCertificate
func Test_App_ListenTLSWithCertificate(t *testing.T) {
t.Parallel()
// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}
app := New()
// invalid port
utils.AssertEqual(t, false, app.ListenTLSWithCertificate(":99999", cer) == nil)
go func() {
time.Sleep(1000 * time.Millisecond)
utils.AssertEqual(t, nil, app.Shutdown())
}()
utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":0", cer))
}
// go test -run Test_App_ListenTLSWithCertificate_Prefork
func Test_App_ListenTLSWithCertificate_Prefork(t *testing.T) {
testPreforkMaster = true
// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}
app := New(Config{DisableStartupMessage: true, Prefork: true})
utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":99999", cer))
}
// go test -run Test_App_ListenMutualTLSWithCertificate
func Test_App_ListenMutualTLSWithCertificate(t *testing.T) {
t.Parallel()
// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}
// Create pool
clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem"))
if err != nil {
utils.AssertEqual(t, nil, err)
}
clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert)
app := New()
// invalid port
utils.AssertEqual(t, false, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool) == nil)
go func() {
time.Sleep(1000 * time.Millisecond)
utils.AssertEqual(t, nil, app.Shutdown())
}()
utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":0", cer, clientCertPool))
}
// go test -run Test_App_ListenMutualTLS_Prefork
func Test_App_ListenMutualTLSWithCertificate_Prefork(t *testing.T) {
testPreforkMaster = true
// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}
// Create pool
clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem"))
if err != nil {
utils.AssertEqual(t, nil, err)
}
clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert)
app := New(Config{DisableStartupMessage: true, Prefork: true})
utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool))
}
func captureOutput(f func()) string { func captureOutput(f func()) string {
reader, writer, err := os.Pipe() reader, writer, err := os.Pipe()
if err != nil { if err != nil {