0부터 시작하는 가상머신과 네트워크 공부 - 라우터와 NAT & PAT

Jaehong Lee·2022년 7월 5일
1
post-thumbnail

0. 들어가기 전에

  • 이런 실습 환경을 구성해보자

    • 서버 관리자는 SSH를 통해 내부 네트워크에 접속할 수 있어야 한다
    • 외부 네트워크에서 라우터를 통해 내부 네트워크와 통신할 수 있어야 한다
  • AWS에서는 어떤 방식으로 구성될까?

    • ELB는 Elastic Load Balancer 이다
    • EC2는 서버, RDS는 DB, S3는 STORAGE이며 ELB를 통해 트래픽을 EC2에 할당해준다. 서버가 여러개 있으므로 AUTO SCALING을 통해 상황에 따라 시스템 자원들의 METRIC 값을 모니터링하여 서버 사이즈를 자동으로 조절한다
  • NIC Type

    • 요청에 대해 Kernel에서 수행 가능한 기능이 있다면 Kernel이 허락한다
    • 가상 자원은 결국 물리 자원을 통해 작동한다

  • Bridge (Switch) : Host OS와 동일 네트워크에 연결됨. 인터넷과 연결이 된다

    • 가상 머신의 NIC Type을 Bridge로 하면 본 컴퓨터와 나란히 Bridge에 직접 연결된다. 따라서 Ip도 본 컴퓨터 네트워크 대역과 동일하다
    • VMNET 0은 Bridge이기에 공유기로부터 직접 Ip를 받아오므로, Host/DHCP/ Subnet Address가 비어있다. 이는 사용자의 관리가 아닌 공유기의 관리를 받기 때문이다
  • NAT (Network Address Translation) : Ip 주소 바꿔준다

    • vmnet10은 가상의 브릿지다. 이 가상의 브릿지의 IP는 . . .1이며, vmnet10은 실제로 win10에 있다. 이 가상의 브릿지는 단순히 스위치 역활로 다수의 동일 네트워크 가상 머신이 연결하게 해준다
    • 본 컴퓨터는 Default Gateway 역활을 하며, vmnet10과 연결된다. 여기서 NAT를 통해 주소 변환을 해준다. 패킷이 도착하면, Gateway에서 패킷의 헤더를 열어서 출발지 Ip를 바꿔준다. 돌아올때도 똑같이 패킷의 헤더를 열어서 도착지 Ip를 바꿔서 가상머신에 전달해준다
    • NAT가 있어도 외부 네트워크에서는 가상머신에게 접근이 불가능하다. 가상머신 Private Ip를 모르기 때문이다. 이때는 포트포워딩이 필요하다
    • 실제로 확인해보면 Public Ip로 바뀐 것을 확인할 수 있다
  • Host-Only (isolated) : 외부와 통신 불가능

    • 본 컴퓨터와 VMNET 1은 연결이 되지 않으므로, 외부와 통신이 불가능하다
    • 동일한 네트워크의 머신끼리는 통신이 가능하다

1. Router 0번 Port 설정

  • 실습 환경 구성도

    • Router에 NAT를 직접 구성하여 외부 네트워크와 연결하게 할 수 있다

  • 라우터와 CLOUD를 가져온다
  • 라우터 configuration에서 라우터 이름을 바꿔준다
  • 이더넷은 브릿지로 실제 랜카드에 연결하는 것이다. ADD해준다
  • CLOUD 2는 VM NET 1을 ADD해준다. CLOUD 2는 이제 독립적인 네트워크 대역이다
  • 연결해준다. 0번은 외부 , 1번은 내부로 연결한다
  • 콘솔을 켜준다. 현재 라우터 이름과 #만 있는 상태는 확인만 가능한 상태로 설정이 불가능하다
  • 명령어 뒤에 ?를 붙이면, 어떤 명령어가 있는지 확인 가능하다
  • conf ter를 통해 설정으로 들어간다
  • fa0/0 interface에 접속
  • 0/0의 ip와 Subnet mask를 설정
  • interface는 기본적으로 shut down이므로, no shut down으로 interface를 활성화 해준다
  • !가 떳으므로 통신이 잘 됬다. 이는 라우터에서 신호를 보내는 것이다
    • !는 ICMP에 대한 응답이고, .은 arp가 실행되는 과정이다. !,.은 icmp에 대한 응답으로 arp과정을 모른다. 따라서 arp 과정중 icmp 응답이 안오므로 .으로 표시한다. !가 나오면 arp table에 저장됬으므로, 그다음부터 !만 나오는게 정상이다

