mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-31 07:19:16 +02:00
Merge remote-tracking branch 'origin/main' into cdoxsey/pass-config
This commit is contained in:
commit
8482a422ca
35 changed files with 418 additions and 254 deletions
2
.github/workflows/benchmark.yaml
vendored
2
.github/workflows/benchmark.yaml
vendored
|
@ -20,7 +20,7 @@ jobs:
|
|||
platform: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a # pin@v2
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f # pin@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
|
|
2
.github/workflows/docker-main.yaml
vendored
2
.github/workflows/docker-main.yaml
vendored
|
@ -83,7 +83,7 @@ jobs:
|
|||
token: ${{ secrets.APPARITOR_GITHUB_TOKEN }}
|
||||
|
||||
- name: Bump psql environment
|
||||
uses: mikefarah/yq@1c7dc0e88aad311c89889bc5ce5d8f96931a1bd0 # pin@v4.23.1
|
||||
uses: mikefarah/yq@3d11b0545dbc0712c2045dc9e8b6c95b298e824e # pin@v4.23.1
|
||||
with:
|
||||
cmd:
|
||||
yq eval '.pomerium.image.tag = "${{ needs.publish.outputs.sha-tag }}"' -i
|
||||
|
|
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
@ -31,7 +31,7 @@ jobs:
|
|||
node-version: 16.x
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a # pin@v2
|
||||
uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f # pin@v2
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
|
||||
|
@ -52,7 +52,7 @@ jobs:
|
|||
run: gcloud auth configure-docker
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@68acf3b1adf004ac9c2f0a4259e85c5f66e99bef # pin@v2
|
||||
uses: goreleaser/goreleaser-action@ff11ca24a9b39f2d36796d1fbd7a4e39c182630a # pin@v2
|
||||
with:
|
||||
version: v0.184.0
|
||||
args: release --config .github/goreleaser.yaml
|
||||
|
@ -122,7 +122,7 @@ jobs:
|
|||
token: ${{ secrets.APPARITOR_GITHUB_TOKEN }}
|
||||
|
||||
- name: Bump test environment
|
||||
uses: mikefarah/yq@1c7dc0e88aad311c89889bc5ce5d8f96931a1bd0 # pin@v4.23.1
|
||||
uses: mikefarah/yq@3d11b0545dbc0712c2045dc9e8b6c95b298e824e # pin@v4.23.1
|
||||
with:
|
||||
cmd: yq eval '.pomerium.image.tag = "${{ needs.goreleaser.outputs.tag }}"' -i projects/pomerium-demo/pomerium-demo/values.yaml
|
||||
|
||||
|
|
12
.github/workflows/test.yaml
vendored
12
.github/workflows/test.yaml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
|||
platform: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
|
@ -62,7 +62,7 @@ jobs:
|
|||
go-version: [1.18.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
|
@ -120,7 +120,7 @@ jobs:
|
|||
idp: [auth0, azure, github, gitlab, google, oidc, okta, onelogin, ping]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
|
@ -166,7 +166,7 @@ jobs:
|
|||
platform: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
|
@ -223,7 +223,7 @@ jobs:
|
|||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- uses: actions/setup-python@b55428b1882923874294fa556849718a1d7f2ca5
|
||||
|
@ -246,7 +246,7 @@ jobs:
|
|||
needs:
|
||||
- build
|
||||
steps:
|
||||
- uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a
|
||||
- uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ RUN make yarn
|
|||
COPY ./ui/ ./ui/
|
||||
RUN make build-ui
|
||||
|
||||
FROM golang:1.19.0-buster@sha256:a7a23f1fba8390b1e038f017c85259c878f406301643653ec6e5b97e75668789 as build
|
||||
FROM golang:1.19.0-buster@sha256:d84495e2ad12dfeb51dec3c9f170659ebd09db234d6990b3364f877785684a14 as build
|
||||
WORKDIR /go/src/github.com/pomerium/pomerium
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install zip
|
||||
|
||||
# cache depedency downloads
|
||||
# cache dependency downloads
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
|
@ -30,7 +30,7 @@ RUN make build-go NAME=pomerium
|
|||
RUN touch /config.yaml
|
||||
|
||||
# build our own root trust store from current stable
|
||||
FROM debian:stable@sha256:b9b1f4a7df16fcf7f287802d827b80f481a1e4caecb62c40c2e26fdebdc2eab9 as casource
|
||||
FROM debian:stable@sha256:3d2aa501c4cefd4415895b1d877dfbba0739cab1d58cbe8f1baa3f01b6739690 as casource
|
||||
RUN apt-get update && apt-get install -y ca-certificates
|
||||
# Remove expired root (https://github.com/pomerium/pomerium/issues/2653)
|
||||
RUN rm /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt && update-ca-certificates
|
||||
|
|
|
@ -13,13 +13,13 @@ RUN make yarn
|
|||
COPY ./ui/ ./ui/
|
||||
RUN make build-ui
|
||||
|
||||
FROM golang:1.19.0-buster@sha256:a7a23f1fba8390b1e038f017c85259c878f406301643653ec6e5b97e75668789 as build
|
||||
FROM golang:1.19.0-buster@sha256:d84495e2ad12dfeb51dec3c9f170659ebd09db234d6990b3364f877785684a14 as build
|
||||
WORKDIR /go/src/github.com/pomerium/pomerium
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install zip
|
||||
|
||||
# cache depedency downloads
|
||||
# cache dependency downloads
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
|
|
|
@ -138,20 +138,25 @@ func (a *Authenticate) VerifySession(next http.Handler) http.Handler {
|
|||
defer span.End()
|
||||
|
||||
state := a.state.Load()
|
||||
idpID := r.FormValue(urlutil.QueryIdentityProviderID)
|
||||
cfg := a.currentConfig.Load()
|
||||
idp, err := cfg.Options.GetIdentityProviderForID(r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sessionState, err := a.getSessionFromCtx(ctx)
|
||||
if err != nil {
|
||||
log.FromRequest(r).Info().
|
||||
Err(err).
|
||||
Str("idp_id", idpID).
|
||||
Str("idp_id", idp.GetId()).
|
||||
Msg("authenticate: session load error")
|
||||
return a.reauthenticateOrFail(w, r, err)
|
||||
}
|
||||
|
||||
if sessionState.IdentityProviderID != idpID {
|
||||
if sessionState.IdentityProviderID != idp.GetId() {
|
||||
log.FromRequest(r).Info().
|
||||
Str("idp_id", idpID).
|
||||
Str("idp_id", idp.GetId()).
|
||||
Str("session_idp_id", sessionState.IdentityProviderID).
|
||||
Str("id", sessionState.ID).
|
||||
Msg("authenticate: session not associated with identity provider")
|
||||
return a.reauthenticateOrFail(w, r, err)
|
||||
|
@ -163,7 +168,7 @@ func (a *Authenticate) VerifySession(next http.Handler) http.Handler {
|
|||
if _, err = session.Get(ctx, state.dataBrokerClient, sessionState.ID); err != nil {
|
||||
log.FromRequest(r).Info().
|
||||
Err(err).
|
||||
Str("idp_id", idpID).
|
||||
Str("idp_id", idp.GetId()).
|
||||
Str("id", sessionState.ID).
|
||||
Msg("authenticate: session not found in databroker")
|
||||
return a.reauthenticateOrFail(w, r, err)
|
||||
|
@ -187,6 +192,11 @@ func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) error {
|
|||
defer span.End()
|
||||
|
||||
state := a.state.Load()
|
||||
cfg := a.currentConfig.Load()
|
||||
idp, err := cfg.Options.GetIdentityProviderForID(r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
redirectURL, err := urlutil.ParseAndValidateURL(r.FormValue(urlutil.QueryRedirectURI))
|
||||
if err != nil {
|
||||
|
@ -216,8 +226,8 @@ func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
// start over if this is a different identity provider
|
||||
if s == nil || s.IdentityProviderID != r.FormValue(urlutil.QueryIdentityProviderID) {
|
||||
s = sessions.NewState(urlutil.QueryIdentityProviderID)
|
||||
if s == nil || s.IdentityProviderID != idp.GetId() {
|
||||
s = sessions.NewState(idp.GetId())
|
||||
}
|
||||
|
||||
newSession := s.WithNewIssuer(state.redirectURL.Host, jwtAudience)
|
||||
|
@ -277,7 +287,7 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
|
|||
|
||||
cfg := a.currentConfig.Load()
|
||||
|
||||
idp, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
authenticator, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -296,14 +306,14 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
|
|||
redirectString = uri
|
||||
}
|
||||
|
||||
endSessionURL, err := idp.LogOut()
|
||||
endSessionURL, err := authenticator.LogOut()
|
||||
if err == nil && redirectString != "" {
|
||||
params := url.Values{}
|
||||
params.Add("id_token_hint", rawIDToken)
|
||||
params.Add("post_logout_redirect_uri", redirectString)
|
||||
endSessionURL.RawQuery = params.Encode()
|
||||
redirectString = endSessionURL.String()
|
||||
} else if !errors.Is(err, oidc.ErrSignoutNotImplemented) {
|
||||
} else if err != nil && !errors.Is(err, oidc.ErrSignoutNotImplemented) {
|
||||
log.Warn(r.Context()).Err(err).Msg("authenticate.SignOut: failed getting session")
|
||||
}
|
||||
if redirectString != "" {
|
||||
|
@ -330,10 +340,15 @@ func (a *Authenticate) reauthenticateOrFail(w http.ResponseWriter, r *http.Reque
|
|||
return httputil.NewError(http.StatusUnauthorized, err)
|
||||
}
|
||||
|
||||
cfg := a.currentConfig.Load()
|
||||
state := a.state.Load()
|
||||
cfg := a.currentConfig.Load()
|
||||
|
||||
idp, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
idp, err := cfg.Options.GetIdentityProviderForID(r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authenticator, err := a.cfg.getIdentityProvider(cfg, idp.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -346,7 +361,7 @@ func (a *Authenticate) reauthenticateOrFail(w http.ResponseWriter, r *http.Reque
|
|||
enc := cryptutil.Encrypt(state.cookieCipher, []byte(redirectURL.String()), b)
|
||||
b = append(b, enc...)
|
||||
encodedState := base64.URLEncoding.EncodeToString(b)
|
||||
signinURL, err := idp.GetSignInURL(encodedState)
|
||||
signinURL, err := authenticator.GetSignInURL(encodedState)
|
||||
if err != nil {
|
||||
return httputil.NewError(http.StatusInternalServerError,
|
||||
fmt.Errorf("failed to get sign in url: %w", err))
|
||||
|
@ -381,8 +396,8 @@ func (a *Authenticate) getOAuthCallback(w http.ResponseWriter, r *http.Request)
|
|||
ctx, span := trace.StartSpan(r.Context(), "authenticate.getOAuthCallback")
|
||||
defer span.End()
|
||||
|
||||
cfg := a.currentConfig.Load()
|
||||
state := a.state.Load()
|
||||
cfg := a.currentConfig.Load()
|
||||
|
||||
// Error Authentication Response: rfc6749#section-4.1.2.1 & OIDC#3.1.2.6
|
||||
//
|
||||
|
@ -428,9 +443,13 @@ func (a *Authenticate) getOAuthCallback(w http.ResponseWriter, r *http.Request)
|
|||
if err != nil {
|
||||
return nil, httputil.NewError(http.StatusBadRequest, err)
|
||||
}
|
||||
idpID := redirectURL.Query().Get(urlutil.QueryIdentityProviderID)
|
||||
|
||||
idp, err := a.cfg.getIdentityProvider(cfg, idpID)
|
||||
idp, err := cfg.Options.GetIdentityProviderForID(r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authenticator, err := a.cfg.getIdentityProvider(cfg, idp.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -439,12 +458,12 @@ func (a *Authenticate) getOAuthCallback(w http.ResponseWriter, r *http.Request)
|
|||
//
|
||||
// Exchange the supplied Authorization Code for a valid user session.
|
||||
var claims identity.SessionClaims
|
||||
accessToken, err := idp.Authenticate(ctx, code, &claims)
|
||||
accessToken, err := authenticator.Authenticate(ctx, code, &claims)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error redeeming authenticate code: %w", err)
|
||||
}
|
||||
|
||||
s := sessions.NewState(idpID)
|
||||
s := sessions.NewState(idp.GetId())
|
||||
err = claims.Claims.Claims(&s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error unmarshaling session state: %w", err)
|
||||
|
@ -583,7 +602,7 @@ func (a *Authenticate) saveSessionToDataBroker(
|
|||
state := a.state.Load()
|
||||
cfg := a.currentConfig.Load()
|
||||
|
||||
idp, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
authenticator, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -593,7 +612,7 @@ func (a *Authenticate) saveSessionToDataBroker(
|
|||
|
||||
s := &session.Session{
|
||||
Id: sessionState.ID,
|
||||
UserId: sessionState.UserID(idp.Name()),
|
||||
UserId: sessionState.UserID(authenticator.Name()),
|
||||
IssuedAt: timestamppb.Now(),
|
||||
AccessedAt: timestamppb.Now(),
|
||||
ExpiresAt: sessionExpiry,
|
||||
|
@ -617,7 +636,7 @@ func (a *Authenticate) saveSessionToDataBroker(
|
|||
Id: s.GetUserId(),
|
||||
}
|
||||
}
|
||||
err = idp.UpdateUserInfo(ctx, accessToken, &managerUser)
|
||||
err = authenticator.UpdateUserInfo(ctx, accessToken, &managerUser)
|
||||
if err != nil {
|
||||
return fmt.Errorf("authenticate: error retrieving user info: %w", err)
|
||||
}
|
||||
|
@ -648,13 +667,18 @@ func (a *Authenticate) saveSessionToDataBroker(
|
|||
// databroker. If successful, it returns the original `id_token` of the session, if failed, returns
|
||||
// and empty string.
|
||||
func (a *Authenticate) revokeSession(ctx context.Context, w http.ResponseWriter, r *http.Request) string {
|
||||
cfg := a.currentConfig.Load()
|
||||
state := a.state.Load()
|
||||
cfg := a.currentConfig.Load()
|
||||
|
||||
// clear the user's local session no matter what
|
||||
defer state.sessionStore.ClearSession(w, r)
|
||||
|
||||
idp, err := a.cfg.getIdentityProvider(cfg, r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
idp, err := cfg.Options.GetIdentityProviderForID(r.FormValue(urlutil.QueryIdentityProviderID))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
authenticator, err := a.cfg.getIdentityProvider(cfg, idp.GetId())
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -667,7 +691,7 @@ func (a *Authenticate) revokeSession(ctx context.Context, w http.ResponseWriter,
|
|||
|
||||
if s, _ := session.Get(ctx, state.dataBrokerClient, sessionState.ID); s != nil && s.OauthToken != nil {
|
||||
rawIDToken = s.GetIdToken().GetRaw()
|
||||
if err := idp.Revoke(ctx, manager.FromOAuthToken(s.OauthToken)); err != nil {
|
||||
if err := authenticator.Revoke(ctx, manager.FromOAuthToken(s.OauthToken)); err != nil {
|
||||
log.Ctx(ctx).Warn().Err(err).Msg("authenticate: failed to revoke access token")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ func TestAuthenticate_OAuthCallback(t *testing.T) {
|
|||
{"bad timing - too soon", http.MethodGet, time.Now().Add(1 * time.Hour).Unix(), "", "", "", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"bad timing - expired", http.MethodGet, time.Now().Add(-1 * time.Hour).Unix(), "", "", "", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"bad base64", http.MethodGet, time.Now().Unix(), "", "", "^", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"too many seperators", http.MethodGet, time.Now().Unix(), "", "", "|ok|now|what", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"too many separators", http.MethodGet, time.Now().Unix(), "", "", "|ok|now|what", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"bad hmac", http.MethodGet, time.Now().Unix(), "", "NOTMAC", "", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
{"bad hmac", http.MethodGet, time.Now().Unix(), base64.URLEncoding.EncodeToString([]byte("malformed_state")), "", "", "", "code", "https://corp.pomerium.io", "https://authenticate.pomerium.io", &mstore.Store{}, identity.MockProvider{AuthenticateResponse: oauth2.Token{}}, "https://corp.pomerium.io", http.StatusBadRequest},
|
||||
}
|
||||
|
@ -474,6 +474,8 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
idp, _ := new(config.Options).GetIdentityProviderForID("")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
headers map[string]string
|
||||
|
@ -487,7 +489,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"good",
|
||||
nil,
|
||||
&mstore.Store{Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
nil,
|
||||
identity.MockProvider{RefreshResponse: oauth2.Token{Expiry: time.Now().Add(10 * time.Minute)}},
|
||||
http.StatusOK,
|
||||
|
@ -495,7 +497,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"invalid session",
|
||||
nil,
|
||||
&mstore.Store{Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
errors.New("hi"),
|
||||
identity.MockProvider{},
|
||||
http.StatusFound,
|
||||
|
@ -503,7 +505,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"good refresh expired",
|
||||
nil,
|
||||
&mstore.Store{Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
nil,
|
||||
identity.MockProvider{RefreshResponse: oauth2.Token{Expiry: time.Now().Add(10 * time.Minute)}},
|
||||
http.StatusOK,
|
||||
|
@ -511,7 +513,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"expired,refresh error",
|
||||
nil,
|
||||
&mstore.Store{Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
sessions.ErrExpired,
|
||||
identity.MockProvider{RefreshError: errors.New("error")},
|
||||
http.StatusFound,
|
||||
|
@ -519,7 +521,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"expired,save error",
|
||||
nil,
|
||||
&mstore.Store{SaveError: errors.New("error"), Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{SaveError: errors.New("error"), Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
sessions.ErrExpired,
|
||||
identity.MockProvider{RefreshResponse: oauth2.Token{Expiry: time.Now().Add(10 * time.Minute)}},
|
||||
http.StatusFound,
|
||||
|
@ -527,7 +529,7 @@ func TestAuthenticate_SessionValidatorMiddleware(t *testing.T) {
|
|||
{
|
||||
"expired XHR,refresh error",
|
||||
map[string]string{"X-Requested-With": "XmlHttpRequest"},
|
||||
&mstore.Store{Session: &sessions.State{ID: "xyz"}},
|
||||
&mstore.Store{Session: &sessions.State{IdentityProviderID: idp.GetId(), ID: "xyz"}},
|
||||
sessions.ErrExpired,
|
||||
identity.MockProvider{RefreshError: errors.New("error")},
|
||||
http.StatusUnauthorized,
|
||||
|
|
|
@ -26,6 +26,8 @@ type Config struct {
|
|||
MetricsPort string
|
||||
// DebugPort is the port the debug listener is running on.
|
||||
DebugPort string
|
||||
// ACMETLSPort is the port that handles the ACME TLS-ALPN challenge.
|
||||
ACMETLSALPNPort string
|
||||
|
||||
// MetricsScrapeEndpoints additional metrics endpoints to scrape and provide part of metrics
|
||||
MetricsScrapeEndpoints []MetricsScrapeEndpoint
|
||||
|
@ -56,11 +58,12 @@ func (cfg *Config) Clone() *Config {
|
|||
AutoCertificates: cfg.AutoCertificates,
|
||||
EnvoyVersion: cfg.EnvoyVersion,
|
||||
|
||||
GRPCPort: cfg.GRPCPort,
|
||||
HTTPPort: cfg.HTTPPort,
|
||||
OutboundPort: cfg.OutboundPort,
|
||||
MetricsPort: cfg.MetricsPort,
|
||||
DebugPort: cfg.DebugPort,
|
||||
GRPCPort: cfg.GRPCPort,
|
||||
HTTPPort: cfg.HTTPPort,
|
||||
OutboundPort: cfg.OutboundPort,
|
||||
MetricsPort: cfg.MetricsPort,
|
||||
DebugPort: cfg.DebugPort,
|
||||
ACMETLSALPNPort: cfg.ACMETLSALPNPort,
|
||||
|
||||
MetricsScrapeEndpoints: endpoints,
|
||||
}
|
||||
|
@ -85,10 +88,11 @@ func (cfg *Config) Checksum() uint64 {
|
|||
}
|
||||
|
||||
// AllocatePorts populates
|
||||
func (cfg *Config) AllocatePorts(ports [5]string) {
|
||||
func (cfg *Config) AllocatePorts(ports [6]string) {
|
||||
cfg.GRPCPort = ports[0]
|
||||
cfg.HTTPPort = ports[1]
|
||||
cfg.OutboundPort = ports[2]
|
||||
cfg.MetricsPort = ports[3]
|
||||
cfg.DebugPort = ports[4]
|
||||
cfg.ACMETLSALPNPort = ports[5]
|
||||
}
|
||||
|
|
|
@ -116,12 +116,12 @@ func NewFileOrEnvironmentSource(
|
|||
EnvoyVersion: envoyVersion,
|
||||
}
|
||||
|
||||
ports, err := netutil.AllocatePorts(5)
|
||||
ports, err := netutil.AllocatePorts(6)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("allocating ports: %w", err)
|
||||
}
|
||||
|
||||
cfg.AllocatePorts(*(*[5]string)(ports))
|
||||
cfg.AllocatePorts(*(*[6]string)(ports))
|
||||
|
||||
metrics.SetConfigInfo(ctx, cfg.Options.Services, "local", cfg.Checksum(), true)
|
||||
|
||||
|
|
53
config/envoyconfig/acmetlsalpn.go
Normal file
53
config/envoyconfig/acmetlsalpn.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package envoyconfig
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
||||
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
)
|
||||
|
||||
// Pomerium implements the ACME TLS-ALPN protocol by adding a filter chain to the main HTTPS listener
|
||||
// that matches the acme-tls/1 application protocol on incoming requests and forwards them to a listener
|
||||
// started in the `autocert` package. The proxying is done using TCP so that the Go listener can terminate
|
||||
// the TLS connection using the certmagic package.
|
||||
|
||||
const (
|
||||
acmeTLSALPNApplicationProtocol = "acme-tls/1"
|
||||
acmeTLSALPNClusterName = "pomerium-acme-tls-alpn"
|
||||
)
|
||||
|
||||
func (b *Builder) buildACMETLSALPNCluster(
|
||||
cfg *config.Config,
|
||||
) *envoy_config_cluster_v3.Cluster {
|
||||
port, _ := strconv.Atoi(cfg.ACMETLSALPNPort)
|
||||
return &envoy_config_cluster_v3.Cluster{
|
||||
Name: acmeTLSALPNClusterName,
|
||||
LoadAssignment: &envoy_config_endpoint_v3.ClusterLoadAssignment{
|
||||
ClusterName: acmeTLSALPNClusterName,
|
||||
Endpoints: []*envoy_config_endpoint_v3.LocalityLbEndpoints{{
|
||||
LbEndpoints: []*envoy_config_endpoint_v3.LbEndpoint{{
|
||||
HostIdentifier: &envoy_config_endpoint_v3.LbEndpoint_Endpoint{
|
||||
Endpoint: &envoy_config_endpoint_v3.Endpoint{
|
||||
Address: buildAddress("127.0.0.1", port),
|
||||
},
|
||||
},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) buildACMETLSALPNFilterChain() *envoy_config_listener_v3.FilterChain {
|
||||
return &envoy_config_listener_v3.FilterChain{
|
||||
FilterChainMatch: &envoy_config_listener_v3.FilterChainMatch{
|
||||
ApplicationProtocols: []string{acmeTLSALPNApplicationProtocol},
|
||||
},
|
||||
Filters: []*envoy_config_listener_v3.Filter{
|
||||
TCPProxyFilter(acmeTLSALPNClusterName),
|
||||
},
|
||||
}
|
||||
}
|
54
config/envoyconfig/acmetlsalpn_test.go
Normal file
54
config/envoyconfig/acmetlsalpn_test.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package envoyconfig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBuilder_buildACMETLSALPNCluster(t *testing.T) {
|
||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
||||
testutil.AssertProtoJSONEqual(t,
|
||||
`{
|
||||
"name": "pomerium-acme-tls-alpn",
|
||||
"loadAssignment": {
|
||||
"clusterName": "pomerium-acme-tls-alpn",
|
||||
"endpoints": [{
|
||||
"lbEndpoints": [{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "127.0.0.1",
|
||||
"portValue": 1234
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}`,
|
||||
b.buildACMETLSALPNCluster(&config.Config{
|
||||
ACMETLSALPNPort: "1234",
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) {
|
||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
||||
testutil.AssertProtoJSONEqual(t,
|
||||
`{
|
||||
"filterChainMatch": {
|
||||
"applicationProtocols": ["acme-tls/1"]
|
||||
},
|
||||
"filters": [{
|
||||
"name": "tcp_proxy",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy",
|
||||
"cluster": "pomerium-acme-tls-alpn",
|
||||
"statPrefix": "acme_tls_alpn"
|
||||
}
|
||||
}]
|
||||
}`,
|
||||
b.buildACMETLSALPNFilterChain())
|
||||
}
|
|
@ -80,6 +80,7 @@ func (b *Builder) BuildClusters(ctx context.Context, cfg *config.Config) ([]*env
|
|||
}
|
||||
|
||||
clusters := []*envoy_config_cluster_v3.Cluster{
|
||||
b.buildACMETLSALPNCluster(cfg),
|
||||
controlGRPC,
|
||||
controlHTTP,
|
||||
controlMetrics,
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
envoy_extensions_filters_listener_proxy_protocol_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/proxy_protocol/v3"
|
||||
envoy_extensions_filters_listener_tls_inspector_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3"
|
||||
envoy_extensions_filters_network_http_connection_manager "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
|
||||
envoy_extensions_filters_network_tcp_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3"
|
||||
envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
|
@ -89,6 +90,21 @@ func ProxyProtocolFilter() *envoy_config_listener_v3.ListenerFilter {
|
|||
}
|
||||
}
|
||||
|
||||
// TCPProxyFilter creates a new TCP Proxy filter.
|
||||
func TCPProxyFilter(clusterName string) *envoy_config_listener_v3.Filter {
|
||||
return &envoy_config_listener_v3.Filter{
|
||||
Name: "tcp_proxy",
|
||||
ConfigType: &envoy_config_listener_v3.Filter_TypedConfig{
|
||||
TypedConfig: protoutil.NewAny(&envoy_extensions_filters_network_tcp_proxy_v3.TcpProxy{
|
||||
StatPrefix: "acme_tls_alpn",
|
||||
ClusterSpecifier: &envoy_extensions_filters_network_tcp_proxy_v3.TcpProxy_Cluster{
|
||||
Cluster: clusterName,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TLSInspectorFilter creates a new TLS inspector filter.
|
||||
func TLSInspectorFilter() *envoy_config_listener_v3.ListenerFilter {
|
||||
return &envoy_config_listener_v3.ListenerFilter{
|
||||
|
|
|
@ -107,7 +107,7 @@ func (b *Builder) buildMainListener(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg, allDomains, "")
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg, allDomains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func (b *Builder) buildMainListener(
|
|||
|
||||
chains, err := b.buildFilterChains(cfg, cfg.Options.Addr,
|
||||
func(tlsDomain string, httpDomains []string) (*envoy_config_listener_v3.FilterChain, error) {
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg, httpDomains, tlsDomain)
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(cfg, httpDomains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -243,8 +243,7 @@ func (b *Builder) buildMetricsListener(
|
|||
}
|
||||
|
||||
func (b *Builder) buildFilterChains(
|
||||
cfg *config.Config,
|
||||
addr string,
|
||||
cfg *config.Config, addr string,
|
||||
callback func(tlsDomain string, httpDomains []string) (*envoy_config_listener_v3.FilterChain, error),
|
||||
) ([]*envoy_config_listener_v3.FilterChain, error) {
|
||||
allDomains, err := getAllRouteableDomains(cfg, addr)
|
||||
|
@ -258,14 +257,9 @@ func (b *Builder) buildFilterChains(
|
|||
}
|
||||
|
||||
var chains []*envoy_config_listener_v3.FilterChain
|
||||
chains = append(chains, b.buildACMETLSALPNFilterChain())
|
||||
for _, domain := range tlsDomains {
|
||||
routeableDomains, err := getRouteableDomainsForTLSServerName(cfg, addr, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// first we match on SNI
|
||||
chain, err := callback(domain, routeableDomains)
|
||||
chain, err := callback(domain, allDomains)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -284,7 +278,6 @@ func (b *Builder) buildFilterChains(
|
|||
func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
||||
cfg *config.Config,
|
||||
domains []string,
|
||||
tlsDomain string,
|
||||
) (*envoy_config_listener_v3.Filter, error) {
|
||||
authorizeURLs, err := cfg.Options.GetInternalAuthorizeURLs()
|
||||
if err != nil {
|
||||
|
@ -349,9 +342,6 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
|||
LuaFilter(luascripts.CleanUpstream),
|
||||
LuaFilter(luascripts.RewriteHeaders),
|
||||
}
|
||||
if tlsDomain != "" && tlsDomain != "*" {
|
||||
filters = append(filters, LuaFilter(fmt.Sprintf(luascripts.FixMisdirected, tlsDomain)))
|
||||
}
|
||||
filters = append(filters, HTTPRouterFilter())
|
||||
|
||||
var maxStreamDuration *durationpb.Duration
|
||||
|
@ -630,36 +620,7 @@ func (b *Builder) buildDownstreamValidationContext(
|
|||
return vc
|
||||
}
|
||||
|
||||
func getRouteableDomainsForTLSServerName(
|
||||
cfg *config.Config,
|
||||
addr string,
|
||||
tlsServerName string,
|
||||
) ([]string, error) {
|
||||
allDomains := sets.NewSorted[string]()
|
||||
|
||||
if addr == cfg.Options.Addr {
|
||||
domains, err := cfg.Options.GetAllRouteableHTTPDomainsForTLSServerName(tlsServerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allDomains.Add(domains...)
|
||||
}
|
||||
|
||||
if addr == cfg.Options.GetGRPCAddr() {
|
||||
domains, err := cfg.Options.GetAllRouteableGRPCDomainsForTLSServerName(tlsServerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allDomains.Add(domains...)
|
||||
}
|
||||
|
||||
return allDomains.ToSlice(), nil
|
||||
}
|
||||
|
||||
func getAllRouteableDomains(
|
||||
cfg *config.Config,
|
||||
addr string,
|
||||
) ([]string, error) {
|
||||
func getAllRouteableDomains(cfg *config.Config, addr string) ([]string, error) {
|
||||
allDomains := sets.NewSorted[string]()
|
||||
|
||||
if addr == cfg.Options.Addr {
|
||||
|
@ -681,17 +642,14 @@ func getAllRouteableDomains(
|
|||
return allDomains.ToSlice(), nil
|
||||
}
|
||||
|
||||
func getAllTLSDomains(
|
||||
cfg *config.Config,
|
||||
addr string,
|
||||
) ([]string, error) {
|
||||
allDomains, err := getAllRouteableDomains(cfg, addr)
|
||||
func getAllTLSDomains(cfg *config.Config, addr string) ([]string, error) {
|
||||
domains := sets.NewSorted[string]()
|
||||
|
||||
routeableDomains, err := getAllRouteableDomains(cfg, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
domains := sets.NewSorted[string]()
|
||||
for _, hp := range allDomains {
|
||||
for _, hp := range routeableDomains {
|
||||
if d, _, err := net.SplitHostPort(hp); err == nil {
|
||||
domains.Add(d)
|
||||
} else {
|
||||
|
@ -699,6 +657,16 @@ func getAllTLSDomains(
|
|||
}
|
||||
}
|
||||
|
||||
certs, err := cfg.AllCertificates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range certs {
|
||||
for _, domain := range cryptutil.GetCertificateDomains(&certs[i]) {
|
||||
domains.Add(domain)
|
||||
}
|
||||
}
|
||||
|
||||
return domains.ToSlice(), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package envoyconfig
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/config/envoyconfig/filemgr"
|
||||
"github.com/pomerium/pomerium/internal/testutil"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -113,7 +115,7 @@ func Test_buildMainHTTPConnectionManagerFilter(t *testing.T) {
|
|||
options := config.NewDefaultOptions()
|
||||
options.SkipXffAppend = true
|
||||
options.XffNumTrustedHops = 1
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(config.New(options), []string{"example.com"}, "*")
|
||||
filter, err := b.buildMainHTTPConnectionManagerFilter(&config.Config{Options: options}, []string{"example.com"})
|
||||
require.NoError(t, err)
|
||||
testutil.AssertProtoJSONEqual(t, `{
|
||||
"name": "envoy.filters.network.http_connection_manager",
|
||||
|
@ -724,6 +726,11 @@ func Test_buildDownstreamTLSContext(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_getAllDomains(t *testing.T) {
|
||||
cert, err := cryptutil.GenerateSelfSignedCertificate("*.unknown.example.com")
|
||||
require.NoError(t, err)
|
||||
certPEM, keyPEM, err := cryptutil.EncodeCertificate(cert)
|
||||
require.NoError(t, err)
|
||||
|
||||
options := &config.Options{
|
||||
Addr: "127.0.0.1:9000",
|
||||
GRPCAddr: "127.0.0.1:9001",
|
||||
|
@ -736,6 +743,8 @@ func Test_getAllDomains(t *testing.T) {
|
|||
{Source: &config.StringURL{URL: mustParseURL(t, "https://b.example.com")}},
|
||||
{Source: &config.StringURL{URL: mustParseURL(t, "https://c.example.com")}},
|
||||
},
|
||||
Cert: base64.StdEncoding.EncodeToString(certPEM),
|
||||
Key: base64.StdEncoding.EncodeToString(keyPEM),
|
||||
}
|
||||
cfg := config.New(options)
|
||||
t.Run("routable", func(t *testing.T) {
|
||||
|
@ -785,9 +794,10 @@ func Test_getAllDomains(t *testing.T) {
|
|||
})
|
||||
t.Run("tls", func(t *testing.T) {
|
||||
t.Run("http", func(t *testing.T) {
|
||||
actual, err := getAllTLSDomains(cfg, "127.0.0.1:9000")
|
||||
actual, err := getAllTLSDomains(&config.Config{Options: options}, "127.0.0.1:9000")
|
||||
require.NoError(t, err)
|
||||
expect := []string{
|
||||
"*.unknown.example.com",
|
||||
"a.example.com",
|
||||
"authenticate.example.com",
|
||||
"b.example.com",
|
||||
|
@ -796,9 +806,10 @@ func Test_getAllDomains(t *testing.T) {
|
|||
assert.Equal(t, expect, actual)
|
||||
})
|
||||
t.Run("grpc", func(t *testing.T) {
|
||||
actual, err := getAllTLSDomains(cfg, "127.0.0.1:9001")
|
||||
actual, err := getAllTLSDomains(&config.Config{Options: options}, "127.0.0.1:9001")
|
||||
require.NoError(t, err)
|
||||
expect := []string{
|
||||
"*.unknown.example.com",
|
||||
"authorize.example.com",
|
||||
"cache.example.com",
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ var luascripts struct {
|
|||
CleanUpstream string
|
||||
RemoveImpersonateHeaders string
|
||||
RewriteHeaders string
|
||||
FixMisdirected string
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -22,7 +21,6 @@ func init() {
|
|||
"luascripts/ext-authz-set-cookie.lua": &luascripts.ExtAuthzSetCookie,
|
||||
"luascripts/remove-impersonate-headers.lua": &luascripts.RemoveImpersonateHeaders,
|
||||
"luascripts/rewrite-headers.lua": &luascripts.RewriteHeaders,
|
||||
"luascripts/fix-misdirected.lua": &luascripts.FixMisdirected,
|
||||
}
|
||||
|
||||
err := fs.WalkDir(luaFS, "luascripts", func(p string, d fs.DirEntry, err error) error {
|
||||
|
|
|
@ -43,61 +43,6 @@ func TestLuaCleanUpstream(t *testing.T) {
|
|||
}, headers)
|
||||
}
|
||||
|
||||
func TestLuaFixMisdirected(t *testing.T) {
|
||||
t.Run("request", func(t *testing.T) {
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
||||
bs, err := luaFS.ReadFile("luascripts/fix-misdirected.lua")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = L.DoString(string(bs))
|
||||
require.NoError(t, err)
|
||||
|
||||
headers := map[string]string{
|
||||
":authority": "TEST",
|
||||
}
|
||||
metadata := map[string]interface{}{}
|
||||
dynamicMetadata := map[string]map[string]interface{}{}
|
||||
handle := newLuaResponseHandle(L, headers, metadata, dynamicMetadata)
|
||||
|
||||
err = L.CallByParam(lua.P{
|
||||
Fn: L.GetGlobal("envoy_on_request"),
|
||||
NRet: 0,
|
||||
Protect: true,
|
||||
}, handle)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, map[string]map[string]interface{}{
|
||||
"envoy.filters.http.lua": {
|
||||
"request.authority": "TEST",
|
||||
},
|
||||
}, dynamicMetadata)
|
||||
})
|
||||
t.Run("empty metadata", func(t *testing.T) {
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
||||
bs, err := luaFS.ReadFile("luascripts/fix-misdirected.lua")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = L.DoString(string(bs))
|
||||
require.NoError(t, err)
|
||||
|
||||
headers := map[string]string{}
|
||||
metadata := map[string]interface{}{}
|
||||
dynamicMetadata := map[string]map[string]interface{}{}
|
||||
handle := newLuaResponseHandle(L, headers, metadata, dynamicMetadata)
|
||||
|
||||
err = L.CallByParam(lua.P{
|
||||
Fn: L.GetGlobal("envoy_on_response"),
|
||||
NRet: 0,
|
||||
Protect: true,
|
||||
}, handle)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLuaRewriteHeaders(t *testing.T) {
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
function envoy_on_request(request_handle)
|
||||
local headers = request_handle:headers()
|
||||
local dynamic_meta = request_handle:streamInfo():dynamicMetadata()
|
||||
|
||||
local authority = headers:get(":authority")
|
||||
|
||||
-- store the authority header in the metadata so we can retrieve it in the response
|
||||
dynamic_meta:set("envoy.filters.http.lua", "request.authority", authority)
|
||||
end
|
||||
|
||||
function envoy_on_response(response_handle)
|
||||
local headers = response_handle:headers()
|
||||
local dynamic_meta = response_handle:streamInfo():dynamicMetadata()
|
||||
|
||||
local filter_meta = dynamic_meta:get("envoy.filters.http.lua")
|
||||
if filter_meta == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local authority = filter_meta["request.authority"]
|
||||
local expected_authority = "%s"
|
||||
|
||||
-- if we got a 404 (no route found) and the authority header doesn't match
|
||||
-- assume we've coalesced http/2 connections and return a 421
|
||||
if headers:get(":status") == "404" and authority ~= expected_authority then
|
||||
headers:replace(":status", "421")
|
||||
end
|
||||
end
|
|
@ -244,7 +244,7 @@ type Options struct {
|
|||
// these requests with this switch
|
||||
ForwardAuthURLString string `mapstructure:"forward_auth_url" yaml:"forward_auth_url,omitempty"`
|
||||
|
||||
// DataBrokerURLString is the routable destination of the databroker service's gRPC endpiont.
|
||||
// DataBrokerURLString is the routable destination of the databroker service's gRPC endpoint.
|
||||
DataBrokerURLString string `mapstructure:"databroker_service_url" yaml:"databroker_service_url,omitempty"`
|
||||
DataBrokerURLStrings []string `mapstructure:"databroker_service_urls" yaml:"databroker_service_urls,omitempty"`
|
||||
DataBrokerInternalURLString string `mapstructure:"databroker_internal_service_url" yaml:"databroker_internal_service_url,omitempty"`
|
||||
|
|
|
@ -17,7 +17,7 @@ echo "=> create our random shared-secret and cookie-secret keys as envars"
|
|||
kubectl create secret generic shared-secret --from-literal=shared-secret=$(head -c32 /dev/urandom | base64)
|
||||
kubectl create secret generic cookie-secret --from-literal=cookie-secret=$(head -c32 /dev/urandom | base64)
|
||||
|
||||
echo "=> initiliaze secrets for TLS wild card for service use"
|
||||
echo "=> initialize secrets for TLS wild card for service use"
|
||||
kubectl create secret generic certificate \
|
||||
--from-literal=certificate=$(base64 -i "$HOME/.acme.sh/*.corp.beyondperimeter.com_ecc/fullchain.cer")
|
||||
kubectl create secret generic certificate-key \
|
||||
|
|
28
go.mod
28
go.mod
|
@ -4,16 +4,16 @@ go 1.18
|
|||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.1
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2
|
||||
github.com/CAFxX/httpcompression v0.0.8
|
||||
github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20200406135749-5c268882acf0
|
||||
github.com/VictoriaMetrics/fastcache v1.10.0
|
||||
github.com/caddyserver/certmagic v0.16.3
|
||||
github.com/caddyserver/certmagic v0.17.0
|
||||
github.com/cenkalti/backoff/v4 v4.1.3
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/client9/misspell v0.3.4
|
||||
github.com/coreos/go-oidc/v3 v3.2.0
|
||||
github.com/coreos/go-oidc/v3 v3.3.0
|
||||
github.com/docker/docker v20.10.17+incompatible
|
||||
github.com/envoyproxy/go-control-plane v0.10.3-0.20220819153403-8a9be01c9575
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.7
|
||||
|
@ -34,7 +34,7 @@ require (
|
|||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/jackc/pgconn v1.13.0
|
||||
github.com/jackc/pgtype v1.12.0
|
||||
github.com/jackc/pgx/v4 v4.17.0
|
||||
github.com/jackc/pgx/v4 v4.17.2
|
||||
github.com/martinlindhe/base36 v1.1.1
|
||||
github.com/mholt/acmez v1.0.4
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
|
@ -52,8 +52,8 @@ require (
|
|||
github.com/prometheus/procfs v0.8.0
|
||||
github.com/rjeczalik/notify v0.9.3-0.20201210012515-e2a77dcc14cf
|
||||
github.com/rs/cors v1.8.2
|
||||
github.com/rs/zerolog v1.27.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.7
|
||||
github.com/rs/zerolog v1.28.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.8
|
||||
github.com/spf13/viper v1.12.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/tniswong/go.rfcx v0.0.0-20181019234604-07783c52761f
|
||||
|
@ -62,15 +62,15 @@ require (
|
|||
github.com/volatiletech/null/v9 v9.0.0
|
||||
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da
|
||||
go.opencensus.io v0.23.0
|
||||
go.uber.org/zap v1.22.0
|
||||
go.uber.org/zap v1.23.0
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
|
||||
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
|
||||
google.golang.org/api v0.93.0
|
||||
google.golang.org/api v0.94.0
|
||||
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f
|
||||
google.golang.org/grpc v1.48.0
|
||||
google.golang.org/grpc v1.49.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/auth0.v5 v5.21.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -130,7 +130,7 @@ require (
|
|||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-critic/go-critic v0.6.3 // indirect
|
||||
github.com/go-kit/log v0.2.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-toolsmith/astcast v1.0.0 // indirect
|
||||
|
@ -177,7 +177,7 @@ require (
|
|||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/puddle v1.2.1 // indirect
|
||||
github.com/jackc/puddle v1.3.0 // indirect
|
||||
github.com/jgautheron/goconst v1.5.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
|
@ -225,7 +225,7 @@ require (
|
|||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/statsd_exporter v0.21.0 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.22.7 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect
|
||||
github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
|
||||
|
|
62
go.sum
62
go.sum
|
@ -68,8 +68,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
|||
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.1 h1:oObVeKo2NxpdF/fIfrPsNj6K0Prg0R0mHM+uANlYMiM=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.1/go.mod h1:t9wvfitlUjGXG2IXAZsuFq26mDGid/JwCEXp+gTG/9U=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg=
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2 h1:YqE293IZrKtqPnpwDPH/lOqTWD/s3Iwabycam74JV3g=
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj3gsxcuytSqtH0dxSWW1RE=
|
||||
|
@ -177,6 +177,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
|
||||
github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=
|
||||
|
@ -244,8 +245,8 @@ github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY
|
|||
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
|
||||
github.com/bytecodealliance/wasmtime-go v0.36.0 h1:B6thr7RMM9xQmouBtUqm1RpkJjuLS37m6nxX+iwsQSc=
|
||||
github.com/bytecodealliance/wasmtime-go v0.36.0/go.mod h1:q320gUxqyI8yB+ZqRuaJOEnGkAnHh6WtJjMaT2CW4wI=
|
||||
github.com/caddyserver/certmagic v0.16.3 h1:1ZbiU7y5X0MnDjBTXywUbPMs/ScHbgCeeCy/LPh4IZk=
|
||||
github.com/caddyserver/certmagic v0.16.3/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
||||
github.com/caddyserver/certmagic v0.17.0 h1:AHHvvmv6SNcq0vK5BgCevQqYMV8GNprVk6FWZzx8d+Q=
|
||||
github.com/caddyserver/certmagic v0.17.0/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||
|
@ -407,8 +408,8 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka
|
|||
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc/v3 v3.2.0 h1:2eR2MGR7thBXSQ2YbODlF0fcmgtliLCfr9iX6RW11fc=
|
||||
github.com/coreos/go-oidc/v3 v3.2.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
||||
github.com/coreos/go-oidc/v3 v3.3.0 h1:Y1LV3mP+QT3MEycATZpAiwfyN+uxZLqVbAHJUuOJEe4=
|
||||
github.com/coreos/go-oidc/v3 v3.3.0/go.mod h1:eHUXhZtXPQLgEaDrOVTgwbgmz1xGOkJNye6h3zkD2Pw=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
|
@ -564,8 +565,9 @@ github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxF
|
|||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
|
@ -944,13 +946,13 @@ github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08
|
|||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.17.0 h1:Hsx+baY8/zU2WtPLQyZi8WbecgcsWEeyoK1jvg/WgIo=
|
||||
github.com/jackc/pgx/v4 v4.17.0/go.mod h1:Gd6RmOhtFLTu8cp/Fhq4kP195KrshxYJH3oW8AWJ1pw=
|
||||
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
||||
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw=
|
||||
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
|
@ -1340,9 +1342,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
|
@ -1359,8 +1361,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
|||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8=
|
||||
github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ=
|
||||
github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0=
|
||||
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
|
||||
github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
|
||||
|
@ -1394,11 +1396,11 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
|||
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
|
||||
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs=
|
||||
github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U=
|
||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
|
@ -1426,8 +1428,8 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
|||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
|
||||
github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4=
|
||||
github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
|
@ -1518,6 +1520,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
|
||||
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
|
||||
|
@ -1710,8 +1713,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
|
||||
go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
|
||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -1828,7 +1831,6 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
|
@ -1867,8 +1869,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4=
|
||||
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1889,8 +1891,8 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
|
|||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 h1:2o1E+E8TpNLklK9nHiPiK1uzIYrIHt+cQx3ynCwq9V8=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -2044,6 +2046,7 @@ golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -2233,8 +2236,8 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69
|
|||
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
|
||||
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
|
||||
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
|
||||
google.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M=
|
||||
google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
|
||||
google.golang.org/api v0.94.0 h1:KtKM9ru3nzQioV1HLlUf1cR7vMYJIpgls5VhAYQXIwA=
|
||||
google.golang.org/api v0.94.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -2381,8 +2384,9 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11
|
|||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
|
||||
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
|
|
@ -3,9 +3,11 @@ package autocert
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
"sync"
|
||||
|
@ -43,11 +45,12 @@ type Manager struct {
|
|||
src config.Source
|
||||
acmeTemplate certmagic.ACMEIssuer
|
||||
|
||||
mu sync.RWMutex
|
||||
config *config.Config
|
||||
certmagic *certmagic.Config
|
||||
acmeMgr *atomicutil.Value[*certmagic.ACMEIssuer]
|
||||
srv *http.Server
|
||||
mu sync.RWMutex
|
||||
config *config.Config
|
||||
certmagic *certmagic.Config
|
||||
acmeMgr *atomicutil.Value[*certmagic.ACMEIssuer]
|
||||
srv *http.Server
|
||||
acmeTLSALPNListener net.Listener
|
||||
|
||||
*ocspCache
|
||||
|
||||
|
@ -152,7 +155,6 @@ func (mgr *Manager) getCertMagicConfig(ctx context.Context, cfg *config.Config)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acmeMgr.DisableTLSALPNChallenge = true
|
||||
mgr.certmagic.Issuers = []certmagic.Issuer{acmeMgr}
|
||||
mgr.acmeMgr.Store(acmeMgr)
|
||||
|
||||
|
@ -207,6 +209,7 @@ func (mgr *Manager) renewConfigCerts(ctx context.Context) error {
|
|||
|
||||
cfg = mgr.src.GetConfig().Clone()
|
||||
mgr.updateServer(ctx, cfg)
|
||||
mgr.updateACMETLSALPNServer(ctx, cfg)
|
||||
if err := mgr.updateAutocert(ctx, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -224,6 +227,7 @@ func (mgr *Manager) update(ctx context.Context, cfg *config.Config) error {
|
|||
defer func() { mgr.config = cfg }()
|
||||
|
||||
mgr.updateServer(ctx, cfg)
|
||||
mgr.updateACMETLSALPNServer(ctx, cfg)
|
||||
return mgr.updateAutocert(ctx, cfg)
|
||||
}
|
||||
|
||||
|
@ -324,6 +328,34 @@ func (mgr *Manager) updateServer(ctx context.Context, cfg *config.Config) {
|
|||
mgr.srv = hsrv
|
||||
}
|
||||
|
||||
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
||||
addr := net.JoinHostPort("127.0.0.1", cfg.ACMETLSALPNPort)
|
||||
if mgr.acmeTLSALPNListener != nil {
|
||||
_ = mgr.acmeTLSALPNListener.Close()
|
||||
mgr.acmeTLSALPNListener = nil
|
||||
}
|
||||
|
||||
tlsConfig := mgr.certmagic.TLSConfig()
|
||||
ln, err := tls.Listen("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
log.Error(ctx).Err(err).Msg("failed to run acme tls alpn server")
|
||||
return
|
||||
}
|
||||
mgr.acmeTLSALPNListener = ln
|
||||
|
||||
go func() {
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if errors.Is(err, net.ErrClosed) {
|
||||
return
|
||||
} else if err != nil {
|
||||
continue
|
||||
}
|
||||
_ = conn.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (mgr *Manager) handleHTTPChallenge(w http.ResponseWriter, r *http.Request) bool {
|
||||
return mgr.acmeMgr.Load().HandleHTTPChallenge(w, r)
|
||||
}
|
||||
|
@ -347,6 +379,8 @@ func configureCertificateAuthority(acmeMgr *certmagic.ACMEIssuer, opts config.Au
|
|||
}
|
||||
if opts.Email != "" {
|
||||
acmeMgr.Email = opts.Email
|
||||
} else {
|
||||
acmeMgr.Email = " " // intentionally set to a space so that certmagic doesn't prompt for an email address
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -262,12 +262,15 @@ func TestConfig(t *testing.T) {
|
|||
var initialOCSPStaple []byte
|
||||
var certValidTime *time.Time
|
||||
mgr.OnConfigChange(ctx, func(ctx context.Context, cfg *config.Config) {
|
||||
log.Info(ctx).Msg("OnConfigChange")
|
||||
if len(cfg.AutoCertificates) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
cert := cfg.AutoCertificates[0]
|
||||
if initialOCSPStaple == nil {
|
||||
initialOCSPStaple = cert.OCSPStaple
|
||||
} else {
|
||||
if bytes.Compare(initialOCSPStaple, cert.OCSPStaple) != 0 {
|
||||
if !bytes.Equal(initialOCSPStaple, cert.OCSPStaple) {
|
||||
log.Info(ctx).Msg("OCSP updated")
|
||||
ocspUpdated <- true
|
||||
}
|
||||
|
@ -393,6 +396,7 @@ func Test_configureCertificateAuthority(t *testing.T) {
|
|||
expected: &certmagic.ACMEIssuer{
|
||||
Agreed: true,
|
||||
CA: certmagic.DefaultACME.CA,
|
||||
Email: " ",
|
||||
TestCA: certmagic.DefaultACME.TestCA,
|
||||
},
|
||||
wantErr: false,
|
||||
|
@ -409,6 +413,7 @@ func Test_configureCertificateAuthority(t *testing.T) {
|
|||
expected: &certmagic.ACMEIssuer{
|
||||
Agreed: true,
|
||||
CA: certmagic.DefaultACME.TestCA,
|
||||
Email: " ",
|
||||
TestCA: certmagic.DefaultACME.TestCA,
|
||||
},
|
||||
wantErr: false,
|
||||
|
|
|
@ -51,7 +51,7 @@ func RenderJSON(w http.ResponseWriter, code int, v interface{}) {
|
|||
// with the appropriate signature, HandlerFunc(f) is a
|
||||
// Handler that calls f.
|
||||
//
|
||||
// adapted from std library to suppport error wrapping
|
||||
// adapted from std library to support error wrapping
|
||||
type HandlerFunc func(http.ResponseWriter, *http.Request) error
|
||||
|
||||
// ServeHTTP calls f(w, r) error.
|
||||
|
|
|
@ -25,7 +25,7 @@ func SetHeaders(headers map[string]string) func(next http.Handler) http.Handler
|
|||
}
|
||||
|
||||
// ValidateSignature ensures the request is valid and has been signed with
|
||||
// the correspdoning client secret key
|
||||
// the corresponding client secret key
|
||||
func ValidateSignature(sharedKey []byte) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
|
|
|
@ -46,7 +46,7 @@ func (s *Sorted[T]) ForEach(callback func(element T) bool) {
|
|||
})
|
||||
}
|
||||
|
||||
// Has returns true if the elment is in the set.
|
||||
// Has returns true if the element is in the set.
|
||||
func (s *Sorted[T]) Has(element T) bool {
|
||||
return s.b.Has(element)
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ func Run(ctx context.Context, src config.Source) error {
|
|||
Str("outbound-port", src.GetConfig().OutboundPort).
|
||||
Str("metrics-port", src.GetConfig().MetricsPort).
|
||||
Str("debug-port", src.GetConfig().DebugPort).
|
||||
Str("acme-tls-alpn-port", src.GetConfig().ACMETLSALPNPort).
|
||||
Msg("server started")
|
||||
|
||||
// create envoy server
|
||||
|
|
|
@ -166,7 +166,7 @@ func EncodePrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
|
|||
func GenerateSelfSignedCertificate(domain string, configure ...func(*x509.Certificate)) (*tls.Certificate, error) {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to geneate private key: %w", err)
|
||||
return nil, fmt.Errorf("failed to generate private key: %w", err)
|
||||
}
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
|
@ -219,6 +219,21 @@ func GenerateSelfSignedCertificate(domain string, configure ...func(*x509.Certif
|
|||
return &cert, nil
|
||||
}
|
||||
|
||||
// EncodeCertificate encodes a TLS certificate into PEM compatible byte slices.
|
||||
// Returns `nil`, `nil` if there is an error marshaling the PKCS8 private key.
|
||||
func EncodeCertificate(cert *tls.Certificate) (pemCertificateBytes, pemKeyBytes []byte, err error) {
|
||||
if cert == nil || len(cert.Certificate) == 0 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
publicKeyBytes := cert.Certificate[0]
|
||||
privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(cert.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: publicKeyBytes}),
|
||||
pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateKeyBytes}), nil
|
||||
}
|
||||
|
||||
// ParsePEMCertificate parses a PEM encoded certificate block.
|
||||
func ParsePEMCertificate(raw []byte) (*x509.Certificate, error) {
|
||||
data := raw
|
||||
|
|
|
@ -165,3 +165,18 @@ func TestPrivateKeyMarshaling(t *testing.T) {
|
|||
t.Fatal("private key encoding did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeCertificate(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
cert, key, err := EncodeCertificate(nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, cert)
|
||||
assert.Nil(t, key)
|
||||
})
|
||||
t.Run("empty certificate", func(t *testing.T) {
|
||||
cert, key, err := EncodeCertificate(&tls.Certificate{})
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, cert)
|
||||
assert.Nil(t, key)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -63,6 +63,30 @@ func GetCertificateForDomain(certificates []tls.Certificate, domain string) (*tl
|
|||
return GenerateSelfSignedCertificate(domain)
|
||||
}
|
||||
|
||||
// GetCertificateDomains gets all the certificate's matching domain names.
|
||||
// Will return an empty slice if certificate is nil, empty, or x509 parsing fails.
|
||||
func GetCertificateDomains(cert *tls.Certificate) []string {
|
||||
if cert == nil || len(cert.Certificate) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
xcert, err := x509.ParseCertificate(cert.Certificate[0])
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var domains []string
|
||||
if xcert.Subject.CommonName != "" {
|
||||
domains = append(domains, xcert.Subject.CommonName)
|
||||
}
|
||||
for _, dnsName := range xcert.DNSNames {
|
||||
if dnsName != "" {
|
||||
domains = append(domains, dnsName)
|
||||
}
|
||||
}
|
||||
return domains
|
||||
}
|
||||
|
||||
func matchesDomain(cert *tls.Certificate, domain string) bool {
|
||||
if cert == nil || len(cert.Certificate) == 0 {
|
||||
return false
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetCertificateForDomain(t *testing.T) {
|
||||
|
@ -62,3 +63,9 @@ func TestGetCertificateForDomain(t *testing.T) {
|
|||
assert.NotNil(t, found)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCertificateDomains(t *testing.T) {
|
||||
cert, err := GenerateSelfSignedCertificate("www.example.com")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"www.example.com"}, GetCertificateDomains(cert))
|
||||
}
|
||||
|
|
|
@ -128,6 +128,17 @@ var migrations = []func(context.Context, pgx.Tx) error{
|
|||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
4: func(ctx context.Context, tx pgx.Tx) error {
|
||||
_, err := tx.Exec(ctx, `
|
||||
ALTER TABLE `+schemaName+`.`+recordChangesTableName+`
|
||||
ALTER data DROP NOT NULL
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ PATH="$PATH:$(go env GOPATH)/bin"
|
|||
export PATH
|
||||
|
||||
_project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/.."
|
||||
_envoy_version=1.23.0
|
||||
_envoy_version=1.23.1
|
||||
_dir="$_project_root/pkg/envoy/files"
|
||||
_target="${TARGET:-"$(go env GOOS)-$(go env GOARCH)"}"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue