728x90

 

교착 상태, dead lock은 다중 프로그래밍 시스템에서 프로세스 or 스레드가 결코 일어나지 않을 일을 무한정으로 기다리는 상태를 말합니다. 

 

시스템에서 dead lock은 프로세스가 요구하는 자원이 엉켜서 더 이상 작업을 실행할 수 없는 상태를 의미합니다. 

 

아래 자동차(프로세스)들이 현재 위치한 길(자원)을 점유함과 동시에 다른 차가 사용하는 길을 사용하려고 대기하고 있지만, 다른 길을 사용할 수 없으며 현재 길에서 벗어나지도 못하는 상태와 같습니다. 

 

 

Dead Lock

 

즉, dead lock이란 둘 이상의 프로세스가 다른 프로세스가 점유하고 있는 자원을 서로 기다릴 때 무한 대기에 빠지는 상황을 말합니다. 

 

교착 상태의 발생 조건

언제 dead lock이 발생할까요? 

 

dead lock이 발생하기 위해서는 아래 네 가지 조건이 충족되어야 합니다. 

 

이 네 가지 중 하나라도 충족되지 않으면 dead lock이 발생하지 않습니다. 

 

  1. 상호배제(Mutual Exclusion) - 한 번에 한 프로세스만 자원을 사용할 수 있어야 합니다. 사용중인 자원을 다른 프로세스가 사용하려면 요청한 자원이 다 사용되고 해제될 때까지 기다려야 합니다. 
  2. 점유와 대기(Hold and Wait) - 최소한 하나의 자원을 점유하고 있으면서 다른 프로세스에 할당되어 사용되고 있는 자원을 추가로 점유하기 위해 대기하는 프로세스가 있어야 합니다. 
  3. 비선점(Non Preemption) - 자원을 선점할 수 없는 조건, 누군가가 자원을 가지고 있을 때 뺏을 수 없습니다. 
  4. 순환 대기(Circle Wait) - 프로세스가 여러 개 있을 때 자원의 점유와 요청의 관계가 순환되는 조건을 말합니다. 

 

아래의 그림은 순환 대기를 나타낸 것 입니다. 

 

 

프로세스 3개를 각각 P1, P2, P3라 할 때, P1이 P2의 자원을 요청하고, P2가 P3의 자원을 요청하고, P3가 P1의 자원을 요청하고 그 자원은 요청한 자원을 얻을 수 있을 때까지 반환할 수 없습니다. 

 

세 가지 프로세스는 자신이 요청한 자원을 얻지 못하기 때문에 계속해서 요청하며 위 사이클을 무한정 순환하게 됩니다. 

 

교착상태의 해결법

dead lock의 해결법은 크게 3가지로 분류할 수 있습니다. 

 

(1) dead lock 예방(prevention)하기 

 

위에서 살펴본 dead lock의 발생 조건 4가지 중 하나라도 발생하지 않게 하는 것이 dead lock을 예방하는 방법입니다. dead lock 발생 가능성을 차단하는 것입니다. 

 

  • 자원의 상호 배제 방지: 한 번에 여러 프로세스가 공유 자원을 사용할 수 있게 합니다. 그러나 추후 동기화 관련 문제가 발생할 수 있다. 
  • 점유와 대기 방지: 프로세스 실행에 필요한 모든 자원을 한꺼번에 요구하고 허용할 때까지 작업을 보류해서, 나중에 또 다른 자원을 점유하기 위한 대기 조건을 성립하지 않도록 한다. 
  • 비선점 방지: 이미 다른 프로세스에게 할당된 자원이 선점권이 없다고 가정할 때, 높은 우선수위의 프로세스가 해당 자원을 선점할 수 있도록 한다. 
  • 순환 대기 방지: 자원을 순환 형태로 대기하지 않도록, 일정한 한쪽 방향으로만 자원을 요구하도록 한다. 

 

물론 이렇게 데드락을 예방할 수 있지만, 시스템의 처리량이나 효율성을 떨어뜨리는 단점이 있습니다. 

 

 

(2) dead lock 회피(avoidance)

 

dead lock 회피는 dead lock 예방보다는 조금 덜 제한적인 방법으로 dead lcok 예방의 단점을 일부 해결할 수 있습니다. 

 

시스템의 프로세스들이 요청하는 모든 자원을 데드락을 발생시키지 않으면서 차례로 모두에게 할당해줄 수 있다면, 안정 상태(safe state)에 있다고 말합니다. 

 

반면, 불안정 상태는 안정 상태가 아닌 상황을 말한다. 데드락 발생 가능성이 있는 상황이며, 데드락은 불안정 상태일 때 발생할 수 있다. 

 

회피 알고리즘자원을 할당한 후에도 시스템이 항상 safe state에 있을 수 있도록 할당을 허용하자는 게 기본 특징이다. 이러한 특징을 살린 알고리즘으로 유명한 것이 은행원 알고리즘이다. 

 

 

