CKA를 준비해보자 28일차 - Networking

0

CKA

목록 보기
28/43

Networking

Linux Networking Basics

서로 다른 host들은 ethernet 네트워크에 연결을 위해 각자의 network interface 카드(NIC)를 사용한다. 이 NIC는 스위치에 연결되어 같은 네트워크를 이루는 것이다.

---A---                      ---B---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.1.0)    -------

자신의 ethernet을 보기위해서는 ip link를 쓰면 된다.

ip link
eth0: ...

switch가 192.168.1.0이라는 IP network를 가지고 있기 때문에, host A와 host B는 다음과 같이 IP를 할당 받을 수 있다.

  • host A
ip addr add 192.168.1.10/24 dev eth0
  • host B
ip addr add 192.168.1.11/24 dev eth0

이렇게 ethernet network에 IP가 할당되면 ping을 통해서 IP를 확인할 수 있다. ping이 전달된다는 것은 이들끼리 같은 network에 있다는 것을 의미하는 것이다.

ping 192.168.1.11
Reply from 192.168.1.11: bytes=32 time=4ms TTl=117
...

그런데 host C, host D는 다른 IP 대역을 가진 네트워크에 있다고 하자.

---A---                      ---B---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.1.0)    -------


---C---                      ---D---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.2.0)    -------

어떻게 서로 다른 이들 간의 network를 연결시킬 수 있는가?? 여기서 바로 router의 개념이 등장한다. router를 통해서 이들을 하나로 연결시킬 수 있는데, 다음과 같다.

---A---                      ---B---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.1.0)    -------
                |
                |
                |
           ---Router---
           |          |
           ------------
                |
                |
---C---         |            ---D---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.2.0)    -------

router는 서로 다른 network를 연결해야하기 때문에, 각 network마다의 IP를 가져야 식별이 가능하다.

---A---                      ---B---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.1.0)    -------
                |
                |
                |
           (192.168.1.1)
           ---Router---
           |          |
           ------------
           (192.168.2.1)
                |
                |
---C---         |            ---D---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.2.0)    -------

이제 서로 다른 두 network가 연결된 것을 볼 수 있다. router는 서로 다른 network를 연결해주는 gateway가 된 것이다.

그런데, 어떻게 router가 host B로 부터 온 packet을 host C로 전달할 수 있을까?? 이를 위해서는 몇 가지 설정이 필요하다. 즉, router에게 host C에 대한 IP 정보를 설정해주는 것이 필요하는 것이다. 이를 routing table을 만든다고 한다.

router의 설정을 볼 수 있는 명령어는 다음과 같다.

route

Kernel IP routing table
Destination     Gateway     Genmask     Flags Metric Ref    Use Iface

이제 host B가 host C, D에 속한 network에 packet을 전달할 수 있도록 routing table을 설정해주어야 한다.

ip route add 192.168.2.0/24 via 192.168.1.1

route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.2.0     192.168.1.1     255.255.255.0   UG    0      0        0 eth0

이렇게 설정하면 router입장에서 192.168.1.1 gateway에 들어온 packet을 연결된 19.168.2.0 switch로 전달할 수 있다. 즉, host B가 host C의 192.168.2.10에 packet을 보내면 packet이 192.168.1.1을 지나고, router는 192.168.2.10을 보고 192.168.2.0 switch로 packet을 보내는 것이다. switch는 192.168.2.10을 보고 host C로 packet을 전달하는 것이다.

반대로 host C에서 host B로 packet을 보내기 위해서도 설정을 해주어야 한다.

ip route add 192.168.1.0/24 via 192.168.2.1

그런데, 수많은 사이트들이 IP를 가지고 있고, 수많은 router들이 있을 것이다. 이들을 routing table로 하나하나 만드는 것은 불가능에 가깝다. 그래서 default gateway를 만드는 것이다.

ip route add default via 192.168.2.1

이제 host C, D가 보내는 packet 중에 routing table에 맞지 않으면 default gateway로 전달되는 것이다.

route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.2.1     0.0.0.0         UG    0      0        0 eth0

default 대신에 0.0.0.0이라고 써도 된다.