2. FRAME을 열어보자

  • 통신할때 패킷을 보낸다? 라우터와 라우터 사이에서는 실질적으로는 frame을 보내지만 실제 출발지에서 목적지까지는 packet을 보낸다고 한다. frame의 mac 부분은 라우터에서 확인한다. 따라서 목적지에서는 frame에서 mac 부분을 없앤 packet부분을 확인하므로 packet을 보낸다고 한다
  • 연결된 선을 우클릭해서 start capture 해준다
  • wireshark가 연결된다. 여러 Frame들이 보인다. filter에 ip.addr == ip주소를 쳐서 해당 주소와 관련된 FRAME이 나오게 한다
  • 해당 주소로 Ping을 쳐보면 해당 주소에 대한 FRAME들이 나온다. 짝수개가 나와야지 정상적인 통신이 되는 것이다 ( 요청과 응답 ). 5개와 같은 홀수개가 나오면 요청만 가고 응답이 안 온 것을 확인할 수 있다
  • 보낸 Frame을 하나 열어보자protocols을 보면 이더넷과 ip, icmp가 보인다. 이는 각각 2,3,4 계층이다
  • 위 그림과 같은 구조다
  • 출발지와 도착지 MAC 주소를 확인할 수 있으며, 밑에는 Ip 주소가 있다
  • icmp를 열어보자. echo는 응답을 요청하는 것이다
  • 받아온 응답 FRAME을 열어보면 icmp의 Type이 reply인것을 확인할 수 있다
  • Arp ( address resolution protocol ) : 통신하고자 하는 목적지의 Ip 주소를 이용하여 해당 목적지의 물리주소인 MAC 주소를 찾기위한 프로토콜이며 정상적으로 ARP가 동작한 이후에는 ARP TABLE에 목적지 IP와 MAC 주소가 등록된다. 이후 자신이 최종적으로 원했던 통신을 하고자 한다면 ARP TABLE에 있는 정보를 참고하여 패킷을 완성하게 된다
  • 위와 같이 목적지는 브로드 캐스트이며 프로토콜은 arp이고 info는 Ip의 MAC 주소를 물어보는 것을 확인할 수 있다
  • FRAME을 보면 목적지 MAC 주소가 0으로 되어있다. 이는 목적지 MAC 주소를 모르는 것이다이때 REPLY가 유니캐스트로 응답을 보내는데, 이때 FRAME에 우리가 보내고자하는 목적지의 MAC 주소가 응답 FRAME의 수신자 MAC 주소에 적혀있다. 우리는 이 MAC 주소를 ARP TABLE에 저장한다
  • ARP TABLE을 확인해보면 알고자하는 MAC 주소와 Aging TIME을 확인할 수 있다
  • 앞에 MAC 주소를 빼면 패킷이다. 이는 3계층 Ip에서 사용하는 단위이며, 패킷을 처리하는 것은 Ip를 처리하는 것이다. 이 Ip는 전송과정에서 절대 바뀌지 않는데, 라우터에서 Ip를 처리한다. 이를 라우팅이라 한다
  • 통신 과정동안 패킷이 왔다갔다하는 것이 아닌 실질적으로 Frame이 왔다갔다한다
  • 위와 같은 과정이다
  • google에 ping을 보내면 연결이 안된다. 요청이 안 가는 것일까? 요청은 가는데 응답이 안 오는 것일까?
  • 아무것도 안 뜨는 것을 보니, 요청이 안 가는 것이다. 이는 우리가 공유기 다음의 경로를 모르기 때문이다
  • 요청은 가는데 응답이 안 오는 경우는 방화벽 때문이다. 이는 icmp를 공격으로 판단하기 때문이다. 이로 인해 공유기에 공유기한테 ping을 요청하면 응답을 받지 못한지만 인터넷을 요청하면 인터넷과 연결 된다
  • 라우팅 경로를 확인해보자. 밑에 보면 라우팅 경로를 확인할 수 있는데, 이를 어떻게 아냐면, 직접 연결됬기 때문이다 ( 앞에 C가 CONNECTED라는 뜻이다 ). 0/0 PORT가 어떤 Ip 주소와 연결됬는지 확인할 수 있다
  • 이 경로는 현재 라우터 0/0 port에서 Bridge를 통해 공유기와 연결된 경로이다. 따라서 해당 Ip로 접근하면 0/0 port로 보내준다는 것이다. 허나, 지금은 공유기 다음의 라우팅 경로를 모르기에 인터넷 연결이 안된다. 직접 설정해주자
  • ip route를 통해 라우팅 경로를 설정해준다. 0.0.0.0은 모든 ip다. 즉 모르는 ip가 접근하면 이를 gateway ( 192.168.1.1 )로 보내주겠다고 설정한다. 다시 경로를 확인하면 추가된 것을 확인할 수 있다
  • 이제 인터넷 연결이 된다
  • 이제 cloud 2쪽 Port Ip를 설정하자
  • 두 port 다 통신 가능한 것을 확인할 수 있다

