Безопасное динамическое обновление DNS записей в Windows домене из Linux (GSS-TSIG)

Необходимость в таком обновлении возникла у меня в такой ситуации: на линуксе поднят openvpn сервер, к нему коннектятся удаленные клиенты. Openvpn сервер сам динамически выдает адреса клиентам и, хотелось бы, чтобы он и создавал dns записи с common name сертификата на DNS сервере, который интегрирован в Active Directory. Тут можно пойти простым путем, и поставить в свойстве зоны «Динамическое обновление» опцию «Небезопасные и безопасные», но тогда любой, кто имеет доступ к DNS серверу, сможет менять записи зоны – не комильфо. Если поставить «Только безопасные», то DNS сервер обязательно будет требовать аутентификацию по протоколу GSS-TSIG. Дальше пойдет речь о том, как это все настроить.


Для начала, создаём пользователя домена с минимальными правами, например ddns и задаём ему сложный пароль и опцию «Срок действия пароля не ограничен». У этого пользователя должно быть достаточно прав на изменение записей dns-зоны. В свойставх dns-зоны должна быть выбрана опция «Только безопасные обновления».

Устанавливаем Kerberos клиент:
sudo apt-get install krb5-user


Отредактируем /etc/krb5.conf:
[libdefaults]
        default_realm = DOMAIN.LOCAL
[realms]
DOMAIN.LOCAL = {
                kdc = 192.168.2.200
                kdc = 192.168.2.202
                default_domain = domain.local
                admin_server = 192.168.2.200
        }

[domain_realm]
.domain.local = DOMAIN.LOCAL
domain.local = DOMAIN.LOCAL


Хотя клиент будет работать даже в такой конфигурации:
[libdefaults]
        default_realm = DOMAIN.LOCAL


Для Kerberos важным моментом является синхронность часов севера и клиента. Можно установить службу ntpd – она будет поддерживать корректное время:
sudo apt-get install ntp


С помощью ktutil создадим keytab файл, в котором будут храниться данные для аутентификации пользователя ddns:
sudo ktutil
ktutil:  addent -password -p ddns@DOMAIN.LOCAL -k 1 -e rc4-hmac
ktutil:  write_kt krb5.keytab
ktutil:  quit


Теперь можно проверить, насколько всё сделано правильно:
kinit -k -t krb5.keytab ddns


Никакого вывода быть не должно. Можно посмотреть полученные билеты:
klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: ddns@DOMAIN.LOCAL

Valid starting       Expires              Service principal
29.04.2014 14:50:39  30.04.2014 00:50:39  krbtgt/DOMAIN.LOCAL@DOMAIN.LOCAL
        renew until 30.04.2014 14:50:39



Если keytab поместить по умолчанию (etc/krb5.keytab), то можно сократить команду:
kinit -k ddns


Теперь остается только настроить openvpn. Для этого в конфигурационном файле сервера openvpn должна быть опция:
learn-address /etc/openvpn/learn-address.sh


Сам скрипт learn-address.sh:
#!/bin/bash

dnsserver=192.168.2.200
fwdzone=domain.local
revzone=7.168.192.in-addr.arpa
ttl=300
op=$1
addr=$2
revaddr=`echo $addr | sed -re 's:([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+):\4.\3.\2.\1.in-addr.arpa:'`
cn=$3
fqdn=$cn.$fwdzone
dir=/etc/openvpn/dns
addfile=$dir/add_$addr
delfile=$dir/del_$addr
keytab_file=/etc/openvpn/krb5.keytab
user=ddns

addRecord() {
        kinit -k -t $keytab_file $user
        cat > $addfile << EOF
gsstsig
server $dnsserver
zone $fwdzone
update delete $fqdn a
update add $fqdn $ttl a $addr
send
zone $revzone
update delete $revaddr ptr
update add $revaddr $ttl ptr $fqdn
send
EOF

        cat > $delfile << EOF
gsstsig
server $dnsserver
zone $fwdzone
update delete $fqdn a
send
zone $revzone
update delete $revaddr ptr
send
EOF

        nsupdate -v $addfile
        rm -f $addfile
}

delRecord() {
        kinit -k -t $keytab_file $user
        nsupdate -v $delfile
        rm -f $delfile
}

case $op in
        add|update)
                addRecord
                ;;
        delete)
                delRecord
                ;;
        *)
                echo "Unable to handle operation $op.  Exiting" exit 1
esac


Подытожу: Ключевым моментом является опция gsstsig в файле, который передается утилите nsupdate. При этом должен быть получен билет (ticket) от контроллера домена с помощью kinit <user>.
  • +11
  • 11,5k
  • 4
Поделиться публикацией
Комментарии 4
    0
    А почему бы не создавать openvpn L2 туннели что бы клиенты получали IP от доменного dhcp и им же самим DNS обновлялся? (опция сервера server-bridge, вроде)
    Хотя статья интересная, любопытно почему выбран имено этот вариант?
      0
      В данном случае клиенты openvpn — это удаленные компьютеры на gprs модемах. В случае server-bridge они смешались бы с офисными компьютерами в одной подсети, что мне совершенно не нужно. Мне нужно было только администрирование по ssh, а регистрация в офисном dns позволяет подключаться командой ssh client12 без каких-либо суффиксов. Еще можно организовать NAT для openvpn-подсети.
      0
      Для безопасного обновления DNS можно использовать winbind (при этом пакет samba ставить не обязательно):

      > aptitude install winbind
      
      > cat /etc/samba/smb.conf
      [global]
              netbios name = MYPC
              workgroup = MYDOMAIN
              realm = MYDOMAIN.NET
              security = ADS
              auth methods = winbind
              passdb backend = tdbsam
              idmap uid = 10000-20000
              idmap gid = 10000-20000
      
      > net ads join -U Administrator
      

      Запись в AD DNS появится автоматически.

      Для того, чтобы обновлять запись (обычно AD DNS настроен автоматическое на удаление «протухших» записей), можно закинуть

      net ads dns register -P
      

      в learn-address, либо в /etc/network/if-up.d [if-down.d]

      Из плюсов подхода — запись в DNS обновляется от имени учетки хоста, как это делают Windows-члены AD, а MD4-хэша пароля пользователя нет в keytab-файле (зато пароль учетки хоста есть в /var/lib/samba/secrets.tdb, но не все об этом знают :) ). Пароль учетки хоста меняется автоматом каждые 30 дней (по дефолту) blogs.technet.com/b/askds/archive/2009/02/15/test2.aspx.
      В довесок потом можно прикрутить к winbind авторизацию пользователей и получение kerberos-тикетов, чтобы ходить без явной авторизации в общие папки.

      Из минусов — net ads dns не позволяет удалять записи в DNS.
        0
        Я пытался выдрать ccache для учетки хоста из базы данных winbind-а (tdb), но, видимо, winbind его там вообще не хранит, что вполне разумно, потому что ccache протухает через 5 минут после получения. А иначе можно было бы скормить его nsupdate и заставить nsupdate обновлять записи в DNS от имени учетки хоста.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое