Come eseguire un LaunchAgent che esegue uno script che causa errori a causa della protezione dell'integrità del sistema

4

Dopo l'aggiornamento a Mojave, il mio script di backup basato su rsync eseguito tramite un launch agent in ~ / Library / LaunchAgents, non poteva più leggere alcune directory in ~ / Library.

    
posta Channing Walton 01.10.2018 - 10:56
fonte

4 risposte

1

Ho trascorso alcune settimane a cercare di risolvere questo problema. Sono d'accordo sul fatto che la risposta attualmente accettata non sia realmente una soluzione: non è molto meglio che disabilitare completamente SIP.

La mia soluzione è una soluzione totalmente hacky, ma non richiede il whitelist% di% co_de interamente. Aggiornamento: soluzione alternativa meno invasiva qui sotto.

Panoramica

  1. Pacchetto di un'applicazione MacOS standard che esegue uno script (uno script di bash nel mio caso, che a sua volta configura un ambiente ed esegue un binario separato che richiede FDA)
  2. Aggiungi l'applicazione all'FDA
  3. Avvia l'applicazione aprendo l'app (facendo doppio clic via GUI o bash ma non utilizzando direttamente l'eseguibile archiviato in ad esempio open /path/to/MyApp.app )

Per il Passaggio 1, puoi facilmente impacchettare il tuo script come un'app utilizzando gli strumenti incorporati in MacOS come Automator.app o Script Editor o Platypus funziona anche.

I contenuti di esempio di questa app potrebbero essere un semplice AppleScript (in Script Editor) come:

on run
    do shell script "/usr/local/bin/bash /path/to/myscript.sh"
end run

Da Script Editor, utilizza il menu a discesa nel menu Salva per salvare come applicazione, quindi CHIUDI SCRIPT EDITOR .

Aggiungi questa app a Accesso completo al disco tramite MyApp.app/Contents/Resources/ - > System Preferences .

NB: se non hai salvato e chiuso Script Editor prima di aggiungere alla FDA come da istruzioni, sembra che qualche tipo di processo invisibile (salva sfondo automatizzato?) cambierà qualcosa (qualche tipo di timestamp o hash?) necessario per l'accesso completo al disco, che può causare errori intermittenti che sono stati un grosso mal di testa da capire. Quindi, se non l'hai fatto, rimuovi la tua app dalla FDA, salva e chiudi Script Editor, quindi aggiungi di nuovo all'FDA.

Per il tuo LaunchAgent, usa qualcosa come:

<string>/usr/bin/open</string>
<string>/path/to/MyApp.app</string>

Accesso root

Se il tuo script di backup ha bisogno di un accesso root (ad esempio per eseguire il backup dei file 0600 di proprietà di root), ti troverai per un altro set di soluzioni alternative, dal momento che Security & Privacy non sembra eseguire nulla come root (anche se tu specifica la chiave /usr/bin/open in un% di proprietà di root% co_de. (Sarei felice di aprirlo come una domanda separata se appropriato, dal momento che penso che la soluzione alternativa qui sotto lascia molto a desiderare.)

Un'opzione per questo è aggiungere UserName nel tuo AppleScript, ma ciò richiede la digitazione manuale della password, vanificando lo scopo del backup automatico. La mia soluzione attuale è:

  1. /Library/LaunchDaemons/ e concedo al mio utente non privilegiato la possibilità di eseguire il mio script di backup come sudo con NOPASSWD: (Ho anche specificato l'hash dello script per migliorare la sicurezza, ad esempio with administrator privileges )
  2. sudo visudo
  3. myuser ALL=(ALL) NOPASSWD: sha256:hashgoeshere /path/to/myscript.sh (4 quindi può ancora essere aggiunto a VCS)
  4. Cambia AppleScript in sudo chown root myscript.sh e salva nuovamente come MyApp.app
  5. Aggiungi MyApp.app all'FDA
  6. Cambia il mio script di avvio per aprire /path/to/MyApp.app
  7. Ricarica lo script launchd con launchctl e prova per accertarti che funzioni.

Ulteriori letture / dettagli:

UPDATE:

Dopo alcuni test preliminari, sembra che una soluzione leggermente meno hacky sia quella di compilare un binario (usando un linguaggio compilato) che chiama il tuo script bash. Aggiungi quel binario alla FDA e sembra funzionare. Aggiungi al% di proprietà di root% co_de e hai un modo per chiamarlo da sudo chmod 0740 myscript.sh senza tutta la pazzia di cui sopra.

Esempio di script in Vai:

// Runrestic provides a binary to run my restic backup script in MacOS Mojave with Full Disk Access
package main

import (
    "log"
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    ex, err := os.Executable()
    if err != nil {
        log.Fatal(err)
    }
    dir := filepath.Dir(ex)
    script := filepath.Join(dir, "restic-backup.sh")
    cmd := exec.Command("/usr/local/bin/bash", script)
    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
}

Per sicurezza, I do shell script "sudo -n /path/to/myscript.sh" e /Library/LaunchDaemons il binario risultante prima di aggiungere a root (anche se ammettiamo che un utente malintenzionato potrebbe semplicemente cambiare lo script bash che chiama se non fosse protetto).

    
risposta data 20.11.2018 - 17:06
fonte
3

Ho risolto questo come segue:

Consenti a Bash di avere accesso completo al disco

  1. Apri le preferenze
  2. Vai a Sicurezza e amp; Preferenze
  3. Seleziona Accesso completo al disco nell'elenco sulla sinistra
  4. Fai clic sul lucchetto per apportare modifiche
  5. Fai clic sul pulsante + nell'elenco a destra
  6. Vai alla radice del tuo HD
  7. Premere CMD + Maiusc +. per mostrare tutti gli oggetti nascosti
  8. Seleziona / bin / bash
  9. Esci dalle preferenze
  10. Riavvia il Mac (non sono sicuro che sia veramente necessario)

Esegui lo script correttamente

L'errore che ho fatto è che l'agente di lancio ha eseguito lo script in questo modo:

<key>ProgramArguments</key>
<array>
    <string>/Users/channing/bin/backup.sh</string>
</array>

Fai questo invece

<key>ProgramArguments</key>
<array>
    <string>/bin/bash</string>
    <string>/Users/channing/bin/backup.sh</string>
</array>

Riavvia il tuo agente:

launchctl unload ~/Library/LaunchAgents/backup.plist
launchctl load ~/Library/LaunchAgents/backup.plist

Rallegratevi.

    
risposta data 01.10.2018 - 10:56
fonte
2

Modifica:

Ho fatto ancora un po 'di test e non riesco più a dare a nessun normale accesso al disco completo del programma †. Ho scritto uno script di shell minimale [1], un binario minimo che chiama lo script di shell [2] e un binario che tenta di accedere a una posizione protetta [3]. Ho quindi fornito tutti questi script / eseguibili Accesso completo al disco e anche a /bin/sh per buona misura. Chiamare qualsiasi di questi direttamente tramite la shell mi dà un errore.

Poi sono incappato in una discussione sui forum di Apple dev su Regole per l'accesso completo al disco . Sembra che tu abbia bisogno di un pacchetto di app per fornire le autorizzazioni di Accesso completo al disco , il che spiega perché la concessione dell'accesso completo a un'app terminale consente a tale app di chiamare correttamente ls ~/Library/Mail .
Tuttavia, not spiega perché puoi concedere l'accesso a /bin/bash e quindi utilizzarlo nel tuo file launchd.plist per avere accesso completo al disco nello script della shell.

† semplice binario, non un pacchetto di app che vive in /Applications

[1] /Users/me/access-test.sh :

#!/bin/sh
ls /Users/me/Library/Mail

[2] /Users/me/access-test.c :

#include <unistd.h>

int main(int argc, char *const argv[]) {
    const char *file = "/Users/me/access-test.sh";
    return execvp(file, argv);
}

[3] /Users/me/access-test-2.c :

#include <stdio.h>
#include <dirent.h>

int main(void) {
    DIR *dp;
    struct dirent *ep;

    dp = opendir("/Users/me/Library/Mail");
    if (dp == NULL) {
        perror("Couldn't open directory");
        return 1;
    } else {
        while ((ep = readdir(dp))) {
            puts(ep->d_name);
        }
        closedir (dp);
    }
}

La mia risposta iniziale, che si è rivelata sbagliata:

Consenti allo script di backup l'accesso completo al disco.

Vai a Preferenze di sistema Sicurezza e amp; Privacy Privacy Accesso completo al disco . Quindi fai clic sul lucchetto

risposta data 30.10.2018 - 21:47
fonte
0

Sto riscontrando lo stesso problema con alcune copie attivate tramite launchd che usano idem. Provando anche alcuni test, vedo cosa posso minimamente aggiungere a Full Disk Access per farlo funzionare. Per gli script di bash mi chiedo se potresti essere in grado di creare un'applicazione AppleScript e usarla per concedere l'accesso e chiamare lo script. Potrebbe darti un modo per concedere l'accesso a quella specifica applicazione ed evitare di concedere l'accesso a tutto ciò che potresti eseguire attraverso bash

    
risposta data 12.10.2018 - 17:43
fonte

Leggi altre domande sui tag