3. linux 문법

  • linux를 root 계정으로 접속하자. echo $(변수) 환경변수로 HOSTNAME을 확인해보자
  • env를 통해 환경변수를 확인할 수 있다
  • 변수 지정할 때, 띄어쓰기를 하면 안된다. 이처럼 스크립트 작성 과정에서 띄어쓰기와 같은 문법이 어렵다. 이는 bash가 linux에 의존적이기 때문이다. 따라서 a = "~"를 쓰면 a를 명령어로, 뒤에를 매개변수로 판단한다. 그래서 command not found가 뜬다. 그러므로, 변수 지정을 할 때는 띄어쓰기를 하면 안된다
  • $a하면 변수가 출력된다. $?하면 결과코드를 출력한다. 0은 정상적인 결과코드다. b하는 변수가 없어도 error는 아니다
  • 이러면 error에 대한 결과코드가 출력된다
  • ens32 | grep ~를 해주면 ifconfig ens32로 나온 결과 ( ens32에 대한 정보 )에서 ~에 맞는 행을 골라서 출력해준다
  • gawk는 열을 골라서 출력해준다

4. 서버와 라우터 연결

  • 우리는 지금 linux 가상 머신의 Ip를 DHCP를 통해 서버로부터 Ip를 받아왔다. 이를 직접 설정해주자
  • Ip 설정창으로 온다
  • 위와 같이 설정한다. 설정하고, Wired를 껏다 켜준다
  • 잘 변경됬다
  • linux는 icmp가 무한대로 가므로, 횟수를 지정해줘야 한다
  • 여기서는 arp를 빠르게 처리해서 icmp 응답이 하나도 빠지지 않는다
  • arp table에 잘 저장됬다. 서버와 라우터가 잘 연결됬다
  • 라우터에서 서버로도 잘 보내진다
  • 허나 아직, 서버에서 인터넷으로 연결이 되지 않는다.

5. Web 서버 접속 과정

  • Domain으로 하면 요청도 안가고, Ip로 보내면 요청은 가지만 응답이 안온다. 왜 Domain으로 하면 요청도 안 갈까?
    • 통신은 Domain 주소가 아닌 Ip주소로 이루어진다. 따라서, Domain 주소를 해석해야한다
    • Domain 주소는 Domain server의 zone 파일 ( 일종의 DB )에 저장한다
    • Domain 주소 입력시
      1. 캐시 검색
      2. 캐시에 없으면 자신의 hosts 파일 검색
      3. hosts 파일에도 없으면 자신의 DNS ( 설정한 DNS 주소 ex. 8.8.8.8 )에게 Query
      4. Domain 서버에 검색 요청
      5. Domian 서버에서 DB 검색
      6. 주소를 담아 Client에게 응답
      7. 받은 주소로 Client는 Packet 생성
    • 통신을 위해서 session을 만들어야한다. 첫 통신에는 session을 만들기 위해 syn을 전송한다 -> syn을 받으면 ack를 전송한다. 이렇게 통신 과정에서 계속 확인을 하기 때문에 TCP는 속도가 느리다
      1. client가 syn( 0 ) 전송 - session 생성 요청
      2. syn을 받은 서버가 ack( 0 + 1 )/syn ( 0 ) 전송 - 요청에 대한 ack와 생성을 위한 syn
      3. syn을 받은 client가 ack( 0 + 1 )을 전송 - session 생성 허가 확인
      4. session 생성
      5. client가 page 요청
      6. 서버가 var/www/http/index.html 파일을 분할하여 packet에 담고, 분할했으므로 번호를 붙여서 전송. 이때 마지막 분할된 파일은 마지막 번호라고 입력된다
  • 그렇다면 현재 라우팅 경로는 다 설정되서 요청은 잘 가는데, 이 요청이 web 서버에 도달이 안됬다는 것이다. 어째서일까?

