---
name: macos-security-hardening
description: Аудит безопасности и усиление защиты macOS — FileVault, SSH, файрволл, LaunchAgents, сетевые сервисы.
version: 2.0
author: Hermes
tags: [macos, security, hardening, filevault, ssh, firewall]
---

## Когда использовать

Когда пользователь просит:
- «проверь безопасность мака/системы»
- «усили защиту macOS»
- «сделай аудит безопасности»
- «настрой SSH/FileVault/файрволл»

## Порядок аудита

### 1. FileVault (шифрование диска)
```bash
fdesetup status
```
Если выключен — включить через `fdesetup enable -inputplist`.

**Важно:** `sudo` требует пароль в macOS. Использовать паттерн с pipe-ом пароля:
```bash
echo 'PASSWORD' | sudo -S bash -c 'fdesetup enable -inputplist < /tmp/fv_enable.plist'
```

plist-файл для включения:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Username</key>
    <string>USERNAME</string>
    <key>Password</key>
    <string>PASSWORD</string>
</dict>
</plist>
```

**Не наследуй stdin heredoc внутри команды с `sudo -S`** — канал пароля и heredoc конфликтуют. Пиши plist в файл отдельно.

Сохрани recovery key из вывода и передай пользователю.

### 2. Файрволл
```bash
# Статус
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
# Stealth mode
/usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode
# Список приложений с правилами
/usr/libexec/ApplicationFirewall/socketfilterfw --listapps
# Удалить правило
/usr/libexec/ApplicationFirewall/socketfilterfw --remove /path/to/app
```

**Типичный мусор в правилах:** MySQL из старой установки (.lbm), Booking Manager, старые геймерские приложения. Удалить без жалости.

### 3. Запущенные сервисы (LaunchAgents/Daemons)
```bash
ls ~/Library/LaunchAgents/
ls /Library/LaunchAgents/
ls /Library/LaunchDaemons/
# Просмотр содержимого всех plist
for f in /Library/LaunchDaemons/*.plist /Library/LaunchAgents/*.plist ~/Library/LaunchAgents/*.plist; do echo "=== $f ==="; plutil -p "$f" 2>/dev/null | head -20; echo; done
```

**Обрати внимание на устаревший софт:**
- Adobe Flash (`com.adobe.fpsaud`) — Flash умер, демон можно удалить
- Google Earth updater — если не пользуется
- Устаревшие VPN-клиенты

Удаление демона:
```bash
echo 'PASSWORD' | sudo -S launchctl unload -w /Library/LaunchDaemons/com.adobe.fpsaud.plist
echo 'PASSWORD' | sudo -S rm -f /Library/LaunchDaemons/com.adobe.fpsaud.plist
echo 'PASSWORD' | sudo -S rm -rf "/Library/Application Support/Adobe/Flash Player Install Manager"
```

### 4. Открытые порты и сетевые сервисы
```bash
# TCP слушающие порты
netstat -an -p tcp 2>/dev/null | grep LISTEN
# Процессы на портах
lsof -iTCP -sTCP:LISTEN -P -n 2>/dev/null
# Проверка конкретного порта
lsof -i :PORT -P -n 2>/dev/null
```

**Типичные легаси-порты на старых Mac:**
- 1110 — Chrome (internal, localhost-only) — норм
- 51453 — rapportd (AirDrop/Nearby) — системный
- 9993 — ZeroTier — если стоит
- 3283 — ARDAgent (Remote Management) — отключать через kickstart

### 5. SSH-конфигурация
Проверить `/etc/ssh/sshd_config`:
- `PasswordAuthentication no` — запретить парольный вход
- `ChallengeResponseAuthentication no` 
- `PermitRootLogin no` — запретить root
- `PubkeyAuthentication yes` — включить ключи

**Редактирование:** используй `sed` с sudo, т.к. инструмент patch отказывается писать в `/etc/ssh/sshd_config`:
```bash
echo 'PASSWORD' | sudo -S sed -i '' -e 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
```

**Рестарт SSH:**
```bash
echo 'PASSWORD' | sudo -S launchctl unload /System/Library/LaunchDaemons/ssh.plist
echo 'PASSWORD' | sudo -S launchctl load -w /System/Library/LaunchDaemons/ssh.plist
```

**Перед отключением пароля убедись, что SSH-ключи есть:**
```bash
ls -la ~/.ssh/
```

### 6. Пользователи и привилегии
```bash
# Локальные пользователи (UID >= 500)
dscl . list /Users UniqueID
# Полная информация о пользователе
dscl . -read /Users/UserName RealName NFSHomeDirectory PrimaryGroupID
# Проверка гостевого аккаунта
dscl . read /Users/Guest
# SUID-бинарники (потенциально опасные)
find / -perm -4000 -type f 2>/dev/null
```

**Удаление ненужного пользователя:**
```bash
echo 'PASSWORD' | sudo -S dscl . -delete /Users/UserName
```
Если есть домашняя папка — удалить отдельно:
```bash
echo 'PASSWORD' | sudo -S rm -rf /Users/UserName
```

**Важно:** не удалять пользователей с данными без согласия владельца.

### 7. Screen Sharing / Remote Management
Отключение:
```bash
echo 'PASSWORD' | sudo -S /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -configure -access -off
```
Проверить, что порты 5900 и 3283 закрылись:
```bash
netstat -an -p tcp 2>/dev/null | grep -E "5900|3283" | grep LISTEN  # должно быть пусто
```

### 8. SMB / File Sharing (порт 445)

Если не используется — отключить:
```bash
echo 'PASSWORD' | sudo -S launchctl unload -w /System/Library/LaunchDaemons/com.apple.smbd.plist
echo 'PASSWORD' | sudo -S launchctl disable system/com.apple.smbd
```
Проверить, что порт 445 больше не слушает:
```bash
netstat -an -p tcp 2>/dev/null | grep 445 | grep LISTEN  # должно быть пусто
```

### 9. Системные проверки
```bash
# SIP
csrutil status
# Gatekeeper
spctl --status
# Версия macOS
sw_vers
```

## Типичные проблемы и решения

### sudo требует пароль в терминале
В macOS нет passwordless sudo по умолчанию. Используй `echo 'PASSWORD' | sudo -S COMMAND`.
**Предупреждение:** пароль пользователя запрашивается однократно, не сохранять в память/скиллы. Использовать `-S` флаг.

### fdesetup enable не работает с heredoc
НЕЛЬЗЯ:
```bash
echo 'PASSWORD' | sudo -S fdesetup enable -inputplist << 'EOF'  # ✗ КОНФЛИКТ STDIN
```
НАДО:
```bash
# 1. Создать plist-файл
cat > /tmp/fv_enable.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Username</key>
    <string>USERNAME</string>
    <key>Password</key>
    <string>PASSWORD</string>
</dict>
</plist>
EOF
# 2. Запустить с перенаправлением из файла
echo 'PASSWORD' | sudo -S bash -c 'fdesetup enable -inputplist < /tmp/fv_enable.plist'
```

### Patch tool отказывается писать в /etc/ssh/
Используй `sed -i ''` через sudo как указано выше.

## После выполнения

1. Перепроверить listen-порты — должно стать меньше
2. Проверить `fdesetup status` (должно быть On, шифрование может идти в фоне)
3. Проверить файрволл — удалённые приложения не должны быть в списке
4. Дать пользователю recovery key от FileVault — **обязательно** сохранить вне Mac
5. Проверить, что SSH-ключи есть в `~/.ssh/` — иначе можно потерять доступ
