웹 서비스는 기본적으로 HTTP 통신 위에서 동작한다. 이 때 HTTP의 큰 특징 중 하나는 바로 stateless하다는 것이다. 간단히 말하면 서버가 클라이언트의 예전 상태를 보존하지 않는다는 뜻으로 비유하자면 클라이언트가 바로 직전에 한 말조차도 기억하지 못한다는 것! 예를 들면..

 

1번째 교신)

클라 : 제주도 가는 비행기 얼마에요?

서버 : 편도 7만원이요

 

2번째 교신)

클라 : 4장 주세요

서버 : ? 뭘요?

 

이런 느낌이다. 좀 더 자세한 얘기는 예전에 쓴 글 참조.

https://jofestudio.tistory.com/57

 

HTTP의 특징(stateless 등..)

1. 클라이언트 - 서버 구조 : HTTP는 클라이언트가 request를 보내면 서버가 response를 보내는 구조이다. 즉 클라이언트와 서버가 개념적으로 분리된 형태이며, 클라이언트로부터 request가 안오면 서버

jofestudio.tistory.com

 

 

암튼 이런 식으로 각 통신의 상태를 저장하지 않기 때문에, 인증 / 인가와 관련한 문제점이 생긴다. 로그인 이후 마이페이지같은 걸 요청할 때, 서버가 내 쪽의 상태를 모르니 매번 새 페이지를 요청할때마다 로그인을 해야 한다. 

 

이런 번거로움을 넘어서 비효율적인 일을 느낌있게 처리해야 한다. 기존에 이미 로그인한 사용자에 대한 정보를 저장해야 할 필요가 있는 것이다. 이를 위한 대표적인 방식들로 세션(Session)과 토큰(Token)을 기반으로 하는 인증방식들이 있다. 둘 다 유저가 로그인 시도 시 일치하는 유저 정보를 찾았다면 인증(Authentication) 완료의 표시로 일종의 확인증을 클라이언트에게 끊어주고, 클라이언트는 이후 로그인한 유저 정보가 필요한 곳에는 발급받은 확인증을 서버에게 건네어 인가(Authorization)를 받는다는 공통점이 있다. 그러나 둘은 차이점이 있고 서로간의 장단점이 있다. 이 둘에 대해 좀 더 뜯어보자.

 

 

세션 (Session)

일정 시간 동안 같은 사용자(정확히는 브라우저)로부터 들어오는 요구들을 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술을 말한다. 쉽게 말해 방문자가 웹서버에 접속해있는 상태를 하나의 단위로 보는 것. 컨셉은 다음과 같다.

 

  1. 유저가 로그인을 시도하면, 서버 쪽에서 DB를 뒤져서 일치하는 유저 정보를 찾는다.
  2. 찾았다면 그 클라이언트에 대한 세션id(일종의 확인증)을 발급해주고, 서버 쪽에서 갖는 세션 스토리지(Session Storage)에도 해당 정보를 저장한다. (세션id가 일종의 식별key)
  3. 클라이언트는 발급받은 세션id를 쿠키에 저장한다. (2번의 response로부터 set-cookie가 옴)
  4. 이후 클라이언트는 request를 보낼 때 쿠키를 헤더에 넣어 함께 전송(세션id가 들어있음)
  5. 서버는 클라이언트로부터 받은 세션id와 자신의 세션 스토리지에 있는 세션id를 대조해 인증 상태를 판단하고, 인가여부를 내린다.

 

서버 쪽에서 클라이언트의 세션정보를 본인의 메모리나 디스크..뭐 이런 곳에 저장하는 방식으로, 결국은 클라이언트의 상태를 계속해서 서버가 갖고 있고 이를 서비스에 이용하는 stateful방식이다.

 

※ 장점

서버가 클라이언트의 상태를 유지하고 있으니 로그인 여부 확인이 매우 용이하다. 맘만 먹으면 강제 로그아웃 등의 제재를 가하는 것도 쉽다. 

 

※ 단점