은행원 알고리즘(Banker's Algorithm)

 

: 다익스트라가 제안한 기법, 어떤 자원의 할당을 허용하는지에 관한 여부를 결정하기 전에 미리 결정된 모든 자원들의 최대 가능한 할당량을 가지고 시뮬레이션해 safe state에 들 수 있는지 여부를 검사한다. 

 

즉, dead lock 가능성을 미리 조사하는 것이다. 

 

(시물레이션 예시)

 

위처럼 은행원 알고리즘을 사용해 자원 할당량을 사전에 파악하고, 데드락을 회피할 수 있도록 하면 된다. 

 

그러나 은행원 알고리즘의 경우, 미리 최대 자원 요구량을 알아야 하고, 할당할 수 있는 자원 수가 일정해야 하는 등 사용에 있어 제약 조건이 많고, 그에 따른 자원 이용도 하락하는 등 단점도 존재한다. 

 

 

(3) 데드락 탐지(detection) 및 회복(recovery)

 

시스템이 데드락 예방이나 회피를 사용하지 않았을 때, 데드락이 발생할 수 있으니 데드락을 탐지하고 회복하는 알고리즘을 사용한다. 

 

탐지 기법

  • Allocation, Request, Available 등으로 시스템에 데드락이 발생했는지 여부를 탐색한다. 
  • 은행원 알고리즘에서 했던 방식과 유사하게 현재 시스템의 자원 할당 상태를 가지고 파악한다. 
  • 이외에도 자원 할당 그래프를 통해 탐지하는 방법도 있다. 

 

회복 기법

  • 데드락 탐지 기법을 통해 데드락을 발견했다면, 순환 대기에서 벗어나 데드락으로부터 회복하기 위한 방법을 사용한다. 
  • 단순히 프로세스 1개 이상을 중단시키기
    • 교착 상태에 빠진 모든 프로세스를 중단시키는 방법: 계속 연산중이던 프로세스들도 모두 일시에 중단되어 부분 결과가 폐기될 수 있는 부작용이 발생할 수 있음
    • 프로세스를 하나씩 중단시킬 때마다 탐지 알고리즘으로 데드락을 탐지하면서 회복시키는 방법: 매번 탐지 알고리즘을 호출 및 수행해야하므로 부담이 되는 작업일 수 있음
  • 자원 선점하기 
    • 프로세스에 할당된 자원을 선점해서, 데드락을 해결할 때까지 그 자원을 다른 프로세스에 할당해주는 방법

 

 

728x90

'CS > 운영체제' 카테고리의 다른 글

동시성(Concurrency) vs 병렬성(Parallelism)  (0) 2021.08.01
시스템 콜(System Call)이란?  (0) 2021.08.01
728x90

 

동시성과 병렬성은 혼동하기 쉬운 개념입니다. 

 

그래서 둘을 비교해 정리해보도록 하겠습니다. 

 

먼저, 표를 통해 비교해보겠습니다. 

 

동시성 병렬성
동시에 실행되는 것 같이 보이는 것 실제로 동시에 여러 작업이 처리되는 것 
싱글 코어에서 멀티 쓰레드(Multi Thread)를 동작 시키는 방식 멀티 코어에서 멀티 쓰레드(Multi Thread)를 동작시키는 방식 
한 번에 많은 을 처리 한 번에 많은을 처리
논리적인 개념 물리적인 개념 

 

표로 봐도 차이가 있지만, 그림으로 더 확실히 차이를 보겠습니다. 

 

Sequential - Concurrent - Parallel

 

Sequential은 일들이 순차적으로 처리되고 있습니다. 하나의 일이 끝나면 다음으로 넘어가고, 그 다음으로 넘어가는 방식입니다. 

 

Concurrent는 파란색과 빨간색 두 개의 작업이 동시에 실행되는 것처럼 보이지만, 실은 번갈아가면서 작업을 수행중입니다. 

 

Parallel은 파란색과 빨간 색 두 개의 작업이 실제로 동시에 실행중입니다. 

 

 

그림을 하나 더 보도록 하겠습니다. 싱글 코어와 멀티 코어에서 동작을 비교하는 그림입니다. 

 

 

싱글 코어에서는 T1과 T2, 2개의 작업을 동시에 실행되는 것처럼 보이게 하기 위해 번갈아가면서 작업을 수행중입니다. 

 

이 때, 다른 작업으로 바꾸어 실행할 때 내부적으로 Context Switch가 일어납니다. 

 

멀티 코어는 실제로 T1과 T2가 동시에 수행중입니다. 

 

 

이제 감을 잡았으니, 동시성과 병렬성을 다시 정리해봅시다. 

 

동시성

  • 싱글 코어에서 멀티 스레드를 동작시키기 위한 방식
  • 멀티 태스킹을 위해 여러 개의 스레드가 번갈아가면서 실행되는 성질
  • 동시에 실행되는 것처럼 보이는 것
  • 싱글 코어에서 멀티 스레드를 이용해 동시성을 구현하는 일부 케이스에 대한 내용, 멀티 코어에서 멀티 스레드를 이용하여 멀티 스레드를 이용하여 동시성을 만족할 경우에는 실제 물리적 시간으로 동시에 실행된다. 

 

병렬성

  • 멀티 코어에서 멀티 스레드를 동작시키는 방식
  • 한 개 이상의 스레드를 포함하는 각 코어들이 동시에 실행되는 성질
  • 병렬성의 핵심은 물리적인 시간에 동시에 수행되는 것, 멀티 코어에 포커스가 맞춰져서는 안 된다.
  • 네트워크 상의 여러 컴퓨터에게 분산 작업을 요청하는 분산 컴퓨팅

 

 

728x90

'CS > 운영체제' 카테고리의 다른 글

교착 상태(dead lock)이란?  (0) 2021.08.01
시스템 콜(System Call)이란?  (0) 2021.08.01
728x90

 

운영체제는 컴퓨터를 제대로 실행 및 사용하게 해주는 프로그램입니다. 

 

마우스를 움직이는 것부터 프로그램 실행과 종료까지 운영체제가 하는 역할은 매우 많고 없으면 컴퓨터를 사용할 수 없습니다. 

 

이러한 운영체제와 시스템 콜은 어떤 관계가 있을까요? 

 

시스템 콜(System Call)이란 프로세스가 운영체제(system)에게 운영체제 기능을 요청(call)하는 것입니다. 

 

즉, 프로세스가 컴퓨터를 관리하는 시스템인 운영체제에게 어떤 기능(서비스)를 사용하게 해달라고 요청할 때 사용하는 방법입니다. 

 

컴퓨터의 대부분의 활동은 운영체제를 통해 실행 및 관리됩니다. 

 

실행중인 프로그램인 프로세스도 운영체제를 통해 실행되고 관리됩니다.  

 

 

운영체제가 회사 관리자면, 프로세스는 말단 직원입니다. 

 

예를 들어, 프로세스 A라는 직원이 자신의 프로그램 외 특정 파일의 데이터를 필요로 한다고 해봅시다.

 

이럴 때, 프로세스 A가 독자적으로 파일 데이터를 읽어들일 수 있을까요? 그럴 수 없습니다. 

 

기본적으로 파일을 읽고, 메모리에 데이터를 올리는 것운영체제의 역할입니다. 

 

프로세스 A는 관리자인 운영체제에게 허락을 요청(call)해야 합니다. 

 

파일 뿐 아니라 운영체제가 관리하는 모든 자원(네트워크, 디스크, 메모리 등)이 필요할 때, 프로세스는 system call을 사용해야 합니다. 

 

파일을 여는 것(open), 기존 프로세스를 다른 프로그램으로 바꾸는 것(exec), 똑같은 프로세스를 하나 더 만드는 것(fork), 다른 프로세스에 어떤 행위를 지시하는 시그널을 보낼 때(kill) 등 운영체제가 관리하고 있는 자원이라면 system call을 사용해야 합니다. 

 

 

아래는 실제 리눅스, 유닉스에서 사용하는 System Call입니다. 

 

리눅스 system call
유닉스 system call ⬅️ 출처: Operating System Concepts 10th - SILBERSCHARTZ 68page 

 

 

 

참고한 글의 링크입니다. 

https://mamu2830.blogspot.com/2021/01/whatIsSystemCall.html

728x90

'CS > 운영체제' 카테고리의 다른 글

교착 상태(dead lock)이란?  (0) 2021.08.01
동시성(Concurrency) vs 병렬성(Parallelism)  (0) 2021.08.01
728x90

 

HTTPS, 대칭키, 공개키, CA에 대해 모른다면 아래 포스팅을 참고해보자. 

https://dolphinsarah.tistory.com/52

 

HTTPS (대칭키, 공개키, CA)

HTTP에 보안처리(SSL)가 된 버전이 HTTPS이다. (요즘은 HTTPS가 웹의 기본 스펙이라고 봐도 무방함) HTTPS는 기존 HTTP 레이어에서 SSL 또는 TLS 프로토콜을 얹어 평문 데이터를 암호화하고,  암호화, 인

dolphinsarah.tistory.com

 

SSL은 아래 3가지 액션으로 인해 동작하게 된다. 

  • 악수(handshake)
  • 데이터 전송
  • 세션 종료

 

악수(handshake)

클라이언트, 서버 간의 통신을 하기 전 실제 통신을 할 수 있는지, 서로 검토하는 단계이다. 

 

사람이 처음 만나면 악수를 하듯이, 클라이언트와 서버도 비슷하다. 

 

클라이언트가 서버에 처음 접속하게 되는 시점, 단계를 Client Hello라고 한다. 

또한, 서버는 Client Hello에 대한 응답으로 Server Hello를 하게 된다. 

 

Client Hello 단계

  • 클라이언트에서 랜덤 데이터를 생성한다. 
  • 클라이언트에서 사용할 수 있는 암호화 방식들을 서버에 전달한다. 
  • 클라이언트에서 사용되는 암호화 방식과 서버에서 가능한 암호화 방식이 다를 수 있기 때문에, 두 군데 모두 사용할 수 있는 암호화 방식에 대해 협상이 필요하다. 

 

Server Hello 단계

  • Client Hello에 대한 응답 과정이다. 
  • 클라이언트와 동일하게 랜덤 데이터를 생성하며, 클라이언트에 전달한다. 
  • 클라이언트가 전달한 암호화 방식 중에서 서버 쪽에서도 사용할 수 있는 암호화 방식을 선택해서 클라이언트로 전달한다. 채택된 암호화 방식으로 클라이언트-서버 간 통신이 진행된다. 물론 클라이언트에서 보내준 암호화 방식을 서버에서 지원하지 않는다면, 암호화 협상 결렬로 인해 악수는 불발된다. 
  • 서버가 발급받은 인증서를 클라이언트로 전달한다. 

 

Client 인증 단계

  • 클라이언트는 서버의 인증서가 CA에 의해서 발급된 것인지를 확인하기 위해 클라이언트에 내장된 CA 리스트를 확인한다. CA 리스트에 인증서가 없다면 사용자에게 경고 메시지를 출력한다. 인증서가 CA에 의해서 발급된 것인지를 확인하기 위해 클라이언트에 내장된 CA의 공개키를 이용해서 인증서를 복호화한다. 복호화에 성공했다면 인증서는 CA의 개인키로 암호화된 문서임이 암시적으로 보증된 것이다. 인증서를 전송한 서버를 믿을 수 있게 된 것이다. 
  • 클라이언트는 Server Hello 단계에서 받은 랜덤 데이터와 Client Hello 단계에서 생성한 랜덤 데이터를 조합하여 pre master secret 키를 생성한다. 이 키는 데이터를 주고받을 때 사용하기 위한 암호화 키이며 대칭키 방식으로 사용되어질 키 값이다. 중요한 키임으로 절대 제 3자에게 노출되면 안된다. 그렇기 때문에 이 pre master secret 키 값을 서버에게 전달할 때 서버가 제공한 공개키로 암호화 하여 전송하며, 서버는 자신의 비공개키로 복호화하여 pre master secret 값을 취득한다. 클라이언트가 사용한 공개키는 Server Hello 단계에서 전달받은 인증서 안에 들어있다

 

Server 인증 단계

  • 서버는 클라이언트가 전송한 pre master secret 값을 자신의 비공개키로 복호화한다. 이제 서버와 클라이언트 모두 pre master secret 값을 공유하게 되었다. 
  • 서버와 클라이언트는 모두 일련의 과정을 거쳐서 pre master secret 값을 master secret 값으로 만든다. 
  • master secret은 session key를 생성하는데, 이 session key 값을 이용해서 서버와 클라이언트는 데이터를 대칭키 방식으로 암호화 한 후에 주고받는다. 이렇게 해서 세션키를 클라이언트와 서버가 공유하게 된다. 

 

악수(handshake) 종료

  • 위의 과정으로 클라이언트와 서버는 악수 단계의 종료를 서로에게 공유한다. 

 

데이터 전송

: 실제로 서버와 클라이언트가 데이터를 주고 받는 과정이다. 상대방에게 데이터를 송신하기 전, 악수 단계에서 발생한 세션 키 값으로 데이터를 대칭키방식으로 암호화한다. 

 

암호화된 데이터는 상대방으로 송신되며, 상대방도 세션키를 알고 있기 때문에 데이터를 복호화할 수 있다. 

 

SSL 통신은 공개키 방식, 대칭키 방식의 하이브리드 조합으로 통신한다. 

공개키 방식은 컴퓨터 자원을 꽤 많이 사용함으로 비용이 많이 드며, 또한 대칭키 방식만 사용하게 되면 인터넷 상 대칭키를 서로 주고받아야 하는데, 보안상 매우 위험하다.

 

그래서 속도는 느리지만 데이터를 안전하게 주고 받을 수 있는 공개키 방식으로 대칭키를 암호화하고, 실제 데이터를 주고 받을 때는 대칭키를 이용해서 데이터를 주고 받는 것이다. 

 

세션 종료

: 데이터 송수신이 끝나면 SSL 통신이 끝났음으로 서로에게 알려준다. 

이때, 통신에서 사용한 세션키(대칭키)를 폐기한다. 

 

728x90

'CS > 네트워크' 카테고리의 다른 글

HTTPS (대칭키, 공개키, CA)  (0) 2021.06.18
포워드 프록시(Forward Proxy)와 리버스 프록시(Reverse Proxy)  (0) 2021.06.17
HTTP 2.0과 특징  (0) 2021.06.11
로드밸런싱  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
728x90

HTTPS

 

HTTP에 보안처리(SSL)가 된 버전이 HTTPS이다. (요즘은 HTTPS가 웹의 기본 스펙이라고 봐도 무방함)

 

HTTP와 HTTPS

 

HTTPS는 기존 HTTP 레이어에서 SSL 또는 TLS 프로토콜을 얹어 평문 데이터를 암호화하고,  

암호화, 인증, 그리고 무결성 보장을 통해 더 안전히 만들어주는 프로토콜이다. 

 

SSL과 TLS

SSL(Secure Sockets Layer)은 TLS(Transport Layer Security)의 과거 명칭이라고 봐도 무방하다. 

TLS는 SSL 3.0을 기초로 해서 IETF가 만든 프로토콜이다. 

 

TLS는 SSL 3.0을 보다 안전하게 하고, 프로토콜의 스펙을 더 정확하게 안정성을 높이는 목적으로 고안하였다. 

 

SSL이나 TLS를 통해 평문을 암호화하고, 복호화할 때,

대칭키나 공개키 방식을 사용하는데 이에 대해 알아보자. 

 

대칭키

대칭키 암호화 방식은 집 열쇠와 같다고 생각하면 된다. 

대칭키를 가지고 데이터를 암호화하고, 또 대칭키로 데이터를 복호화한다. 

 

예를 들어 'abc'라는 키로 데이터를 암호화했다면, 데이터를 복호화하기 위해서는 반드시 'abc' 키가 필요하다. 

 

즉, 클라이언트와 서버가 대칭키 방식으로 통신을 한다면, 클라이언트도 키를 가지고 있어야 한다. 

 

그런데 대칭키 방식은 치명적인 단점이 있다. 

암호를 주고 받는 사이에서 대칭키를 전달하는 것이 어렵고

만약, 중간에 대칭키가 탈취 또는 유출되면 그 키로 암호화 되었던 데이터들은 모두 유출된다. 

 

즉, 원거리에서 대칭키를 안전하게 전달하는 것은 매우 어렵다

 

이러한 대칭키의 단점을 극복하고자 나온 방식이 공개키 방식(PKI, Public Key Infrastructure)이다.

 

공개키(비대칭키)

공개키 방식은 공개키개인키(비밀키)라는 2가지의 비대칭키를 가진다. 

 

만약, A키로 암호화하면 B키로 복호화 가능하며, 반대로 B키로 암호화하면 A키로 복호화가 가능하다. 

 

A와 B 중 하나는 공개키(public key)가 되고, 나머지 하나는 비공개키(private key)가 된다. 

 

비공개키소유자, 즉, private한 사용자가 가지고 있게 되며, 

공개키소유자와 타인에게 공개되는 키이다. 

 

타인공개키를 이용하여 데이터를 암호화해 소유자에게 전달하면, 

소유자비공캐기복호화하여 그 데이터를 얻을 수 있게 된다. 

 

이 방식은 안전하게 데이터를 주고받을 수 있게 만들어주지만, 속도가 느리다는 단점이 있다. 

 

전자서명

비공개키의 소유자는 비공개키를 이용해서 정보를 암호화 한 후에 공개키와 함께 암호화된 정보를 전송한다. 

 

정보와 공개키를 획득한 사람은, 공개키를 이용해 암호화된 정보를 복호화한다. 

 

이 과정에서 공개키가 유출된다면 의도하지 않은 공격자에 의해 데이터가 복호화될 위험이 있다. 

 

이런 위험에도 불구하고 비공개키를 이용해 암호화를 하는 이유가 뭘까? 

비공개키는 데이터를 보호하는 것이 목적이 아니다

 

암호화된 데이터를 공개키를 가지고 복호화할 수 있다는 것은 그 데이터가 공개키와 쌍을 이루는 비공개키에 의해서 암호화되었다는 것을 의미한다. 

 

즉, 공개키가 데이터를 제공한 사람의 신원을 보장해주는 것이다. 이러한 것을 전자서명이라고 부른다.

 

SSL 인증서와 CA(Certificate Authority)

SSL을 적용하기 위해서는 인증서가 필요하다. 

 

SSL 인증서는 아래의 2가지를 제공한다. 

  • 클라이언트가 접속한 서버가 신뢰 있는 서버임을 증명(인증서 발급 CA, 도메인 등)한다. 즉, 클라이언트가 접속한 서버가 클라이언트가 목적한 서버가 맞는지 확인한다. 
  • SSL 통신에 사용될 공개키를 클라이언트에 제공(서버 공개키)한다. 서버와 클라이언트가 통신할 때 사용될 공개키와 공개키 암호화 방법들의 정보가 있다. 

 

CA는 이 SSL 인증서를 발급해주는 기업이다. 

인증서가 보안에 관련된 것인만큼 CA는 신뢰할 수 있는 기업에서만 가능하다. 

 

SSL 인증서 및 내용은 CA에 의해서 암호화된다. 이때 CA는 자신의 비공개키로 서버가 제출한 인증서를 암호화한다. 

 

CA의 비공개키는 절대로 유출되어서는 안되며, 실제로 디지노타라는 회사에서 CA의 비공개키가 유출된 사례가 있어 CA 자체가 파산된 경우도 있다고 한다. 

 

브라우저와 CA

브라우저는 내부적으로 CA의 리스트를 미리 알고 있다. 

즉, 브라우저 소스 안에 CA 리스트가 존재한다는 말이다. 

CA 리스트 뿐만 아니라, 각 CA의 공개키도 이미 브라우저 안에 내장되어 있다. 

 

브라우저가 서버에 접속할 때, 서버는 클라이언트에게 인증서를 제공한다. 

브라우저는 서버에서 받은 인증서가 자신이 가지고 있는 CA 리스트에 있나 확인을 한다. 

 

비교 후 정상적인 인증서이면, 해당 CA의 공개키(브라우저 안에 있는)를 이용하여, 인증서를 복호화한다. 

 

복호화가 됐다면, 그 인증서는 CA의 비공개키로 암호화된 것을 의미한다.

 

즉, 해당 CA에 의해 정상적으로 발급된 인증서라는 의미가 되며, 그것은 클라이언트가 접속한 서버에서 제공한 인증서가 해당 CA에 의해 정상적으로 발급됐다는 의미이다. 

 

=> 클라이언트가 접속한 서버에서 받은 인증서가 CA에서 정상적으로 발급된 인증서이다. 

 

 

다음 포스팅에서는 HTTPS의 동작 원리에 대해 알아보도록 하자. 

https://dolphinsarah.tistory.com/53

 

HTTPS 동작 원리

HTTPS, 대칭키, 공개키, CA에 대해 모른다면 아래 포스팅을 참고해보자. https://dolphinsarah.tistory.com/52 HTTPS (대칭키, 공개키, CA) HTTP에 보안처리(SSL)가 된 버전이 HTTPS이다. (요즘은 HTTPS가 웹의 기..

dolphinsarah.tistory.com

 

 

 

 

 

 

728x90

'CS > 네트워크' 카테고리의 다른 글

HTTPS 동작 원리  (0) 2021.06.18
포워드 프록시(Forward Proxy)와 리버스 프록시(Reverse Proxy)  (0) 2021.06.17
HTTP 2.0과 특징  (0) 2021.06.11
로드밸런싱  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
728x90

 

프록시(Proxy)는 대신해준다는 뜻이다. 

 

프록시는 여러 곳에서 쓰이는데, 디자인 패턴 중에도 프록시 패턴이 있고, 자바스크립트에서도 프록시 객체가 쓰인다. 

 

오늘 알아볼 포워드 프록시(Forward Proxy)와 리버스 프록시(Reverse Proxy)는 프록시 서버다. 

 

프록시 서버는 클라이언트나 서버를 대신해 인터넷과 연결한다. 

 

프록시의 위치에 따라 포워드 프록시와 리버스 프록시로 구별되기도 하고, 

사용하는 프로토콜에 따라 HTTP 프록시, SOCKS 프록시 등으로 구분하기도 한다. 

 

HTTP 프록시는 일반적으로 HTTP와 HTTPS 프로토콜들을 연결한다. 

 

SOCKS 프록시는 Socket Secure인데 클라이언트와 네트워크가 패킷을 교환할 때, FTP, HTTP, SMTP 등의 여러 프로토콜을 받을 수 있다. 

 

포워드 프록시(Forward Proxy)

 

포워드 프록시는 클라이언트, 즉, 사용자들을 대신해 인터넷과 연결한다. 

 

Forward Proxy

 

좀 더 와닿게 설명하자면, 

웹브라우저나 토렌트 같은 곳에 프록시를 설정해주면 그 프록시를 통해서 데이터를 주고 받는다

 

즉, 포워드 프록시란 '목적지에 직접 접근하지 않고 프록시를 통해 데이터를 주고 받기 위해 사용하는 프록시'이다. 

 

아이패드나 아이폰은 와이파이 연결 정보에서 자체적으로 포워드 프록시 정보를 설정할 수 있도록 제공한다고 한다. 

 

만약, 아이폰에서 포워드 프록시를 설정한 뒤 인터넷을 사용한다면, 

아이폰이 와이파이를 통해 직접 외부 서버에 데이터를 요청하는 것이 아니라, 

포워드 프록시로부터 간접적으로 원하는 서버의 데이터를 받아오게 된다. 

 

 

프록시 서버는 네트워크 계층의 여러 곳에 존재할 수 있다. 

 

인트라넷을 묶어서 프록시를 통해 인터넷과 연결시킬 수도 있고, 여러 유저들이 프록시 서버를 이용해 인터넷에 접속할 수도 있다. 

 

포워드 프록시를 이용해서 얻는 이점은 다음과 같다. 

 

속도

프록시 서버는 여러 사용자들의 요청을 캐싱한다. 

초기에는 캐싱으로 인한 속도 향상을 기대하고 프록시 서버를 사용했지만, 

집집마다 초고속 인터넷이 되는 요즘 시대에 큰 이점이라고 하기는 어렵지만.... 초기에는 이점이었다!

 

검열

초등학교 컴퓨터실에서 특정 사이트에 들어가려고 하면 막혀 있는 경우가 있다.

프록시 서버를 사용했기 떄문이다. 

 

또, 회사 컴퓨터는 외부 이메일을 막아 보안 기능으로 활용한다. 

 

이것이 가능한 것은 프록시가 필터 기능트랜스코드를 할 수 있기 때문이다. 

 

프록시 서버는 사용자를 검열, 보안, 감시할 수 있다. 

 

익명성

프록시는 사용자의 요청을 대신 처리하기 때문에 IP 우회가 가능하다. 

 

IP 주소를 숨기긴 하지만, 데이터를 암호화하지 않는다. (VPN은 한다.)

 

VPN

: Virtual Private Network, 가상 사설망이다. 프록시에 보안을 더했다고 보면 된다.

vpn은 망 내에서 일어나는 모든 과정을 암호화한다. 그래서 일반 프록시보다는 훨씬 안전하다. 

(물론 vpn 운영자가 나쁜 마음을 먹을 경우는 결코 안전하다고 말할 수 없다)

 

 

리버스 프록시(Reverse Proxy) 

 

리버스 프록시는 포워드 프록시와는 반대로 서버를 대신해 인터넷과 연결한다. 

 

Reverse Proxy

 

즉, 다른 서버의 정보를 프록시를 통해 받아오는 부류의 프록시를 뜻한다.

 

단, 포워드 프록시와는 다르게 사용자가 요청하는 Endpoint(서버 요청 url)는 접근하고자 하는 최종 목적지 서버가 아닌, 리버스 프록시가 된다. 

 

보통 HA(High Availability)를 위한 Load Balancing이나 보안상의 이유로 쓰이는 것이 일반적인데, 

리버스 프록시의 back-end 단에 여러 개의 서비스 서버를 배치하고, 

사용자의 요청을 리버스 프록시를 통해 분산할 때 유용하게 쓰일 수 있기 때문이다. 

 

Load Balancing

 

보안 상의 이유로 직접 내부망 서버들, 즉 back-end 단의 서버에 접근하는 것을 

원하지 않을 때 DMZ와 같은 네트워크 zone에 리버스 프록시를 구성함으로써

간접적으로 서버에 접근하는 용도로 쓰일 수도 있다. 

 

대표적인 리버스 프록시로는 nginx, apache 웹서버 등이 있다. 

haproxy도 비슷한 의미의 리버스 프록시라고 볼 수 있으며, 

도커 엔진이 자체적으로 제공하고 있는 도커 스윙 모드 서비스의 Virtual IPs를 이용한 요청 분산도 같은 맥락이라고 볼 수 있다. 

 

리버스 프록시를 이용해 얻는 이점은 아래와 같다.

 

검열

포워드 프록시와 마찬가지로 필터링 기능을 이용해 검열이 가능하다.

유저의 IP를 확인하고 접속을 허용한다. 

 

분산부하

큰 서비스들은 서버를 여러 대 사용한다. 

이때, 리버스 프록시는 쏟아지는 트래픽을 여러 대의 서버로 분산해주는 '로드밸런싱'을 해준다. 

 

 

 

 

 

 

 

728x90

'CS > 네트워크' 카테고리의 다른 글

HTTPS 동작 원리  (0) 2021.06.18
HTTPS (대칭키, 공개키, CA)  (0) 2021.06.18
HTTP 2.0과 특징  (0) 2021.06.11
로드밸런싱  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
728x90

 

HTTP 2.0이라고도 불리는 HTTP/2는 Hypertext Transfer Protocol Version 2의 약자이다. 

 

2015년 IETF(Internet Engineering Task Force, 국제 인터넷 표준화 기구, 인터넷의 운영, 관리, 개발에 대해 협의하고 프로토콜과 구조적인 사안들을 분석하는 인터넷 표준화 작업 기구)에 의해 공식적으로 발표된 HTTP/1.1(기존 표준)의 차기 버전이다. 

 

HTTP/1.x이 느린 이유

 

HTTP/1.x이 느린 이유, 바꿔 말하면 HTTP 2.0이 등장하게 된 배경은 아래와 같다. 

 

 

위의 사진만 봐도 알 수 있듯, HTTP 1.0버전대만 하더라도, Request를 날릴 때마다 Connection을 새로 생성했다. 

 

Short-lived connections는 너무 비효율적이어서, HTTP 1.1에서는 Persistent Connection이라는 개념과 HTTP Pipelining이라는 개념이 만들어졌다. 

 

커넥션을 재사용할 수 있고, request를 미리 여러 개 서버에 날릴수도 있게 되었다. 

 

그러나 이러한 개선에도 불구하고, request를 보낸 순서대로 response를 받을 수 있다는 지점에서 문제가 발생했다. 

 

HOL(Head of line) blocking (특정 응답 지연)

만약, 처음에 요청한 request에 문제가 발생해 응답이 늦어질 경우, 

 

2번째, 3번째에 요청한 request의 응답도 같이 늦어진다는 문제점이 발생한다. 

 

RTT(Round Trip Time) 증가 (양방향 지연) 

Round Trip Time은 네트워크 시작 지점에서 대상 지점으로 이동하고 시작 지점으로 다시 이동하는 데 걸리는 시간이다. 

 

앞서 말한 것처럼 매 요청별로 connection을 만들게 되고, TCP 상에서 동작하는 HTTP의 특성상 3-way-Handshake가 반복적으로 일어나게 되며, 불필요한 RTT 증가와 네트워크 지연을 초래하여 성능을 저하시키게 된다. 

 

무거운 헤더(특히 쿠키)

HTTP 1.x의 헤더에는 많은 메타 정보들이 저장되어 있다. 

 

사용자가 방문한 웹페이지는 다수의 http 요청이 발생하게 되는데, 이 경우 매 요청마다 중복된 헤더 값을 전송하게 되며, 각 도메인에 설정된 쿠키 정보도 매 요청마다 헤더에 포함되어 전송된다. (전송값보다 헤더가 더 큰 경우도 있다) 

 

 

문제점들을 해결하기 위한 UI & 프론트엔드 개발자의 노력

 

  • 이미지 스프라이트 
    • 여러 개의 이미지를 하나의 이미지로 합쳐서 관리하는 이미지(사용할 때는 좌표 범위로 구분해 사용)
  • 도메인 샤딩
    • 리소스를 여러 개의 도메인으로 나누어 저장하여, 페이지 로드 시간을 빠르게 하는 일종의 트릭 혹은 방법
    • 여러 개의 도메인으로 나누어진 리소스를 다운받기 때문에 브라우저는 더 많은 리소스를 한 번에 받을 수 있다. 
    • 최신 브라우저들은 보통 한 도메인에 약 6개의 동시 다운로드를 제공한다. 
    • 이 개수를 초과하는 페이지의 경우, 초과하는 개수를 6으로 나눈 도메인에 리소를 뿌려두면, 병렬적으로 리소스들을 다운 받을 수 있다. 
  • CSS/JavaScript 압축
  • Data URI

 

HTTP 2.0의 등장 

SPDY

구글은 더 빠른 WEB을 실형하기 위해 Latency 관점에서 HTTP를 고속화한 SPDY라 불리는 새 프로토콜을 만들었다. 

 

SPDY는 HTTP를 대치하는 프로토콜이 아니라, HTTP를 통한 전송을 재정의하는 형태로 만들어졌다. 

 

SPDY는 실제로 HTTP/1.1에 비해 상당한 성능 향상과 효율성을 보여줬고, 이는 HTTP/2.0 초안의 참고 규격이 되었다. 

 

 

 

HTTP 2.0은 완전히 새로운 프로토콜이 아니라 SPDY의 개선사항을 적용해 성능 향상에 초점을 맞춘 프로토콜이라고 생각하면 될 것 같다. 

 

HTTP 2.0이 빠른 이유 

  1. Multiplexed Streams - 한 커넥션에 여러개의 메시지를 동시에 주고받을 수 있고, 응답은 순서에 상관없이 stream으로 주고 받는다. 
  2. 요청이 커넥션 상에서 다중화되므로 HOL(Head Of Line) Blocking이 발생하지 않음 
  3. Stream Prioritization(요청 리소스 간 의존관계를 설정) - 클라이언트가 요청한 HTML 문서 안에 CSS 파일 1개와 Image 파일 2개가 존재하고, 이를 클라이언트가 각각 요청한 후, Image 파일 보다 CSS 파일의 수신이 늦어지는 경우, 브라우저의 렌더링이 늦어지는 문제가 발생한다. HTTP/2의 경우 리소스 간 의존 관계(우선 순위)를 설정해 이런 문제를 해결했다. 
  4. Header Compression(Header 정보를 HPACK 압축 방식을 이용하여 압축 전송) - HTTP/2에서는 Header에 중복값이 존재하는 경우, Static/Dynamic Header Table 개념을 사용하여 중복 Header를 검출하고, 중복된 Header는 index 값만 전송하고 중복되지 않은 Header 정보의 값은 Huffman Encoding 기법으로 인코딩 처리하여 전송한다. 
  5. Server Push(HTML 문서 상에 필요한 리소스를 클라이언트 요청없이 보내줄 수 있음) - 클라이언트가 HTML 문서를 요청하고 해당 HTML에 여러 개의 리소스(CSS, Image,...)가 포함되어 있는 경우, HTTP/1.1에서는 클라이언트는 요청한 HTML 문서를 수신한 후, HTML 문서를 해석하면서 필요한 리소스를 재요청하는 반면, HTTP/2에서는 Server Push 기법을 통해 클라이언트가 요청하지 않은 리소스를 push해주는 방법으로 클라이언트의 요청을 최소화하여 성능 향상을 이끌어냈다. PUSH_PROMISE라고 부르며, PUSH_PROMISE를 통해 서버가 전송한 리소스에 대해서 클라이언트는 요청하지 않는다. 
  6. 프로토콜 협상 메커니즘 - 프로토콜 선택. like HTTP / 1.1, HTTP / 2 또는 기타 
  7. HTTP / 1.1과의 높은 수준의 호환성 - 메소드, 상태코드, URI 및 헤더 필드
  8. 페이지 로딩 속도 향상

 

하지만, HTTP/2는 여전히 TCP를 이용하기 때문에 HandShake의 RTT(Round Trip Time)로 인한 Latency(지연 시간), TCP의 HOL Blocking은 해결할 수 없다. 

 

그래서 HTTP/3가 등장했다. 

 

다음 포스팅에서는 HTTP/3에 대해 알아보자. 

 

728x90

'CS > 네트워크' 카테고리의 다른 글

HTTPS (대칭키, 공개키, CA)  (0) 2021.06.18
포워드 프록시(Forward Proxy)와 리버스 프록시(Reverse Proxy)  (0) 2021.06.17
로드밸런싱  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
JWT - 토큰 기반 인증  (1) 2021.06.04
728x90

 

클라이언트가 한 두 명일때, 서버는 여유롭게 사용자가 원하는 결과를 응답해줄 수 있다. 

 

하지만 대규모의 서비스는 클라이언트가 수천만명 혹은 그 이상이다. 

 

아무리 성능이 뛰어난 서버라고 해도 모든 트래픽을 감당할 수 없다. 

 

그래서 기업들은 서버를 추가로 구비하고, 여러 대의 서버에 동일한 데이터를 저장하여

수많은 트래픽을 효과적으로 분산하게 된다. 

 

그런데, 단순히 다수의 서버를 구축해 운영한다고 해서 모든 클라이언트의 요청에 일관성 있게 응답할 수 있을까?

 

쏟아지는 트래픽을 여러 대의 서버로 분산해주는 기술이 없다면, 한 곳의 서버에 모든 트래픽이 몰리는 상황이 발생할 것이다.

 

이 때 필요한 기술이 바로 로드밸런싱이다! 

 

로드밸런서

Load Balancer Architecture

로드밸런서서버에 가해지는 부하(=Load)를 분산(=balancing)해주는 장치 또는 기술을 말한다.

 

클라이언트와 서버풀(Server Pool, 분산 네트워크를 구성하는 서버들의 그룹) 사이에 위치하며,

 

한 대의 서버로 부하가 집중되지 않도록 트래픽을 관리해 각각의 서버가 최적의 퍼포먼스를 낼 수 있게 한다. 

 

위에서 언급한 엄청난 트래픽에 대처할 수 있는 방법은 크게 두 가지이다. 

 

바로, scale-up과 scale-out!

 

Scale-up

Scale-up은 서버 자체의 성능을 확장하는 것을 의미한다. 

 

비유하자면 CPU가 i3인 컴퓨터를 i9으로 업그레이드하는 것과 같다. 

 

Scale-out

Scale-out은 기존 서버와 동일하거나, 낮은 성능의 서버를 두 대 이상 증설하여 운영하는 것을 의미한다. 

 

이는 CPU가 i3인 컴퓨터를 여러 대 추가 구입해 운영하는 것에 비유할 수 있다. 

 

Scale-out의 방식으로 서버를 증설하기로 결정했다면, 

여러 대의 서버로 트래픽을 균등하게 분산해주는 로드밸런싱이 반드시 필요하다. 

 

 

로드밸런서의 종류

 

로드밸런서는 OSI 7계층을 기준으로 어떻게 부하를 분산하는지에 따라 종류가 나뉜다. 

 

2계층을 기준으로 부하를 분산한다면 L2, 3계층을 기준으로 부하를 분산한다면 L3. 

 

상위 계층으로 갈수록 섬세한 부하 분산이 가능하지만 가격이 비싸진다. 

 

반대로, 하위 계층으로 갈수록 간단한 부하 분산이 가능하고 가격이 저렴해진다. 

 

L2 Data Link 계층을 사용, Mac 주소 기반 부하 분산  
L3 Network 계층을 사용, IP 주소 기반 부하 분산  
L4 Transport 계층을 사용, Port 기반 부하 분산 TCP, UDP
L7 Application 계층을 사용, 요청(URL) 기반 부하 분산 HTTP, HTTPS 등

 

 

 

로드밸런서의 기본 기능 

Health Check

기본적으로 보통의 로드 밸런서는 서버들(또는 다음의 노드)에 대한 주기적인 Health Check를 통해 서버들의 장애 여부를 판단할 수 있다. 

 

이로 인해 로드 밸런서가 있을 때, 서버 몇 대에 이상이 생기더라도 다른 정상 동작 중인 서버로 트래픽을 보내주는 Fail-over가 가능하다. 

 

또, TCP/UDP 분석이 가능하기 때문에 Firewall의 역할도 수행할 수 있다. 

 

  • L3 체크 - ICMP를 이용해 서버의 IP 주소가 통신 가능한 상태인지 확인한다.
  • L4 체크 - TCP는 3-Way-Handshaking(전송 >> 확인/전송 >> 확인)를 기반으로 통신한다. 이러한 TCP의 특성을 바탕으로 각 포트 상태를 체크하는 방식이다. 예를 들어, HTTP 웹 서버의 경우 80 포트를 사용하므로 TCP 80 포트에 대한 체크를 통해 서버가 살아있는 상태인지 확인한다. 
  • L7 체크 - 어플리케이션 계층에서 체크한다. 즉, 실제 웹페이지(like index.html)에 통신을 시도하여 이상 유무를 파악한다. 

 

Tunneling 

눈에 보이지 않는 통로를 만들어 통신할 수 있게 하는 개념이다. 

 

로드밸런서는 클라이언트와 서버 간 중간에서 터널링을 제공해준다. 

 

즉, 연결된 상호 간에만 캡슐화된 패킷을 구별해 캡슐화를 해제하게 한다. 

 

NAT(Network Address Translation)

IP 주소를 변환해주는 기능이다. (목적지와 수신지의 IP 주소와 TCP/UDP 포트를 재기록하여 변환하며 네트워크 트래픽을 주고받을 수 있다)

 

예를 들어, 내부 네트워크에서 사용하던 사설 IP 주소를 로드밸런서 외부의 공인 IP 주소로 변경해준다. (반대로도 가능하다)

 

이렇게 하면, 부족한 공인 IP 주소를 효율적으로 사용할 수 있지만, 로드밸런싱 관점에서는 여러 개의 호스트가 하나의 공인 IP 주소(VIP)를 통해 접속하는 것이 주 목적이다. 

 

  • SNAT(Source Network Address Translation) - 내부에서 외부로 트래픽이 나가는 경우, 내부 사설 IP 주솔르 외부의 공인 IP 주소로 변환하는 방식이다. 집에서 사용하는 공유기가 대표적인 예이다. 
  • DNAT(Destination Network Address Translation) - 외부에서 내부로 트래픽이 들어오는 경우, 외부 공인 IP 주소를 내부의 사설 IP 주소로 변환하는 방식이다. 로드밸런서가 대표적인 예이다. 

 

DSR(Direct Server Routing)

서버에서 클라이언트로 되돌아가는 경우, 목적지를 클라이언트로 설정한 다음, 

 

네트워크 장비나 로드밸런서를 거치지 않고 바로 클라이언트를 찾아가는 방식이다. 

 

이 경우, 로드밸런서의 부하를 줄여줄 수 있는 장점이 있다. 

 

 

로드밸런서가 동작하는 방법

 

로드밸런서는 대부분 아래와 같은 절차로 동작하게 된다. 

 

(1) 클라이언트의 브라우저에서 dolphinsarah.com이라고 입력

(2) 클라이언트에 설정된 메인 DNS 서버로 dolphinsarah.com의 IP 주소 문의 

(3) 메인 DNS 서버는 dolphinsarah.com 주소를 관리하는 별도의 DNS 서버에 IP 주소 문의

(4) 별도 관리 DNS 서버는 로드밸런서의 IP(Virtual IP)주소를 메인 DNS 서버에게 알려줌

(5) 메인 DNS 서버는 획득한 VIP 주소를 클라이언트에 전송

(6) 클라이언트에서 로드밸런서의 VIP 주소로 http 요청

(7) 로드밸런서는 별도 로드밸런싱 방법(like 라운드 로빈)을 통해 서버에 요청을 전송

(8) 서버의 작업 결과를 받은 로드밸런서는 전달 받은 http 결과를 클라이언트에 전송

 

 

로드밸런서가 서버를 선택하는 방법 - L4 계층

 

라운드로빈 방식(Round Robin Method)

서버에 들어온 요청을 순서대로 돌아가며 배정하는 방식. 클라이언트의 요청을 순서대로 분배하기 때문에 여러 대의 서버가 동일한 스펙을 갖고 있고, 서버와의 연결(세션)이 오래 지속되지 않는 경우에 활용하기 적합하다. 

 

가중 라운드로빈 방식(Weigthed Round Robin Method)

각각의 서버마다 가중치를 매기고, 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분한다. 주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 부하 분산 방식이다. 예를 들어, A라는 서버가 5라는 가중치를 갖고, B라는 서버가 2라는 가중치를 갖는다면 로드밸런서는 라운드로빈 방식으로 A서버에 5개, B서버에 2개의 요청을 전달한다. 

 

IP 해시 방식(IP Hash Method)

클라이언트의 IP 주소를 특정 서버로 매핑하여 요청을 처리하는 방식이다. 사용자의 IP를 해싱(Hashing, 임의의 길이를 지닌 데이터를 고정된 길이의 데이터로 매핑하는 것 또는 그러한 함수)해 로드를 분배하기 때문에 사용자가 항상 동일한 서버로 연결되는 것을 보장한다. 

 

최소 연결 방식(Least Connection Method)

요청이 들어온 시점에 가장 적은 연결 상태를 보이는 서버에 우선적으로 트래픽을 배분한다. 자주 세션이 길어지거나, 서버에 분배된 트래픽들이 일정하지 않은 경우에 적합한 방식이다. 

 

최소 리스폰타임(Least Response Time Method)

서버의 현재 연결 상태와 응답시간(Response Time, 서버에 요청을 보내고 최초 응답을 받을 때까지 소요되는 시간)을 모두 고려하여 트래픽을 배분한다. 가장 적은 연결 상태와 가장 짧은 응답 시간을 보이는 서버에 우선적으로 로드를 배분하는 방식이다. 

 

 

로드밸런서가 서버를 선택하는 방법 - L7 계층 

 

L7 로드밸런서는 위와 같은 L4 로드밸런서의 기능을 포함하는 것뿐만 아니라 OSI 7계층의 프로토콜(like HTTP, SMTP, FTP etc)을 바탕으로도 분산 처리가 가능하다. 

 

예를 들어, 온라인 쇼핑몰의 장바구니에 물건들을 담아놓았는데 다른 서버에서의 처리는 어려울 것이다. 

 

L7 로드밸런싱에는 다음과 같은 방법들이 있다. 

 

URL 스위칭 방식(URL Switching)

특정 하위 URL 들은 특정 서버로 처리하는 방식이다. 

 

예를 들어, '../image' 또는 '../video'와 같은 특정 URL을 가진 주소들은 서버가 아닌 별도의 스토리지에 있는 객체 데이터로 바로 연결되도록 구성할 수 있다. 

 

컨텍스트 스위칭 방식(Context Switching)

클라이언트가 요청한 특정 리소스에 대해 특정 서버 등으로 연결해줄 수 있다. 

 

예를 들어, 이미지 파일에 대해서는 확장자를 참조하여 별도로 구성된 이미지 파일이 있는 서버/스토리지로 연결해줄 수 있다. 

 

쿠키 지속성(Persistence with Cookie)

쿠키 정보를 바탕으로 클라이언트가 연결했던 동일한 서버에 계속 할당해주는 방식이다. 

 

특히 사설 네트워크에 있던 클라이언트의 IP 주소가 공인 IP주소로 치환되어 전송하는 방식을 지원한다. 

 

 

 

위 포스팅은 아래 링크를 참고하여 작성했습니다.

https://www.stevenjlee.net/2020/06/30/%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%9D%98-%EB%B6%80%ED%95%98%EB%B6%84%EC%82%B0-%EB%A1%9C%EB%93%9C%EB%B0%B8%EB%9F%B0%EC%8B%B1-load-balancing-%EA%B7%B8/?openLinerExtension=true

https://post.naver.com/viewer/postView.nhn?volumeNo=27046347&memberNo=2521903&openLinerExtension=true

728x90

'CS > 네트워크' 카테고리의 다른 글

포워드 프록시(Forward Proxy)와 리버스 프록시(Reverse Proxy)  (0) 2021.06.17
HTTP 2.0과 특징  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
JWT - 토큰 기반 인증  (1) 2021.06.04
Authentication과 Authorization의 차이  (0) 2021.05.31
728x90

 

지난 포스팅에서는 토큰 기반 인증 시스템에 대해 알아보았다. 

 

JWT - 토큰 기반 인증

JWT에 대해 알아보기 전에, 모던 웹서비스에 많이 사용되고 있는 '토큰(Token) 기반 인증'에 대해 먼저 알아보자. API를 사용하는 웹서비스를 개발한다면, 토큰을 사용하여 유저들의 인증 작업을 처

dolphinsarah.tistory.com

 

이번 포스팅에서는, 토큰 기반 인증 시스템의 구현체인 JWT(JSON Web Token)에 대한 소개 후,

JWT 토큰의 기본 구조를 알아보자. 

 

 

JSON Web Token이란?

 

JSON Web Token(JWT)은 웹표준으로서, 두 개체에서 JSON 객체를 사용하여

가볍고 자가수용적인(self-contained) 방식으로 정보를 안정성 있게 전달해준다. 

 

  • 수많은 프로그래밍 언어에서 지원된다 - JWT는 C, Java, Python, C++, R, C#, PHP, JavaScript, Ruby, Go, Swift 등 대부분의 주류 프로그래밍 언어에서 지원된다.
  • 자가 수용적(self-contained)이다 - JWT는 필요한 모든 정보를 자체적으로 지니고 있다. JWT 시스템에서 발급된 토큰은, 토큰에 대한 기본 정보, 전달할 정보(로그인 시스템이라면 유저 정보), 그리고 토큰이 검증됐다는 것을 증명해주는 signature를 포함하고 있다. 
  • 쉽게 전달될 수 있다 - JWT는 자가수용적이므로, 두 개체 사이에서 손쉽게 전달될 수 있다. 웹서버의 경우 HTTP의 헤더에 넣어서 전달할 수도 있고, URL의 파라미터로 전달할 수도 있다. 

 

JWT는 어떤 상황에서 사용될까?

 

아래와 같은 상황에서 JWT가 유용하게 사용될 수 있다. 

 

회원 인증

JWT를 사용하는 가장 흔한 시나리오다. 

 

유저가 로그인을 하면, 서버는 유저의 정보에 기반한 토큰을 발급하여 유저에게 전달해준다. 

 

그 후, 유저가 서버에 요청을 할때마다 JWT를 포함하여 전달한다. 

 

서버가 클라이언트에게서 요청을 받을 때마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 

유저가 요청한 작업에 관한 권한이 있는지 확인하여 작업을 처리한다. 

 

서버에서는 유저의 세션을 유지할 필요가 없다. 

 

즉, 유저가 로그인되어 있는지 아닌지 신경쓸 필요가 없고, 유저가 요청을 했을 때 토큰만 확인하면 되기 때문에,

세션 관리가 필요 없어서 서버 자원을 많이 아낄 수 있다. 

 

정보 교류

JWT는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법이다. 

 

그 이유는, 정보가 sign 되어 있기 때문에 정보를 보낸이가 바뀌진 않았는지

정보가 도중에 조작되지는 않았는지 검증할 수 있다. 

 

 

JWT의 생김새 

 

JWT는 .을 구분자로 3가지의 문자열로 되어 있다. 구조는 아래와 같다. 

 

aaaaaa.bbbbbb.cccccc
헤더(header).내용(payload).서명(signature)

 

(JWT 토큰을 만들때는 JWT를 담당하는 라이브러리가 자동으로 인코딩 및 해싱 작업을 해준다.)

 

그럼 위와 같이 3가지 부분으로 나뉘어져 있는 각각에 대해 알아보자. 

 

헤더(Header)

헤더는 두 가지의 정보를 지니고 있다. 

 

  • typ: 토큰의 타입을 지정한다. 즉, JWT이다. 
  • alg: 해싱 알고리즘을 지정한다. 해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA가 사용되며, 이 알고리즘은 토큰을 검증할 때 사용되는 signature 부분에서 사용된다. 

 

정보(payload)

payload 부분에는 토큰에 담을 정보가 들어 있다. 

 

여기에 담는 '정보의 한 조각'클레임(claim)이라고 부른다. 

 

name/value의 한 쌍으로 이루어져 있다. 

 

그리고 토큰에는 여러 개의 클레임들을 넣을 수 있다. 

 

클레임은 등록된(registered) 클레임, 공개(public) 클레임, 비공개(private) 클레임으로 나뉘어져 있다. 

 

# 등록된(registered) 클레임

 

등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위해

이름이 이미 정해진 클레임들이다.

 

등록된 클레임의 사용은 모두 선택적(optional)이며, 이에 포함된 클레임 이름들은 다음과 같다. 

  • iss: 토큰 발급자(issuer)
  • sub: 토큰 제목(subject)
  • aud: 토큰 대상자(audience)
  • exp: 토큰의 만료시간(expiration). 시간은 NumericDate 형식으로 되어 있어야 하며(ex: 1480849147370), 언제나 현재 시간보다 이후로 설정되어 있어야 한다. 
  • nbf: Not Before를 의미. 토큰의 활성 날짜와 비슷한 개념. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다. 
  • iat: 토큰이 발급된 시간(issued at). 이 값을 사용하여 토큰의 age가 얼마나 되었는지 판단할 수 있다.
  • jti: JWT의 고유 식별자. 주로 중복 처리를 방지하기 위해 사용된다. 일회용 토큰에 사용하면 유용하다. 

 

# 공개(public) 클레임

 

공개 클레임들은 충돌이 방지된(collision-resistant) 이름을 가지고 있어야 한다. 

 

충돌을 방지하기 위해서, 클레임 이름을 아래와 같이 URI(Uniform Resource Identifier) 형식으로 짓는다. 

 

{
    "https://dolphinSarah.com/jwt_claims/is_admin": true
}

 

# 비공개(private) 클레임 

 

등록된 클레임도 아니고, 공개된 클레임도 아니다. 

 

양 측간에(보통 클라이언트 <-> 서버) 협의 하에 사용되는 클레임 이름이다. 

 

공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니, 사용할 때 유의해야 한다. 

 

{
    "username": "dolphinSarah"
}

 

아래 예제 payload는 2개의 등록된 클레임, 1개의 공개 클레임, 2개의 비공개 클레임으로 이루어져 있다. 

 

{
    "iss": "dolphinSarah.com",
    "exp": "1485270000000",
    "https://dolphinSarah.com/jwt_claims/is_admin": true,
    "userId": "11028373727102",
    "username": "dolphinSarah"
}

 

서명(signature)

JSON Web Token의 마지막 부분은 바로 서명(signature)이다. 

 

이 서명은 헤더의 인코딩 값과, 정보의 인코딩 값을 합친 후

주어진 비밀키로 해쉬를 하여 생성한다. 

 

서명 부분을 만드는 pseudo-code의 구조는 다음과 같다. 

 

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

 

이렇게 만든 해쉬를, base64 형태로 나타내면 된다. 

 

 

 

 

위 포스팅은 아래 링크를 참고하여 작성했습니다.

https://velopert.com/2389

728x90

'CS > 네트워크' 카테고리의 다른 글

HTTP 2.0과 특징  (0) 2021.06.11
로드밸런싱  (0) 2021.06.11
JWT - 토큰 기반 인증  (1) 2021.06.04
Authentication과 Authorization의 차이  (0) 2021.05.31
알아두면 좋은 HTTP X 헤더  (0) 2021.05.28
728x90

 

JWT에 대해 알아보기 전에, 모던 웹서비스에 많이 사용되고 있는 '토큰(Token) 기반 인증'에 대해 먼저 알아보자. 

 

API를 사용하는 웹서비스를 개발한다면, 토큰을 사용하여 유저들의 인증 작업을 처리하는 게 가장 좋다. 

 

토큰 기반 인증 시스템을 선택하는 것에는 여러가지 이유가 있다. 

그 중 주요 이유들은 아래와 같다. 

 

Stateless 서버

Stateless 서버를 이해하려면, Stateful 서버가 무엇인지 알아야 한다. 

Stateful 서버는 클라이언트에게서 요청을 받을 때마다, 클라이언트의 상태를 계속해서 유지하고, 이 정보를 서비스 제공에 이용한다. 

 

Stateful 서버의 예제로는 세션을 유지하는 웹서버가 있다. 

예를 들어 유저가 로그인을 하면, 세션에 로그인이 되었다고 저장을 하고,

서비스를 제공할 때 그 데이터를 사용한다. 

 

여기서 이 세션은, 서버컴퓨터의 메모리에 담을 때도 있고, 데이터베이스 시스템에 담을 때도 있다. 

 

반대로, Stateless 서버는 상태를 유지하지 않는다. 

상태 정보를 저장하지 않으면, 서버는 클라이언트 측에서 들어오는 요청으로만 작업을 처리한다. 

 

이렇게 상태가 없는 경우, 클라이언트와 서버의 연결고리가 없기 때문에 

서버의 확장성(Scalability)이 높아진다. 

 

모바일 어플리케이션에 적합하다

Android/ios 모바일 어플리케이션을 개발할 때, 안전한 API를 만들기 위해서 쿠키 같은 인증시스템은 이상적이지 않다. (쿠키 컨테이너를 사용해야 하기 때문에) 

 

토큰 기반 인증을 도입한다면, 더욱 간단하게 번거로움을 해결할 수 있다. 

 

인증 정보를 다른 어플리케이션으로 전달할 수 있다

대표적인 예제로, OAuth가 있다. 

페이스북/구글 같은 소셜 계정들을 이용하여 다른 웹서비스에서도 로그인할 수 있게 할 수 있다. 

 

보안

토큰 기반 인증 시스템을 사용하여 어플리케이션의 보안을 높일 수 있다. 

단, 이 토큰 기반 인증을 사용한다고 해서 무조건 해킹의 위험에서 벗어나는 건 아니다.

 

왜 토큰을 사용하게 되었을까?

 

토큰 기반 인증 시스템은 어떻게 나타나게 되었을까? 

이를 알아보기 위해서, 과거의 인증시스템이 어떤 방식으로 작동했는지 먼저 살펴보자.

 

서버 기반 인증

기존의 인증 시스템에서는 서버에서 유저들의 정보를 기억하고 있어야 한다. 

이 세션을 유지하기 위해서는 여러 방법이 사용된다. 

메모리 / 디스크 / 데이터베이스 시스템에 이를 담는다. 

 

서버 기반 인증 시스템의 흐름은 다음과 같다. 

 

서버 기반 인증 시스템의 흐름

 

이런 방식의 인증 시스템은 아직도 많이 사용되고 있다. 

하지만, 요즘 웹어플리케이션들이 부흥하면서, 이런 방식의 인증 시스템은 문제를 보이기 시작했다. 

예를 들면, 서버를 확장하기가 어렵다

 

서버 기반 인증의 문제점 

세션

: 유저가 인증을 할 때, 서버는 이 기록을 서버에 저장해야 한다. 이를 세션이라고 부른다.

대부분의 경우에는 메모리에 이를 저장하는데, 로그인 유저의 수가 늘어난다면 어떻게 될까?

서버의 램이 과부하될 것이다. 이를 피하기 위해, 세션을 데이터베이스 시스템에 저장하는 방식도 있지만, 

이 또한 유저의 수가 많으면 데이터베이스 성능에 무리를 줄 수 있다. 

 

확장성

: 세션을 사용하면 서버를 확장하는 것이 어려워진다. 여기서 서버의 확장이란, 

단순히 서버의 사양을 업그레이드 하는 것이 아니라 더 많은 트래픽을 감당하기 위해

여러 개의 프로세스를 돌리거나, 여러 대의 서버 컴퓨터를 추가하는 것을 의미한다.

세션을 사용하면서 분산된 시스템을 설계하는 게 불가능한 것은 아니지만, 과정이 매우 복잡해진다. 

 

CORS(Cross-Origin Resource Sharing)

: 웹 어플리케이션에서 세션을 관리할 때 자주 사용되는 쿠키단일 도메인 및 서브 도메인에서만 

작동하도록 설계되어 있다. 따라서, 쿠키를 여러 도메인에서 관리하는 것은 좀 번거롭다. 

 

토큰 기반 시스템의 작동원리

 

토큰 기반 시스템stateless하다. 즉, 상태 유지를 하지 않는다. 

이 시스템에서는 더 이상 유저의 인증 정보를 서버나 세션에 담아두지 않는다

 

이거 하나만으로도 위에서 서술한 서버에서 유저의 인증 정보를 서버측에 담아둠으로

발생하는 많은 문제점들이 해소된다. 

 

세션이 존재하지 않으니, 유저들이 로그인 되어있는지 아닌지 신경 쓰지 않으면서

서버를 손쉽게 확장할 수 있을 것이다. 

 

토큰 기반 시스템의 구현 방식은 시스템마다 크고 작은 차이가 있겠지만, 

대략 다음과 같다. 

 

  1. 유저가 아이디와 비밀번호로 로그인한다. 
  2. 서버에서 해당 계정 정보를 검증한다.
  3. 계정 정보가 정확하다면, 서버측에서 유저에게 signed 토큰을 발급해준다. (signed는, 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature를 지니고 있다는 뜻이다) 
  4. 클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청을 할때마다 해당 토큰을 서버에 함께 전달한다. 
  5. 서버토큰을 검증하고, 요청에 응답한다. 

토큰 기반 시스템의 구현 방식

 

웹서버에서 토큰을 서버에 전달할 때는, HTTP 요청의 헤더에 토큰 값을 포함시켜 전달한다. 

 

토큰의 장점

무상태(Stateless), 확장성(Scalability)

StatelessScalability는 토큰 기반 인증 시스템의 중요한 속성이다. 

토큰은 클라이언트사이드에 저장하기 때문에 완전히 stateless하며,

서버를 확장하기에 매우 적합한 환경을 제공한다. 

 

만약, 세션을 서버에 저장하고 있고, 서버를 여러 대 사용하여 요청을 분산했다면, 

어떤 유저가 로그인 했을 때, 그 유저는 처음 로그인했던 그 서버에만 요청을 보내도록 설정을 해야 한다. 

 

하지만, 토큰을 사용한다면 어떤 서버로 요청이 들어가든 상관 없다

 

보안성

클라이언트가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로

쿠키를 사용함으로 인해 발생하는 취약점이 사라진다

 

하지만, 토큰을 사용하는 환경에서도 취약점이 존재할 수 있으니,

언제나 취약점에 대비해야 한다. 

 

Extensibility(확장성)

여기서의 확장성은, Scalability와는 또 다른 개념이다. 

 

Scalability는 서버를 확장하는 걸 의미하지만, 

Extensibility로그인 정보가 사용되는 분야를 확장하는 것을 의미한다. 

 

토큰을 사용하여 다른 서비스에서도 권한을 공유할 수 있다. 

 

예를 들어, 로켓펀치에서는 Facebook, LinkedIn, GitHub, Google 계정으로 로그인할 수 있다. 

 

토큰 기반 시스템에서는, 토큰에 선택적인 권한만 부여하여 토큰을 발급할 수 있다.

(예를 들어, 로켓펀치에서 Facebook 계정으로 로그인을 했다면, 프로필 정보를 가져오는 권한은 있어도, 포스트를 작성할 수 있는 권한은 없다)  

 

여러 플랫폼 및 도메인

서버 기반 인증 시스템의 문제점 중 하나는 CORS이다. 

 

어플리케이션과 서비스의 규모가 커지면, 여러 디바이스를 호환시키고,

더 많은 종류의 서비스를 제공하게 된다.

 

토큰을 사용하면, 그 어떤 디바이스에서도, 그 어떤 도메인에서도, 

토큰만 유효하다면 요청이 정상적으로 처리된다. 

 

서버에서 어플리케이션의 응답 부분에 다음 헤더만 포함시켜주면 된다.

 

Access-Control-Allow-Origin: *

 

 

이번 포스트에서는 토큰 기반 인증 시스템과 기존의 시스템과 어떤 차이가 있는지 알아보았다. 

 

다음 포스트에서는 JWT에 대해 본격적으로 알아보도록 하자. 

 

 

위 포스팅은 아래 링크를 참고하여 작성했습니다. 

https://velopert.com/2350?openLinerExtension=true

 

 

728x90

'CS > 네트워크' 카테고리의 다른 글

로드밸런싱  (0) 2021.06.11
JWT - JSON Web Token  (0) 2021.06.04
Authentication과 Authorization의 차이  (0) 2021.05.31
알아두면 좋은 HTTP X 헤더  (0) 2021.05.28
알아두면 좋은 HTTP 쿠키, 캐시 헤더  (0) 2021.05.28

+ Recent posts