Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion handlers/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,26 @@ type Emitter interface {

func LogWrap(logger, accessLogger lager.Logger, loggableHandlerFunc LoggableHandlerFunc) http.HandlerFunc {
lagerDataFromReq := func(r *http.Request) lager.Data {
return lager.Data{
lagerData := lager.Data{
"method": r.Method,
"remote_addr": r.RemoteAddr,
"request": r.URL.String(),
}

if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
indexLeafCertConnectionIsVerifiedAgainst := 0 // see also https://github.com/golang/go/blob/e929fb78e47dc191a402d34ca949d2e0c67e31b8/src/crypto/tls/common.go#L281-L282
cert := r.TLS.PeerCertificates[indexLeafCertConnectionIsVerifiedAgainst]

lagerData["peer_cert_subject_common_name"] = cert.Subject.CommonName
lagerData["peer_cert_subject_organizational_unit"] = cert.Subject.OrganizationalUnit
lagerData["peer_cert_subject_organization"] = cert.Subject.Organization

lagerData["peer_cert_issuer_common_name"] = cert.Issuer.CommonName
lagerData["peer_cert_issuer_organizational_unit"] = cert.Issuer.OrganizationalUnit
lagerData["peer_cert_issuer_organization"] = cert.Issuer.Organization
Comment on lines +34 to +40
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can definitely discuss these key names (peer_cert_*), maybe you have a better idea

}

return lagerData
Comment on lines +30 to +43
Copy link
Copy Markdown
Contributor Author

@geigerj0 geigerj0 May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: this causes the LogWrap-middleware to always log peer cert information. however, the related log messages are being emitted with log level DEBUG and thus will more or less never be visible because no one runs this with DEBUG productively

} else {
return func(w http.ResponseWriter, r *http.Request) {
requestLog := logger.Session("request")
requestLog.Debug("serving", lagerDataFromReq(r))
defer requestLog.Debug("done", lagerDataFromReq(r))

}

if accessLogger != nil {
Expand Down
41 changes: 41 additions & 0 deletions handlers/middleware/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package middleware_test

import (
"code.cloudfoundry.org/bbs/cmd/bbs/config"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"net/http"
"time"

Expand Down Expand Up @@ -308,6 +311,44 @@ var _ = Describe("Test Middleware", func() {
Expect(accessLogger.Buffer()).To(gbytes.Say("remote_addr\":\"127.0.0.1:8080\""))
Expect(accessLogger.Buffer()).To(gbytes.Say("request\":\"http://example.com\""))
})

When("request has TLS peer certificates", func() {
BeforeEach(func() {
accessLogger = lagertest.NewTestLogger("")
accessLogger.RegisterSink(lager.NewWriterSink(GinkgoWriter, lager.INFO)) // peer cert information should be logged at INFO level
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is very important to test that the log messages appear also for INFO-logging because this is the level the access logger is being set up with:

accessLogger.RegisterSink(lager.NewWriterSink(file, lager.INFO))


handler := middleware.LogWrap(logger, accessLogger, loggableHandlerFunc)
req, err := http.NewRequest("", "", nil)
Expect(err).NotTo(HaveOccurred())
req.TLS = &tls.ConnectionState{
PeerCertificates: []*x509.Certificate{
{
Subject: pkix.Name{
CommonName: "subject-cn",
OrganizationalUnit: []string{"subject-ou"},
Organization: []string{"subject-o"},
},
Issuer: pkix.Name{
CommonName: "issuer-cn",
OrganizationalUnit: []string{"issuer-ou"},
Organization: []string{"issuer-o"},
},
},
},
}

handler.ServeHTTP(nil, req)
})

It("logs peer certificate information", func() {
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_subject_common_name\":\"subject-cn\""))
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_subject_organization\":\\[\"subject-o\"\\]"))
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_subject_organizational_unit\":\\[\"subject-ou\"\\]"))
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_issuer_common_name\":\"issuer-cn\""))
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_issuer_organization\":\\[\"issuer-o\"\\]"))
Expect(logger.Buffer()).To(gbytes.Say("peer_cert_issuer_organizational_unit\":\\[\"issuer-ou\"\\]"))
})
})
})
})
})
Expand Down