서버가 각 클라이언트들의 상태를 모두 갖고있는 셈이니, 당연히 메모리나 디스크 등에 부하가 걸리기 쉽다. 가장 치명적인 단점은 MSA(Micro Service Architecture)문제점이다.  사용자가 많아지면 서버를 여러 개로 늘려 확장한 다음, 로드밸런서(Load Balancer)를 둬서 각 클라이언트들의 보내는 request들을 처리할 서버를 이곳 저곳으로 전달해야 한다. 이 때 내가 로그인을 요청했던 서버와 이후 요청을 보낸 서버가 달라지면, 그 서버에는 내가 아까 로그인을 할 때 저장된 세션 정보가 없다는 문제가 발생하게 되는 것. 이렇게 되면 세션 정보가 없는 다른 서버에 접속할 때마다 계속 로그인을 해야 하는 참사가 생겨버린다. 이를 위해 각 서버들의 세션 스토리지를 동기화해주는 세션매니저(Session Manager)를 두는 방법 등이 있긴 하지만 추가적인 cost가 발생하게 된다..

 

 

토큰(Token)

세션 기반 인증 빙삭이 세션 정보(즉 인증 정보)를 서버에 저장하고 사용하는 식이라면, 토큰 기반 인증 방식은 서버가 아닌 클라이언트가 인증 정보를 직접 들고 있는 방식이다. 대표적으로 JWT(Json Web Token)방식이 가장 유명하다.

 

저작권 문제시 삭제하겠습니다..

 

컨셉은 다음과 같다

 

  1. 유저가 로그인을 시도하면, DB를 뒤져서 일치하는 유저 정보를 찾는다
  2. 찾았다면, 서버 쪽에서 가지고 있는 Secret key로 토큰을 발급한다.
  3. 클라이언트는 발급된 토큰을 저장하고, 이후 요청부터 토큰을 HTTP header에 실어 함께 보낸다.
  4. 서버는 단순히 전달받은 토큰이 유효한지 검증하고, 유효하면 인가해준다.

 

※ 장점

서버 쪽에서 저장하는 게 아니니 서버 쪽의 메모리가 확보된다. 또한 서버를 여러 개로 확장한 경우에도 모든 서버컴퓨터가 유저 정보를 기억하게 할 필요가 없다. 즉 확장성 쪽에서 엄청난 장점을 가진다. 

 

※ 단점

세션 인증 방식의 경우 세션 id만 실어서 보낸다. 반면 토큰의 경우는 사용자 인증 정보 뿐만 아니라 토큰의 발급 시각, 토큰의 id등의 정보도 가지고 있다. 즉 세션id보다 토큰의 사이즈가 더 크기 때문에 훨씬 더 많은 네트워크 트래픽이 유발된다.

뿐만 아니라 세션 인증 방식은 인증 정보를 서버에서 관리하는 반면 토큰은 클라이언트가 모든 인증 정보를 들고 있는 셈이라 보안 측면에서 좀 아쉽다. 세션id는 해커들에게 탈취돼도 서버측에서 해당 세션을 무효 처리하면 되는 반면 토큰은 해커들도 탈취한 다음 지들 맘대로 사용할 수 있다. 

상태 코드

: 클라이언트가 보낸 request의 처리 상태를 response에서 알려주는 것. 100번대 코드부터 500번대 코드까지 종류는 다양하며 각 번호대별로 다음과 같은 의미를 지닌다.

 

  • 1XX (Informational) : 요청이 수신되어 처리중
  • 2XX (Successful) : 요청이 정상적으로 처리됨
  • 3XX (Redirection) : 요청을 완료하려면 추가적인 행동이 필요함
  • 4XX (Client Error) : 클라이언트 측의 문제로 서버가 요청을 수행할 수 없음
  • 5XX (Server Error) : 서버 측 문제로 요청을 정상적으로 처리할 수 없음

 

만약, 클라이언트가 인식할 수 없는 상태 코드 즉 잘 모르는 상태 코드를 서버가 반환한다면, 클라이언트는 그걸 상위 상태코드로 해석해서 처리한다. 예를 들어 299번같은 상태코드는 "아 그냥 2XX : Successful로 뭉퉁쳐서 처리해야지~"하는 거다.


2XX - Successful

: 클라이언트의 request를 성공적으로 처리함을 알리는 상태코드.

 

  • 200 OK : 요청 성공을 의미
  • 201 Created : 요청을 성공해서 새로운 리소스가 생성됨을 의미. response message의 Location field에 새로 만들어진 리소스의 경로가 적힘
  • 202 Accepted : 요청이 접수됐으나 처리가 완료되지 않음을 의미. 예를 들면 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리하는 경우 등..
  • 204 No content : 서버가 request를 성공적으로 처리했으나 response message의 body에 넣어보낼 데이터가 없을 때. 예를 들어 save버튼을 눌러도 그 결과로 아무 내용이 없어도 괜찮을 때 등등..이 땐 결과 내용이 없어도 204 메시지만으로 성공여부를 식별 가능

 

