Как добавить постоянные статические маршруты (persistent static routes) в Mac OS X.

В Mac OS X задача добавления постоянных статических маршрутов оказалась нетривиальна. Гугление не дало желаемого результата, в результате чего пришлось включать голову и делать свой велосипед. Вполне возможно, что эту задачу можно решить проще, но у меня давно было желание разобраться с демонами и агентами OS X, так что воспользовался случаем и совместил интересное с полезным.

ТЗ: Прописать статические маршруты, автоматически подгружаемые при перезагрузке PC под управлением OS X.

В примере будет использована маршрутизация сети 172.1.0.0/22 на маршрутизатор 172.0.0.200.

1. Создаем Launch Daemon.

Launch Daemon загружается при загрузке ОС, Launch Agent при загрузке профиля. В целях безопасности OS X блокирует попытку запуска Launch Agent под root, а необходимая нам команда route add требует его привилегий. Конечно можно было бы поправить конфиг sudo, но в этом случае обновление системы может сломать реализуемую функциональность, так что было принято решение использовать именно Launch Daemon.

info: Все последующие операции выполняются в консоли.

Создадим и заполним конфиг нового Launch Daemon:

1
sudo nano /Library/LaunchDaemons/com.user.AddRoute.plist
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//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.AddRoute</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/scripts/AddRoute.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Как видно из конфига, мы будем запускать скрипт /usr/local/scripts/AddRoute.sh. Он будет исполняться от root.

2. Пишем скрипт.

1
2
sudo mkdir /usr/local/scripts/ 
sudo nano /usr/local/scripts/AddRoute.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh
. /etc/rc.common
CheckForNetwork
while [ "${NETWORKUP}" != "-YES-" ]
do
sleep 5
NETWORKUP=
CheckForNetwork
done
# Set static routing tables
/sbin/route add -net 172.1.0.0 -netmask 255.255.252.0 -gateway 172.0.0.200

Дадим скрипту доступ на исполнение:

1
sudo chmod +x /usr/local/scripts/AddRoute.sh

Внимательно рассмотрим конструкцию:

1
2
3
4
5
6
7
CheckForNetwork
while [ "${NETWORKUP}" != "-YES-" ]
do
sleep 5
NETWORKUP=
CheckForNetwork
done

Без нее скрипт может не работать, так как на момент его запуска сеть может еще не подняться. Apple рекомендует использовать отдельные инструменты для контроля сети, что усложнило бы реализацию, но в файле /etc/rc.common была найдена подходящая для таких случаев функция.

В итоге после запуска скрипта выполняется проверка доступности сети и, если она недоступна, повторение попытки через 5 секунд. Как только сеть появится, цикл завершится и выполнится команда:

1
/sbin/route add -net 172.1.0.0 -netmask 255.255.252.0 -gateway 172.0.0.200

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

1
netstat -nr |grep 172.1

Вывод должен быть аналогичным:

1
172.1/22 172.0.0.200 UGSc 1 0 en0

Смотрите также

comments powered by Disqus