그런데, 만약 host C에서 host D로 packet을 보낸다고 한다면 사실 router를 거칠 필요가 없다. 때문에 router에 gateway로 0.0.0.0으로 넣을 수 있다.

route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.2.0     0.0.0.0         255.255.255.0   UG    0      0        0 eth0

다음과 같이 192.168.2.0 switch안에서의 network는 gateway를 거치지 않아도 되므로 0.0.0.0으로 설정한다.

만약 다음과 같이 host C, D의 switch가 public internet router와 하나 더 연결될 때는 어떻게 route table을 설정할 수 있을까??

---A---                      ---B---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.1.0)    -------
                |
                |
                |
           (192.168.1.1)
           ---Router---   ---Router---
           |          |   |          |---->Internet
           ------------   ------------
           (192.168.2.2)  (192.168.2.1)        
                |               |
                |               |
                |----------------
                |
---C---         |            ---D---
|     |      ----------      |     |
|    eth0 ---| Switch | --- eth0   |
|     |      ----------      |     |
-------     (192.168.2.0)    -------

이 경우 host C, host D의 경우 다음과 같이 routing table을 설정해야한다.

route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.2.1     0.0.0.0         UG    0      0        0 eth0
192.168.1.0     192.168.2.2     255.255.255.0   UG    0      0        0 eth0

192.168.1.0로 향하는 network packet은 192.168.2.2 router gateway를 지나도록 하는 것이다. 그리고 나머지에 대해서는 192.168.2.1 router gateway를 지나도록 하여, internet에 접속하도록 하는 것이다.

재밌는 것은 host를 통해서도 router를 구현할 수 있는데 다음과 같다.

--A--                   ---B---                     --C--
|   |                   |     |                     |   |
| eth0--(192.168.1.0)--eth0  eth1--(192.168.2.0)--eth0  |
|   |                   |     |                     |   |
-----                   -------                     -----
eth0: 192.168.1.5   eth0: 192.168.1.6          eth0: 192.168.2.5
                    eth1: 192.168.2.6

어떻게 host A가 host C에 packet을 보낼 수 있을까?? host B를 통해서 가능하다.

host A에 다음과 같이 ip route를 추가하도록 한다.

ip route add 192.168.2.0/24 via 192.168.1.6

192.168.2.0/24는 host C에 대한 network인데, 이 packet이 오는 경우 host B의 192.168.1.6 ethernet에 바로 보내도록 하는 것이다.

반대로 host C 역시도 마찬가지인 것이다.

ip route add 192.168.1.0/24 via 192.168.2.6

이제 host A에서 host C로 전달하기 위해서 ping을 써보자.

ping 192.168.2.5

그런데 아무것도 출력되지 않는 것을 볼 수 있을 것이다. 이는 host B로 전달되었지만, host C로 가지 않았다는 것이다. 즉, host B가 packet을 drop한 것이다. 왜일까?? 이는 security를 위한 것인데, host B의 eth0와 eth1이 서로 자동으로 연결되지 않는다. 왜냐하면 만약 eth0가 private network에 연결되고, eth1은 public network에 연결되어 있다면 private network에서 전달된 packet이 함부로 public network로 포워딩되기 때문이다.

따라서, 하나의 host안에서 ethernet interface끼리의 packet을 서로 주고 받게하기 위해서는 포워딩 정책을 켜주는 수 밖에 없다.

cat /proc/sys/net/ipv4/ip_forward
0

이 값이 0이라면 forward가 지원되지 않는다는 것이다. 1로 바꿔주면 되는데, reboot 후에도 지속적으로 적용되는 설정을 하고 싶다면, 다음과 같이 /etc/sysctl.conf를 바꿔주면 된다.

  • /etc/sysctl.conf
net.ipv4.ip_forward = 1

DNS

다음의 host A, host B가 있다고 하자. host B는 DB로서 동작하는 것이다.

                          db
--A--                   ---B---
|   |                   |     |
| eth0--(192.168.1.0)--eth0   |
|   |                   |     |
-----                   -------
eth0: 192.168.1.10      eth0: 192.168.1.11

