Compare commits

..

17 Commits

Author SHA1 Message Date
crapStone d980cd4e57 revert changes 2024-05-02 19:00:15 +00:00
crapStone fa10cfae82 just use expirable cache 2024-05-02 19:00:15 +00:00
crapStone de823fbd16 test 2024-05-02 19:00:15 +00:00
crapStone 19e1471c71 fix everything 2024-05-02 19:00:15 +00:00
crapStone ca4f62a496 fix repo 2024-05-02 19:00:15 +00:00
crapStone 558b3f6075 fix certs again 2024-05-02 19:00:15 +00:00
crapStone 3a1ba2d5ac fix spelling 2024-05-02 19:00:15 +00:00
crapStone 5954ca83c5 remove unnecessary stuff 2024-05-02 19:00:15 +00:00
crapStone e320f34ec1 remove unnecessary stuff 2024-05-02 19:00:15 +00:00
crapStone a8f6bbda85 fix leaf nil reference 2024-05-02 19:00:15 +00:00
crapStone 3566fd62b8 remove domain from cache when scheduled for renewal 2024-05-02 19:00:15 +00:00
crapStone 50221cf531 format code 2024-05-02 19:00:15 +00:00
crapStone 687f06e107 add issue number 2024-05-02 19:00:15 +00:00
crapStone acd02709c7 minor improvements 2024-05-02 19:00:15 +00:00
Moritz Marquardt 7071ee9bff Use hashicorp's LRU cache for DNS & certificates
DNS caching is also limited to 30 seconds now instead of 5 minutes
2024-05-02 19:00:15 +00:00
Dependency bot eb08c46dcd chore(deps): update golang docker tag to v1.22 (#326)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| golang | minor | `1.21` -> `1.22` |

---

### Configuration

📅 **Schedule**: Branch creation - "every weekend" (UTC), Automerge - "before 4am" (UTC).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zMzMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjMzMy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: woodpecker-bot <woodpecker-bot@obermui.de>
Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/326
Reviewed-by: crapStone <codeberg@crapstone.dev>
Co-authored-by: Dependency bot <renovate-bot@noreply.codeberg.org>
Co-committed-by: Dependency bot <renovate-bot@noreply.codeberg.org>
2024-05-02 13:20:17 +00:00
crapStone 56d44609ea Add option to start http server for profiling (#323)
https://rafallorenz.com/go/go-profiling-http-service-with-pprof-and-expvar/
Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/323
Co-authored-by: crapStone <me@crapstone.dev>
Co-committed-by: crapStone <me@crapstone.dev>
2024-04-30 19:50:03 +00:00
7 changed files with 63 additions and 32 deletions

View File

@ -11,7 +11,7 @@ depends_on:
steps:
# use vendor to cache dependencies
vendor:
image: golang:1.21
image: golang:1.22
commands:
- go mod vendor

View File

@ -1,13 +1,13 @@
CGO_FLAGS := '-extldflags "-static" -linkmode external'
TAGS := 'sqlite sqlite_unlock_notify netgo'
dev:
dev *FLAGS:
#!/usr/bin/env bash
set -euxo pipefail
set -a # automatically export all variables
source .env-dev
set +a
go run -tags '{{TAGS}}' .
go run -tags '{{TAGS}}' . {{FLAGS}}
build:
CGO_ENABLED=1 go build -tags '{{TAGS}}' -ldflags '-s -w {{CGO_FLAGS}}' -v -o build/codeberg-pages-server ./

View File

@ -124,3 +124,18 @@ now these pages should work:
- <https://momar.localhost.mock.directory:4430/ci-testing/>
- <https://momar.localhost.mock.directory:4430/pag/@master/>
- <https://mock-pages.codeberg-test.org:4430/README.md>
### Profiling
> This section is just a collection of commands for quick reference. If you want to learn more about profiling read [this](https://go.dev/doc/diagnostics) article or google `golang profiling`.
First enable profiling by supplying the cli arg `--enable-profiling` or using the environment variable `EENABLE_PROFILING`.
Get cpu and mem stats:
```bash
go tool pprof -raw -output=cpu.txt 'http://localhost:9999/debug/pprof/profile?seconds=60' &
curl -so mem.txt 'http://localhost:9999/debug/pprof/heap?seconds=60'
```
More endpoints are documented here: <https://pkg.go.dev/net/http/pprof>

View File

@ -139,6 +139,18 @@ var (
EnvVars: []string{"CONFIG_FILE"},
},
&cli.BoolFlag{
Name: "enable-profiling",
Usage: "enables the go http profiling endpoints",
EnvVars: []string{"ENABLE_PROFILING"},
},
&cli.StringFlag{
Name: "profiling-address",
Usage: "specify ip address and port the profiling server should listen on",
EnvVars: []string{"PROFILING_ADDRESS"},
Value: "localhost:9999",
},
// ############################
// ### ACME Client Settings ###
// ############################

View File

@ -14,7 +14,7 @@ import (
"github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
"github.com/go-acme/lego/v4/lego"
lru "github.com/hashicorp/golang-lru/v2"
"github.com/hashicorp/golang-lru/v2/expirable"
"github.com/reugn/equalizer"
"github.com/rs/zerolog/log"
@ -37,10 +37,7 @@ func TLSConfig(mainDomainSuffix string,
noDNS01 bool,
rawDomain string,
) *tls.Config {
keyCache, err := lru.New[string, *tls.Certificate](32)
if err != nil {
panic(err) // This should only happen if 32 < 0 at the time of writing, which should be reason enough to panic.
}
keyCache := expirable.NewLRU[string, *tls.Certificate](32, nil, 24*time.Hour)
return &tls.Config{
// check DNS name & get certificate from Let's Encrypt
@ -112,13 +109,8 @@ func TLSConfig(mainDomainSuffix string,
}
if tlsCertificate, ok := keyCache.Get(domain); ok {
if tlsCertificate.Leaf.NotAfter.Before(time.Now().Add(7 * 24 * time.Hour)) {
// if cert is up for renewal remove it from the cache
keyCache.Remove(domain)
} else {
// we can use an existing certificate object
return tlsCertificate, nil
}
// we can use an existing certificate object
return tlsCertificate, nil
}
var tlsCertificate *tls.Certificate
@ -143,7 +135,6 @@ func TLSConfig(mainDomainSuffix string,
}
}
log.Error().Interface("cert", tlsCertificate).Msg("AAAAAAAAAAAAAAAAAAAAAAAAAAAAa")
keyCache.Add(domain, tlsCertificate)
return tlsCertificate, nil
@ -194,13 +185,13 @@ func (c *AcmeClient) retrieveCertFromDB(sni, mainDomainSuffix string, useDnsProv
if err != nil {
return nil, err
}
tlsCertificate.Leaf, err = leaf(&tlsCertificate)
if err != nil {
return nil, err
}
// TODO: document & put into own function
if !strings.EqualFold(sni, mainDomainSuffix) {
tlsCertificate.Leaf, err = leaf(&tlsCertificate)
if err != nil {
return nil, err
}
// renew certificates 7 days before they expire
if tlsCertificate.Leaf.NotAfter.Before(time.Now().Add(7 * 24 * time.Hour)) {
// TODO: use ValidTill of custom cert struct
@ -238,10 +229,6 @@ func (c *AcmeClient) obtainCert(acmeClient *lego.Client, domains []string, renew
if err != nil {
return nil, fmt.Errorf("certificate failed in synchronous request: %w", err)
}
cert.Leaf, err = leaf(cert)
if err != nil {
return nil, err
}
return cert, nil
}
defer c.obtainLocks.Delete(name)
@ -329,10 +316,6 @@ func (c *AcmeClient) obtainCert(acmeClient *lego.Client, domains []string, renew
if err != nil {
return nil, err
}
tlsCertificate.Leaf, err = leaf(&tlsCertificate)
if err != nil {
return nil, err
}
return &tlsCertificate, nil
}

21
server/profiling.go Normal file
View File

@ -0,0 +1,21 @@
package server
import (
"net/http"
_ "net/http/pprof"
"github.com/rs/zerolog/log"
)
func StartProfilingServer(listeningAddress string) {
server := &http.Server{
Addr: listeningAddress,
Handler: http.DefaultServeMux,
}
log.Info().Msgf("Starting debug server on %s", listeningAddress)
go func() {
log.Fatal().Err(server.ListenAndServe()).Msg("Failed to start debug server")
}()
}

View File

@ -3,7 +3,6 @@ package server
import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"net"
"net/http"
@ -43,9 +42,6 @@ func Serve(ctx *cli.Context) error {
}
log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().Timestamp().Logger().Level(logLevel)
foo, _ := json.Marshal(cfg)
log.Trace().RawJSON("config", foo).Msg("starting server with config")
listeningSSLAddress := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
listeningHTTPAddress := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.HttpPort)
@ -130,6 +126,10 @@ func Serve(ctx *cli.Context) error {
}()
}
if ctx.IsSet("enable-profiling") {
StartProfilingServer(ctx.String("profiling-address"))
}
// Create ssl handler based on settings
sslHandler := handler.Handler(cfg.Server, giteaClient, canonicalDomainCache, redirectsCache)