mirror of
https://github.com/caddyserver/caddy.git
synced 2026-05-24 08:26:58 -04:00
Detect HTTPS interception (#1430)
* WIP: Implement HTTPS interception detection by Durumeric, et. al.
Special thanks to @FiloSottile for guidance with the custom listener.
* Add {{.IsMITM}} context action and {mitm} placeholder
* Improve MITM detection heuristics for Firefox and Edge
* Add tests for MITM detection heuristics
* Improve Safari heuristics for interception detection
* Read ClientHello during first Read() instead of during Accept()
As far as I can tell, reading the ClientHello during Accept() prevents
new connections from being accepted during the read. Since Read() should
be called in its own goroutine, this keeps Accept() non-blocking.
* Clean up MITM detection handler; make possible to close connection
* Use standard lib cipher suite values when possible
* Improve Edge heuristics and test cases
* Refactor MITM checking logic; add some debug statements for now
* Fix bug in MITM heuristic tests and actual heuristic code
* Fix gofmt
* Remove debug statements; preparing for merge
This commit is contained in:
@@ -47,6 +47,18 @@ func NewServer(addr string, group []*SiteConfig) (*Server, error) {
|
||||
}
|
||||
|
||||
s.Server.Handler = s // this is weird, but whatever
|
||||
tlsh := &tlsHandler{next: s.Server.Handler}
|
||||
s.Server.ConnState = func(c net.Conn, cs http.ConnState) {
|
||||
// when a connection closes or is hijacked, delete its entry
|
||||
// in the map, because we are done with it.
|
||||
if tlsh.listener != nil {
|
||||
if cs == http.StateHijacked || cs == http.StateClosed {
|
||||
tlsh.listener.helloInfosMu.Lock()
|
||||
delete(tlsh.listener.helloInfos, c.RemoteAddr().String())
|
||||
tlsh.listener.helloInfosMu.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable HTTP/2 if desired
|
||||
if !HTTP2 {
|
||||
@@ -75,6 +87,10 @@ func NewServer(addr string, group []*SiteConfig) (*Server, error) {
|
||||
s.Server.TLSConfig.NextProtos = []string{"h2"}
|
||||
}
|
||||
|
||||
if s.Server.TLSConfig != nil {
|
||||
s.Server.Handler = tlsh
|
||||
}
|
||||
|
||||
// Compile custom middleware for every site (enables virtual hosting)
|
||||
for _, site := range group {
|
||||
stack := Handler(staticfiles.FileServer{Root: http.Dir(site.Root), Hide: site.HiddenFiles})
|
||||
@@ -156,7 +172,10 @@ func (s *Server) Serve(ln net.Listener) error {
|
||||
// not implement the File() method we need for graceful restarts
|
||||
// on POSIX systems.
|
||||
// TODO: Is this ^ still relevant anymore? Maybe we can now that it's a net.Listener...
|
||||
ln = tls.NewListener(ln, s.Server.TLSConfig)
|
||||
ln = newTLSListener(ln, s.Server.TLSConfig, s.Server.ReadTimeout)
|
||||
if handler, ok := s.Server.Handler.(*tlsHandler); ok {
|
||||
handler.listener = ln.(*tlsHelloListener)
|
||||
}
|
||||
|
||||
// Rotate TLS session ticket keys
|
||||
s.tlsGovChan = caddytls.RotateSessionTicketKeys(s.Server.TLSConfig)
|
||||
|
||||
Reference in New Issue
Block a user