6. NAT & PAT

  • 아파트에서는 다음과 같이 허브에서 관리실 스위치에 연결된 다음, ISP에서 트래픽에 대해 검사한다. 왜 검사할까?

  • Ip는 Isp 에게 비용을 지불했느냐 여부에 따라 Public Ip, Private Ip로 분류된다. 이 Private Ip는 인터넷 연결이 안된다. 외부 네트워크로 요청을 보낼 수는 있지만 Public Ip가 아니므로, Web server에 도달하지 못한다. 따라서 응답이 안온다

    • 대표적인 사설 Ip 주소 대역
      • 10.X.X.X
      • 172.16.X.X ~ 172.31.X.X
      • 192.168.X.X
  • NAT ( network address translation )

    • IP 변환 기술로 주로, Private Ip 하나를 Public Ip로 바꿔준다
    • 이 Public Ip는 사용하고 반납해야하므로, 재접속시 Public Ip가 바뀐다. 다시 할당받기 때문이다
    • NAT 실행시 NAT Table에 기록해서, 요청에 대한 응답이 돌아올때 이 Table을 확인해서 Public Ip를 반납하고, 해당 Private Ip로 연결해준다
      1. 동적 NAT : 다수의 Public Ip는 Public Ip pool에 담겨있고, Private Ip가 이를 요청시 pool에서 Public Ip ( Floating Ip )를 꺼내서 변경해준다. 따라서 Public/Private Ip는 지정되지 않는다. 할당 받는 Public Ip가 그때그때 다르다. 외부에서는 Public Ip로 접근하므로 Private Ip의 주소를 모르기에 접근할 수 없다
      2. 정적 NAT : 특정 Private Ip는 무조건 지정된 Public Ip를 사용하도록 정적으로 매핑해 두는 기술이다. 정적 NAT는 1대1 매핑으로, 외부에서 Private Ip에 접근할 수 있다. 클라우드에서는 대부분 1대1 매핑해준다. Aws의 elastic Ip도 정적 NAT를 사용한다. 다만, 이는 유료 서비스다. 이때는 포트포워딩이 필요없다
  • PAT ( port address translation )

    • Public Ip가 한 개인 경우 다수의 Private Ip가 한 개의 Public Ip를 공유하여 Ip 변경을 하고자 하는 경우에 사용하는 기술
    • 1대1 매핑이 아니라면, Public Ip로 왔을때 어떤 Private Ip인지 모른다. 이를 구분하기 위해 Port를 지정한다
    • Ip를 Public으로 바꿔주면서, Port를 NAT의 Port로 바꿔준다
    • 하나의 Public Ip에 대해 NAT의 Port 번호만을 바꿔주어, 여러대의 Private Ip가 동시에 외부 네트워크와 연결할 수 있다
  • 더 자세한 내용은 뒤에 NAT & PAT 심화편을 참조하자

7. 동적 PAT 구성 실습 ( 일반적으로 공유기에서 제공하는 기능 )

  • 동적 PAT는 공유기에서 임의로 자동으로 port를 매핑해준다. 따라서 port가 그때그때 바뀌므로 서버 운용에는 부적합하다
  • 자동으로 포트포워딩을 해준다. 이는 외부에서 내부로 접속이 가능은 하지만 왠만해선 안 사용한다. 임의로 포트를 할당해서 Table에 기록하고, 응답이 오면 Port를 반납하는 방식이다
  • end를 통해 처음 상태로 돌아간다
  • 설정 환경으로 들어간다
    • access-list 1 permit any : 들어오는 모든 Ip를 변경할 Ip로 지정한 것이다. 이 any는 모든 Ip로 밑에 코드에서 inside로 들어가서 outside로 나갈 Ip들을 말한다. 이 Ip들은 list 1에 지정한다
    • ip nat ; 주소를 변경하는 것이다
    • inside source list 1 : 주소를 변경할 출발지 주소는 list 1에 지정된 주소들이다
    • int fa 0/0 : fa0/0에 할당된 공인 주소로 변경한다 -> 여기까진 NAT
    • overload : PAT 활성화. 다수의 Private Ip가 fa0/0의 Ip를 공유한다

  • Port 0/0과 0/1을 outside와 inside로 지정
  • 인터넷에 접속이 된다
  • 출발지 Ip가 Private에서 Public으로 바뀐 것을 확인할 수 있으며, 도착지 Ip가 Public에서 Private으로 바뀐 것을 확인할 수 있다
  • 이제 Private에서 Public으로 접속이 가능하다. 허나, 아직 반대는 안된다
  • http 서버를 실행하자
  • 자신의 라우터에 들어가진다

8. 정적 PAT 구성 실습 - PAT

  • 외부에 있는 사용자들은 192.168.1.1xx:8001 포트로 접속할 경우 내부에 있는 사설 주소인 172.16.1.100의 80번 포트로 접속되도록 한다

  • Port 매핑이기에 Tcp를 해야한다

  • 172.16.1.100의 Tcp 80 Port를 Public ip가 할당된 interface fa0/0의 8001 Port와 매핑시켜준거다. 즉 8001 Port로 들어가면 Private Ip와 연결되야한다

  • 잘 접속된다. 이러면 우리는 172.16.1.100 ( 타인의 Private Ip )의 80 Port에 접속한 것이다

  • 192.168.1.118 : 8001로 접속하면 잘 접속된다

    • linux 명령어
    • systemctl start httpd : http 서버 실행
    • systemctl stop firewalld : 방화벽 종료
    • echo : 출력
    • echo "aaa" > /var/www/http/index.html : index.html에 aaa를 새로 써서 출력
    • echo "aaa" >> /var/www/http/index.html : 기존 내용에 aaa를 덧붙여서 출력
    • cat : 파일의 내용을 보는 것
  • 다른 사람한테도 잘 접속된다

  • 스스로 192.168.1.118 : 8001로 접속하면 접속이 안된다. 이는 라우터의 outside port이기 때문이다. 따라서 172.16.1.100 : 80으로 접속하면 접속된다

9. SSH 연결 실습

  • ssh -l root -p 20022 192.168.1.199로 해당 Ip의 20022 Port에 접속하면 내부의 리눅스 웹 서버로 ssh 연결이 가능해야한다. 화면에는 public key를 저장할 것인지를 물을 것이고, yes를 타이프 한 후에 password인 test123을 입력하면 정상적으로 원격지 서버에 접속할 수 있어야 한다. 참고로 ssh port 번호는 22번이다
  • 199번 서버에 ssh로 연결했다. 이름이 testserver로 바뀌는 것을 확인할 수 있다. 이제 199번 서버에 명령어를 입력할 수 있다
  • nat에서 잘못된 것 삭제하고 싶을때?
      1. do show run으로 확인
      1. no [삭제하고 싶은 코드]
      1. 만약 사용중이라고 하면 do clear ip nat trans * : 강제로 테이블 삭제
      1. 2를 다시 실행

  • ssh에 해당하는 22번 Port와 20022 Port를 매핑해주면 된다
  • 이렇게 명령어와 같이 보내줘도 된다

10. SSH 폴더

  • cd로 홈 디렉토리로 가서 ls로 해당 디렉토리에 존재하는 파일을 출력하되 -al을 통해 숨겨진 파일까지 출력한다
  • .은 현재 디렉토리, ..은 상위 디렉토리이다
  • .폴더는 숨겨진 폴더다
  • 해당 폴더에 pwd를 이용해서 들어가서 known_hosts 파일의 내용을 출력하면, 내가 ssh 연결을 시도한 기록이 나온다
  • 위에서 PASSWORD를 통해 SSH 연결을 했다. 이번에는 Key-Pair를 통해 연결해보자. 이때 public key는 서버가, private key는 클라이언트가 가져간다
  • key gen을 통해 key를 만들면 private key와 public key (pub)가 생성되는 것을 확인할 수 있다. 생성할때 ""는 null값을 넣어주는 것이다
  • 키 내용을 출력해보면 위와 같이 출력된다
  • Private Key를 이용해 스스로 ssh 연결을 해봤다
  • 이렇게 해당 Ip의 Key를 가져와서 인증할 수 있게 저장해줄 수 있다. 이러면 해당 Ip가 내 컴퓨터에 ssh 연결을 할때 해당 Ip의 Private Key로 접속이 가능하다
profile
멋진 엔지니어가 될 때까지

0개의 댓글