Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Как через systemd, запустить несколько экземпляров dnscrypt?  (Прочитано 1375 раз)

0 Пользователей и 1 Гость просматривают эту тему.

vlad001

  • Автор темы
  • Гость
Приветствую!
Ubuntu Server 16.04 LTS, нужно запустить несколько экземпляров dnscrypt-proxy из пакета в репозитории, который запускается в одном экземпляре. Следую вот этой инструкции: https://wiki.archlinux.org/index.php/DNSCrypt, для чего сделал следующее. Создал несколько файлов dnscrypt-proxy@X, где X число (у меня от 1 до 4 включительно), расположение их в /etc/default/, т.е. где и оригинальный. В них произвёл изменения в 4-й и 9-й строках:
# What local IP the daemon will listen to, with an optional port.
# The default port is 53. If using systemd, this is not used and must be
# specified in dnscrypt-proxy.socket.
DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.2.1:5353

# Remote DNS(Crypt) resolver.
# You can find a list of resolvers at
# /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv.
DNSCRYPT_PROXY_RESOLVER_NAME=d0wn-au-ns1

# Extra flags to pass to dnscrypt-proxy
DNSCRYPT_PROXY_OPTIONS=""
Все файлы одинаковые, изменения только в тех строках, порт увеличивается на единицу (5354, 5355 и т.д.), в 9-й после знака равенства разные имена из файла, находящегося тут /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv. Так же созданы файлы типа dnscrypt-proxy@X.socket, где X такое же число как выше. Содержимое одного такого файла:
[Unit]
Description=dnscrypt-proxy listening socket
Documentation=man:dnscrypt-proxy(8)
After=network.target
Wants=dnscrypt-proxy-resolvconf.service

[Socket]
ListenStream=127.0.2.1:5353
ListenDatagram=127.0.2.1:5353

[Install]
WantedBy=sockets.target
Т.е. это модификация оригинального, в других таких же файлах, увеличивается на единицу номер порта (строки 8 и 9) как выше. Создал файл (копия с оригинального) dnscrypt-proxy@.service с содержимым:
[Unit]
Description=DNSCrypt proxy
Documentation=man:dnscrypt-proxy(8)
After=network.target iptables.service firewalld.service
Requires=dnscrypt-proxy@%i.socket

[Service]
Type=notify
NonBlocking=true
User=_dnscrypt-proxy
Environment=DNSCRYPT_PROXY_RESOLVER_NAME=cisco "DNSCRYPT_PROXY_OPTIONS="
EnvironmentFile=-/etc/default/dnscrypt-proxy@%i
ExecStart=/usr/sbin/dnscrypt-proxy \
    --resolver-name=${DNSCRYPT_PROXY_RESOLVER_NAME} \
    $DNSCRYPT_PROXY_OPTIONS
Restart=always

[Install]
WantedBy=multi-user.target
Also=dnscrypt-proxy@%i.socket
Добавлено @%i, как по описанию по ссылке выше. Не уверен в правильности. Так же создан файл dnscrypt-proxy-resolvconf@.service из dnscrypt-proxy-resolvconf.service, его содержимое:
[Unit]
Description=DNSCrypt proxy resolvconf support
Documentation=man:dnscrypt-proxy(8)
After=dnscrypt-proxy.socket
Requires=dnscrypt-proxy@%i.socket
ConditionFileIsExecutable=/sbin/resolvconf

[Service]
Type=oneshot
RemainAfterExit=true
Environment="%i"
EnvironmentFile=-/etc/default/dnscrypt-proxy@%i
ExecStart=/bin/sh -c 'echo "nameserver ${DNSCRYPT_PROXY_LOCAL_ADDRESS}" \
                    | cut -d ":" -f 1 \
                    | /sbin/resolvconf -a lo.dnscrypt-proxy'
ExecStop=/sbin/resolvconf -d lo.dnscrypt-proxy

