Tutorial

Novas atualizações e melhorias para a Macfleet.

Aviso importante

Os exemplos de código e scripts fornecidos nestes tutoriais são apenas para fins educacionais. A Macfleet não é responsável por quaisquer problemas, danos ou vulnerabilidades de segurança que possam surgir do uso, modificação ou implementação destes exemplos. Sempre revise e teste o código em um ambiente seguro antes de usá-lo em sistemas de produção.

Manage FileVault Encryption on macOS

FileVault provides full-disk encryption for macOS devices, protecting sensitive data even if the device is lost or stolen. This tutorial shows how to automate FileVault management across your MacFleet using command-line scripts.

Understanding FileVault

FileVault encrypts the entire startup disk using XTS-AES-128 encryption with a 256-bit key. Key benefits include:

  • Data Protection - Encrypts all data on the startup disk
  • Compliance - Meets enterprise security requirements
  • Performance - Hardware-accelerated encryption on modern Macs
  • Recovery - Multiple recovery options available

Basic FileVault Commands

Check FileVault Status

#!/bin/bash

# Check current FileVault status
fdesetup status

# Get detailed encryption information
diskutil apfs listCryptoUsers /

Enable FileVault

#!/bin/bash

# Basic FileVault enable command
sudo fdesetup enable --user "username" --password "password"

# Enable with specific keychain
sudo fdesetup enable --user "username" --password "password" --keychain /Library/Keychains/System.keychain

Disable FileVault

#!/bin/bash

# Basic FileVault disable command
sudo fdesetup disable --user "username" --password "password"

Enterprise FileVault Management Script

Complete script for managing FileVault across your MacFleet:

#!/bin/bash

# FileVault Management Script for MacFleet
# Compatible with macOS 10.14+

# Configuration
LOG_FILE="/var/log/filevault_management.log"
KEYCHAIN_PATH="/Library/Keychains/System.keychain"

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Function to get current user
get_current_user() {
    stat -f "%Su" /dev/console
}

# Function to check if user has secure token
check_secure_token() {
    local username="$1"
    
    if sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -q "ENABLED"; then
        return 0
    else
        return 1
    fi
}

# Function to check FileVault status
check_filevault_status() {
    local status
    status=$(fdesetup status)
    
    if echo "$status" | grep -q "FileVault is On"; then
        echo "enabled"
    elif echo "$status" | grep -q "FileVault is Off"; then
        echo "disabled"
    elif echo "$status" | grep -q "Encryption in progress"; then
        echo "encrypting"
    elif echo "$status" | grep -q "Decryption in progress"; then
        echo "decrypting"
    else
        echo "unknown"
    fi
}

# Function to get encryption progress
get_encryption_progress() {
    fdesetup status | grep -o '[0-9]\+%' | head -1
}

# Function to validate user credentials
validate_user_credentials() {
    local username="$1"
    local password="$2"
    
    # Check if user exists
    if ! id "$username" &>/dev/null; then
        log_message "✗ User does not exist: $username"
        return 1
    fi
    
    # Check if user has admin privileges
    if ! dsmemberutil checkmembership -U "$username" -G admin &>/dev/null; then
        log_message "✗ User is not an administrator: $username"
        return 1
    fi
    
    # Check if user has secure token
    if ! check_secure_token "$username"; then
        log_message "✗ User does not have secure token: $username"
        return 1
    fi
    
    # Verify password (basic check)
    if [[ -z "$password" ]]; then
        log_message "✗ Password cannot be empty for user: $username"
        return 1
    fi
    
    log_message "✓ User credentials validated: $username"
    return 0
}

# Function to enable FileVault
enable_filevault() {
    local username="$1"
    local password="$2"
    local force_enable="$3"
    
    log_message "Starting FileVault enablement for user: $username"
    
    # Check current status
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "enabled")
            log_message "! FileVault is already enabled"
            if [[ "$force_enable" != "true" ]]; then
                return 0
            fi
            ;;
        "encrypting")
            log_message "! FileVault encryption is already in progress"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Encryption progress: ${progress:-Unknown}"
            return 0
            ;;
        "decrypting")
            log_message "✗ Cannot enable FileVault while decryption is in progress"
            return 1
            ;;
    esac
    
    # Validate user credentials
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Enable FileVault
    log_message "Enabling FileVault..."
    
    if fdesetup enable -user "$username" -password "$password" -keychain "$KEYCHAIN_PATH" 2>/dev/null; then
        log_message "✓ FileVault enable command executed successfully"
        
        # Wait a moment and check status
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "enabled")
                log_message "✓ FileVault is now enabled"
                ;;
            "encrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ FileVault encryption started (${progress:-0%})"
                ;;
            *)
                log_message "! FileVault status unclear: $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Failed to enable FileVault"
        return 1
    fi
}

# Function to disable FileVault
disable_filevault() {
    local username="$1"
    local password="$2"
    local force_disable="$3"
    
    log_message "Starting FileVault disablement for user: $username"
    
    # Check current status
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "disabled")
            log_message "! FileVault is already disabled"
            if [[ "$force_disable" != "true" ]]; then
                return 0
            fi
            ;;
        "decrypting")
            log_message "! FileVault decryption is already in progress"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Decryption progress: ${progress:-Unknown}"
            return 0
            ;;
        "encrypting")
            log_message "✗ Cannot disable FileVault while encryption is in progress"
            return 1
            ;;
    esac
    
    # Validate user credentials
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Disable FileVault
    log_message "Disabling FileVault..."
    
    if fdesetup disable -user "$username" -password "$password" 2>/dev/null; then
        log_message "✓ FileVault disable command executed successfully"
        
        # Wait a moment and check status
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "disabled")
                log_message "✓ FileVault is now disabled"
                ;;
            "decrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ FileVault decryption started (${progress:-0%})"
                ;;
            *)
                log_message "! FileVault status unclear: $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Failed to disable FileVault"
        return 1
    fi
}

# Function to get system information
get_system_info() {
    log_message "=== System Information ==="
    log_message "Hostname: $(hostname)"
    log_message "macOS Version: $(sw_vers -productVersion)"
    log_message "Current User: $(get_current_user)"
    log_message "FileVault Status: $(check_filevault_status)"
    
    # Get FileVault users
    local fv_users
    fv_users=$(fdesetup list 2>/dev/null)
    if [[ -n "$fv_users" ]]; then
        log_message "FileVault Enabled Users:"
        echo "$fv_users" | while read -r line; do
            log_message "  $line"
        done
    fi
}

# Function to display usage
usage() {
    echo "Usage: $0 {enable|disable|status} [options]"
    echo ""
    echo "Commands:"
    echo "  enable    Enable FileVault"
    echo "  disable   Disable FileVault"
    echo "  status    Check FileVault status"
    echo ""
    echo "Options:"
    echo "  -u, --user USERNAME      Specify username"
    echo "  -p, --password PASSWORD  Specify password"
    echo "  -f, --force             Force operation even if already in desired state"
    echo "  -h, --help              Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 enable -u admin -p password123"
    echo "  $0 disable -u admin -p password123 -f"
    echo "  $0 status"
}

