macOS · AmneziaVPN · launchd

Часовой пояс по VPN

Готовые команды для автоматической смены часового пояса при включении AmneziaVPN — и возврата обратно при отключении. Проверено и исправлено после разбора черновика.

3 секинтервал проверки соединения
utun / 10.xпризнак активного туннеля
launchdавтозапуск, без Терминала
Как это работает. Фоновый скрипт каждые 3 секунды смотрит таблицу маршрутизации macOS. Как только там появляется интерфейс utun с подсетью 10.x.x.x — признак поднятого туннеля Amnezia — система переключается на часовой пояс VPN. Как только маршрут исчезает, время мгновенно возвращается на домашний пояс. Скрипт работает как системная служба launchd, поэтому не зависит от открытого окна Терминала и переживает перезагрузку.
1

Отключите автоопределение пояса

По умолчанию macOS сама выставляет часовой пояс по геолокации и не даёт скрипту его менять. Это нужно выключить вручную:

  • Системные настройки → Основные → Дата и время
  • Выключите «Устанавливать часовой пояс автоматически, используя текущее геоположение»
  • Автоматическую установку самого времени можно оставить включённой
2

Разрешите смену времени без пароля

Иначе macOS будет просить пароль администратора каждые 3 секунды. Команда добавляет точечное правило только для systemsetup и сразу проверяет, что файл написан без ошибок:

Терминал
echo "$(whoami) ALL=(ALL) NOPASSWD: /usr/sbin/systemsetup" | sudo tee /etc/sudoers.d/vpn_timezone > /dev/null
sudo chmod 440 /etc/sudoers.d/vpn_timezone
sudo visudo -cf /etc/sudoers.d/vpn_timezone
Пароль от Mac спросят один раз. Последняя строка должна ответить /etc/sudoers.d/vpn_timezone: parsed OK — это значит, что правило рабочее и не сломает sudo.
3

Создайте фоновый скрипт

Скопируйте блок целиком и вставьте в Терминал. Он создаст исполняемый файл ~/vpn_time.sh. Замените значения VPN_TZ и HOME_TZ, если нужны другие пояса.

~/vpn_time.sh
cat << 'EOF' > ~/vpn_time.sh
#!/bin/bash
# Часовые пояса: свой и для VPN
VPN_TZ="America/New_York"
HOME_TZ="Europe/Moscow"

while true; do
    if netstat -rn 2>/dev/null | grep "utun" | grep -q " 10\."; then
        TARGET_TZ="$VPN_TZ"
    else
        TARGET_TZ="$HOME_TZ"
    fi

    CURRENT_TZ=$(sudo systemsetup -gettimezone | awk '{print $3}')
    if [ "$CURRENT_TZ" != "$TARGET_TZ" ]; then
        sudo systemsetup -settimezone "$TARGET_TZ"
    fi

    sleep 3
done
EOF
chmod +x ~/vpn_time.sh
4

Подключите его как системную службу

Файл службы launchd запускает скрипт при загрузке Mac и мгновенно перезапускает его, если он вдруг завершится. Путь к скрипту подставляется автоматически — блок можно копировать на любой Mac без правок:

com.user.vpntimezone.plist
mkdir -p ~/Library/LaunchAgents
cat << EOF > ~/Library/LaunchAgents/com.user.vpntimezone.plist
<?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>Label</key>
    <string>com.user.vpntimezone</string>
    <key>ProgramArguments</key>
    <array>
        <string>$HOME/vpn_time.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/vpn_timezone.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/vpn_timezone.err</string>
</dict>
</plist>
EOF

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.user.vpntimezone.plist
Готово — перезагрузка не нужна, служба уже запущена. Если позже она перестанет реагировать на VPN, лог ошибок лежит в /tmp/vpn_timezone.err.
5

Проверьте, что всё работает

Подключите Amnezia и посмотрите на пояс в строке меню, либо спросите систему напрямую:

Терминал
launchctl print gui/$(id -u)/com.user.vpntimezone | grep state
sudo systemsetup -gettimezone

Управление службой

Служба перезапускает себя сама (KeepAlive), поэтому обычный pkill её не остановит — она поднимется снова в течение секунды. Чтобы по-настоящему остановить или перезапустить, используйте launchctl.

Что нужноКоманда
Проверить статус и последний код выходаlaunchctl print gui/$(id -u)/com.user.vpntimezone
Остановить совсем (не будет перезапускаться)launchctl bootout gui/$(id -u)/com.user.vpntimezone
Запустить снова после остановкиlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.user.vpntimezone.plist
Перезапустить прямо сейчас (после правки скрипта)launchctl kickstart -k gui/$(id -u)/com.user.vpntimezone
Вручную поставить московское времяsudo systemsetup -settimezone Europe/Moscow
Посмотреть лог ошибок скриптаcat /tmp/vpn_timezone.err

Другой часовой пояс вместо Нью-Йорка

Остановите службу, отредактируйте одну строку в скрипте, запустите снова:

Терминал
launchctl bootout gui/$(id -u)/com.user.vpntimezone
nano ~/vpn_time.sh   # поменяйте строку VPN_TZ="...", сохраните: Ctrl+O, Enter, Ctrl+X
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.user.vpntimezone.plist

Что было не так в черновике

Черновик описывал рабочую идею, но два места ломали её на новом Mac или после включения автозапуска — вот что изменилось.

Путь к скрипту в файле службы был захардкожен
−<string>/Users/claude/vpn_time.sh</string> — сработает только на компьютере, где пользователя зовут «claude»
+<string>$HOME/vpn_time.sh</string> — путь подставляется автоматически на любом Mac
Инструкция «остановить» не работала после перехода на launchd
−pkill -9 -f vpn_time.sh — launchd видит, что служба с KeepAlive упала, и поднимает её обратно за секунду
+launchctl bootout gui/$(id -u)/com.user.vpntimezone — снимает саму службу, а не только процесс
Полное удаление не трогало службу launchd
−Черновик удалял только скрипт и старую строку в ~/.zshrc, оставшуюся от первой, ещё не финальной версии
+Ниже удаление сначала выгружает службу launchd, затем чистит все файлы, включая эту старую строку — на случай, если она осталась
Правило sudo ничем не проверялось
−sudo sh -c "echo ... >> /etc/sudoers.d/vpn_timezone" — опечатка в этом файле может заблокировать sudo для всех правил разом
+Добавлена проверка sudo visudo -cf и права доступа 440 — синтаксис подтверждается перед сохранением

Удаление

Если автоматизация больше не нужна — снимает службу, стирает скрипт, файл службы и разрешение на sudo:

Действие необратимо: скрипт и файлы будут удалены без возможности восстановить их из корзины.

Терминал
launchctl bootout gui/$(id -u)/com.user.vpntimezone 2>/dev/null
rm -f ~/Library/LaunchAgents/com.user.vpntimezone.plist
rm -f ~/vpn_time.sh
sed -i '' '/vpn_time.sh/d' ~/.zshrc 2>/dev/null
sudo rm -f /etc/sudoers.d/vpn_timezone