3XX - Redirection

: 요청을 완료하기 위해 client의 추가적인 조치가 필요할 때

 

※ Redirection?

웹 브라우저는 3XX 응답의 결과에 Location 헤더가 있으면 그 위치로 자동적으로 이동되는데 이를 Redirect라고 한다. 예를 들어 client가 /event를 요청했지만 서버 입장에선 /event를 더 이상 안 쓰고 /new_event를 쓴다고 할 때, 서버는 3XX 응답과 함께 클라이언트를 /new_event로 redirect시킬 수 있다. 클라이언트 입장에선 브라우저가 지가 알아서 URL을 입력하고 엔터를 누른 느낌과 비슷하다. Redirection의 종류는

 

1. 영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동. 예를 들면 /members가 아니라 /users를 쓰기로 한 경우, /members로 들어오면 /users로 리다이렉트시킨다.

  • 301 Moved Permanently : 리다이렉트 시 요청 메소드가 GET으로 변함. 따라서 본문이 제거될 수 있음(앵간하면 제거됨)
  • 308 Permanent Redirect : 301과 기능은 같으나 리다이렉트 시 기존의 요청 메소드와 본문을 유지함(처음에 POST로 보냈었으면 리다이렉트도 POST로)

2. 일시 리다이렉션 : 일시적인 변경 즉 잠깐 이동시키는 리다이렉션. 예를 들면 주문 완료 후 주문 내역 화면으로 이동하는 리다이렉션 등이 있다. 

  • 302 Fount : 리다이렉트 시 요청 메소드가 GET으로 변하고 본문이 제거될 수 있음
  • 307 Temporary Redirect : 302와 기능은 같으나 리다이렉트 시 요청 메소드와 본문 유지
  • 303 See Other : 302와 기능은 같으나 리다이렉트 시 요청 메소드가 GET으로 변하는걸 확실하게 보장

3. 특수 리다이렉션

  • 304 Not modified : 캐시를 목적으로 사용. 클라이언트가 요청한 리소스가 수정되지 않았음을 알려주는 기능. 따라서 클라이언트는 로컬PC에 저장된 캐시를 재사용할 수 있음.

참고로 영구 리다이렉션과 일시 리다이렉션은 육안으로 보기엔 비슷함. 그러나 브라우저 입장에서는 이 차이가 뚜렷하다. /members리소스가 /users로 영구적으로 바뀌었다고 하면 브라우저는 그 변화를 반영한다. 즉 영구 리다이렉션은 브라우저가 그 변화를 반영함그러나 일시 리다이렉션의 경우는 일시적으로 리소스 위치가 바뀐 거니까 브라우저가 그 변화를 반영하지 않는다. 즉 클라이언트 입장에선 일시 리다이렉션의 경우 향후 보내는 요청도 바뀐 URI가 아니라 기존 URI로 보내야 한다. 영구 리다이렉트를 서버가 하는 리다이렉트, 일시 리다이렉트를 클라이언트가 하는 리다이렉트라고도 부른다.

 

4XX - Client Error

: 클라이언트 측의 request에 잘못된 문법 등으로 서버가 요청을 수행할 수 없는 것. 오류의 원인이 클라이언트 쪽에 있음을 의미한다. 

  • 400 Bad Request : 요청 구문, 메시지 등등 오류. 요청 파라미터가 잘못 되거나 API 스펙이 맞지 않는 상황 등..클라이언트는 요청 내용을 다시 검토하고 보내야 한다.
  • 401 Unauthorized : 클라이언트가 해당 리소스에 대한 인증이 필요함을 의미. 인증(Authentication)되지 않음을 의미. 따라서 원래 이름은 Unauthentiaction이 맞는 듯..ㅠ
  • 403 Forbidden : 서버가 요청을 이해했지만 승인을 거부. 주로 인증은 됐는데 권한이 없는 상황일 때 이런 응답 코드를 받음
  • 404 Not Found : 요청 리소스를 찾을 수 없을 때. 요청 리소스가 서버에 없을 때 등등

 

5XX - Server Error

: 서버 문제로 오류가 발생한 것

  • 500 Internal Server Error : 서버 내부 문제로 오류가 발생함을 의미. 애매하면 걍 다 500 오류임
  • 503 Service Unavailable : 서버가 일시적 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없을 때

 

4XX 에러는 클라이언트 쪽 문제니까 다시 시도해도 똑같이 안 되지만, 5XX에러는 서버 측 문제라 다시 하면 될 수도 있다는 차이점이 있다.

 

 

 

1. 클라이언트 - 서버 구조

: HTTP는 클라이언트가 request를 보내면 서버가 response를 보내는 구조이다. 즉 클라이언트와 서버가 개념적으로 분리된 형태이며, 클라이언트로부터 request가 안오면 서버는 자신의 힘으로 클라이언트 측으로 HTTP메시지를 보낼 수 없다는 얘기다.(HTTP는 서버가 클라이언트에게 먼저 메시지를 보낼 수 없고 클라이언트의 요청메시지에 대한 응답만 할 수 있다는 이야기임)

 

2. 무상태 프로토콜(stateless)이다

: HTTP는 서버가 클라이언트의 상태를 보존하지 않는 stateless한 프로토콜이다.

 

stateful, 즉 상태를 유지한다고 하면 서버는 클라이언트의 이전 상태를 기억한다. 쉽게 말해 내가 친구랑 맥북에 대해 대화하다가 "그거 살까?"라고 했다면 친구는 '그거'가 맥북을 지칭한다는 것을 알고 있다.stateless, 상태를 유지하지 않는다면 서버는 클라이언트의 이전 상태를 기억 못 한다. 내가 친구랑 맥북에 대해 대화하다가도 "그거 살까?"라고 했을 때 친구는 '그거'가 맥북을 말하는 건지 아이폰을 말하는건지 아이패드를 말하는 건지 모른다는 뜻이다. 따라서 이 상태라면 친구에게 "그거 살까?"가 아니라 "맥북 살까?"라는 식으로 대화해야 한다.

 

즉, stateless는 서버가 이전 상태를 기억하지 못 하기 때문에 매 요청 시마다 필요한 데이터를 몽땅 다 넘겨야 한다! 때문에 얼핏 보면 stateless방식은 전송하는 데이터 양이 더 많으니까 안 좋은 거 아닌가?할 수 있지만 이 방식은 서버 확장성이 높다는 엄청난 장점을 가진다. 생각해보면, stateful방식은 내가 재준이한테 맥북 얘기하다가 다훈이한테 가서 "그거 살까?"라고 하면 다훈이는 그게 뭔데 임마라고 하겠지만, stateless방식은 재준이한테 맥북 얘기하다가 다훈이한테 가서 "맥북 살까?"라고 얘기해도 괜찮다. 즉 stateless방식은 응답 서버를 쉽게 바꿀 수 있는 것이다. 때문에 클라이언트 요청이 폭증해도 서버를 대거 투입할 수 있으며 이론상 무한한 서버 증설이 가능하다. stateful방식은 클라이언트가 서버 A와 통신하기 시작했다면 계속 그 놈과 통신해야 하지만 stateless방식은 아무 서버나 입맛대로 호출해도 된다는 것.

 

3. 비연결성

: 연결을 유지한다는 것은 이는 클라이언트-서버 간에 딱히 주고받을 것이 없는 순간에도 계속해서 TCP/IP연결을 맺고 있는 걸 말하고 이는 서버의 자원을 소모하는 것을 의미한다. HTTP는 기본적으로 연결을 유지하지 않는다 즉 볼일이 끝나면 TCP/IP연결을 종료한다. 이로 인해 최소한의 서버 자원을 유지할 수 있음이 보장된다. 같은 시간동안 수천 수만 명이 서비스를 사용하다 특정 시간대에 서버에서 처리되고 있는 요청은 매우 적을 것이다(검색 기능이 있다고 할 때 동시에 검색 기능을 누르는 일은 많지 않은 것처럼). 따라서 이 비연결성 특성을 통해 서버 자원을 매우 효율적으로 이용할 수 있게 된다.

 

 그러나 이런 비연결성의 단점은 자원 요청 시마다 매번 TCP/IP 연결을 맺어야 하는데 이 작업은 3 way handshake가 수반되므로 overhead가 누적될 수밖에 없다는 것. 이 문제점은 HTTP 지속 연결(Persistent Connections)로 해결됐다.

 