[Install]
WantedBy=multi-user.target
Also=dnscrypt-proxy@%i.socket
Замена в 11-й строке, там было после знака равенства DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.2.1:53, ну и @%i по аналогии выше. Здесь тоже нет уверенности в правильности выполненных действий, особенно в 11-й строке.
Отключил оригинальные службы (dnscrypt-proxy.service и dnscrypt-proxy.socket), новые файлы поместил с одноимёнными оригинальными по тем же местам, выполнил systemctl daemon-reload, потом запустил каждый .socket. В итоге вижу что порты слушает init, но dnscrypt не запускается. Например команда host ya.ru так ничего и не выводит (прерываю по ctrl-c). В логе вижу:
Feb 25 23:32:57 home-router systemd[1]: Listening on dnscrypt-proxy listening socket.
Feb 25 23:33:01 home-router systemd[1]: Listening on dnscrypt-proxy listening socket.
Наверно что-то где-то не правильно :'(.


Пользователь добавил сообщение 26 Февраля 2017, 15:28:55:
Удалось правильно запустить, оказывается нужно было запускать dncrypt-proxy@X.service, где X в моём случае число от 1 до 4-х. Можно создать новый .service файл, где перечислить эти .service файлы для одновременного запуска/автозагрузки и останова. Для этого можно посмотреть другие .service файлы в системе. В systemctl status видно как все 4-е службы запускаются и данные с dns серверов получены. Но осталась одна проблема, файл  dnscrypt-proxy-resolvconf.service, точнее его копия виде dnscrypt-proxy-resolvconf@.service, без этой штуки не разрешаются имена, а если его запускать то требуется ещё какой-то .socket файл. Что в нём должно быть я не знаю. На этом пока всё остановилось.

Пользователь добавил сообщение 26 Февраля 2017, 18:37:17:
В общем, файл типа dnscrypt-proxy-resolvconf@.service не нужен с таким именем. Нужно "обычное" имя без @. Я его переименовал в dnscrypt-proxy-resolvconf-all.service и прихлось его подкорректировать, теперь он вот такой:
[Unit]
Description=DNSCrypt proxy resolvconf support
Documentation=man:dnscrypt-proxy(8)
After=dnscrypt-proxy.socket
Requires=dnscrypt-proxy@%i.socket
ConditionFileIsExecutable=/sbin/resolvconf

[Service]
Type=oneshot
RemainAfterExit=true
Environment=%i
EnvironmentFile=-/etc/default/dnscrypt-proxy%i
ExecStart=/bin/sh -c 'echo "nameserver ${DNSCRYPT_PROXY_LOCAL_ADDRESS}" \
                    | cut -d ":" -f 1 \
                    | /sbin/resolvconf -a lo.dnscrypt-proxy@%i'
ExecStop=/sbin/resolvconf -d lo.dnscrypt-proxy@%i

[Install]
WantedBy=multi-user.target
Also=dnscrypt-proxy@%i.socket

Запускаю всё вот так (создал файл dnscrypt-proxy-all.service)
[Unit]
Description=Starting all dnscrypt copies
After=network.target iptables.service firewalld.service

[Service]
Type=oneshot
ExecStart=/bin/systemctl start dnscrypt-proxy@1.service dnscrypt-proxy@2.service dnscrypt-proxy@3.service dnscrypt-proxy@4.service
ExecStop=/bin/systemctl stop dnscrypt-proxy@1.socket dnscrypt-proxy@2.socket dnscrypt-proxy@3.socket dnscrypt-proxy@4.socket dnscrypt-proxy-resolvconf-all.service
RemainAfterExit=true

[Install]
WantedBy=multi-user.target
В .socket файлах так же заменил
Wants=dnscrypt-proxy-resolvconf.serviceна
Wants=dnscrypt-proxy-resolvconf-all.servicesystemctl start dnscrypt-proxy-all.service, запускаются все службы, но на:
host ya.ruничего не происходит, приходится жать ctrl+c. Если останавливаю всё это хозяйство, то на команду host вижу нормальный ответ. Понимаю что файл dnscrypt-proxy-resolvconf-all.service кривоватый получился. Что в нём не так, понять не могу. Если запустить dnscrypt с конфигом из пакета, то всё нормально, к тому что в принципе работает.
« Последнее редактирование: 26 Февраля 2017, 18:40:42 от vlad001 »

vlad001

  • Автор темы
  • Гость