# Main function
main() {
    local command="$1"
    local username=""
    local password=""
    local force="false"
    
    # Parse arguments
    shift
    while [[ $# -gt 0 ]]; do
        case $1 in
            -u|--user)
                username="$2"
                shift 2
                ;;
            -p|--password)
                password="$2"
                shift 2
                ;;
            -f|--force)
                force="true"
                shift
                ;;
            -h|--help)
                usage
                exit 0
                ;;
            *)
                echo "Unknown option: $1"
                usage
                exit 1
                ;;
        esac
    done
    
    # Execute command
    case "$command" in
        "enable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Error: Username and password required for enable command"
                usage
                exit 1
            fi
            
            log_message "=== Starting FileVault Enable Operation ==="
            get_system_info
            
            if enable_filevault "$username" "$password" "$force"; then
                log_message "=== FileVault Enable Operation Completed Successfully ==="
                exit 0
            else
                log_message "=== FileVault Enable Operation Failed ==="
                exit 1
            fi
            ;;
        "disable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Error: Username and password required for disable command"
                usage
                exit 1
            fi
            
            log_message "=== Starting FileVault Disable Operation ==="
            get_system_info
            
            if disable_filevault "$username" "$password" "$force"; then
                log_message "=== FileVault Disable Operation Completed Successfully ==="
                exit 0
            else
                log_message "=== FileVault Disable Operation Failed ==="
                exit 1
            fi
            ;;
        "status")
            get_system_info
            exit 0
            ;;
        *)
            echo "Error: Invalid command: $command"
            usage
            exit 1
            ;;
    esac
}

# Execute main function
main "$@"

Quick FileVault Scripts

Simple Enable Script

#!/bin/bash

USERNAME="admin"
PASSWORD="your_password_here"

if fdesetup enable -user "$USERNAME" -password "$PASSWORD"; then
    echo "FileVault enabled successfully"
else
    echo "Failed to enable FileVault"
    exit 1
fi

Simple Status Check

#!/bin/bash

STATUS=$(fdesetup status)
echo "FileVault Status: $STATUS"

if echo "$STATUS" | grep -q "FileVault is On"; then
    echo "✓ FileVault is enabled"
    exit 0
elif echo "$STATUS" | grep -q "FileVault is Off"; then
    echo "✗ FileVault is disabled"
    exit 1
else
    echo "! FileVault status unclear"
    exit 2
fi

Recovery Key Management

Generate Personal Recovery Key

#!/bin/bash

# Enable FileVault with personal recovery key
sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -outputplist > /tmp/filevault_key.plist

# Extract recovery key
RECOVERY_KEY=$(grep -A1 "RecoveryKey" /tmp/filevault_key.plist | tail -1 | sed 's/.*<string>\(.*\)<\/string>.*/\1/')

echo "Recovery Key: $RECOVERY_KEY"

# Securely store recovery key
echo "$RECOVERY_KEY" | sudo tee /var/root/filevault_recovery_key.txt
sudo chmod 600 /var/root/filevault_recovery_key.txt

# Clean up
rm -f /tmp/filevault_key.plist

Enable Institutional Recovery Key

#!/bin/bash

# Create institutional recovery key
CERT_PATH="/path/to/institutional_certificate.cer"

if [[ -f "$CERT_PATH" ]]; then
    sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -certificate "$CERT_PATH"
    echo "FileVault enabled with institutional recovery key"
else
    echo "Institutional certificate not found: $CERT_PATH"
    exit 1
fi

Troubleshooting Common Issues

Fix Secure Token Issues

#!/bin/bash

USERNAME="admin"

# Grant secure token to user
sudo sysadminctl -secureTokenOn "$USERNAME" -password -

# Verify secure token
if sysadminctl -secureTokenStatus "$USERNAME" | grep -q "ENABLED"; then
    echo "✓ Secure token enabled for $USERNAME"
else
    echo "✗ Failed to enable secure token for $USERNAME"
fi

Handle Blank Password Error

#!/bin/bash

USERNAME="admin"

# Check if user has a password set
if dscl . -read "/Users/$USERNAME" AuthenticationAuthority | grep -q "No such key"; then
    echo "User $USERNAME has no password set"
    echo "Setting password..."
    sudo dscl . -passwd "/Users/$USERNAME" "" "new_password_here"
fi

Monitoring and Reporting

FileVault Status Report

#!/bin/bash

# Generate FileVault status report
REPORT_FILE="/tmp/filevault_report.txt"