4. 단순하고, 확장 가능하다

 

본 포스트는 아래 영상을 요약한 글로 원작자의 허락을 받고 올립니다. 저작권 문제시 본 글은 삭제조치하겠습니다

https://www.youtube.com/watch?v=1QiOXWEbqYQ&t=1s 

 


로그인? 아이디랑 비번 DB에 갖고있다가 로그인할 때는 그게 DB에 있는지 조회하면 될 줄 알았지만 그건 너무 날먹이었고~ㅋㅋㅋ 보안문제땜에 당연히 그렇게 안 한다고 한다.

 

로그인 기능을 만들기도 쉽지 않지만, 더 까다로운 건 로그인 상태를 유지하는 것! 지메일에 로그인했는데 메일 열 때마다 뭐 할때마다 로그인할 수는 없다. 내가 로그인하면 로그인했다는 걸 서버가 계속 알고 있어야 한다. 인증(Authentication)과 인가(Authorization)의 차이가 중요한 것.

 

JWT는 인가 즉 Authorization에 관련된 기술로, 어떤 사이트나 서비스에 사용자가 로그인했다가 서버에 인지시키는 것과 관련된다.

 

인가란 분야에서 전통적으로 많이 사용된 건 세션(session)이다. 사용자가 로그인에 성공하면 서버는 세션표딱지를 출력하는데 이걸 쭉 찢어서 반쪽은 브라우저라 보내고 반쪽은 자기가 갖는다. 브라우저는 이를 session ID라는 이름의 쿠키로 저장한다! 브라우저는 그럼 로그인된 사이트에 요청을 보낼따마다 이 표딱지를 실어보내고, 서버는 요청에 표딱지반쪽이(즉 session ID가) 서버는 자신이 가진 표딱지들 중 브라우저로부터 받은 반쪽짜리와 맞는 표딱지가 있는지 보고 ‘인가’한다. 이렇게 session ID를 사용해 서버에 로그인되어있음이 지속되는 상태를 ‘세션’이라고 표현한다. 그러나 이는 서버쪽 메모리가 날아가거나(재부팅 등으로) 너무 많은 유저들이 로그인하면 여러 반쪽표딱지들을 갖고 있어서 메모리가 부족해지는 현상이 생기기도 한다. 또한 여러 서버를 운영할 경우 로드밸런싱 문제로 로그인은 A 서버에서 하고(반쪽표딱지가 A 서버 메모리에 저장됨) 인가는 B 서버에서 진행될 수도 있는데, B 서버에는 A 서버에서 로그인한 반쪽표딱지가 없으니 에러가 생기기도 한다..

 

그래서 이런 부담없이 고안된 인가 방식이 토큰 방식인 JWT다. JSON WEB TOKEN의 줄임말이다. 토큰방식은 로그인하면 토큰이랑 딱지를 주는데, 세션방식과는 달리 반으로 찢지 않고 그대로 준다. 이는 서버가 뭔가를 기억하지 않는다는 얘기다! 토큰은 알파벳과 숫자들이 마구잡이로 섞인 문자열로 인코딩 또는 암호화된 3가지 데이터를 이어붙인 거다. XXXXXX.YYYYYY.ZZZZZZ같은 형태이며 마침표를 기준으로 세 가지 부분(헤더, 페이로드, 서명)으로 구분한다.

Payload

디코딩하면 JSON형식으로 여러 정보들이 들어있다. 토큰을 누가 누구에게 발급했는지, 언제까지 유효한지 등..토큰에 담긴 사용자 정보 등의 데이터를 Claim이라고 한다. 이를 통해 로그인 이후 요청들마다 사용자로부터 서버로 이 Claim들이 전해지는데, 사용자가 발급받아 갖고 있는 토큰 자체에 이런 정보들이 들어있으면 서버는 요청마다 하나하나 DB에서 뒤질 필요가 없으니 더 편하다. 근데 디코딩이 매우 쉬워서 누군가 수정할 오류가 있다! 근데 조금이라도 바뀌면 금방 알아챌 수 있다. 어떻게 하는지는 다음에 계속 서술

Header

디코딩하면 type(언제나 JWT가 들어감)과 alg(알고리즘)정보가 나온다. 여기는 ‘3번 서명값’을 만드는데 사용될 알고리즘이 지정된다(ex : HS256)

즉, Header와 Payload 그리고 서버에 감춰둔 비밀 값 이라는 3가지 요소를 암호화 알고리즘에 넣고 돌리면 3번 서명값이 나오는 거다. 암호화 알고리즘은 한쪽 방향으로만 계산이 돼서 토큰을 탈취해서 염병을 해도 서버가 감춰둔 비밀 값을 알아낼 수 없다.

여기서 주목. 서버는 요청에 토큰 값이 실려오면 Header와 Payload를 서버가 감춘 비밀값과 함께 알고리즘을 돌려서 계산된 값이 3번 서명값과 같다면, 그리고 유효기간이 지나지 않았다면 인가처리를 해준다. 이것이 JWT다. 참고로 Payload가 조금이라도 바뀌면 알고리즘 돌려서 나오는 값이 완전히 달라져서 3번 서명값과 같아지지 않는다. 이를 통해 payload변조를 알아챌 수 있다.

이를 통해, 서버는 사용자들의 상태를 어디다가 기록해둘 필요 없이 자신의 비밀 값만 가지고 있다면 요청들 들어올 때마다 헤비한 작업을 할 필요가 없다. 이처럼 시간에 따라 바뀌는 어떠한 상태값을 갖지 않는 걸 stateless하다고 표현한다. 세션은 반대로 stateful하다고 표현할 수 있다

그러나 JWT의 결점

stateful방식 즉 모든 사용자들의 상태를 기억하는 건 구현이 어렵고 고려사항도 많지만 구현만 되면 기억하는 대상의 상태들을 언제든 제어가능하다. 예를 들어 한 기기에서만 로그인가능한 서비스를 만든다고 하자. PC에서 로그인한 상태의 어떤 유저가 핸드폰으로 또 로그인하려하면 PC에서는 로그아웃되도록 만들 수도 있다는 얘기! JWT는 이런게 불가능하다. 이미 줘버린 토큰을 뺏을 수도 없고 토큰의 발급 내역(payload에 저장되는 정보)를 서버가 따로 추적할 수도 없으니..

즉 JWT는 내가 쥐고 있을 필요가 없어 편하긴 한데 그만큼 통제를 못 하는 방식이다.

또한 토큰이 만약 탈취된다면, 이 토큰을 무효화할 방법이 없다는 것도 큰 단점이다ㅋㅋ. 때문에 토큰을 두 개 발급하는 방법이 쓰이곤 한다. 완벽한 해결책은 아님. 이런 문제들이 큰 이슈가 안되는 서비스들에 한해서만 JWT만을 쓰는 인가방식을 쓰는 게 좋다.

※ 아래 영상을 보고 개인공부를 위해 정리할 겸 작성한 글입니다. 

https://www.youtube.com/watch?v=6fc9NAQkcv0&t=4s 

원작자의 허락을 받았으며, 문제가 될 시 본 글은 삭제조치하겠습니다 :)

 


1. DNS란 무엇인가?

Domain Name System의 줄임말이다. www.naver.com이란  란 url이 있을 때, naver.com이 도메인에 해당하고 www는 호스트 네임에 해당하는 부분이다.

 

2. 근데 잠깐! 도메인은 왜 있는거야?

우리가 어느 웹사이트에 들어가려 하면, 우리가 쓰는 웹 브라우저(ex : 크롬, 사파리 등)이 그 사이트를 제공하는 지구의 어딘가에 있는 서버에다가 요청 즉 request를 해야 한다. 이를 위해선 이 서버의 IP주소를 알아야 한다. 그런데 사실 모든 웹 사이트의 IP주소를 하나하나 외우고 다니는 건 힘드니까..친구들 전화번호 하나하나 외우기 싫어서 전화번호부 만드는 것처럼, 이 IP주소들을 key : value처럼(전화번호부 예로는 친구이름 : 전화번호) 특정이름 : IP주소 관계로 만들면 좋겠다고 사람들이 생각한거지.  여기서 특정이름에 해당하는 부분이 도메인.

 

3. 도메인을 IP주소와 대응시킨 거구나. 그럼 이 '전화번호부'가 저장되는 곳이 따로 있어?

그게 바로 DNS! 근데 System이란 말에서 알 수 있듯이 이 전화번호부가 어느 한 군데에 싹 몰려 있는게 아니다! 다층적으로 구성된 네트워크에 분산되어 있다.

 