host A, B 둘 다 192.168.1.0 network 대역에 연결되어 있으므로 IP를 통한 통신이 가능하다. host A 입장에서 host B를 db로 사용해야하는데, 고정된 이름으로 호출하고 싶다. 가령 db로 말이다.

ping db
ping: unknown host db

다음과 같이 ping에 실패하고 말 것이다. 왜냐하면 db에 대한 IP를 모르기 때문이다.

이를 위해서 linux에서는 dns service를 제공하는데, /etc/hosts를 수정하면 된다.

vi /etc/hosts

192.168.1.11        db

이제 db에 ping을 보내면 성공할 것이다.

ping db

참고로 이 db라는 이름은 host name과는 다르다. 따라서 host B의 이름이 host-2라도 host A에서는 상관없이 db로 접근이 가능한 것이다.

이제 ssh db로도 접속이 가능한 것이다.

그런데 문제는 이러한 DNS rule이 너무 많아짐에 따라, 하나하나 host에 DNS rule을 추가해주기 어렵다는 것이다. 따라서, 중앙화된 DNS server를 하나 두는 것이 좋은데, 이것이 바로 DNS server이다.

N개의 host가 있다면 N개 모두 /etc/hosts를 수정하여 모든 DNS rule을 추가하는 것이 아니라, DNS server를 보도록 하는 것이다.

그럼 어떻게 DNS server를 host에 pointing시킬 수 있는가??

--A--                   --DNS--
|   |                   |     |
| eth0--(192.168.1.0)--eth0   |
|   |                   |     |
-----                   -------
192.168.1.10            192.168.1.100

DNS 서버의 /etc/hosts에 dns rule들이 모두 적용되어 있다고 하자. 이제 host A가 DNS server를 어떻게 참조하여 DNS로 IP를 얻어올 수 있는가?? 이는 /etc/resolv.conf를 수정하면 된다.

cat /etc/resolv.conf
nameserver      192.168.1.100

다음과 같이 /etc/resolv.conf 파일에 nameserver에 대한 IP를 제공하도록 수정해놓으면 된다.

물론, DNS server를 쓴다해서 직접 DNS rule을 추가하는 것이 불가능한 것은 아니다. /etc/hosts를 통해서도 단일 dns record를 추가할 수 있다.

그런데 만약 DNS server와 /etc/hosts가 서로 다른 IP값을 가진다면 어떻게 할까?

            TEST(192.168.1.115)
            |   |
            |   |
            -----
              |
--A--         |         --DNS--
|   |         |         |     |
| eth0--(192.168.1.0)--eth0   |
|   |                   |     |
-----                   -------
192.168.1.10            192.168.1.100

host A의 /etc/hosts는 다음과 같다고 하자.

192.168.1.115       test

반면 DNS server의 경우는 다음과 같다고 하자.

192.168.1.116       test

사실 local DNS rule이 먼저 적용되고 DNS server의 rule이 적용된다. 따라서, /etc/hosts에서 test를 확인했으니 192.168.1.115가 된다.

만약 이 순서를 바꾸고 싶다면 /etc/nsswitch.conf를 바꾸면 된다.

...
hosts:      files dns
...

files가 먼저 설정된 것을 볼 수 있다. 즉, local file을 먼저보고 DNS server를 본다는 것이다.

그런데, 여기서 궁금한 것이 수 많은 host 이름들이 있을 것이다. goole, facebook, naver 등등이 있는데, 이들을 어떻게 하나하나 DNS server에서 설정해주냐는 것이다.

이를 위해서 제공되는 것이 바로 well-known public name server이다. 이는 8.8.8.8로 시작하며, 다음과 같이 설정되어 있을 것이다.

cat /etc/resolv.conf
...
nameserver      8.8.8.8
nameserver      192.168.1.100

8.8.8.8이 바로 모든 website에 대한 DNS server 역할을 하는 것이다. 따라서, 이 설정을 지우면 public service들에 대한 요청이 전달되지 않는다.

가령, www.goole.com으로 요청을 보내도 전달되지 않는 것이다.

이렇게 www.google.com과 같은 것들을 domain names라고 하는데, .을 기준으로 그룹화되어 있다. 재밌는 것은 domain name들은 뒤부터 그룹화 된다는 것인데,

www.google.com

위의 경우 그룹핑이 된 것이 다음과 같다.

------com------
|              |
| --google--   |
| | www    ||
| ----------   |
|              |
----------------

즉, 최상위는 .com, 그 다음이 google 그 다음이 www이다.

만약 goole내의 app, mail, drive, maps와 같은 서비스가 있다면, 다음과 같이 나줄 수 있다.

Root:                             .
Top level Domain Name:          .com
                               google
subdomain               mail, drive, www, maps, app
...

이렇게 계층화되는 것이다.

만약, apps.google.com으로 요청으로 보내면 먼저, 먼저 회사의 org DNS를 거친다음 root DNS로 보내고, .com DNS로 보낸다. 다음으로 google인 것을 확인하고 google DNS로 보낸다. 이제 google DNS내부에서 apps DNS를 찾아 IP를 전달하는 것이다.

그렇게해서 216.58.221.78이라는 IP를 알아내면 회사의 org DNS로 전달되고 lorg DNS에서는 해당 DNS에 대해서 몇 분간 캐싱을 하게된다.

이는 public network의 domain인 경우이다. 그렇다면 organization의 경우는 어떻게 될까?? 비슷하게 동작한다.

org DNS에서 요청된 domain을 분석한다.

Root                      org DNS
doamin                 mycompany.com
sub domain        mail. drive, www, pay, hr

즉, org DNS에서 다음과 같이 rule을 설정하는 것이다.

192.168.1.10        web.mycompany.com
192.168.1.11        db.mycompany.com
192.168.1.12        nfs.mycompany.com
192.168.1.13        web-1.mycompany.com
192.168.1.14        sql.mycompancy.com

다음으로 해당 org DNS를 사용하는 host들은 org DNS에 대한 nameserver를 등록해야한다.

cat /etc/resolv.conf
nameserver      192.168.1.100

이제 ping을 보내보면 성공한다.

ping web.mycompany.com

그런데 web으로만 ping을 보내면 실패하고 말 것이다. 만약, subdomain인 web으로만 보내도 ping이 성공하게끔 하고 싶다면 다음과 같이 /etc/resolv.confsearch를 설정해주면 된다.

cat /etc/resolv.conf
nameserver      192.168.1.100
search          mycompany.com   prod.mycompany.com

ping web으로 보내면 mycompany.com이라는 top level domain에서 해당 sub domain이 있는 지 확인하는 것이다. 즉 web.mycompany.com을 찾아보는 것이다 . 만약 없다면 web.prod.mycompany.com에도 요청을 보내보는 것이다.

이렇게 /etc/resolv.conf르 ㄹ설정하는 것을 DNS record 설정이라고 한다. record에도 종류가 있는데 다음과 같다.

typekeyvalue
Aweb-server192.168.1.1
AAAAweb-server2001:0db8:85a3:0000:0000:8a2e:0370:7334
CNAMEfood.web-servereat.web-server, hungry.web-server

dns record type이 3가지가 있는 것인데, A는 IPv4로 key는 name이고, value가 IP이다. 위에서 우리가 설정한 것이 같은 것이다. AAAA는 IPv6이다. CNAME같은 경우는 이름을 맵핑하는 것이다. 가령 food.web-server로 요청이 오면 eat.web-server 후에 hungry.web-server에 요청을 보내는 것이다. 즉 하나의 alias를 설정하는 것이다.

DNS ping을 통해서 DNS record가 잘 설정된 것을 볼 수 있지만, nslookup을 통해서도 가능하다.

nslookup www.google.com
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   www.google.com
Address: 172.217.0.132

이를 dns resultion을 test한다고 한다. 단, nslookup을 사용할 때는 조심해야할 것이 해당 dns record를 DNS server에서 잘 찾을 수 있는 지 확인하기 위해서 사용한다는 것이다. 즉, local etc host file의 entry들은 참조하지 않는다는 것이다.

따라서, nslookup web이렇게 query하면 실패한다. 오직 DNS server로 query를 보내기 때문이다.

또 다른 DNS name resolution으로 dig가 있다.

dig www.google.com
...

dig 역시도 DNS server에 query를 보내어 확인받는 것이다.

0개의 댓글