Кажется, решил задачу в меру своего понимания. Подкорректировал файл dnscrypt-proxy-resolvconf-all.service:
[Unit]
Description=DNSCrypt proxy resolvconf support
Documentation=man:dnscrypt-proxy(8)
After=dnscrypt-proxy@%i.socket
Requires=dnscrypt-proxy@%i.socket
ConditionFileIsExecutable=/sbin/resolvconf

[Service]
Type=oneshot
RemainAfterExit=true
Environment="DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.2.1"
#EnvironmentFile=-/etc/default/dnscrypt-proxy%i
ExecStart=/bin/sh -c 'echo "nameserver ${DNSCRYPT_PROXY_LOCAL_ADDRESS}" \
                    | cut -d ":" -f 1 \
                    | /sbin/resolvconf -a lo.dnscrypt-proxy'
ExecStop=/sbin/resolvconf -d lo.dnscrypt-proxy

[Install]
WantedBy=multi-user.target
#Also=dnscrypt-proxy@%i.socket
EnvironmentFile= за-комментирован, ввиду того что %i не воспринимается. В Environment="DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.2.1" было Environment="DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.2.1:53". Как я понял, дальнейшие действия вырезают из файла всё что идёт после двоеточия и записывается в файл lo.dnscrypt-proxy в итоге там должно быть при запуске dnscrypt "nameserver 127.0.2.1" без кавычек. При останове этот файл удаляется. "Also" тоже пришлось за-комментировать, иначе говорит что нужен ещё какой-то *.socket. В итоге стартовый (dnscrypt-proxy-all.service) юнит выглядит так:
[Unit]
Description=Start all dnscrypt copies
After=network.target iptables.service firewalld.service

[Service]
Type=oneshot
ExecStart=/bin/systemctl start dnscrypt-proxy@1.service dnscrypt-proxy@2.service dnscrypt-proxy@3.service dnscrypt-proxy@4.service
ExecStop=/bin/systemctl stop dnscrypt-proxy@1.service dnscrypt-proxy@2.service dnscrypt-proxy@3.service dnscrypt-proxy@4.service dnscrypt-proxy-resolvconf-all.service
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

Запускаются 4-е копии службы. Нужно периодически обновлять файл dnscrypt-resolvers.csv, который расположен в /usr/share/dnscrypt-proxy/. Конечно, нужно сделать скрипт:
#!/bin/bash
wget -N -P /usr/share/dnscrypt-proxy/ https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv &> /dev/null
Наверно можно добавить проверку наличия интернета и т.п.
Так же желательно иногда менять серверы dnscrypt, они могут падать и т.п, хотя при 4-х запущенных службах (для этого и сделано) проблем должно быть минимум и тем не менее конфигурации лучше менять иногда. Понятно что без ещё одного скрипта в таком случае не обойтись:
#!/bin/bash
SUM=`sed 's/,\s/ /g' /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv | awk -F "," '$8 == "yes" && $9 == "yes" {print $1}' | sed -n '$='`
for I in 1 2 3 4; do
NUM=`shuf -i 1-$SUM -n 1`
RESOLV=`sed 's/,\s/ /g' /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv | awk -F "," '$8 == "yes" && $9 == "yes" {print $1}' | sed -n $NUM'p'`
sed -r s/.+NAME.+/DNSCRYPT_PROXY_RESOLVER_NAME=$RESOLV/ -i /etc/default/dnscrypt-proxy@$I
systemctl kill -s SIGUSR1 dnscrypt-proxy@$I.service
done
Смысл такой что в переменной SUM подсчитывается количество dns-серверов при наличии в колонках 8 (dnssec) и 9 (no log) слова "yes". Переменная NUM генерит случайное число от 1 до величины в переменой SUM. В переменной RESOLV получается название сервера при переборе значений в переменной NUM. Потом эта переменная (RESOLV) записывается в каждый файл конфигурации, 21-я строка и перезапускаются экзепляры dnscrypt-proxy, 24-я строка. На оригинальность не претендую, сделал в меру своего понимания. Дальше я использую dnsmasq, туда добавил:
no-resolv
server=127.0.2.1#5353
server=127.0.2.1#5354
server=127.0.2.1#5355
server=127.0.2.1#5356
proxy-dnssec
Наверно всё.
« Последнее редактирование: 05 Марта 2017, 19:32:57 от vlad001 »

 

Страница сгенерирована за 0.055 секунд. Запросов: 23.