4. DNS의 동작원리 간단하게 한 입

내 컴퓨터에서 www.naver.com에  에 접속하려는 상황이라고 하자. 그러면 naver사이트를 제공하는 서버에다가 request를 해야 하는데 그 서버의 IP주소를 현재 모르는 상태다! 이 때 브라우저는 PC에 설정된 로컬 DNS서버에 naver.com이라는 도메인과 www이라는 호스트 네임을 가지는 IP를 갖고 있는지 물어본다. (이 때 로컬 DNS서버는 통신사마다 다르며 사용자가 다른 곳으로 바꿀 수도 있음) 이 로컬 DNS서버엔 내가 원하는 IP주소가 이미 캐싱(caching)돼있을 수도 있고 아닐 수도 있는데, 캐싱돼있다면 바로 그 주소를 가져다가 쓰면 되고 없다면 다른 곳을 거쳐서 가져와야 한다.

 

여기서 '다른 곳을 거쳐오는 작업'은 우선 첫 번째로 Root DNS 서버에 이 주소(www.naver.com)에 해당하는 IP주소를 어디서 찾을 수 있냐고 물어본다. Root DNS 서버는 이에 대한 응답(response)로 .com으로 끝나는 도메인들을 담당하는 DNS 서버의 IP주소를 돌려준다! 이를 통해 로컬 DNS서버가 .com을 담당하는 DNS 서버에게 찾아가 내가 원하는 주소의 IP주소가 어딨느냐고 물으면, .com 담당 서버는 이에 대한 응답으로 naver.com의 도메인 정보를 가진 서버의 IP주소를 준다! 다시 이를 통해 로컬 DNS 서버가 naver.com의 도메인 정보를 가진 DNS 서버에게 찾아가고, 거기엔 여러 호스트 네임별(www, mail, blog 등)로 IP주소가 있는데 그 중 www와 매칭되는 IP주소 즉 www.naver.com의  IP주소를 준다. 이를 로컬 DNS서버가 브라우저에게 반환하면 비로소 www.naver.com의  의 서버로 접속하게 되는 것.

 

(개인적으론 컴퓨터 구조 시간에 배운 메모리, 캐시 등의 관계가 DNS서버간에도 있다는 게 신기했다)

 

5.  아니 그러면 DNS 서버들에 문제가 생기면 인터넷도 못하는거야?

Yes. 정확히 말하자면 DNS서버들에 문제가 생기면 전화전호부를 못 쓰게 되는 것이니 도메인을 통한 접속만 안되는 거고, IP주소를 안다면 그것을 활용한 접속이 가능. 그러나 IP주소로 직접 접근하는 걸 막아놓은 사이트는 아예 못 쓰는 것이 된다.

 

6. 가만 생각해보니, 해커가  DNS를 해커가 악의적으로 조작할 수 있을 것 같아

맞다. 해커가 악의적으로 내가 원하는 사이트의 IP주소가 아니라 다른 엉뚱한 사이트의 IP주소를 알려주도록 할 수 있다. 이를 DNS 스푸핑(DNS spoofing)이라 함!

 

7. 근데 로컬 DNS서버를 바꾼다는 건 뭐야?

로컬 DNS서버는 일반적으로 통신사 것으로 설정돼있는데, 이걸 수정한다는 것은 정부에서 막아놓은 사이트에 접속하거나 국가검열받은 전화번호부 대신 외국의 전화번호부를 쓴다는 것과 같은 의미! 또는 특정 서비스를 보다 빠르게 이용하기 위해 로컬 DNS서버를 바꾸기도 함. 예를 들어 기본 로컬 DNS서버를 구글의 서버 주소로 세팅하면 유튜브처럼 구글에서 제공하는 서비스를 보다 빠르게 이용가능! (그러나 다른 서비스들은 느려질 수 있으니 그냥 쓰던 대로 쓰자..)

'WEB > 그 외 필요한 지식' 카테고리의 다른 글

[짧] 단방향 암호화 vs 양방향 암호화  (0) 2023.01.24
세션 인증 방식 vs 토큰 인증 방식  (2) 2023.01.24
HTTP 상태 코드  (0) 2022.07.12
HTTP의 특징(stateless 등..)  (0) 2022.07.06
JWT(JSON WEB TOKEN)  (0) 2022.06.22

+ Recent posts