Add Joplin, old Mac, and Fedora WiFi runbooks; simplify JA3 Whisky scripts and hotspot recovery.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,111 +1,110 @@
|
||||
# Emergency: сеть после смены хотспота (macOS)
|
||||
|
||||
Симптом: **отключили Mac от Wi‑Fi / переподключились к другому хотспоту — «интернета нет», помогает только перезагрузка.**
|
||||
|
||||
Документ описывает **проверенную на машине причину** в вашей конфигурации, **ручное восстановление без перезагрузки** и **скрипт** из репозитория.
|
||||
# Emergency: сеть после переподключения хотспота (macOS)
|
||||
|
||||
---
|
||||
|
||||
## Причина (точная по конфигурации)
|
||||
## Одна команда (из любой папки)
|
||||
|
||||
На macOS в **Системных настройках → Сеть → Wi‑Fi → Подробнее → Прокси** часто включён **автоматический прокси (PAC)** с URL вида **`http://localhost:1089/proxy.pac`** (см. [PROXY_GUIDE.md](./PROXY_GUIDE.md) → раздел про системный PAC).
|
||||
```bash
|
||||
bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
```
|
||||
|
||||
Проверка на рабочей машине (2026): **PAC для сервиса Wi‑Fi включён (Enabled: Yes)**, при этом **на порту 1089 нет процесса**, который отдаёт `proxy.pac` — соединение к `127.0.0.1:1089` отклоняется.
|
||||
Запросит **пароль sudo**, затем: PAC/SOCKS off → **DHCP** → `ifconfig down` → **`route -n flush`** → DNS → DHCP → **Joplin alias `*.100`**.
|
||||
|
||||
В таком состоянии:
|
||||
Диагностика:
|
||||
|
||||
1. Система и часть приложений **сначала** должны получить PAC с localhost; при недоступном URL поведение **нестабильно** (часть трафика «в никуда», таймауты).
|
||||
2. При **смене хотспота** меняются шлюз, DNS, часто появляется **captive portal**; страница входа может **не открыться**, пока PAC мешает или DNS закеширован со старой сети.
|
||||
3. **Перезагрузка** «лечит», потому что заново поднимаются **configd**, **mDNSResponder**, порядок инициализации Wi‑Fi и иногда снова стартует локальный PAC‑сервер (Clash / Surge / свой сервис на 1089).
|
||||
|
||||
Дополнительные усилители сбоя (проверять при `status`):
|
||||
|
||||
- **Системный SOCKS** на `127.0.0.1:1080` (Shadowsocks и т.д.) — если включён, а клиент не слушает порт, трафик через системный прокси тоже падает.
|
||||
- **VPN / туннели** с политикой «весь трафик» — после смены сети маршруты могут остаться битые до отключения VPN.
|
||||
|
||||
**SOCKS Telegram (1081) и SSH‑туннели сами по себе не отключают Wi‑Fi** — они приложенческие. Проблема класса «всё мёртво до ребута» у вас с высокой вероятностью — **системный PAC/SOCKS на localhost без живого сервиса + кэш DNS / состояние Wi‑Fi**.
|
||||
```bash
|
||||
bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Быстро: один скрипт (рекомендуется)
|
||||
## RCA (почему старый `recover` не помогал)
|
||||
|
||||
Из корня репозитория `local_machine`:
|
||||
### 1. Ядерный сброс не выполнялся
|
||||
|
||||
```bash
|
||||
chmod +x ./docs/connectivity/scripts/macos-hotspot-network-recover.sh
|
||||
./docs/connectivity/scripts/macos-hotspot-network-recover.sh status
|
||||
./docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
Скрипт проверял `sudo -n` (passwordless). Без NOPASSWD в sudoers он **пропускал** `route flush` и делал только toggle Wi‑Fi — **недостаточно** при ARP `REJECT`.
|
||||
|
||||
Ручная «ядерная кнопка» работала, потому что вы вводили пароль и реально сбрасывали маршруты.
|
||||
|
||||
**Исправлено:** `recover` всегда вызывает `sudo` с запросом пароля.
|
||||
|
||||
### 2. Manual IPv4 на Wi‑Fi (Joplin) ломал маршрут
|
||||
|
||||
`/var/log/wifi.log` при reconnect:
|
||||
|
||||
```
|
||||
IP Address: 10.219.227.100
|
||||
Default Gateway IP Address: 10.219.227.39
|
||||
No Router MAC Address
|
||||
ROUTER_MAC_ADDR = 0x000000000000
|
||||
```
|
||||
|
||||
`recover` делает: **выключает PAC** (те же сервисы, что и `macos-system-pac.sh`), **выключает системный SOCKS на Wi‑Fi**, по возможности **сбрасывает DNS** и **кратко перезапускает Wi‑Fi** и DHCP.
|
||||
В prefs оставался шлюз `10.219.227.39`, хотспот уже в `10.36.136.x` → `ping` → `Host is down`, `curl` мёртв.
|
||||
|
||||
Если скрипт пишет, что нет `sudo` без пароля — выполните вручную команды из раздела «Вручную» ниже.
|
||||
**Исправлено:** Wi‑Fi **только DHCP**; Joplin — **alias** `<подсеть>.100` на `en0` (не трогает default route). См. [apps/joplin/STABLE_SETUP.md](./apps/joplin/STABLE_SETUP.md).
|
||||
|
||||
После появления интернета, если вам снова нужен PAC:
|
||||
### 3. PAC / SOCKS (вторично)
|
||||
|
||||
```bash
|
||||
./docs/connectivity/scripts/macos-pac-on.sh
|
||||
```
|
||||
|
||||
Только **после** того как процесс на **1089** реально запущен и отдаёт `proxy.pac`.
|
||||
PAC на `:1089` без сервера усиливает сбои, но **не объясняет** `ping 8.8.8.8 → No route to host`.
|
||||
|
||||
---
|
||||
|
||||
## Вручную (без скрипта)
|
||||
## Что делает `recover` сейчас
|
||||
|
||||
### 1. Отключить автоматический PAC
|
||||
| Шаг | Действие |
|
||||
|-----|----------|
|
||||
| 1 | PAC off |
|
||||
| 2 | SOCKS off |
|
||||
| 3 | `networksetup -setdhcp Wi-Fi` (снимает Manual) |
|
||||
| 4 | `sudo ifconfig en0 down` |
|
||||
| 5 | `sudo route -n flush` |
|
||||
| 6 | DNS flush + `ifconfig up` + `ipconfig DHCP` |
|
||||
| 7 | Ждёт gateway (до 30 с) |
|
||||
| 8 | `ifconfig en0 alias <subnet>.100` для Joplin |
|
||||
|
||||
**GUI:** Системные настройки → Сеть → Wi‑Fi → Подробнее → Прокси → снять **«Автоматическая настройка прокси (PAC)»**.
|
||||
---
|
||||
|
||||
**CLI** (из репо):
|
||||
|
||||
```bash
|
||||
./docs/connectivity/scripts/macos-pac-off.sh
|
||||
./docs/connectivity/scripts/macos-system-pac.sh status
|
||||
```
|
||||
|
||||
### 2. Отключить системный SOCKS (если включали для Shadowsocks)
|
||||
|
||||
```bash
|
||||
networksetup -setsocksfirewallproxystate "Wi-Fi" off
|
||||
networksetup -getsocksfirewallproxy "Wi-Fi"
|
||||
```
|
||||
|
||||
### 3. Сброс DNS
|
||||
## Ядерная кнопка (если скрипт недоступен)
|
||||
|
||||
```bash
|
||||
sudo networksetup -setdhcp "Wi-Fi"
|
||||
sudo ifconfig en0 down
|
||||
sudo route -n flush
|
||||
sudo dscacheutil -flushcache
|
||||
sudo killall -HUP mDNSResponder
|
||||
```
|
||||
|
||||
### 4. Обновить DHCP и «пнуть» Wi‑Fi
|
||||
|
||||
Узнать интерфейс Wi‑Fi (часто `en0`):
|
||||
|
||||
```bash
|
||||
networksetup -listallhardwareports | sed -n '/Hardware Port: Wi-Fi/,/Ethernet Address/p'
|
||||
```
|
||||
|
||||
Дальше (подставьте свой `Device`, например `en0`):
|
||||
|
||||
```bash
|
||||
sudo ifconfig en0 up
|
||||
sudo ipconfig set en0 DHCP
|
||||
networksetup -setairportpower en0 off
|
||||
sleep 2
|
||||
networksetup -setairportpower en0 on
|
||||
bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
```
|
||||
|
||||
### 5. Captive portal
|
||||
|
||||
Откройте в браузере **`http://captive.apple.com`** или **`http://neverssl.com`** — должна открыться страница входа в сеть отели/кафе.
|
||||
|
||||
---
|
||||
|
||||
## Профилактика (архитектурно)
|
||||
## Диагностика
|
||||
|
||||
1. **Не держать PAC включённым**, если сервис на **1089** не запущен: сначала поднять Clash/Surge/свой HTTP‑сервер с PAC, **затем** `macos-pac-on.sh`.
|
||||
2. Перед подключением к **чужому хотспоту** с обязательной страницей входа — **временно PAC off** (`macos-pac-off.sh`), залогиниться в сеть, затем при необходимости снова **on**.
|
||||
3. Разнести роли: **глобальный PAC** — только когда стабильно есть локальный конфиг‑сервер; для «чистого» интернета в дороге — **PAC выключен**, прокси только в приложениях (Telegram SOCKS **1081**, Cursor **10809** и т.д.) — см. [TELEGRAM_GUIDE.md](./TELEGRAM_GUIDE.md), [PROXY_EMERGENCY.md](./PROXY_EMERGENCY.md).
|
||||
```bash
|
||||
networksetup -getinfo "Wi-Fi"
|
||||
ifconfig en0 | grep inet
|
||||
route -n get default
|
||||
bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh status
|
||||
./docs/apps/joplin/scripts/joplin-webdav-status.sh
|
||||
grep -E 'Router MAC|No Router' /var/log/wifi.log | tail -5
|
||||
```
|
||||
|
||||
| Признак | Причина |
|
||||
|---------|---------|
|
||||
| Manual + другая подсеть в gateway | Старый Joplin static |
|
||||
| `No Router MAC` в wifi.log | ARP на шлюз не прошёл |
|
||||
| `REJECT` в route get gateway | Нужен route flush |
|
||||
| Primary DHCP OK, нет `*.100` alias | Запустить `recover` |
|
||||
|
||||
---
|
||||
|
||||
## Профилактика
|
||||
|
||||
1. **Не** использовать Manual Wi‑Fi для Joplin — только DHCP + alias.
|
||||
2. После **каждого** reconnect: одна команда `recover` выше.
|
||||
3. PAC on — только если на **1089** слушает сервер.
|
||||
4. `exit-via-ru-do.sh` — **после** рабочего `curl https://1.1.1.1`.
|
||||
|
||||
---
|
||||
|
||||
@@ -113,10 +112,6 @@ networksetup -setairportpower en0 on
|
||||
|
||||
| Документ | Зачем |
|
||||
|----------|--------|
|
||||
| [PROXY_GUIDE.md](./PROXY_GUIDE.md) | Системный PAC, порты, скрипты `macos-pac-*.sh` |
|
||||
| [PROXY_EMERGENCY.md](./PROXY_EMERGENCY.md) | SSH, SOCKS 1081, прод |
|
||||
| [README.md](./README.md) | Оглавление `connectivity/` |
|
||||
|
||||
---
|
||||
|
||||
*Если после `recover` сеть всё ещё мёртвая — проверьте аппаратный тумблер Wi‑Fi, другое SSID, и логи: Консоль → `Wi-Fi` / `configd`.*
|
||||
| [apps/joplin/STABLE_SETUP.md](./apps/joplin/STABLE_SETUP.md) | DHCP + alias |
|
||||
| [PROXY_EMERGENCY.md](./PROXY_EMERGENCY.md) | SSH / SOCKS |
|
||||
| [README.md](./README.md) | Оглавление |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Одна страница на случай, когда «всё слетело». Полная схема, безопасность и нюансы `~/.ssh/config`: [PROXY_GUIDE.md](./PROXY_GUIDE.md).
|
||||
|
||||
**Сеть / хотспот (интернет есть только после перезагрузки):** чаще всего системный **PAC на localhost:1089** без живого сервера или системный SOCKS на **1080**. Пошагово: **[HOTSPOT_NETWORK_EMERGENCY.md](./HOTSPOT_NETWORK_EMERGENCY.md)**.
|
||||
**Сеть / хотспот (интернет есть только после перезагрузки):** чаще всего **Manual IPv4 на Wi‑Fi (Joplin)** при смене подсети Android + битые маршруты; также PAC **1089** / SOCKS **1080** без клиента. Пошагово: **[HOTSPOT_NETWORK_EMERGENCY.md](./HOTSPOT_NETWORK_EMERGENCY.md)**.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
| **[BUILD_AAB_FROM_RUSSIA_GUIDE.md](./BUILD_AAB_FROM_RUSSIA_GUIDE.md)** | Сборка AAB/APK из России: Maven proxy на проде + SSH-туннель |
|
||||
| **[WINDOWS_CURSOR_TUNNEL.md](./WINDOWS_CURSOR_TUNNEL.md)** | Cursor из РФ на **Windows**: туннель через прокси, скрипт .ps1, автозапуск |
|
||||
| **[WINDOWS_SSH_KEY_INSTALL.md](./WINDOWS_SSH_KEY_INSTALL.md)** | Установка SSH-ключа на Windows (один файл `setup-ssh-key-for-proxy.ps1`, только для туннеля) |
|
||||
| **[HOTSPOT_NETWORK_EMERGENCY.md](./HOTSPOT_NETWORK_EMERGENCY.md)** | Сеть после смены хотспота: причина (PAC localhost), ручной сброс без ребута, `macos-hotspot-network-recover.sh` |
|
||||
| **[HOTSPOT_NETWORK_EMERGENCY.md](./HOTSPOT_NETWORK_EMERGENCY.md)** | Сеть после reconnect хотспота: Joplin Manual IP + смена подсети Android, route flush, PAC; `macos-hotspot-network-recover.sh` |
|
||||
| **[apps/joplin/STABLE_SETUP.md](./apps/joplin/STABLE_SETUP.md)** | Joplin: стабильный URL на телефоне (статический IP Mac на Android-хотспоте) |
|
||||
| **[apps/joplin/RUNBOOK.md](./apps/joplin/RUNBOOK.md)** | Joplin Mac ↔ телефон: диагностика, ETIMEDOUT/401, логи |
|
||||
| **[scripts/](./scripts/)** | Скрипты для туннелей и локальной работы |
|
||||
| **[launchd/](./launchd/)** | LaunchAgent для macOS: автозапуск SOCKS-туннеля при входе |
|
||||
|
||||
@@ -28,6 +30,7 @@
|
||||
- **Загрузка файлов на прод через прокси** — [PROXY_GUIDE.md → Загрузка файлов на прод (scp)](./PROXY_GUIDE.md#-загрузка-файлов-на-прод-через-туннель-scp)
|
||||
- **Безопасность прокси (nginx, fail2ban)** — [PROXY_GUIDE.md → Безопасность](./PROXY_GUIDE.md#-безопасность), SECURITY.md (если есть в папке)
|
||||
- **Сборка AAB из РФ** — [BUILD_AAB_FROM_RUSSIA_GUIDE.md](./BUILD_AAB_FROM_RUSSIA_GUIDE.md)
|
||||
- **Joplin: синк Mac ↔ телефон** — настройка [apps/joplin/STABLE_SETUP.md](./apps/joplin/STABLE_SETUP.md), поломки [apps/joplin/RUNBOOK.md](./apps/joplin/RUNBOOK.md), `./docs/apps/joplin/scripts/joplin-webdav-status.sh`
|
||||
|
||||
---
|
||||
|
||||
@@ -36,7 +39,7 @@
|
||||
| Скрипт | Описание |
|
||||
|--------|----------|
|
||||
| **telegram-socks-tunnel.sh** | SOCKS5 на 1081 для Telegram. `TELEGRAM_SOCKS_VIA_DO=1` — только Mac→RU→DO (`telegram-socks-via-do`); без RU — ошибка. См. PROXY_GUIDE. |
|
||||
| **macos-hotspot-network-recover.sh** | После смены хотспота: `status` / `recover` (PAC off, SOCKS off на Wi‑Fi, DNS, DHCP, перезапуск радио). См. HOTSPOT_NETWORK_EMERGENCY.md. |
|
||||
| **macos-hotspot-network-recover.sh** | Reconnect хотспота: `bash …/macos-hotspot-network-recover.sh recover` — DHCP, route flush (sudo), Joplin alias `*.100`. См. HOTSPOT_NETWORK_EMERGENCY.md. |
|
||||
| **ssh-hunab-prod.sh** | Опционально: сначала `hunab-prod-direct`, иначе `hunab-prod` (в конфиге по умолчанию уже через RU). См. PROXY_GUIDE. |
|
||||
|
||||
---
|
||||
|
||||
23
docs/connectivity/apps/joplin/README.md
Normal file
23
docs/connectivity/apps/joplin/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Joplin (локальный синк Mac ↔ телефон)
|
||||
|
||||
WebDAV через rclone на Mac, Android-хотспот.
|
||||
|
||||
| Документ | Назначение |
|
||||
|----------|------------|
|
||||
| **[STABLE_SETUP.md](./STABLE_SETUP.md)** | Рабочая схема: alias `*.100` |
|
||||
| **[RUNBOOK.md](./RUNBOOK.md)** | Синк сломался |
|
||||
| [docs/apps/joplin/scripts/](../../../apps/joplin/scripts/) | Скрипты |
|
||||
|
||||
## URL (Android-хотспот)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Mac | `http://127.0.0.1:8080` |
|
||||
| Телефон | `http://<подсеть>.100:8080` (см. `joplin-hotspot-alias.sh status`) |
|
||||
|
||||
**Не** `http://*.local:8080` — с телефона-хотспота не работает.
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-webdav-status.sh
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status
|
||||
```
|
||||
263
docs/connectivity/apps/joplin/RUNBOOK.md
Normal file
263
docs/connectivity/apps/joplin/RUNBOOK.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Runbook: Joplin — синк Mac ↔ телефон (WebDAV / Android-хотспот)
|
||||
|
||||
Симптом: **синхронизация перестала работать** между Joplin на Mac и на телефоне.
|
||||
|
||||
Стек: **rclone serve webdav** на Mac → `~/JoplinSync` → Joplin (Mac + Android) по HTTP. Облако Joplin не используется.
|
||||
|
||||
**Рабочая схема (2026-06, проверено):** Mac на **DHCP**, alias **`*.100`** на `en0`, телефон → `http://<подсеть>.100:8080`. Подробно: [STABLE_SETUP.md](./STABLE_SETUP.md).
|
||||
|
||||
---
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
Телефон (Joplin) ──HTTP──► Mac en0 alias *.100:8080 ──► rclone ──► ~/JoplinSync/
|
||||
Mac (Joplin) ──HTTP──► 127.0.0.1:8080 (тот же rclone)
|
||||
```
|
||||
|
||||
| Компонент | Путь / имя |
|
||||
|-----------|------------|
|
||||
| Данные | `~/JoplinSync` |
|
||||
| Учётка | `~/.config/joplin-webdav/env` (`600`, не в git) |
|
||||
| WebDAV | LaunchAgent `com.eternal.joplin-webdav` |
|
||||
| Alias `*.100` | LaunchAgent `com.eternal.joplin-hotspot-alias` (опционально + sudoers) |
|
||||
| Лог rclone | `~/Library/Logs/joplin-webdav/rclone.log` |
|
||||
| Лог alias | `~/Library/Logs/joplin-webdav/alias.log` |
|
||||
| Лог Joplin Mac | `~/.config/joplin-desktop/log.txt` |
|
||||
| Настройки Mac | `~/.config/joplin-desktop/settings.json` → `sync.6.path` |
|
||||
|
||||
Скрипты: `docs/apps/joplin/scripts/`.
|
||||
|
||||
---
|
||||
|
||||
## Шаг 0: диагностика
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-webdav-status.sh
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status
|
||||
```
|
||||
|
||||
| Что смотреть | OK | Проблема |
|
||||
|--------------|-----|----------|
|
||||
| rclone / `:8080` | процесс слушает | `joplin-webdav-serve.sh` или `joplin-webdav-install.sh` |
|
||||
| `alias: OK` | `*.100` на en0 | `joplin-hotspot-alias.sh ensure` (sudo) |
|
||||
| rclone.log | `from 10.` или `from 192.` | только `127.0.0.1` — телефон не достучался |
|
||||
| Mac URL | `127.0.0.1:8080` | настроить WebDAV на Mac |
|
||||
|
||||
---
|
||||
|
||||
## Правильные URL
|
||||
|
||||
### Android раздаёт хотспот, Mac — клиент Wi‑Fi (основной сценарий)
|
||||
|
||||
| Устройство | WebDAV URL |
|
||||
|------------|------------|
|
||||
| **Mac** | `http://127.0.0.1:8080` |
|
||||
| **Телефон** | `http://<подсеть>.100:8080` — сейчас часто `http://10.74.21.100:8080` |
|
||||
|
||||
Узнать актуальный URL:
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status
|
||||
# или
|
||||
grep JOPLIN_PHONE_URL ~/.config/joplin-webdav/env
|
||||
```
|
||||
|
||||
**Не использовать на телефоне:**
|
||||
|
||||
| URL | Почему |
|
||||
|-----|--------|
|
||||
| `http://eternals.local:8080` | Android-хотспот **не резолвит** `.local` клиентов; в rclone.log нет запросов с телефона |
|
||||
| `http://10.219.227.100:8080` | старая подсеть, если хотспот уже выдал `10.74.x` |
|
||||
| `http://10.x.x.84:8080` (primary DHCP) | IP меняется при reconnect |
|
||||
|
||||
### Общее для Joplin
|
||||
|
||||
- Логин: `joplin`
|
||||
- Пароль: `JOPLIN_WEBDAV_PASS` из env
|
||||
- **Без** `/` в конце URL
|
||||
- **Без пробела** в конце
|
||||
- `http://`, не `https://`
|
||||
- **Настройки → Синхронизация → Self-hosting → WebDAV** (не «Прокси»)
|
||||
|
||||
После смены URL на Mac: **Quit Joplin** → открыть снова → **Синхронизировать**.
|
||||
|
||||
---
|
||||
|
||||
## Симптом → причина → действие
|
||||
|
||||
### 1. «Синк OK, заметок нет на Mac»
|
||||
|
||||
Mac Joplin не на WebDAV — в `~/JoplinSync` только данные с телефона.
|
||||
|
||||
→ URL `http://127.0.0.1:8080`, проверить конфигурацию, синк.
|
||||
|
||||
---
|
||||
|
||||
### 2. `ETIMEDOUT` / `connect ETIMEDOUT 10.x.x.x:8080`
|
||||
|
||||
**Причина:** на телефоне **устаревший IP** (другая подсеть или нет alias `.100`).
|
||||
|
||||
**Признаки:** Joplin `ETIMEDOUT`; rclone — нет свежих `GET`/`PUT` с `10.`.
|
||||
|
||||
**Действие:**
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh ensure # sudo
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status # новый URL
|
||||
```
|
||||
|
||||
→ Обновить URL на телефоне **только если сменилась подсеть** (`10.219` → `10.74`).
|
||||
|
||||
---
|
||||
|
||||
### 3. `401 Unauthorized`
|
||||
|
||||
Пароль в Joplin ≠ env, или rclone не перезапущен.
|
||||
|
||||
```bash
|
||||
grep JOPLIN_WEBDAV_PASS ~/.config/joplin-webdav/env
|
||||
./docs/apps/joplin/scripts/joplin-webdav-reload.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `Not a valid URL: …/info.json`
|
||||
|
||||
Пробел в конце URL в настройках Joplin → переписать URL.
|
||||
|
||||
---
|
||||
|
||||
### 5. Порт 8080 не слушает
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-webdav-status.sh
|
||||
./docs/apps/joplin/scripts/joplin-webdav-serve.sh
|
||||
```
|
||||
|
||||
Лог: `~/Library/Logs/joplin-webdav/launchd.err.log`.
|
||||
|
||||
---
|
||||
|
||||
### 6. `ECONNREFUSED` / телефон «не достаёт», Mac — да
|
||||
|
||||
**Причина:** alias **`*.100` отсутствует** на `en0` (слетел после reconnect).
|
||||
|
||||
```bash
|
||||
ifconfig en0 | grep inet
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status
|
||||
curl -s -o /dev/null -w '%{http_code}\n' http://10.74.21.100:8080/ # подставьте *.100 из status
|
||||
```
|
||||
|
||||
→ `joplin-hotspot-alias.sh ensure`
|
||||
→ В браузере **на телефоне**: `http://<subnet>.100:8080` — запрос логина
|
||||
→ Нет интернета на Mac: [HOTSPOT_NETWORK_EMERGENCY.md](../../HOTSPOT_NETWORK_EMERGENCY.md)
|
||||
|
||||
---
|
||||
|
||||
### 7. `eternals.local` / `*.local` не работает с телефона
|
||||
|
||||
**Ожидаемо.** mDNS на Mac резолвится, Android-хотспот — нет. Использовать **`http://<subnet>.100:8080`**, не `.local`.
|
||||
|
||||
---
|
||||
|
||||
## Процедура: переподключили хотспот / сменили Wi‑Fi
|
||||
|
||||
### 1. Интернет на Mac
|
||||
|
||||
Если `curl` / браузер мёртвы:
|
||||
|
||||
```bash
|
||||
bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
```
|
||||
|
||||
Wi‑Fi должен быть **DHCP**, не Manual ([HOTSPOT_NETWORK_EMERGENCY.md](../../HOTSPOT_NETWORK_EMERGENCY.md)).
|
||||
|
||||
### 2. Joplin
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-webdav-status.sh
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias.sh ensure # если alias MISSING
|
||||
```
|
||||
|
||||
Чеклист:
|
||||
|
||||
- [ ] rclone слушает `:8080`
|
||||
- [ ] `alias: OK` (или `ensure` выполнен)
|
||||
- [ ] **Mac:** `http://127.0.0.1:8080` — без изменений
|
||||
- [ ] **Телефон:** URL из `status` — **не менять**, если подсеть та же (`10.74.21.x`)
|
||||
- [ ] Подсеть **сменилась** → один раз новый `http://<new-subnet>.100:8080`
|
||||
- [ ] В rclone.log появились `from 10.` после синка на телефоне
|
||||
|
||||
### 3. Авто-alias (рекомендуется один раз)
|
||||
|
||||
```bash
|
||||
bash ./docs/apps/joplin/scripts/joplin-android-hotspot-setup.sh install
|
||||
bash ./docs/apps/joplin/scripts/joplin-hotspot-alias-install-sudo.sh
|
||||
```
|
||||
|
||||
LaunchAgent поднимает `*.100` каждые 60 с после reconnect.
|
||||
|
||||
---
|
||||
|
||||
## Скрипты
|
||||
|
||||
| Скрипт | Когда |
|
||||
|--------|--------|
|
||||
| `joplin-webdav-status.sh` | Первая диагностика |
|
||||
| `joplin-hotspot-alias.sh status\|ensure` | URL телефона, поднять alias |
|
||||
| `joplin-android-hotspot-setup.sh install` | Полная настройка хотспота |
|
||||
| `joplin-hotspot-alias-install-sudo.sh` | Alias без пароля (LaunchAgent) |
|
||||
| `joplin-webdav-install.sh` | Первая установка rclone + launchd |
|
||||
| `joplin-webdav-reload.sh` | После смены пароля в env |
|
||||
| `joplin-mdns-setup.sh` | Справочно; **не для URL на телефоне-хотспоте** |
|
||||
|
||||
Путь: `docs/apps/joplin/scripts/`.
|
||||
|
||||
---
|
||||
|
||||
## Логи
|
||||
|
||||
**rclone.log** — успех: `PROPFIND`, `GET`, `PUT from <IP>`. Телефон часто виден как IP **шлюза** (`10.74.21.61`), не IP Mac — нормально для Android.
|
||||
|
||||
**log.txt Mac:**
|
||||
|
||||
```bash
|
||||
grep -E 'Synchronizer: \[error\]|ETIMEDOUT|ECONNREFUSED|Unauthorized|Not a valid URL' \
|
||||
~/.config/joplin-desktop/log.txt | tail -20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Безопасность
|
||||
|
||||
- WebDAV только в LAN (`0.0.0.0:8080` пока rclone работает); не пробрасывать в интернет.
|
||||
- env и пароль — не в git.
|
||||
|
||||
---
|
||||
|
||||
## Связанные документы
|
||||
|
||||
| Документ | Зачем |
|
||||
|----------|--------|
|
||||
| [STABLE_SETUP.md](./STABLE_SETUP.md) | Схема alias `*.100`, установка |
|
||||
| [README.md](./README.md) | Оглавление |
|
||||
| [docs/apps/joplin/README.md](../../../apps/joplin/README.md) | Установка с нуля |
|
||||
| [HOTSPOT_NETWORK_EMERGENCY.md](../../HOTSPOT_NETWORK_EMERGENCY.md) | Сеть macOS после reconnect |
|
||||
|
||||
---
|
||||
|
||||
## История инцидентов
|
||||
|
||||
| Дата | Симптом | Корень | Фикс |
|
||||
|------|---------|--------|------|
|
||||
| 2026-06-02 | 401 | Пароль env ≠ Joplin | `joplin-webdav-reload.sh` |
|
||||
| 2026-06-08 | ETIMEDOUT | Старый IP на телефоне | Обновить URL |
|
||||
| 2026-06-09 | Телефон не достаёт `.100` | Mac без alias | `joplin-hotspot-alias ensure` |
|
||||
| 2026-06-15 | Нет интернета после reconnect | Manual Wi‑Fi + битые маршруты | `macos-hotspot-network-recover.sh recover`, DHCP |
|
||||
| 2026-06-19 | `eternals.local` не работает | Android-хотспот не резолвит mDNS клиентов | URL `http://10.74.21.100:8080` + alias |
|
||||
| 2026-06-19 | Синк OK | alias `.100` + LaunchAgent | [STABLE_SETUP.md](./STABLE_SETUP.md) |
|
||||
|
||||
---
|
||||
|
||||
*Актуальный URL телефона: `./docs/apps/joplin/scripts/joplin-hotspot-alias.sh status`.*
|
||||
55
docs/connectivity/apps/joplin/STABLE_SETUP.md
Normal file
55
docs/connectivity/apps/joplin/STABLE_SETUP.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Стабильная настройка: Android-хотспот + Mac + Joplin
|
||||
|
||||
---
|
||||
|
||||
## Важно: `.local` с телефона **не работает**
|
||||
|
||||
`http://eternals.local:8080` резолвится на **Mac**, но **Android, раздающий хотспот, не умеет** резолвить `.local` имён **подключённых** клиентов (Mac). Запросы до rclone не доходят.
|
||||
|
||||
**Рабочая схема:** alias **`*.100`** на `en0` + URL `http://<подсеть>.100:8080`.
|
||||
|
||||
| Устройство | URL |
|
||||
|------------|-----|
|
||||
| Mac | `http://127.0.0.1:8080` |
|
||||
| Телефон | `http://10.74.21.100:8080` (подсеть меняется → см. ниже) |
|
||||
|
||||
---
|
||||
|
||||
## Установка (один раз)
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-webdav-install.sh
|
||||
bash ./docs/apps/joplin/scripts/joplin-android-hotspot-setup.sh install
|
||||
```
|
||||
|
||||
На телефоне — URL из вывода (`joplin-hotspot-alias.sh status`).
|
||||
|
||||
Автоподнятие alias после reconnect:
|
||||
|
||||
```bash
|
||||
./docs/apps/joplin/scripts/joplin-hotspot-alias-install-sudo.sh # sudoers, без пароля
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## После reconnect
|
||||
|
||||
1. Alias поднимается LaunchAgent (если sudoers установлен)
|
||||
2. Проверка: `./docs/apps/joplin/scripts/joplin-webdav-status.sh`
|
||||
3. Если подсеть **та же** (`10.74.21.x`) — URL на телефоне **не менять**
|
||||
4. Если подсеть **сменилась** (`10.219` → `10.74`) — **один раз** новый URL из `status`
|
||||
|
||||
Интернет пропал: `bash .../macos-hotspot-network-recover.sh recover`
|
||||
|
||||
---
|
||||
|
||||
## Почему URL иногда меняется
|
||||
|
||||
Android выдаёт **разные подсети** (`10.219.227.x`, `10.74.21.x`). Без Tailscale/VPN **нельзя** иметь один HTTP-URL при любой подсети с телефона-хотспота. Фиксированный **хвост `.100`** + автоподнятие alias минимизируют ручную работу.
|
||||
|
||||
---
|
||||
|
||||
## Связанное
|
||||
|
||||
- [RUNBOOK.md](./RUNBOOK.md)
|
||||
- [HOTSPOT_NETWORK_EMERGENCY.md](../../HOTSPOT_NETWORK_EMERGENCY.md)
|
||||
@@ -1,32 +1,244 @@
|
||||
#!/bin/sh
|
||||
# Сброс сетевого стека macOS после смены хотспота / «интернет не поднимается без перезагрузки».
|
||||
# Типичная причина в связке с docs/connectivity: системный PAC на localhost:1089 при мёртвом/ещё не
|
||||
# поднятом PAC-сервере + кэш DNS / Wi‑Fi. См. HOTSPOT_NETWORK_EMERGENCY.md
|
||||
# Сброс сети после переподключения Android-хотспота (macOS).
|
||||
#
|
||||
# Использование (из корня репозитория):
|
||||
# ./docs/connectivity/scripts/macos-hotspot-network-recover.sh status
|
||||
# ./docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
# RCA (почему старый recover не помогал):
|
||||
# - Ядерный сброс (route flush, ifconfig down) выполнялся только при sudo -n (passwordless).
|
||||
# - Без NOPASSWD в sudoers скрипт делал лишь toggle Wi‑Fi — ARP REJECT и битые маршруты оставались.
|
||||
# - Manual IPv4 на Wi‑Fi (Joplin 10.219.227.100) конфликтует с новой подсетью хотспота (10.36.x).
|
||||
#
|
||||
# Решение:
|
||||
# - Wi‑Fi всегда DHCP (правильный шлюз после reconnect).
|
||||
# - Joplin: вторичный IP (alias) *.100 в текущей подсети — не трогает default route.
|
||||
# - recover всегда запрашивает sudo (пароль) для полного сброса.
|
||||
#
|
||||
# Из любой папки (одна команда, чинит интернет + Joplin alias):
|
||||
# bash /Users/eternal/code/local_machine/docs/connectivity/scripts/macos-hotspot-network-recover.sh recover
|
||||
#
|
||||
# Переменные:
|
||||
# MACOS_PAC_SERVICES — как в macos-system-pac.sh (по умолчанию Wi-Fi|Thunderbolt Bridge 2)
|
||||
# WIFI_DEVICE — например en0; иначе авто: первый Device у Hardware Port: Wi-Fi
|
||||
# HOTSPOT_JOPLIN_MODE=alias|manual|off alias (по умолчанию при ~/.config/joplin-webdav/env), manual, off
|
||||
# HOTSPOT_RECOVER_SKIP_JOPLIN=1 не трогать Joplin alias
|
||||
# JOPLIN_STATIC_IP последний октет .100 из env; подсеть — текущая
|
||||
# MACOS_PAC_SERVICES, WIFI_DEVICE
|
||||
|
||||
set -e
|
||||
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||||
PAC_SCRIPT="$ROOT/macos-system-pac.sh"
|
||||
JOPLIN_ENV="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
|
||||
JOPLIN_ALIAS_SCRIPT="${JOPLIN_ALIAS_SCRIPT:-$(cd "$ROOT/../../apps/joplin/scripts" 2>/dev/null && pwd)/joplin-hotspot-alias.sh}"
|
||||
SCRIPT_SELF="$ROOT/$(basename "$0")"
|
||||
|
||||
wifi_device() {
|
||||
if [ -n "${WIFI_DEVICE:-}" ]; then
|
||||
printf '%s\n' "$WIFI_DEVICE"
|
||||
return
|
||||
fi
|
||||
# "Device: en0" под блоком "Hardware Port: Wi-Fi"
|
||||
networksetup -listallhardwareports 2>/dev/null \
|
||||
| awk '/Hardware Port: Wi-Fi$/ {p=1; next} p && /^Device: / {print $2; exit}'
|
||||
}
|
||||
|
||||
ipv4_subnet() {
|
||||
printf '%s\n' "$1" | awk -F. '{print $1"."$2"."$3}'
|
||||
}
|
||||
|
||||
ipv4_last_octet() {
|
||||
printf '%s\n' "$1" | awk -F. '{print $4}'
|
||||
}
|
||||
|
||||
load_joplin_env() {
|
||||
if [ -f "$JOPLIN_ENV" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$JOPLIN_ENV"
|
||||
fi
|
||||
}
|
||||
|
||||
wifi_config_method() {
|
||||
networksetup -getinfo "Wi-Fi" 2>/dev/null | awk 'NR==1 {print $1; exit}'
|
||||
}
|
||||
|
||||
wifi_manual_router() {
|
||||
networksetup -getinfo "Wi-Fi" 2>/dev/null | awk -F': ' '/^Router: / {print $2; exit}'
|
||||
}
|
||||
|
||||
wifi_manual_ip() {
|
||||
networksetup -getinfo "Wi-Fi" 2>/dev/null | awk -F': ' '/^IP address: / {print $2; exit}'
|
||||
}
|
||||
|
||||
default_gateway() {
|
||||
route -n get default 2>/dev/null | awk '/gateway:/{print $2; exit}'
|
||||
}
|
||||
|
||||
joplin_mode() {
|
||||
if [ "${HOTSPOT_RECOVER_SKIP_JOPLIN:-0}" = "1" ]; then
|
||||
echo off
|
||||
return
|
||||
fi
|
||||
if [ -n "${HOTSPOT_JOPLIN_MODE:-}" ]; then
|
||||
echo "$HOTSPOT_JOPLIN_MODE"
|
||||
return
|
||||
fi
|
||||
# mDNS (joplin-mac.local) — URL на телефоне не зависит от подсети; alias не нужен
|
||||
echo off
|
||||
}
|
||||
|
||||
joplin_target_ip() {
|
||||
load_joplin_env
|
||||
gw="$(default_gateway 2>/dev/null || true)"
|
||||
[ -n "$gw" ] || return 1
|
||||
subnet="$(ipv4_subnet "$gw")"
|
||||
if [ -n "${JOPLIN_STATIC_IP:-}" ]; then
|
||||
last="$(ipv4_last_octet "$JOPLIN_STATIC_IP")"
|
||||
else
|
||||
last=100
|
||||
fi
|
||||
printf '%s\n' "${subnet}.${last}"
|
||||
}
|
||||
|
||||
list_en0_alias_ips() {
|
||||
dev="${1:-en0}"
|
||||
ifconfig "$dev" 2>/dev/null | awk '/inet / && /alias/ {print $2}'
|
||||
}
|
||||
|
||||
sudo_run() {
|
||||
echo " \$ sudo $*"
|
||||
sudo "$@"
|
||||
}
|
||||
|
||||
ensure_dhcp_wifi() {
|
||||
method="$(wifi_config_method 2>/dev/null || true)"
|
||||
if [ "$method" = "Manual" ]; then
|
||||
echo " Wi‑Fi Manual $(wifi_manual_ip) → $(wifi_manual_router) — переводим на DHCP..."
|
||||
networksetup -setdhcp "Wi-Fi" 2>/dev/null || sudo_run networksetup -setdhcp "Wi-Fi"
|
||||
else
|
||||
echo " Wi‑Fi уже DHCP (или не Manual)."
|
||||
fi
|
||||
}
|
||||
|
||||
nuclear_network_reset() {
|
||||
dev="$1"
|
||||
echo " Ядерный сброс на $dev (нужен пароль sudo)..."
|
||||
sudo_run ifconfig "$dev" down
|
||||
sudo_run route -n flush
|
||||
sudo_run dscacheutil -flushcache
|
||||
sudo_run killall -HUP mDNSResponder
|
||||
sudo_run ifconfig "$dev" up
|
||||
sudo_run ipconfig set "$dev" DHCP
|
||||
}
|
||||
|
||||
wait_for_connectivity() {
|
||||
dev="$1"
|
||||
i=0
|
||||
while [ "$i" -lt 30 ]; do
|
||||
gw="$(default_gateway 2>/dev/null || true)"
|
||||
ip="$(ipconfig getifaddr "$dev" 2>/dev/null || true)"
|
||||
if [ -n "$gw" ] && [ -n "$ip" ]; then
|
||||
if ping -c 1 -W 1500 "$gw" >/dev/null 2>&1; then
|
||||
echo " Связность OK: IP=$ip gateway=$gw (${i}s)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
echo " WARN: gateway/IP не поднялись за 30с — проверьте captive portal" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
remove_joplin_aliases() {
|
||||
dev="$1"
|
||||
target="$2"
|
||||
for ip in $(list_en0_alias_ips "$dev"); do
|
||||
case "$ip" in
|
||||
*.*.*.100|"$target")
|
||||
echo " Удаляем alias $ip на $dev"
|
||||
sudo_run ifconfig "$dev" inet "$ip" -alias 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
setup_joplin_alias() {
|
||||
dev="$1"
|
||||
target="$(joplin_target_ip 2>/dev/null || true)"
|
||||
[ -n "$target" ] || { echo " Joplin alias: нет gateway" >&2; return 1; }
|
||||
primary="$(ipconfig getifaddr "$dev" 2>/dev/null || true)"
|
||||
if [ "$primary" = "$target" ]; then
|
||||
echo " Joplin: primary IP уже $target"
|
||||
return 0
|
||||
fi
|
||||
remove_joplin_aliases "$dev" "$target"
|
||||
if ifconfig "$dev" 2>/dev/null | grep -q "inet $target "; then
|
||||
echo " Joplin alias $target уже на $dev"
|
||||
return 0
|
||||
fi
|
||||
echo " Joplin alias: $target/24 на $dev (primary DHCP: ${primary:-?})"
|
||||
sudo_run ifconfig "$dev" inet "$target" netmask 255.255.255.0 alias
|
||||
echo " URL на телефоне: http://${target}:8080"
|
||||
if [ -f "$JOPLIN_ENV" ] && [ -n "${JOPLIN_STATIC_IP:-}" ]; then
|
||||
cur_sub="$(ipv4_subnet "$target")"
|
||||
env_sub="$(ipv4_subnet "$JOPLIN_STATIC_IP")"
|
||||
if [ "$cur_sub" != "$env_sub" ]; then
|
||||
echo " ⚠ Подсеть сменилась ($env_sub.x → $cur_sub.x) — обновите URL в Joplin на телефоне"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_joplin_manual() {
|
||||
gw="$(default_gateway 2>/dev/null || true)"
|
||||
[ -n "$gw" ] || return 1
|
||||
target="$(joplin_target_ip 2>/dev/null || true)"
|
||||
echo " Joplin manual (legacy): $target → router $gw"
|
||||
networksetup -setmanual "Wi-Fi" "$target" 255.255.255.0 "$gw"
|
||||
}
|
||||
|
||||
print_manual_ipv4_status() {
|
||||
info="$(networksetup -getinfo "Wi-Fi" 2>/dev/null || true)"
|
||||
echo "$info" | head -5
|
||||
method="$(printf '%s\n' "$info" | awk 'NR==1 {print $1; exit}')"
|
||||
dev="$(wifi_device 2>/dev/null || echo en0)"
|
||||
current_ip="$(ipconfig getifaddr "$dev" 2>/dev/null || true)"
|
||||
gw="$(default_gateway 2>/dev/null || true)"
|
||||
echo "--- runtime $dev ---"
|
||||
echo "primary IP: ${current_ip:-(none)}"
|
||||
echo "default gateway: ${gw:-(none)}"
|
||||
aliases="$(list_en0_alias_ips "$dev" | tr '\n' ' ')"
|
||||
if [ -n "$aliases" ]; then
|
||||
echo "aliases: $aliases"
|
||||
fi
|
||||
if [ -f "$JOPLIN_ENV" ]; then
|
||||
target="$(joplin_target_ip 2>/dev/null || true)"
|
||||
echo "joplin target: ${target:-?} (mode: $(joplin_mode))"
|
||||
if [ -n "$target" ] && ! ifconfig "$dev" 2>/dev/null | grep -q "inet $target "; then
|
||||
echo "⚠ Joplin IP $target не на интерфейсе — телефон не достучится"
|
||||
fi
|
||||
fi
|
||||
if [ "$method" = "Manual" ]; then
|
||||
manual_ip="$(printf '%s\n' "$info" | awk -F': ' '/^IP address: / {print $2; exit}')"
|
||||
manual_router="$(printf '%s\n' "$info" | awk -F': ' '/^Router: / {print $2; exit}')"
|
||||
if [ -n "$manual_router" ] && [ -n "$gw" ]; then
|
||||
if [ "$(ipv4_subnet "$manual_router")" != "$(ipv4_subnet "$gw")" ]; then
|
||||
echo "⚠ MISMATCH: Manual router $(ipv4_subnet "$manual_router").x vs gateway $(ipv4_subnet "$gw").x"
|
||||
echo " → запустите: bash $SCRIPT_SELF recover"
|
||||
elif [ -n "$current_ip" ] && [ "$current_ip" != "$manual_ip" ]; then
|
||||
echo "⚠ MISMATCH: Manual IP $manual_ip, runtime $current_ip"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ -n "$gw" ]; then
|
||||
echo "--- gateway $gw ---"
|
||||
arp -n "$gw" 2>/dev/null || true
|
||||
route -n get "$gw" 2>/dev/null | grep -E 'interface|flags' || true
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
printf '%s\n' "Usage: $(basename "$0") status|recover" >&2
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") status|recover
|
||||
|
||||
recover — PAC/SOCKS off, DHCP, ядерный сброс (sudo), Joplin alias *.100
|
||||
status — диагностика
|
||||
|
||||
Полная команда из любой папки:
|
||||
bash $SCRIPT_SELF recover
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -35,69 +247,70 @@ cmd=$1
|
||||
|
||||
case "$cmd" in
|
||||
status)
|
||||
echo "=== Wi-Fi device (hardware) ==="
|
||||
echo "=== Wi-Fi device ==="
|
||||
wifi_device || true
|
||||
echo "=== networksetup -listallnetworkservices (excerpt) ==="
|
||||
networksetup -listallnetworkservices 2>/dev/null | head -15 || true
|
||||
echo "=== PAC / autoproxy (Wi-Fi + Thunderbolt Bridge 2 if present) ==="
|
||||
echo "=== IPv4 ==="
|
||||
print_manual_ipv4_status || true
|
||||
echo "=== PAC ==="
|
||||
if [ -x "$PAC_SCRIPT" ]; then
|
||||
MACOS_PAC_SERVICES="${MACOS_PAC_SERVICES:-Wi-Fi|Thunderbolt Bridge 2}" "$PAC_SCRIPT" status || true
|
||||
fi
|
||||
echo "=== SOCKS firewall (Wi-Fi) ==="
|
||||
echo "=== SOCKS (Wi-Fi) ==="
|
||||
networksetup -getsocksfirewallproxy "Wi-Fi" 2>/dev/null || true
|
||||
echo "=== Web proxy (Wi-Fi) ==="
|
||||
networksetup -getwebproxy "Wi-Fi" 2>/dev/null || true
|
||||
echo "=== Listener on 1089 (PAC URL default) ==="
|
||||
if lsof -i :1089 -sTCP:LISTEN 2>/dev/null | head -5; then
|
||||
:
|
||||
else
|
||||
echo "(none — при Enabled PAC в Safari/системе возможны сбои)"
|
||||
fi
|
||||
echo "=== PAC listener :1089 ==="
|
||||
lsof -i :1089 -sTCP:LISTEN 2>/dev/null | head -3 || echo "(none)"
|
||||
echo "=== Default route ==="
|
||||
route -n get default 2>/dev/null | head -12 || true
|
||||
echo "=== Quick reachability (ICMP may be blocked on some hotspots) ==="
|
||||
ping -c 1 -W 2000 1.1.1.1 >/dev/null 2>&1 && echo "ping 1.1.1.1: ok" || echo "ping 1.1.1.1: fail"
|
||||
route -n get default 2>/dev/null | head -8 || echo "(no default route)"
|
||||
gw="$(default_gateway 2>/dev/null || true)"
|
||||
if [ -n "$gw" ]; then
|
||||
ping -c 1 -W 2000 "$gw" >/dev/null 2>&1 && echo "ping gateway: ok" || echo "ping gateway: fail"
|
||||
fi
|
||||
curl -sS --max-time 5 -o /dev/null https://1.1.1.1 2>/dev/null && echo "curl: ok" || echo "curl: fail"
|
||||
;;
|
||||
recover)
|
||||
echo "1) Отключаем автоматический PAC на выбранных сервисах..."
|
||||
echo "=== Hotspot recover (DHCP + route flush) ==="
|
||||
echo "Скрипт запросит пароль sudo для сброса маршрутов."
|
||||
echo ""
|
||||
echo "1) PAC off..."
|
||||
if [ -x "$PAC_SCRIPT" ]; then
|
||||
MACOS_PAC_SERVICES="${MACOS_PAC_SERVICES:-Wi-Fi|Thunderbolt Bridge 2}" "$PAC_SCRIPT" off
|
||||
else
|
||||
echo "WARN: нет $PAC_SCRIPT — вручную: Системные настройки → Сеть → Wi‑Fi → Подробнее → Прокси → снять «Автоматическая настройка прокси»" >&2
|
||||
fi
|
||||
echo "2) Отключаем системный SOCKS-прокси на Wi-Fi (если был включён Shadowsocks и т.п.)..."
|
||||
if networksetup -listallnetworkservices 2>/dev/null | grep -Fqx "Wi-Fi"; then
|
||||
networksetup -setsocksfirewallproxystate "Wi-Fi" off 2>/dev/null || true
|
||||
fi
|
||||
echo "3) Сброс DNS-кэша (нужен sudo)..."
|
||||
if sudo -n true 2>/dev/null; then
|
||||
sudo dscacheutil -flushcache 2>/dev/null || true
|
||||
sudo killall -HUP mDNSResponder 2>/dev/null || true
|
||||
echo " mDNSResponder перезагружен."
|
||||
else
|
||||
echo " Пропуск (нет sudo без пароля). Выполните вручную:"
|
||||
echo " sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder"
|
||||
fi
|
||||
echo "2) SOCKS off..."
|
||||
networksetup -setsocksfirewallproxystate "Wi-Fi" off 2>/dev/null || true
|
||||
echo "3) Wi‑Fi → DHCP (снимаем конфликтный Manual Joplin)..."
|
||||
ensure_dhcp_wifi
|
||||
dev="$(wifi_device)"
|
||||
if [ -n "$dev" ]; then
|
||||
echo "4) Обновление DHCP на $dev (нужен sudo)..."
|
||||
if sudo -n true 2>/dev/null; then
|
||||
sudo ipconfig set "$dev" DHCP 2>/dev/null || true
|
||||
else
|
||||
echo " Пропуск. Вручную: sudo ipconfig set $dev DHCP"
|
||||
fi
|
||||
echo "5) Краткое выключение/включение Wi‑Fi радиомодуля ($dev)..."
|
||||
networksetup -setairportpower "$dev" off 2>/dev/null || true
|
||||
sleep 2
|
||||
networksetup -setairportpower "$dev" on 2>/dev/null || true
|
||||
else
|
||||
echo "4–5) Не удалось определить Wi‑Fi device — пропуск DHCP/airport power. Вручную выключите/включите Wi‑Fi в меню."
|
||||
if [ -z "$dev" ]; then
|
||||
echo "Ошибка: Wi‑Fi device не найден" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "=== Готово. Проверка: ==="
|
||||
"$0" status
|
||||
echo "4) Ядерный сброс $dev..."
|
||||
nuclear_network_reset "$dev"
|
||||
echo "5) Ожидание DHCP..."
|
||||
wait_for_connectivity "$dev" || true
|
||||
mode="$(joplin_mode)"
|
||||
case "$mode" in
|
||||
alias)
|
||||
echo "6) Joplin: alias IP (не ломает маршрутизацию)..."
|
||||
if [ -x "$JOPLIN_ALIAS_SCRIPT" ]; then
|
||||
"$JOPLIN_ALIAS_SCRIPT" ensure || true
|
||||
else
|
||||
setup_joplin_alias "$dev" || true
|
||||
fi
|
||||
;;
|
||||
manual)
|
||||
echo "6) Joplin: manual Wi‑Fi (legacy)..."
|
||||
setup_joplin_manual || true
|
||||
;;
|
||||
*)
|
||||
echo "6) Joplin: пропуск (нет $JOPLIN_ENV)"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
echo "Если интернет всё ещё нет: откройте хотспот в браузере (captive portal), затем при необходимости снова включите PAC:"
|
||||
echo " ./docs/connectivity/scripts/macos-pac-on.sh"
|
||||
echo "=== Итог ==="
|
||||
"$SCRIPT_SELF" status
|
||||
echo ""
|
||||
echo "Captive portal: http://neverssl.com"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
|
||||
Reference in New Issue
Block a user