Домой Edit me on GitHub

2020-10-14

Каналы передачи данных | Сетевое программирование | Базы данных | Основы Веб-программирования

DNS (система доменных имен)

Доменное имя

Доменное имя — символьное имя, служащее для идентификации областей — единиц административной автономии в сети Интернет — в составе вышестоящей по иерархии такой области. Каждая из таких областей называется доменом. Общее пространство имён Интернета функционирует благодаря DNS — системе доменных имён. Доменные имена дают возможность адресации интернет-узлов и расположенных на них сетевых ресурсов (веб-сайтов, серверов электронной почты, других служб) в удобной для человека последовательности.

Примеры доменов

../_images/DNS-names-ru.svg

Дерево доменных зон

0-й уровень

  • .

1-й уровень

  • ru
  • com
  • org

2-й уровень

  • ya.ru
  • sql.ru

3-й уровень

  • linux.org.ru
  • ru.wikipedia.org
  • lectureswww.readthedocs.org

Привязка к IP адресу

hosts — текстовый файл, содержащий базу данных доменных имен и используемый при их трансляции в сетевые адреса узлов. Запрос к этому файлу имеет приоритет перед обращением к DNS-серверам. В отличие от DNS, содержимое файла контролируется администратором компьютера.

Расположение:

В Unix /etc/hosts

В Windows %SystemRoot%\\system32\\drivers\\etc\\hosts

Пример файла hosts

213.180.204.3   google.com
127.0.0.1       localhost
127.0.1.1       x220t
10.0.0.1        server1
10.0.0.2        postgres
10.0.0.3        redis

localhost (так называемый, «локальный хост», по смыслу — этот компьютер) — в компьютерных сетях, стандартное, официально зарезервированное, доменное имя для частных IP-адресов (в диапазоне 127.0.0.1 — 127.255.255.255, RFC 2606). Для сети, состоящей только из одного компьютера, как правило, используется всего один адрес — 127.0.0.1, который устанавливается на специальный сетевой интерфейс «внутренней петли» (англ. loopback) в сетевом протоколе TCP/IP. В Unix-подобных системах данный интерфейс обычно именуется «loN», где N — число, либо просто «lo». При установке соединений в этой вырожденной «сети» присутствует только один компьютер, при этом сетевые протоколы выполняют функции протоколов межпроцессного взаимодействия.

Использование адреса 127.0.0.1 позволяет устанавливать соединение и передавать информацию для программ-серверов, работающих на том же компьютере, что и программа-клиент, независимо от конфигурации аппаратных сетевых средств компьютера (не требуется сетевая карта, модем, и прочее коммуникационное оборудование, интерфейс реализуется при помощи драйвера псевдоустройства в ядре операционной системы). Таким образом, для работы клиент-серверных приложений на одном компьютере не требуется изобретать дополнительные протоколы и дописывать программные модули.

../_images/dns_request.png

Способы получения IP адреса по доменному имени

Утилиты dig, host, nslookup были разработаны в составе ДНС сервера BIND.

dig

$ dig lectureswww.readthedocs.org +nostats +nocomments +nocmd
; <<>> DiG 9.9.5-4.3ubuntu0.1-Ubuntu <<>> lectureswww.readthedocs.org +nostats +nocomments +nocmd
;; global options: +cmd
;lectureswww.readthedocs.org.   IN      A
lectureswww.readthedocs.org. 299 IN     A       162.209.114.75

host

$ host lectureswww.readthedocs.org
lectureswww.readthedocs.org has address 162.209.114.75
lectureswww.readthedocs.org mail is handled by 20 alt1.aspmx.l.google.com.
lectureswww.readthedocs.org mail is handled by 30 aspmx3.googlemail.com.
lectureswww.readthedocs.org mail is handled by 10 aspmx.l.google.com.
lectureswww.readthedocs.org mail is handled by 20 alt2.aspmx.l.google.com.
lectureswww.readthedocs.org mail is handled by 30 aspmx2.googlemail.com.
$ host 162.209.114.75
75.114.209.162.in-addr.arpa domain name pointer readthedocs.org.

ping

$ ping lectureswww.readthedocs.org
PING lectureswww.readthedocs.org (162.209.114.75) 56(84) bytes of data.
64 bytes from readthedocs.org (162.209.114.75): icmp_seq=1 ttl=46 time=186 ms
64 bytes from readthedocs.org (162.209.114.75): icmp_seq=2 ttl=46 time=203 ms
64 bytes from readthedocs.org (162.209.114.75): icmp_seq=3 ttl=46 time=442 ms
^C
--- lectureswww.readthedocs.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 186.876/277.601/442.618/116.878 ms

nslookup

$ nslookup lectureswww.readthedocs.org
Server:     192.168.1.1
Address:    192.168.1.1#53

Non-authoritative answer:
Name:    lectureswww.readthedocs.org
Address: 162.209.114.75

telnet

Устанавливает TCP соединение по сокету предварительно определив IP адрес домена.

$ telnet lectureswww.readthedocs.org 80
Trying 23.100.69.251...
Connected to lectureswww.readthedocs.org.
Escape character is '^]'.

whois

WHOIS (от англ. who is — «кто такой?») — сетевой протокол прикладного уровня, базирующийся на протоколе TCP (порт 43). Основное применение — получение регистрационных данных о владельцах доменных имён, IP-адресов и автономных систем.

Протокол подразумевает архитектуру «клиент-сервер» и используется для доступа к публичным серверам баз данных (БД) регистраторов IP-адресов и регистраторов доменных имён. Текущая версия этого протокола описана в RFC 3912. Чаще всего WHOIS-клиенты реализованы в виде консольных программ. Однако, поскольку для многих пользователей командная строка недоступна или неудобна, на основе консольных клиентов обычно создаются веб-формы, доступные пользователям на многих сайтах в Интернете. Кроме того, существуют WHOIS-клиенты и с графическим интерфейсом.

$ whois ustu.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English)

domain:        USTU.RU
nserver:       ns2.ustu.ru. 93.88.182.2
nserver:       ns.ustu.ru. 93.88.181.2
state:         REGISTERED, DELEGATED, VERIFIED
org:           UrFU
registrar:     RU-CENTER-RU
admin-contact: https://www.nic.ru/whois
created:       1997.09.28
paid-till:     2015.10.01
free-date:     2015.11.01
source:        TCI

Last updated on 2015.02.25 11:51:31 MSK

TLD (Top-Level Domain). Некоторые Whois сервера ничего не знают о доменах «ru.»

$ whois --host whois.pir.org ustu.ru
TLD "ru" is not supported

Чтобы посмотреть какой сервер используется, нужно добавить опцию --verbose.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ whois --verbose ustu.ru
Используется сервер whois.tcinet.ru.
Строка запроса: "ustu.ru"

% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        USTU.RU
nserver:       ns2.ustu.ru. 93.88.182.2
nserver:       ns.ustu.ru. 93.88.181.2
state:         REGISTERED, DELEGATED, VERIFIED
org:           UrFU
registrar:     RU-CENTER-RU
admin-contact: https://www.nic.ru/whois
created:       1997.09.28
paid-till:     2015.10.01
free-date:     2015.11.01
source:        TCI

Last updated on 2015.02.25 12:01:33 MSK

Получение IP адреса программным путем

Единого способа получения IP адреса нет, поэтому сравним как это делают утилиты рассмотренные выше.

Возьмем утилиты ping и host они похожи друг на друга. Обе утилиты возвращают корректный IP адрес при указании доменного имени.

$ ping ya.ru
PING ya.ru (87.250.250.242) 56(84) bytes of data.
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=245 time=35.3 ms
$ host ya.ru
ya.ru has address 87.250.250.242
ya.ru has IPv6 address 2a02:6b8::2:242
ya.ru mail is handled by 10 mx.yandex.ru.

Проверяем кому принадлежит IP адрес 87.250.250.242:

$ whois 87.250.250.242 -d

inetnum:        87.250.250.0 - 87.250.250.255
netname:        YANDEX-87-250-250
status:         ASSIGNED PA
country:        RU
descr:          Yandex enterprise network
admin-c:        YNDX1-RIPE
tech-c:         YNDX1-RIPE
remarks:        INFRA-AW
mnt-by:         YANDEX-MNT
created:        2007-03-13T13:27:33Z
last-modified:  2014-03-26T08:17:27Z
source:         RIPE

role:           Yandex LLC Network Operations
address:        Yandex LLC
address:        16, Leo Tolstoy St.
address:        119021
address:        Moscow
address:        Russian Federation
phone:          +7 495 739 7000
fax-no:         +7 495 739 7070

Стандартного системного вызова решающего эту задачу в ОС не существует, есть несколько практик где можно найти IP адрес. Чаще всего утилиты используют эти практики но в разном порядке.

В примере выше обе утилиты показывают один и тотже результат, следовательно они делают одно и тоже но это не совсем верно.

Вот файлы, которые ping просматривает на моем ПК, которые имеют отношение к DNS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ sudo strace -e openat,open -f ping -c1 ya.ru
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libnettle.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_mdns4_minimal.so.2", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 5
openat(AT_FDCWD, "/etc/gai.conf", O_RDONLY|O_CLOEXEC) = 5
PING ya.ru (87.250.250.242) 56(84) bytes of data.
openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 5
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=245 time=35.6 ms

--- ya.ru ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 35.670/35.670/35.670/0.000 ms
+++ exited with 0 +++

Повторим с host то же самое:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$ sudo strace -e openat,open -f host ya.ru
...
[pid 16237] openat(AT_FDCWD, "/proc/self/task/16240/comm", O_RDWR) = 6
[pid 16237] openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 16237] openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 16237] openat(AT_FDCWD, "/usr/share/locale/en/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 16237] openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 16237] openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 6
strace: Process 16239 attached
[pid 16237] openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY) = 6
ya.ru has address 87.250.250.242
ya.ru has IPv6 address 2a02:6b8::2:242
ya.ru mail is handled by 10 mx.yandex.ru.
[pid 16237] --- SIGTERM {si_signo=SIGTERM, si_code=SI_TKILL, si_pid=16237, si_uid=0} ---
[pid 16238] +++ exited with 0 +++
[pid 16240] +++ exited with 0 +++
[pid 16239] +++ exited with 0 +++
+++ exited with 0 +++

Как можно заметить host не обращается к файлу nsswitch.conf в отличии от утилиты ping, а сразу просматривает файл настроек resolv.conf.

NSSwitch.conf

Это конфигурационный файл который позволяет некоторым функциям в языке С определить порядок поиска программ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cat /etc/nsswitch.conf

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         compat systemd
group:          compat systemd
shadow:         compat
gshadow:        files

hosts:          files dns myhostname
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

Параметр hosts в этом файле определяет порядок мест в которых функция gethostbyname и ей подобные будут искать IP.

                             --> myhostname ---> /etc/hostname
                            /
gethostbyname ---> NSSwitch ---> DNS        ---> /etc/resolv.conf ---> DNS Server
                            \
                             --> Files      ---> /etc/hosts

Проведем эксперимент: в файле nsswitch.conf оставим только значение files. После этого проверим будут ли работать утилиты.

hosts:          files

ping сразу перестает работать, а host продолжает работать потому, что не использует файл настроек nsswitch.conf.

$ ping ya.ru
ping: ya.ru: Name or service not known

Оставив в последовательности только атрибут files мы указали, что имена нужно брать только из файла /etc/hosts. Чтобы в этом убедиться добавим IP ya.ru в файл /etc/hosts.

$ cat /etc/hosts
127.0.0.1       localhost
87.250.250.242  ya.ru

ping опять стал работать:

$ ping ya.ru
PING ya.ru (87.250.250.242) 56(84) bytes of data.
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=245 time=35.7 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=2 ttl=245 time=35.2 ms
^C
--- ya.ru ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 35.229/35.492/35.756/0.323 ms

Таким образом программист может разными способами получить IP адрес по доменному имени и редактирование файла /etc/hosts не во всех случаях гарантирует переопределение адреса хоста. Для определения каким именно способом программа находит IP адрес лучше всего посмотреть трасировку системных вызовов этой программы при помощи утилиты strace.

Previous: ARP протокол Next: HTTP протокол