{
    echo "=== FileVault Status Report ==="
    echo "Generated: $(date)"
    echo "Hostname: $(hostname)"
    echo ""
    
    echo "=== FileVault Status ==="
    fdesetup status
    echo ""
    
    echo "=== Enabled Users ==="
    fdesetup list
    echo ""
    
    echo "=== Secure Token Status ==="
    for user in $(dscl . -list /Users | grep -v '^_'); do
        if [[ "$user" != "daemon" ]] && [[ "$user" != "nobody" ]]; then
            token_status=$(sysadminctl -secureTokenStatus "$user" 2>/dev/null | grep -o "ENABLED\|DISABLED")
            echo "User: $user - Token: ${token_status:-UNKNOWN}"
        fi
    done
    
} > "$REPORT_FILE"

echo "Report generated: $REPORT_FILE"

Common Error Solutions

ErrorCauseSolution
"Blank password"User has no passwordSet password with dscl . -passwd
"Master keychain found"Keychain ambiguityAdd -keychain parameter
"Secure token required"User lacks secure tokenGrant token with sysadminctl
"Already encrypted"FileVault already onUse -force or check status first
"Encryption in progress"Concurrent operationWait for completion

Security Best Practices

  • Use strong passwords for FileVault-enabled accounts
  • Store recovery keys securely in enterprise key management
  • Test scripts on isolated devices before fleet deployment
  • Monitor encryption progress to ensure completion
  • Backup recovery keys before making changes
  • Validate user permissions before attempting operations

Performance Considerations

  • Initial encryption can take several hours
  • System performance may be impacted during encryption
  • Schedule operations during maintenance windows
  • Monitor disk space (encryption requires free space)
  • Consider SSD vs HDD performance differences

Important Notes

  • FileVault requires admin privileges and secure tokens
  • Recovery keys are essential for data recovery
  • Encryption/decryption cannot be interrupted safely
  • Test all scripts thoroughly before production use
  • Always have a backup recovery plan

Tutorial

Novas atualizações e melhorias para a Macfleet.

Configurando um Runner do GitHub Actions em um Mac Mini (Apple Silicon)

Runner do GitHub Actions

GitHub Actions é uma plataforma poderosa de CI/CD que permite automatizar seus fluxos de trabalho de desenvolvimento de software. Embora o GitHub ofereça runners hospedados, runners auto-hospedados fornecem maior controle e personalização para sua configuração de CI/CD. Este tutorial o guia através da configuração e conexão de um runner auto-hospedado em um Mac mini para executar pipelines do macOS.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Um Mac mini (registre-se no Macfleet)
  • Um repositório GitHub com direitos de administrador
  • Um gerenciador de pacotes instalado (preferencialmente Homebrew)
  • Git instalado em seu sistema

Passo 1: Criar uma Conta de Usuário Dedicada

Primeiro, crie uma conta de usuário dedicada para o runner do GitHub Actions:

# Criar a conta de usuário 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Definir a senha para o usuário
sudo dscl . -passwd /Users/gh-runner sua_senha

# Adicionar 'gh-runner' ao grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Mude para a nova conta de usuário:

su gh-runner

Passo 2: Instalar Software Necessário

Instale Git e Rosetta 2 (se estiver usando Apple Silicon):

# Instalar Git se ainda não estiver instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Passo 3: Configurar o Runner do GitHub Actions

  1. Vá para seu repositório GitHub
  2. Navegue para Configurações > Actions > Runners

Runner do GitHub Actions

  1. Clique em "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecione macOS como imagem do runner e ARM64 como arquitetura
  3. Siga os comandos fornecidos para baixar e configurar o runner

Runner do GitHub Actions

Crie um arquivo .env no diretório _work do runner:

# arquivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Execute o script run.sh em seu diretório do runner para completar a configuração.
  2. Verifique se o runner está ativo e ouvindo por trabalhos no terminal e verifique as configurações do repositório GitHub para a associação do runner e status Idle.

