***4. Опишите максимально подробно насколько вы это можете сделать, что происходит, когда вы делаете запрос curl -I http://netology.ru*** - Сначала происходит анализ конфигурационных файлов. - Проверяется очерёдность БД для резолва. `[pid 13168] 08:19:11 openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC <unfinished ...>` - Содержимое файла: ``` root@vagrant:~# cat /etc/nsswitch.conf hosts: files dns networks: files ``` - Судя по всему - получаем приоритетность информации (локальная приоритетнее данных из DNS) `[pid 13168] 08:19:11 openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC <unfinished ...>` - Содержимое файла: ``` root@vagrant:~# cat /etc/host.conf order hosts,bind ``` - Обращение к файлу, содержащему IP-адреса DNS-серверов. `[pid 13168] 08:19:11 openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC <unfinished ...>` - Содержимое файла: ``` root@vagrant:~# cat /etc/resolv.conf nameserver 127.0.0.53 ``` - Обращение к файлу с проверкой, нет ли этого хоста в локальном файле hosts `[pid 13168] 08:19:11 openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC <unfinished ...>` - Содержимое файла: ``` root@vagrant:~# cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 vagrant.vm vagrant ``` - Открываем сокет, присваеваем ему fd = 7 ``` [pid 13168] 08:19:11 socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP = 7 [pid 13168] 08:19:11 setsockopt(7, SOL_IP, IP_RECVERR, [1], 4 = 0 ``` - Устанавливаем соединение с этим сокетом ``` [pid 13168] 08:19:11 connect(7, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, 16 <unfinished ...> [pid 13168] 08:19:11 <... sendmmsg resumed>[{msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\263{\1\0\0\1\0\0\0\0\0\1\7netology\2ru\0\0\1\0\1\0\0)\4"..., iov_len=39}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=39}, {msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\0y\1\0\0\1\0\0\0\0\0\1\7netology\2ru\0\0\34\0\1\0\0)\4"..., iov_len=39}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=39}], 2, MSG_NOSIGNAL) = 2 [pid 13168] 08:19:11 <... recvfrom resumed>"\0y\201\200\0\1\0\0\0\0\0\1\7netology\2ru\0\0\34\0\1\0\0)\377"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, [28->16]) = 39 [pid 13168] 08:19:11 <... recvfrom resumed>"\263{\201\200\0\1\0\1\0\0\0\1\7netology\2ru\0\0\1\0\1\300\f\0\1"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, [28->16]) = 55 ``` - За счёт того, что 127.0.0.53 слушает наш же компьютер (без подсказке в чате я бы не понял как это посмотреть мне кажется) ``` vagrant@vagrant:~$ sudo lsof -ni @127.0.0.53:53 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd-r 608 systemd-resolve 12u IPv4 22556 0t0 UDP 127.0.0.53:domain systemd-r 608 systemd-resolve 13u IPv4 22557 0t0 TCP 127.0.0.53:domain (LISTEN) ``` - Вот конфигурация самого systemd-resolve ``` root@vagrant:~# systemd-resolve --status` Link 2 (eth0) Current Scopes: DNS DefaultRoute setting: yes LLMNR setting: yes MulticastDNS setting: no DNSOverTLS setting: no DNSSEC setting: no DNSSEC supported: no Current DNS Server: 10.0.2.3 DNS Servers: 10.0.2.3 ``` - Дальше идёт ARP-запрос от нашего компьютера в наш бродкастный домен с вопросом: кто такой 10.0.2.3 ? Идёт ARP запрос, т.к. IP находится в нашей подсети. `08:00:27:81:2f:f8 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 10.0.2.3 tell 10.0.2.15, length 28` - Дальше от 10.0.2.3 прилетает ответ с его MAC-адрресом. `11:50:53.475218 52:54:00:12:35:03 > 08:00:27:81:2f:f8, ethertype ARP (0x0806), length 60: Reply 10.0.2.3 is-at 52:54:00:12:35:03, length 46` - Собственно IP-пакет энкапсулируется в Ethernet-фрейм с полученным ранее MAC в dest, и отправляется по этому MAC-адресу. - Вот собственно наш запрос. По UDP запросили A и AAAA запись домена netology.ru ``` 08:19:11.648332 IP 10.0.2.15.45731 > 10.0.2.3.53: 29743+ [1au] A? netology.ru. (39) 08:19:11.648449 IP 10.0.2.15.44139 > 10.0.2.3.53: 12721+ [1au] AAAA? netology.ru. (39) ``` - Дальше приходит ответ от DNS сервера ``` 08:19:11.667699 IP 10.0.2.3.53 > 10.0.2.15.44139: 12721 0/1/1 (101) 08:19:11.670141 IP 10.0.2.3.53 > 10.0.2.15.45731: 29743 1/0/1 A 172.67.75.22 (55) ``` - После чего открывается socket и ему присваевается fd = 5. ``` 08:19:11 socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5 08:19:11 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0 08:19:11 setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 08:19:11 setsockopt(5, SOL_TCP, TCP_KEEPIDLE, [60], 4) = 0 08:19:11 setsockopt(5, SOL_TCP, TCP_KEEPINTVL, [60], 4) = 0 08:19:11 connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("172.67.75.22")}, 16) = -1 EINPROGRESS (Operation now in progress) ``` - И устанавливается соединение с сокетом ``` 08:19:11 getpeername(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("172.67.75.22")}, [128->16]) = 0 08:19:11 getsockname(5, {sa_family=AF_INET, sin_port=htons(50630), sin_addr=inet_addr("10.0.2.15")}, [128->16]) = 0 08:19:11 sendto(5, "HEAD / HTTP/1.1\r\nHost: netology.r"..., 75, MSG_NOSIGNAL, NULL, 0) = 75 ``` - Дальше, т.к. указанный IP-адрес не находится в нашей локальной сети, необходимо отправить этот пакет на default gw. Аналогично предыдущему разу - идёт запрос - какой MAC у 10.0.2.2 и приходит ответ. ``` 08:00:27:81:2f:f8 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 10.0.2.2 tell 10.0.2.15, length 28 52:54:00:12:35:02 > 08:00:27:81:2f:f8, ethertype ARP (0x0806), length 60: Reply 10.0.2.2 is-at 52:54:00:12:35:02, length 46 ``` - Это на 2 и 3-м уровнях. - На 4-м уровне начинается установление TCP-сессии. - Наш хост отправляет пакет cо своим source ip и source портом из диапазона 1025-65535 на адрес 172.67.75.22 на порт 80 по протоколу TCP, с флагом SYN, номером последовательности 552696288 и размером окна 64240, mss 1460 и window scale = 7. `length 74: 10.0.2.15.51872 > 172.67.75.22.80: Flags [S], seq 552696288, win 64240, options [mss 1460,sackOK,TS val 1977256836 ecr 0,nop,wscale 7], length 0` - В случае прохождения через маршрутизаторы, каждый раз в фреймах меняется как source mac, так и dest mac. При этом (кроме NAT) source ip и dest ip не меняются. - В нашем случае на нашем default gw настроен NAT, поэтому на следующем этапе прохождения пакета, source ip изменится на наш "реальный" адрес, и будет сделана запись в таблице NAT-трансляций, чтобы ответный пакет был перенаправлен на нужный "внутренний" адрес. 10.0.2.15.51872 -> REAL-IP:new-port - То есть до веб-сервера долетает пакет с source REAL-IP:new-port с тем же destination. - После этого хост 172.67.75.22 отвечает с порта 80 на REAL-IP:new-port, но долетев до нашего роутера, destination меняется на 10.0.2.15.51872 благодаря прошлой записи в таблице NAT-трансляций. - Отвечает пакетом с флагами SYN-ACK с новым SEQ 671552001 и ACK на 1 больше. `length 60: 172.67.75.22.80 > 10.0.2.15.51872: Flags [S.], seq 671552001, ack 552696289, win 65535, options [mss 1460], length 0` - Наш компьютер подтверждает получение пакета флагом ACK. `length 54: 10.0.2.15.51872 > 172.67.75.22.80: Flags [.], ack 1, win 64240, length 0` - После этого наш компьютер отправляет необходимые данные по протоколу http ( HEAD / HTTP/1.1 ) (флаг Push Data) `length 130: 10.0.2.15.51872 > 172.67.75.22.80: Flags [P.], seq 1:77, ack 1, win 64240, length 76: HTTP: HEAD / HTTP/1.1` - Сервер подтверждает получение пакета ACK'ом. `length 60: 172.67.75.22.80 > 10.0.2.15.51872: Flags [.], ack 77, win 65535, length 0` - После чего отвечает на запрос "HTTP/1.1 301 Moved Permanently" `length 430: 172.67.75.22.80 > 10.0.2.15.51872: Flags [P.], seq 1:377, ack 77, win 65535, length 376: HTTP: HTTP/1.1 301 Moved Permanently` - Система получает информацию `08:19:11 recvfrom(5, "HTTP/1.1 301 Moved Permanently\r\n"..., 102400, 0, NULL, NULL) = 257` - И затем выводит её пользователю на экран `08:19:11 write(1, "HTTP/1.1 301 Moved Permanently\r\n"..., 257) = 257` - Наш компьютер подтверждает получение, следом отправляет FIN-ACK ``` length 54: 10.0.2.15.51872 > 172.67.75.22.80: Flags [.], ack 377, win 63864, length 0 length 54: 10.0.2.15.51872 > 172.67.75.22.80: Flags [F.], seq 77, ack 377, win 63864, length 0 ``` - Сервер подтверждает получение ACK'ом, затем отправляет FIN-ACK. ``` length 60: 172.67.75.22.80 > 10.0.2.15.51872: Flags [.], ack 78, win 65535, length 0 length 60: 172.67.75.22.80 > 10.0.2.15.51872: Flags [F.], seq 377, ack 78, win 65535, length 0 ``` - Наш компьютер отправляет последний ACK. TCP сессия закончена. `length 54: 10.0.2.15.51872 > 172.67.75.22.80: Flags [.], ack 378, win 63864, length 0` - После этого система закрывает ранее открытый fd=5 и сокет. `08:19:11 close(5) = 0`