На этот раз при переезде с Mac mini на MacBook Pro Chrome преподал очень показательный урок: пользовательский каталог Chrome — это не обычная папка с данными, которую можно просто целиком перезаписать. Особенно расширения, скрипты Tampermonkey, Cookie и состояния входа — всё это лежит на разных уровнях, а часть данных ещё и защищена самим Chrome с помощью проверки целостности.
В этой заметке я зафиксирую процесс диагностики, грабли, на которые наступил, и то, как в будущем правильно переносить Chrome.
Симптомы
На новой машине Chrome открывался, закладки и Profile вроде бы вернулись, но состояние расширений было неправильным:
- Список расширений Chrome сначала был пустым или в нём оставались только несколько встроенных пунктов;
- Tampermonkey BETA вернулся, но в интерфейсе какое-то время не было видно старых скриптов;
- После повторного входа в аккаунт Google расширения из магазина начали постепенно синхронизироваться обратно;
- Самодельные плагины, установленные локально в распакованном виде, автоматически не вернулись;
- Chrome также показывал сообщение «Chrome сбросил эти настройки», где явно упоминались «расширения».
Самое запутанное было в том, что на уровне файлов старые данные фактически уже были видны. Например, локальный каталог LevelDB у Tampermonkey всё ещё был на месте, и внутри можно было найти фрагменты старых скриптов вроде ==UserScript==, @name, linux.do, v2ex. Но интерфейс Chrome поначалу просто их не признавал.
Первая ошибочная гипотеза: перезаписать весь каталог — значит полностью восстановить
Самая очевидная мысль — взять со старой машины:
~/Library/Application Support/Google/Chrome
```Полностью скопируйте в тот же путь на новой машине.
Этот шаг действительно копирует большой объём данных, включая:
- `Default/Extensions`
- `Default/Local Extension Settings`
- `Default/Sync Extension Settings`
- `Default/IndexedDB`
- `Default/Storage`
- `Default/Cookies`
- `Default/Login Data`
- `Default/History`
- `Default/Sessions`
Но проблема возникает из-за самопроверки Chrome после запуска. Chrome не просто «читает эти JSON и LevelDB» — он также проверяет часть защищённых настроек.
Ключевые файлы:
```text
Default/Preferences
Default/Secure Preferences
Local State
В Secure Preferences есть такие защитные структуры, как protection.macs и protection.super_mac. Информация о регистрации расширений тоже входит в эту защищённую область.
Если напрямую перезаписать Secure Preferences со старой машины на новой, при запуске Chrome посчитает, что конфигурация расширений была изменена извне Chrome, и запустит безопасный сброс. В результате пакеты расширений и данные расширений могут всё ещё оставаться на диске, но уровень регистрации расширений будет очищен, и останутся только встроенные элементы.
Именно поэтому «файлы уже скопированы, но список плагинов пуст».
Второе наблюдение: скрипты Tampermonkey пропадают не сразу
Скрипты Tampermonkey в основном находятся не в каталоге пакета расширения, а в собственном хранилище данных расширения. Типичный путь выглядит примерно так:
Default/Local Extension Settings/<extension-id>
На этот раз ID расширения Tampermonkey BETA не изменился, поэтому старый каталог с данными скриптов по-прежнему мог читаться тем же расширением.
Когда аккаунт Google прошёл проверку, а Chrome Sync заново зарегистрировал Tampermonkey BETA, старые данные скриптов снова нормально отобразились.
То есть тогда Tampermonkey выглядел так, будто был в «совершенно новом состоянии», но на самом деле ситуация скорее была такой:
- старые данные скриптов были на диске;
- уровень регистрации расширений сначала был сброшен Chrome;
- Google Sync заново установил расширение с тем же ID;
- расширение снова считало прежние локальные данные.
Это очень важно: пока ID расширения не меняется и контейнер с данными всё ещё на месте, всё ещё можно спасти.
Третье наблюдение: локально распакованные расширения не синхронизируются обратно
Расширения из Chrome Web Store могут вернуться через Google Sync, а локально установленные распакованные расширения — нет.
Локальное расширение в Secure Preferences обычно зарегистрировано через абсолютный путь, например:
/Users/<user>/Documents/.../some-local-extension
Google Sync не будет синхронизировать этот каталог и не станет автоматически заново загружать это unpacked extension. Правильный порядок действий:
- скопировать каталог с исходным кодом локального расширения на новый компьютер;
- открыть
chrome://extensions; - включить «Режим разработчика»;
- нажать «Загрузить распакованное расширение»;
- выбрать каталог с исходным кодом этого расширения.
Если старого пути не существует, даже оставшаяся в Chrome запись о регистрации не поможет.
Почему Cookie и состояние входа — тоже не обычные файлы
Cookie и база данных паролей на первый взгляд выглядят просто как эти файлы:
Default/Cookies
Default/Login Data
Но их чувствительные поля зашифрованы. В macOS Chrome опирается на элемент Chrome Safe Storage в Связке ключей.
После этой проверки выяснилось, что Chrome Safe Storage на старом и новом компьютерах фактически совпадает, поэтому после копирования Cookies и Login Data со старого компьютера их можно продолжать использовать. В противном случае, даже если файлы базы данных успешно скопированы, Chrome может не суметь расшифровать содержащиеся в них значения.
Поэтому при полном восстановлении состояния входа нужно учитывать два уровня:
- скопированы ли файлы базы данных;
- совпадает ли элемент Связки ключей, который Chrome использует для расшифровки этих данных.
Не стоит напрямую заменять всю системную Связку ключей. Более надежный способ — проверить или перенести только тот элемент Связки ключей, который нужен Chrome.
Итоговое рабочее решение
В итоге стабильный процесс оказался не «перезаписать весь каталог», а разделить восстановление на два этапа:
1. Сначала дать Chrome самому восстановить регистрационный уровень
На новом компьютере войдите в аккаунт Google и включите синхронизацию, пройдите проверку личности, чтобы Chrome Sync заново создал регистрацию расширений.
Этот шаг снова приведет Secure Preferences в состояние, которое новый компьютер считает допустимым. После этого больше не перезаписывайте его файлом Secure Preferences со старого компьютера.
2. Затем перезаписать уровень данных
После выхода из Chrome скопируйте уровень данных со старого компьютера, но исключите эти файлы:
Local State
Default/Preferences
Default/Secure Preferences
Сохраните регистрационный уровень, уже созданный самим Chrome на новом компьютере, а затем перезапишите:```text
Default/Cookies
Default/Login Data
Default/History
Default/Sessions
Default/Extensions
Default/Local Extension Settings
Default/Sync Extension Settings
Default/Managed Extension Settings
Default/Extension State
Default/Extension Rules
Default/Extension Scripts
Default/DNR Extension Rules
Default/IndexedDB
Default/Storage
Default/Local Storage
Default/Session Storage
Так регистрация расширений больше не будет снова определяться Chrome как внешнее вмешательство, а данные смогут вернуться к состоянию старого компьютера.
## План будущей миграции Chrome
Если в будущем я снова буду переносить Chrome, я буду действовать в таком порядке:1. Закройте Chrome на обеих сторонах и убедитесь, что ни один процесс Chrome не записывает данные в Profile.
2. На новой машине сначала войдите в Google и включите синхронизацию, чтобы расширения из магазина и идентичность Profile успели стабилизироваться.
3. Проверьте, совпадает ли `Chrome Safe Storage` на старой и новой машинах; если не совпадает, обрабатывайте только элементы связки ключей, относящиеся к Chrome, а не заменяйте всю связку ключей целиком.
4. Скопируйте данные Chrome со старой машины в staging-каталог.
5. С помощью `rsync` или аналогичного инструмента перезапишите слой данных, но явно исключите:
- `Local State`
- `Default/Preferences`
- `Default/Secure Preferences`
6. Проверьте ID расширений, размер хранилищ данных расширений, временные метки Cookie/Login Data.
7. Запустите Chrome и проверьте, появляется ли сообщение «Chrome сбросил эти настройки».
8. Вручную загрузите локально распакованные плагины.
9. В конце проверьте расширения с большим объёмом данных, такие как Tampermonkey, Stylus, менеджер паролей и редактор Cookie.
## Извлечённые уроки
Chrome Profile можно рассматривать как минимум в трёх слоях:
- **Слой регистрации**: `Preferences`, `Secure Preferences`, `Local State`
- **Слой данных**: Cookie, History, Login Data, различные IndexedDB/LevelDB
- **Слой внешних зависимостей**: macOS Keychain, локальные каталоги исходного кода распакованных плагинов, Google Sync
Сбой миграции обычно происходит не потому, что какой-то один файл не был скопирован, а потому, что состояния этих трёх слоёв не согласованы.
Самый важный вывод:
> Миграцию Chrome не следует понимать как «скопировать одну папку». Её следует понимать как «дать новой машине создать корректный слой регистрации, а затем подключить к нему слой данных со старой машины».
Интересный момент в этот раз как раз в этом: первое полное перезаписывание всего каталога выглядело наиболее полноценным, но, наоборот, запустило механизм самозащиты Chrome; позже, когда слой регистрации новой машины был сохранён, а заменён был только слой данных, всё действительно стало стабильным.