Runner do GitHub Actions

Passo 4: Configurar Sudoers (Opcional)

Se suas ações requerem privilégios de root, configure o arquivo sudoers:

sudo visudo

Adicione a seguinte linha:

gh-runner ALL=(ALL) NOPASSWD: ALL

Passo 5: Usar o Runner em Fluxos de Trabalho

Configure seu fluxo de trabalho do GitHub Actions para usar o runner auto-hospedado:

name: Fluxo de trabalho de exemplo

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

O runner está autenticado em seu repositório e rotulado com self-hosted, macOS, e ARM64. Use-o em seus fluxos de trabalho especificando estes rótulos no campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Melhores Práticas

  • Mantenha seu software do runner atualizado
  • Monitore regularmente os logs do runner para problemas
  • Use rótulos específicos para diferentes tipos de runners
  • Implemente medidas de segurança adequadas
  • Considere usar múltiplos runners para balanceamento de carga

Solução de Problemas

Problemas comuns e soluções:

  1. Runner não conectando:

    • Verifique conectividade de rede
    • Verifique validade do token GitHub
    • Certifique-se de permissões adequadas
  2. Falhas de build:

    • Verifique instalação do Xcode
    • Verifique dependências necessárias
    • Revise logs do fluxo de trabalho
  3. Problemas de permissão:

    • Verifique permissões do usuário
    • Verifique configuração sudoers
    • Revise permissões do sistema de arquivos

Conclusão

Agora você tem um runner auto-hospedado do GitHub Actions configurado em seu Mac mini. Esta configuração fornece mais controle sobre seu ambiente CI/CD e permite executar fluxos de trabalho específicos do macOS de forma eficiente.

Lembre-se de manter regularmente seu runner e mantê-lo atualizado com os patches de segurança e versões de software mais recentes.

Aplicativo Nativo

Aplicativo nativo do Macfleet

Guia de Instalação do Macfleet

Macfleet é uma solução poderosa de gerenciamento de frota projetada especificamente para ambientes Mac Mini hospedados na nuvem. Como provedor de hospedagem na nuvem Mac Mini, você pode usar o Macfleet para monitorar, gerenciar e otimizar toda sua frota de instâncias Mac virtualizadas.

Este guia de instalação o conduzirá através da configuração do monitoramento do Macfleet em sistemas macOS, Windows e Linux para garantir supervisão abrangente de sua infraestrutura na nuvem.

🍎 macOS

  • Baixe o arquivo .dmg para Mac aqui
  • Clique duas vezes no arquivo .dmg baixado
  • Arraste o aplicativo Macfleet para a pasta Aplicativos
  • Ejete o arquivo .dmg
  • Abra Preferências do Sistema > Segurança e Privacidade
    • Aba Privacidade > Acessibilidade
    • Marque Macfleet para permitir monitoramento
  • Inicie o Macfleet a partir de Aplicativos
  • O rastreamento inicia automaticamente

🪟 Windows

  • Baixe o arquivo .exe para Windows aqui
  • Clique com o botão direito no arquivo .exe > "Executar como administrador"
  • Siga o assistente de instalação
  • Aceite os termos e condições
  • Permita no Windows Defender se solicitado
  • Conceda permissões de monitoramento de aplicativo
  • Inicie o Macfleet a partir do Menu Iniciar
  • O aplicativo começa o rastreamento automaticamente

🐧 Linux

  • Baixe o pacote .deb (Ubuntu/Debian) ou .rpm (CentOS/RHEL) aqui
  • Instale usando seu gerenciador de pacotes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permita permissões de acesso X11 se solicitado
  • Adicione o usuário aos grupos apropriados se necessário
  • Inicie o Macfleet a partir do menu Aplicativos
  • O aplicativo começa o rastreamento automaticamente

Nota: Após a instalação em todos os sistemas, faça login com suas credenciais do Macfleet para sincronizar dados com seu painel de controle.