Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to logging in mdmproxy #20201

Merged
merged 1 commit into from
Jul 17, 2024
Merged
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
67 changes: 64 additions & 3 deletions tools/mdm/migration/mdmproxy/mdmproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,21 @@ type mdmProxy struct {
// mutex is used to sync reads/updates to the migrateUDIDs and migratePercentage
mutex sync.RWMutex
// token is used to authenticate updates to the migrateUDIDs and migratePercentage
token string
token string
debug bool
logSkipped bool
}

func skipRequest(r *http.Request) bool {
// Throw out a bunch of common junk requests
return strings.Contains(r.URL.Path, ".php") ||
strings.Contains(r.URL.Path, ".git") ||
strings.Contains(r.URL.Path, ".yml") ||
strings.Contains(r.URL.Path, ".txt") ||
strings.Contains(r.URL.Path, ".py") ||
strings.Contains(r.URL.Path, "wp-") ||
strings.Contains(r.URL.Path, "private") ||
(r.URL.Path == "/" && r.Method == http.MethodPost)
Copy link
Member

Choose a reason for hiding this comment

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

if we find out this is not enough, we could also skip requests that don't contain Content-Type: application/x-apple-aspen-mdm-checkin or Content-Type: application/x-apple-aspen-mdm

}

func (m *mdmProxy) handleProxy(w http.ResponseWriter, r *http.Request) {
Expand All @@ -41,6 +55,14 @@ func (m *mdmProxy) handleProxy(w http.ResponseWriter, r *http.Request) {
return
}

if skipRequest(r) {
if m.logSkipped {
log.Printf("Forbidden skipped request: %s %s", r.Method, r.URL.String())
}
http.Error(w, "Forbidden", http.StatusForbidden)
return
}

// Send all SCEP requests to the existing server
if strings.Contains(r.URL.Path, "scep") {
log.Printf("%s %s -> Existing (SCEP)", r.Method, r.URL.String())
Expand All @@ -53,7 +75,20 @@ func (m *mdmProxy) handleProxy(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s -> Existing (API)", r.Method, r.URL.String())
m.existingProxy.ServeHTTP(w, r)
return
}

if r.URL.Path == "/" && r.Method == http.MethodGet {
log.Printf("%s %s -> Existing (Home)", r.Method, r.URL.String())
m.existingProxy.ServeHTTP(w, r)
return
}

if !strings.HasPrefix(r.URL.Path, "/mdm") {
if m.logSkipped {
log.Printf("Forbidden non-mdm request: %s %s", r.Method, r.URL.String())
}
http.Error(w, "Forbidden", http.StatusForbidden)
return
}

// Read the body of the request
Expand All @@ -78,6 +113,9 @@ func (m *mdmProxy) handleProxy(w http.ResponseWriter, r *http.Request) {
// Migrated UDIDs go to the Fleet server, otherwise requests go to the existing server.
if udid != "" && m.isUDIDMigrated(udid) {
log.Printf("%s %s (%s) -> Fleet", r.Method, r.URL.String(), udid)
if m.debug {
log.Printf("Fleet request: %s", string(body))
}
m.fleetProxy.ServeHTTP(w, r)
} else {
log.Printf("%s %s (%s) -> Existing", r.Method, r.URL.String(), udid)
Expand Down Expand Up @@ -238,12 +276,29 @@ func makeExistingProxy(existingURL, existingDNSName string) *httputil.ReversePro
return proxy
}

func makeFleetProxy(fleetURL string) *httputil.ReverseProxy {
func makeFleetProxy(fleetURL string, debug bool) *httputil.ReverseProxy {
targetURL, err := url.Parse(fleetURL)
if err != nil {
panic("failed to parse fleet-url: " + err.Error())
}
proxy := httputil.NewSingleHostReverseProxy(targetURL)
if debug {
proxy.ModifyResponse = func(r *http.Response) error {
b, err := io.ReadAll(r.Body)
if err != nil {
return err
}
err = r.Body.Close()
if err != nil {
return err
}
r.Body = io.NopCloser(bytes.NewReader(b))

log.Println("Fleet response: ", string(b))
Copy link
Member

Choose a reason for hiding this comment

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

should we print any extra information here? worried about the logs being harder to distinguish with multiple concurrent requests.

guessing this is just for staging testing with very few devices so not a concern, feel free to ignore if so


return nil
}
}

return proxy
}
Expand All @@ -256,6 +311,8 @@ func main() {
migratePercentage := flag.Int("migrate-percentage", 0, "Percentage of clients to migrate from existing MDM to Fleet")
migrateUDIDs := flag.String("migrate-udids", "", "Space/newline-delimited list of UDIDs to migrate always")
serverAddr := flag.String("server-address", ":8080", "Address for server to listen on")
debug := flag.Bool("debug", false, "Enable debug logging")
logSkipped := flag.Bool("log-skipped", false, "Log skipped requests (usually from web scanners)")
flag.Parse()

// Check required flags
Expand All @@ -278,6 +335,8 @@ func main() {
log.Printf("--existing-url set: %s", *existingURL)
log.Printf("--existing-hostname set: %s", *existingHostname)
log.Printf("--fleet-url set: %s", *fleetURL)
log.Printf("--debug set: %v", *debug)
log.Printf("--log-skipped set: %v", *logSkipped)
if *authToken != "" {
log.Printf("--auth-token set. Remote configuration enabled.")
} else {
Expand All @@ -292,7 +351,9 @@ func main() {
migratePercentage: *migratePercentage,
migrateUDIDs: udids,
existingProxy: makeExistingProxy(*existingURL, *existingHostname),
fleetProxy: makeFleetProxy(*fleetURL),
fleetProxy: makeFleetProxy(*fleetURL, *debug),
debug: *debug,
logSkipped: *logSkipped,
}

mux := http.NewServeMux()
Expand Down
Loading