mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Add a tool to extract MDM assets from a Fleet database (#20659)
This commit is contained in:
parent
ea354ef479
commit
650914519d
2 changed files with 135 additions and 0 deletions
30
tools/mdm/assets/README.md
Normal file
30
tools/mdm/assets/README.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
## MDM asset extractor
|
||||
|
||||
The MDM Asset Extractor is a tool designed to extract all MDM assets from a
|
||||
Fleet database. The assets are extracted unencrypted; hence, the key used for
|
||||
encrypting the assets must be provided.
|
||||
|
||||
### Usage
|
||||
|
||||
During development, a typical usage example would be:
|
||||
|
||||
```
|
||||
go run tools/mdm/assets/main.go -key=E6Ow1t2dbKARxEF6O9GFI3DDQRMROhI8 -dir=mdm_assets
|
||||
```
|
||||
|
||||
Supported flags are:
|
||||
|
||||
```
|
||||
-db-address string
|
||||
Address used to connect to the MySQL instance (default "localhost:3306")
|
||||
-db-name string
|
||||
Name of the database with the asset information in the MySQL instance (default "fleet")
|
||||
-db-password string
|
||||
Password used to connect to the MySQL instance (default "insecure")
|
||||
-db-user string
|
||||
Username used to connect to the MySQL instance (default "fleet")
|
||||
-dir string
|
||||
Directory to put the exported assets
|
||||
-key string
|
||||
Key used to encrypt the assets
|
||||
```
|
||||
105
tools/mdm/assets/main.go
Normal file
105
tools/mdm/assets/main.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
"github.com/fleetdm/fleet/v4/server/config"
|
||||
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
)
|
||||
|
||||
const (
|
||||
testUsername = "fleet"
|
||||
testPassword = "insecure"
|
||||
testAddress = "localhost:3306"
|
||||
testDatabase = "fleet"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flagKey := flag.String("key", "", "Key used to encrypt the assets")
|
||||
flagDir := flag.String("dir", "", "Directory to put the exported assets")
|
||||
flagDBUser := flag.String("db-user", testUsername, "Username used to connect to the MySQL instance")
|
||||
flagDBPass := flag.String("db-password", testPassword, "Password used to connect to the MySQL instance")
|
||||
flagDBAddress := flag.String("db-address", testAddress, "Address used to connect to the MySQL instance")
|
||||
flagDBName := flag.String("db-name", testDatabase, "Name of the database with the asset information in the MySQL instance")
|
||||
flag.Parse()
|
||||
|
||||
if *flagKey == "" {
|
||||
log.Fatal("-key flag is required")
|
||||
}
|
||||
|
||||
if *flagDir != "" {
|
||||
if err := os.MkdirAll(*flagDir, os.ModePerm); err != nil {
|
||||
log.Fatal("ensuring directory: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
db, err := sql.Open(
|
||||
"mysql",
|
||||
fmt.Sprintf("%s:%s@tcp(%s)/?multiStatements=true", testUsername, testPassword, testAddress),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("opening MySQL connection:", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
mysqlCfg := config.MysqlConfig{
|
||||
Username: *flagDBUser,
|
||||
Password: *flagDBPass,
|
||||
Address: *flagDBAddress,
|
||||
Database: *flagDBName,
|
||||
}
|
||||
ds, err := mysql.New(
|
||||
mysqlCfg,
|
||||
clock.NewMockClock(),
|
||||
mysql.LimitAttempts(1),
|
||||
mysql.WithFleetConfig(&config.FleetConfig{
|
||||
Server: config.ServerConfig{
|
||||
PrivateKey: *flagKey,
|
||||
},
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("creating datastore instance:", err)
|
||||
}
|
||||
defer ds.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
assets, err := ds.GetAllMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{
|
||||
fleet.MDMAssetCACert,
|
||||
fleet.MDMAssetCAKey,
|
||||
fleet.MDMAssetAPNSKey,
|
||||
fleet.MDMAssetAPNSCert,
|
||||
fleet.MDMAssetABMCert,
|
||||
fleet.MDMAssetABMKey,
|
||||
fleet.MDMAssetABMToken,
|
||||
fleet.MDMAssetSCEPChallenge,
|
||||
})
|
||||
if err != nil && !errors.Is(err, mysql.ErrPartialResult) {
|
||||
log.Fatal("retrieving assets from db:", err)
|
||||
}
|
||||
|
||||
for _, asset := range assets {
|
||||
path := filepath.Join(*flagDir, string(asset.Name))
|
||||
switch {
|
||||
case strings.Contains(path, "_key"):
|
||||
path = path + ".key"
|
||||
case strings.Contains(path, "_cert"):
|
||||
path = path + ".crt"
|
||||
}
|
||||
if err := os.WriteFile(path, asset.Value, 0600); err != nil {
|
||||
log.Fatal("writing asset:", err)
|
||||
}
|
||||
|
||||
log.Printf("wrote %s in %s", asset.Name, path)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue