RPC 는 기술 문서를 읽다보면, 현업에서 흔히 접하게 되는 용어지만 은근히 개념을 이해하기는 쉽지 않다.

 

RPC 의 개념을 인터넷에서 (혹은 최근에 핫한 ChatGPT 에서) 찾아보자면 다음과 같이 나온다.

 

Remote Procedure Call 은 원격 컴퓨터나 프로세스에 존재하는 함수를 호출하는데 사용하는 프로토콜로, 원격지의 프로세스를 동일 프로세스의 함수를 호출하는 것 처럼 사용하는 것을 말한다.

 

하지만 위의 개념을 읽고 한번에 와닿는 사람들은 많지 않을 것이라고 생각한다. 실제로 현업의 엔지니어들도 애매모호하게 해석하게 되는 개념 중 하나이다.

 

그도 그런게 RPC 는 특정 프로토콜 이라기 보다는 전통적인 개념의 API 호출 규약이기 때문이다.

예시를 보면 이해가 보다 쉬울 것이다.

 

POST /sayHello HTTP/1.1
HOST: api.example.com
Content-Type: application/json

{"name": "Tom"}

 

위의 예시는 HTTP 위에서 구현된 RPC 방식의 예시이다. 위의 HTTP 스키마는 HTTP Client (웹 브라우저) 를 통해 HTTP Server (웹 서버) 에 전달될 것이고, WAS 는 위의 프로토콜을 처리하기 위한 로직을 구현하게 된다.

 

여기서 보통은 "그냥 HTTP 프로토콜 아닌가?" 라는 생각이 들 것이고, 그 생각은 맞다.

하지만 일반적인 REST API 처럼 보인다면, 엄밀히 따지자면 그렇지 않다. RPC 와 REST 의 차이점은 다음과 같다.

 

  REST RPC
Protocol HTTP  프로토콜에 무관 (TCP, UDP, HTTP, WebSocket, ...)
Scheme Resource 기반의 API 인터페이스
(예) 강아지 목록을 반환하는 API 를 GET /dogs 로 설계
Action 기반의 API 인터페이스
(예) 강아지 목록을 반환하는 API 를 POST /listDogs 로 설계
Design RESTful API 는 Stateless 를 전제 제약이나 규약이 없음

 

즉, RPC 는 서버와 클라이언트가 통신하기 위한 API 의 통신 패러타임 중 하나이고, REST API 와 비교될 수 있는 차원의 개념이라고 할 수 있다.

RPC 는 기본적으로 정해진 구조를 갖고있지는 않지만, 기본적인 Terminology 를 몇가지 갖고있다.

 

  • IDL (Interface Definition Language) : 서로 다른 언어로 작성된 서비스들 사이에서 공통된 인터페이스를 정의하기 위한 중간 언어
  • Stub : 서버와 클라이언트는 서로 다른 주소 공간을 사용하므로 함수 호출에 사용된 매개변수를 변화해줘야하며, 그 역할을 담당한다
    • client stub - 함수 호출에 사용된 파라미터의 변환(Marshalling) 및 함수 실행 후 서버에서 전달된 결과의 반환
    • server stub - 클라이언트가 전달한 매개변수의 역변환(Unmarshalling) 및 함수 실행 결과 변환을 담당

그리고 위의 개념에 따라서 다음과 같은 순서로 통신이 이뤄지게 된다.

 

  • IDL 을 사용하여 호출 규약을 정의한다. IDL 파일을 rpcgen 으로 컴파일하면 stub code 가 자동으로 생성
  • Stub Code 에 명시된 함수는 원시 코드의 형태로 상세 기능은 server 에서 구현된다. Stub 코드는 서버/클라이언트에서 각각 빌드된다
  • 클라이언트에서 stub 에 정의된 함수를 사용 시 client stub 은 RPC runtime 을 통해 함수를 호출하고 서버는 수신된 Procedure 호출에 대해 처리 후 결과를 반환
  • 클라이언트는 서버로부터 응답을 받고 함수를 로컬에 있는 것처럼 사용할 수 있다

 

이해가 잘 되지 않는다면 쉽게 말해서, RPC 는 이를 해석하고 처리하기 위한 Client / Server 가 존재하며, 그 사이에 규약(IDL) 을 정의하고 IDL 을 클라이언트측 / 서버측 Stub 을 통해 해석하고 비즈니스 로직을 구현한다고 보면 된다. 

 

RPC 는 RESTful API 에 비해 복잡하며, 프로젝트에 따라 Learning Curve 가 있기 때문에,

근래에 RPC 의 개념은 전통적인 방식으로는 잘 사용되지 않으며 gRPC (Google RPC) 와 같은 발전된 개념으로 사용되어진다.

 

RESTful API 가 갖는 개념적 제한에서 벗어나서 보다 자유로운 설계를 위해 사용되는 개념이고, gRPC 와 같은 Modern RPC 는 Micro Service Architecture 등에서 Internal Bidirectional Communication 을 위해 사용되어진다.

 

 

위의 예시는 gRPC 를 이용해서 Micro Service Architecture 를 구현하는 방식을 보여준다. gRPC 의 경우 Protobuf 를 스키마로 사용하기 때문에, 통신을 위한 서버-클라이언트 간에 .proto 파일에 대한 별도 관리가 필요하다.

 

Protobuf 는 구글이 만든 언어 및 플랫폼 중립적인 Data Format 으로, 일반적인 JSON Serialize / Deserialize 대비 효율적인 통신이 큰 장점이다. 관련해서는 블로그의 다음 글을 참고해볼 수 있다.

 

현업에서 RPC 는 주로, 웹 서비스 보다는 게임이나 IoT, Device 등 Non HTTP 기반 산업에서 보다 많이 보이는 형태이지만 Micro Service Architecture 가 시장에 자리잡기 시작하면서 Modern RPC 형태로 많이 보이고 있다.

 

기술이 어떻게 진화할지 모르겠지만 여러 기술적인 문제를 해결하기 위한 시도 중 하나로 알아둘 법한 패러다임이라고 생각되어진다.

 

 

 

CSR (Client Side Rendering) 이니 SPA (Single Page Application) 과 같은 내용들은 10년도 지난 개념들이지만, 시장이 변하는건 그렇게 빠르지 않다.

 

많은 웹 서비스들이 아직 SSR (Server Side Rendering) 기반으로 백엔드와 프론트엔드를 관리하고 있으며 아키텍처를 어떻게 디자인하는 것이 좋은지는 장단점이 있는 중요한 설계 포인트 중 하나가 된다.

특히 팀의 개발 환경 구성 및 전체적인 설계도를 구상해야하는 시니어 개발자 및 Tech Lead 라면 사용 사례를 잘 분석하고 알맞은 접근 방법을 택하는 것이 중요해진다.

 

이번 포스팅에서는 CSR 기반의 Single Page Application 을 위한 프론트엔드 개발 파이프라인을 알아본다.

 

여전히 Java 와 Spring 환경은 주류이지만, 이 환경이 지배적이던 수 년 전에는 프론트엔드 코드가 백엔드 어플리케이션과 같이 묶여서 개발되어지고 배포되어지는 SSR (Server Side Rendering) 방식이 대부분이었다.

이렇게 되면 개발 환경이 분리되지 않기 때문에 역할 분리나 협업에 있어서 애로 사항들이 발생하고, 무엇보다도 하나의 WAS 가 프론트엔드 & 백엔드를 모두 서비스하게 되다보니 배포도 같이 일어나며 인프라 비용의 비효율성도 생기게 된다.

백엔드의 버그가 생겼는데 프론트엔드 코드까지 재빌드가 되어야하거나, 프론트엔드는 리소스를 거의 잡아먹지 않는데 백엔드가 리소스를 많이 잡아먹어서 Scaling 을 해야하는 경우를 생각해보면 이해가 빠를 것이다.

 

무튼.. 이러저러한 애로사항이 있던 와중에 밀결합(Decoupling)의 개념이 세계적으로 대세가 되며 프론트엔드와 백엔드가 분리되어 각자의 라이프사이클을 가지며, API 를 통해 통신하는 CSR 방식이 점차 확산되어졌다.

CSR 방식에서는 프론트엔드와 백엔드가 물리적으로 분리되기 때문에 인프라를 각자 관리할 수 있으며 개발 환경이 나뉘어지기 때문에 역할 분리 및 작업의 비효율성이 개선되어질 수 있다.

 

그렇다면 Client Side Rendering 을 위한 아키텍처 설계는 어떻게 이뤄질까?

먼저 동적 코드에서 정적 코드가 분리된다는 점에 주목해야한다.

기존에 프론트엔드는 Javascript 가 동적 로직을 처리하기는 하지만 기본적으로 클라이언트 브라우저에서 동작한다는 측면 때문에 정적 리소스 (Static Resource) 로 분류되어진다. 

 

이와 같은 정적 리소스들은 인터넷에서 접근될 때 클라이언트 브라우저가 "다운로드" 하여 "실행" 하는 방식이기 때문에 웹 기반의 스토리지에서 제공되어질 수 있다.

이 말은 웹 서버만으로도 정적 리소스는 제공될 수 있으며, 당연히 CDN 을 통한 가속화도 가능하다는 것이다.

 

예전에는 웹 서버 스택을 nginx, apache 위에서 로드밸런싱을 구축해서 제공을 했었지만 클라우드 환경이 대세가 되면서 이 역시 Amazon S3 와 같은 웹 기반의 스토리지로 옮겨가게 되었다. 그리고 이런 정적 웹사이트는 Amazon CloudFront 와 같은 CDN 을 통해 사용자 더 가까운 위치에서 제공될 수 있게끔 디자인이 되게 된다.

 

위와 같이 구성 시 사용자는 CDN 을 통해 전세계 어디에서든 빠르게 정적 리소스를 접근할 수 있으며, 해당 리소스의 렌더링을 받을 수 있다. 또한 S3 와 같은 스토리지는 내구성이나 가용성을 AWS 에서 관리해주기 때문에 개발자 입장에서는 nginx 환경 구성이나 Auto Scaling 을 직접 구축할 필요없이 최소한의 노력으로 서비스를 구축할 수 있게 된다.

 

특히 위와 같은 구조는 동적인 처리가 적게 요구되는 마케팅 페이지 등에서 많이 활용하는 아키텍처이기도 하다.

 

그러면 위와 같은 변경된 구조에서 코드의 배포는 어떻게 수행해야할까?

전통적인 환경에서는 Jenkins 등을 통해 백엔드와 프론트엔드가 전체 빌드된 이후 서버 머신들 위에 직접 배포되었지만, 위와 같은 경우에는 머지된 코드가 단순히 Amazon S3 라는 오브젝트 스토리지 위에 배포되기만 하면 된다. 다만 React 와 같이 프론트엔드 코드를 빌드해주는 경우, 이에 대한 작업 구성은 별도로 필요해진다.

 

AWS 의 CodePipeline 은 위의 배포를 지원하며, 코드 저장소에서 작업한 코드가 Merge 되면 자동으로 S3 에 빌드가 배포되게 구성할 수 있다.

다음 샘플은 AWS 의 Infra As A Code 툴인 AWS CDK 를 이용해서 위의 파이프라인을 만들어놓은 샘플이다.

CDK 를 구동하기만 함으로써 쉽게 AWS 를 활용해서 정적 페이지의 구성과 개발을 위한 파이프라인을 만들어 볼 수 있다.

 

코드 참고 : 

https://github.com/jinspark-lab/cdk-samples/tree/main/frontend-cicd 

 

React 기반으로 어플리케이션을 배포하는 프론트엔드 파이프라인이 만들어져있기 때문에 React 개발 및 배포 환경 구성이 필요할 때 참고해볼 수 있을 것 같다.

 

CSR 이 무조건적인 장점만 있는 것은 아니며, SEO (Search Engine Optimization, 검색 엔진 최적화) 에 있어서 불리한 측면이나 작업 완료 시간이 SSR 에 비해 느리다는 점 등이 단점으로 뽑히며, 현재 두 개념은 적절히 혼합되어 사용 사례에 알맞게 사용되고 있다고 볼 수 있다.

 

 

 

 

빅데이터 기반 분석은 많은 엔터프라이즈에서 기본적으로 고려하는 부분이 되었으며, 이에 대해 기본적으로 이해하는데 도움이 되는 몇가지 기본 지식들을 정리해보았다.

 

최근의 데이터 분석의 추세는 Data Gravity 라는 용어로 시작할 수 있을 것 같다. 기술적인 용어라기 보다는 추세를 비유하는 용어에 가까운데, 이 개념은 다음과 같다

 

  • 개념 : 데이터 규모가 커지고 무거워질 수록 비즈니스를 끌어당기는 중력(Gravity) 이 강해지는 현상을 나타내는 개념
  • 성질 : 데이터를 저장할 스토리지, 데이터를 운용 및 관리할 인력, 데이터 활용을 위한 어플리케이션 등 비즈니스는 데이터에 기반해서 함께 이동한다

즉, 데이터 기반의 의사 결정을 통해 서비스의 방향이 결정되고 향후 비즈니스 가치를 판단하는 기준이 바뀔 수 있다는 측면이다.

이러한 데이터 기반의 의사 결정을 위해 데이터를 다루는 큰 두가지 틀이 있을 수 있다.

 

(1) Data Warehouse (데이터 웨어하우스)

  • 데이터를 저장해두는 창고. 데이터 분석이 필요할 때 창고의 데이터를 가져다 이용하자는 개념
  • 분석을 위해 OLAP 툴 또는 SQL 을 이용하여 최종 정보 이용자들이 활용한다
  • 데이터들에 대해 정형화된 형식으로 통합해 단일 형식으로 구성
  • 복잡한 데이터 모델에 대해 갖고 있는 데이터 모델에 제약을 맞춰야하는 이유 등으로 인해 데이터 모델 통합이 어렵고, 인프라 증설에 따른 운영 비용이 많이 발생

 

데이터 웨어하우스는 잘 구성된 데이터를 규격화된 데이터베이스에 적재해놓고 쿼리를 조합해서 필요한 정보를 얻어내는 방식이다.

가장 친숙하게는 관계형 데이터베이스(RDB) 에서 쿼리를 통해 데이터를 조회하는 것도 웨어하우싱 방식의 접근 방식이라 할 수 있겠다.

 

장점으로는 적재(Storing)된 데이터를 정해진 Case 에 대해서는 다루기가 아주 쉽다. 정형화된 형식이기 때문에 마케팅, 사업 등 엔지니어가 아니라도 쉽게 조회 및 집계 등이 가능하다.

단점으로는 데이터를 잘 구성해서 적재해주는 측면이 중요하다. 특히 최근에 생성되는 비정형 데이터를 사용할 수 있는 형태의 정형 데이터로 바꿔줘야 한다. 또한 데이터가 적재되는 방식은 데이터가 사용되는 방식과 다른 경우가 많아 확장성을 갖추기가 쉽지 않다.

 

 

(2) Data Lake (데이터 레이크)

  • 정형 데이터로 구성된 전통적 소스 외에도 수많은 비정형 데이터들을 실시간으로 수집, 정제, 통합하여 활용하기 위해 확장된 개념
  • Raw 데이터 형식으로 저장했다가 나중에 쉽게 분석할 수 있도록 구성
    • 이를 위해 분산 시스템 환경에서 데이터를 독립적으로 쪼개고 다시 취합하는 기법을 사용
    • 하둡과 같은 맵리듀스 방식이 대표적
  • 데이터를 구축하고 활용하는 기술이 어려워서 습득과 활용이 쉽지 않다

데이터 레이크는 데이터 웨어하우스에서 접근 방식을 바꾼 방법이다. 비정형 데이터를 정형화시키지 않고 Raw 데이터 형태로 적재하고, 사용할 때 필요에 맞게끔 구성하는 방법이다.

 

장점으로는 데이터의 수집(Ingestion) 및 적재(Storing) 에 있어서 부담을 덜 수 있다. 데이터의 정형화에 대한 부담이 적기 때문에 새로이 비즈니스 확장이나 새로운 데이터가 들어오더라도 비정형으로 그냥 적재하면 된다. 따라서 데이터의 수집 자체가 더 용이하다.

단점으로는 결국 데이터는 사용 시에 Use Case 에 맞게 형변환되어야 한다. 따라서 적재된 데이터의 사용을 위해 별도의 인프라 및 시스템이 필요한 경우가 많다. 이런 측면으로 인해 비개발자가 다루기가 쉽지 않다.

 

 

최근의 추세는 Data Lake 형태로 온갖 데이터를 몰아넣고, 이를 적절한 사례에 맞게 가져가 쓰는 것으로 보인다.

비즈니스 확장성이 중요해진 추세다보니, 언제 어떤 데이터가 어떻게 쓰일지 모르고, 따라서 일단 적재해놓고 적합한 사용 사례에 맞게 데이터 분석 시스템을 모두 갖춰놓고, 이용하는 방식으로 많이 사용되어지는 것 같다.

이제 빅데이터도 어느새 알아야하는 기본 지식이 되어가기 때문에, 기반 지식들을 알아두면 많이 도움이 될 것으로 보인다.

 

 

웹 서버는 Stateless 프로토콜인 HTTP 를 사용하기 때문에 웹사이트에서 인증을 관리하기 위한 방안이 필요하다.

로그인을 한 유저들에 대해 권한이 필요한 매 요청마다 재로그인을 시킬수는 없는 일이다.

그렇기 때문에 웹사이트는 일반적으로 유저의 접속 정보를 관리하기 위한 몇가지 방안을 사용한다.

 

1. Session 기반 인증

세션 기반인증을 위해 Session 과 Cookie 가 사용된다. 다음 Flow 로 인증 절차가 진행된다.

 

 - 유저가 로그인을 하고 세션이 서버 메모리 상에 저장된다. 이 때 세션을 식별하기 위한 Session Id 를 기준으로 정보를 저장한다.

 - 브라우저에 쿠키로 Session Id 가 저장된다.

 - 쿠키에 정보가 담겨있기 때문에 브라우저는 해당 사이트에 대한 모든 Request 에 Session Id 를 쿠키에 담아 전송한다.

 - 서버는 클라이언트가 보낸 Session Id 와 서버 메모리로 관리하고 있는 Session Id 를 비교하여 Verification 을 수행한다.

 

Session 기반 인증은 다음과 같은 장단점을 갖는다.

 

+ 세션 기반 인증 방식은 구현이 상당히 명확하다는 장점이 있다. 또한 실제 서버에서 로그인 상태 확인이 굉장히 유용하다.

+ 상대적으로 안전하다. 서버측에서 관리하기 때문에 클라이언트 변조에 영향받거나 데이터의 Stale (손상) 우려가 없다.

- 유저들의 세션에 대한 정보를 서버 메모리에 들고 있게 된다는 부담이 있다.

- 서버 메모리에 세션 정보가 저장되기 때문에 Scale Out / Scale In 이 부담이 될 수 있으며, 결국에는 유저 상태에 무관하게 동작할 수 있도록 Data-Driven 아키텍처가 요구된다.

- 멀티 디바이스 환경에서 로그인 시 신경써줘야할 부분들이 생긴다. 

 

2. Token 기반 인증

Token 기반 인증의 방법으로 많은 웹 서버들은 JWT(JSON Web Token) 을 사용한다.

Token 기반 인증 방식과 Session 기반 인증 방식의 가장 큰 차이점은 유저의 정보가 서버에 저장되지 않는다는 점이다.

Flow 는 다음과 같다.

 

 - 유저가 로그인을 하고 서버에 세션을 이용해서 정보를 기록하는대신, Token 을 발급한다.

 - 클라이언트는 발급된 Token 을 저장한다 (일반적으로 local storage 에 저장한다.)

 - 클라이언트는 요청 시 저장된 Token 을 Header 에 포함시켜 보낸다. 

 - 서버는 매 요청시 클라이언트로부터 전달받은 Header 의 Token 정보를 Verification 한 뒤, 해당 유저에 권한을 인가한다.

 

Flow 에서 차이를 확인할 수 있듯, Session 기반 서버가 서버측에 정보를 기록하는 반면, Token 기반 인증은 Token 에 대한 Verification 만 수행할 뿐 저장은 클라이언트에서 수행한다.

Token 기반 인증은 다음과 같은 장단점을 갖는다.

 

+ 클라이언트에 저장되기 때문에 서버의 메모리에 부담이 되지않으며 Scale 에 있어 대비책을 고려할 필요가 없다

+ 멀티 디바이스 환경에 대한 부담이 없다.

- 상대적으로 Stale (손상) 의 위험이 크다.

- 결국 구현을 하다보면 서버측에 token blacklist 를 관리하게 될 가능성이 있고 그렇게 되면 서버측 메모리의 소모가 발생하게 된다

- Token 은 일반적으로 Session ID 보다 길다.

- XSS 공격에 취약할 수 있어 가능한 민감한 정보는 포함시키지 않을 필요가 있다.

 

최근에는 Scaling 이슈와 멀티 디바이스 이슈로 Token 방식이 좀 더 핫한 느낌이지만, Session 방식도 여전히 많이 쓰인다.

두 방식 모두 장단점이 있기 때문에 적합한 구조를 선택하는 것이 좋겠다.

 

 

사실 보안쪽에 문외한이다보니 처음 배웠을 때 아주 생소한 개념이었다.

하지만 백엔드에 종사하다보니 얼마나 중요한지 알게되었고, 다시 한번 정리를 해보았다.

 

 

사실 Threat Modeling 이라는 단어는 비단 IT에서만 쓰는 용어는 아니고, 위험 요소에 대해 평가해보는 전반에 걸쳐 사용되는 언어이다.

하지만 IT 용어로써 Threat Modeling 이란 MS 사에서 대중화한 개념으로 잠재적인 위협을 모델링하고 이를 완화할 수 있도록 할 수 있는 프로세스를 말한다.

가령, 구조적 취약점이나 방화벽 등 보안장치의 부재와 같은 위협들이 모델링의 대상이 될 수 있다. 

위협 모델링의 목적은 시스템의 특성과 방어 시스템을 고려했을 때 어떤 부분에 있어서 방어가 필요하고 보안상 취약할 수 있는지 가능성을 찾는 것으로 특히 특정한 위협포인트에 대해 미지수일 경우 가능한 취약점을 찾는 것이 되겠다.

또한 공격자의 입장을 시뮬레이션해보고 공격 측면(Attack Surfaces) 을 찾아내는 일이 포함된다.

 

그렇기 때문에 Threat Modeling 이 가능하려면 먼저 다음을 알아야 한다.

    - 시스템의 구조 (Architecture)

    - 시스템의 보안 상태

    - 보호해야하는 가치있는(Valueable) 자산이 무엇인지

    - 가능한 공격자 후보군

위협요소 탐지를 위한 Threat Modeling 방법론으로 주로 언급되는 4가지를 정리해본다.

 

  1. STRIDE : 다음의 머릿글자만 딴 약어이며 다음 6가지에 대한 위협을 측정한다.

Spoofing(공격자가 권한이 있는 사용자인척 위장하는 공격 방식)

Tampering(목적을 위해 시스템 내부 데이터를 악의적 수정해서 공격)

Repudiation(악의적 활동 이후에 해당 활동에 대해 부인하는 것)

Information Disclosure(보호된 정보에 대한 노출)

Denial of Service(서비스에 대한 믿을 수 있는 접근을 바탕으로 한 공격. 분산해서 공격하는 것을 DDoS라 한다.)

 

  2. DREAD : 다음의 머릿글자만 딴 약어이다. MS 에서는 현재 제공되고 있지 않는 것으로 보이지만 OpenStack 등에서는 여전히 쓰이고 있는 방법이라 한다.

Damage Potential(취약점이 노출되었을 경우 발생 가능한 피해량)

Reproducibility(재공격 당하기 쉬운 정도)

Exploitability(공격을 하기 위해 필요한 공수)

Affected Users(위협이 얼마나 많은 유저에게 노출되는지)

Discoverability(얼마나 위협을 탐지하기 쉬운지)

위의 수치의 평균을 Risk 로 정의한다.

 

  3. P.A.S.T.A : Process for Attack Simulation and Threat Analysis 의 약어로 비즈니스 컨텐츠 및 기술 요구 사항에 따라 7단계로 프로세스가 구성된다. 방법의 목적은 직접 위협 요소를 검증하고 위협 요소들에 대해 점수를 부여해서 분석하고 완화시키기 위한 방법을 개발자에게 제시하는 것이다.

 

  4. VAST : Visual, Agile, and Simple Threat modeling 의 약어로 인프라 및 시스템 전체에 대한 모델링이 필요하며 Agile 프로세스에 위협 모델링 정보를 Visualize 할 수 있는 부분을 포함한다. 그렇기 때문에 전문적 지식없이 간단하게 진행되며 그를 지원해줄 수 있는 어플리케이션이 요구된다.

 

개발자 입장에서는 놓치기 쉬운 측면이고 정책적인 부분 또한 강하지만 OWASP(Open Web Application Security Project) 에서도 강조하고 있는 보안 위험을 대하는 구조화된 접근 방식이다.

다음을 참고하자 - (https://www.owasp.org/index.php/Threat_Modeling_Cheat_Sheet)

 

위협 모델링은 운영이 편리하고 취약점을 공유할 수 있는 부분이 큰 장점으로, 그에 따라 위험을 공유하고 같이 협력해서 대처할 수 있다는 큰 장점이 있다.

하지만 중요함에도 이를 적절하고 의미있게 실행하기는 쉽지 않은데, Best Practice 가 많지 않고 향후 위협 가능성보다는 현재의 위협에 초점을 두고 취약점 위주의 분석이 주가 되기 때문이다.

 

개발자 뿐만 아니라 시스템 전반에 걸친 모두의 협력이 지속적으로 이루어져야 가능한 부분이 아닐까 생각이 든다.

 

Dynamic Contents 와 Static Contents 의 차이는 명확하다.

용어가 생소하더라도 개념은 익히 알려진 내용일 것이다. 그럼에도 짚고 넘어가자면,

Static Contents 는 유저/지역 등 어떤 기준을 막론하고 같은 데이터, 즉 정적 데이터를 말하고,

Dynamic Contents 는 유저/지역 또는 어떤 기준에 대하 다를 수 있는, 동적 데이터를 말한다.

 

쉽게 이해하자면 변수와 상수의 차이 정도로 보면 쉽다.

 

너무나도 간단한 개념이지만, 캐싱의 관점에서는 또 다르게 적용될 수 있다.

Static Contents 의 캐싱은 간단하다. 단순히 변하지않는 정적 데이터를 캐싱해주면 된다.

일반적으로 API 등에서 Meta data 를 캐싱하는 경우 In memory 에 캐싱하거나 혹은 설정값으로 관리하는 경우가 많다.

Meta data 가 아닌 종류의 리소스들이라면 CDN 이라는 훌륭한 솔루션이 있고, Cache-invalidation 정책만 조절하여 관리해준다.

 

반면 Dynamic Contents 의 캐싱은 조금 다르다. 계속 변하는 컨텐츠이기 때문에 자체만으로는 캐싱이 불가능하다.

가령 "Wellcome Home" 과 "Wellcome Tom" 이라는 두 종류의 웹페이지가 있다고 해보자. 앞선 페이지는 Static web page 이고 다음 페이지는 Dynamic web page 이다.

Static web page 의 캐싱은 간단하며, 단순히 해당 페이지(컨텐츠)를 저장하지만, Dynamic web page 의 경우 동적 요소를 따로 분리해서 로직으로 저장해주고(web page 의 경우 javascript 객체로 매핑시켜줄 수 있겠다.) static contents 만 캐싱해서 응답을 재구성하다.

 

CDN 및 캐시 솔루션 중에는 Dynamic Contents 에 대한 캐싱을 서비스해주려는 노력들이 꽤 있다.

가령 AWS 의 CloudFront 같은 경우 별도의 Backbone Network 를 구성해서 오리진 서버(비즈니스 로직이 처리될 서버)까지의 Latency 를 줄이고 Region 을 확장하는 방식으로 노력을 하고 있다.

 

 

 

JWT 란 JSON Web Token 의 약어로 필요한 모든 정보와 검증을 위한 Signature 를 포함하는 JSON 객체를 통해 만들어내는 토큰의 일종이다.

웹표준으로 지정되면서 계정에 대한 인증 및 API 사용에 있어서 권한 확인을 위한 Security Token 으로 사용된다.

 

토큰은 지정한 객체(주로 인증 정보가 된다.)를 JSON 화하여 만든 데이터를 암호화하고, 특정 키를 이용해 서명하게 된다. 따라서 발급된 토큰은 해당 서버 / 서비스가 인증한 Token 이라는 의미가 되고, 이는 권한 인증에 있어 Key 로 사용할 수 있게 된다.

 

JWT 토큰은 Header 와 Payload, Signature 의 3가지 부분을 포함한다.

자세한 설명은 다음을 참고하자.

(https://velopert.com/2389)

 

 

JWT 를 사용한 일반적인 인증 절차는 다음과 같다.

 

 (1) 허용된 API 로 토큰을 발급. 주로 회원가입 / 로그인 API 만을 Token 없이 접근 가능하도록 설계하고, 해당 API 들에서 토큰을 발급해준다.

 (2) JWT Token 이 발급된다.

 (3) 클라이언트는 모든 요청에 Token 을 Header 에 포함시켜서 전달한다.

 (4) 서버는 유효한 JWT 토큰의 경우 인증하고 API 의 사용을 승인시키지만 아닐 경우 401 오류를 표시한다.

 

이는 일반적인 Token 을 이용한 API 프로세스와 동일하다.

 

JWT 의 장점은 다음과 같다.

 - 간편한 사용 및 인증 절차

 - Horizontal Scalable

 - REST API 에 최적화된 키 인증 방식

 - Expired date 정보의 포함

 - 관리와 서버 부하에 있어 부담이 적음

 

반면 다음과 같은 단점도 있다.

 - 인증 정보가 커질 수록 토큰의 크기가 커진다

 - 모든 요청에 토큰 정보가 포함되므로 Token 의 크기가 Message 의 크기보다 커질 경우 비효율적인 통신 구조가 된다.

 

 

다음 예제는 JWT 토큰을 이용한 인증절차를 가장 알기 쉽고 직관적인 예제를 통해 설명한다.

구현이 처음이라면 강추 하는 예제이다.

 

https://medium.com/swlh/spring-boot-security-jwt-hello-world-example-b479e457664c

 

Spring Boot Security + JWT Hello World Example

In this tutorial, we will be developing a Spring Boot application that makes use of JWT authentication for securing an exposed REST API…

medium.com

 


HTTP 와 HTTPS 의 차이점에 대해 면접 볼 때 질문 받은 적이 있었다.
당시 많이 긴장하고 해당 면접에 대해 Deep 한 질문들이 나오던 와중에 받은 질문이어서 보안을 위한 HTTP 라는 정도로 얼버무린 기억이 있는데,
만약 다음에 질문받게되면 깔끔하고 완벽하게 답변할 수 있도록 정리해보았다.


HTTP 란 일반적으로 웹 서버 통신을 위한 프로토콜이다.
HTTPS 란 정확히 어떤 것일까?
간략하게 정리하자면, HTTPS 란 "암호화된 통신을 제공하는 HTTP" 를 일컫는다.

HTTP 를 이용해 클라이언트와 서버가 통신을 할때, 암호화 통신을 위한 키를 설정하고 통신을 하게 된다.

이 때 사용되는 암호화 방식은 공개키 암호화방식을 사용하며, 데이터를 암호화하는데 2개의 키를, 복호화하는데 한개의 키를 사용한다.

HTTP 프로토콜을 사용하면 공격자가 패킷을 가로챌 경우, 평문이기 때문에 해당 데이터를 갈취하고, 변조해서 공격이 가능하다. (Man in the middle)
이에 반해 HTTPS 프로토콜을 사용하면, 패킷이 중간에 탈취되더라도 공격자가 메시지를 알아내고 암호화까지 하여 변조하는데, 일반적으로 천문학적인 시간을 소모하게 된다.

이처럼 암호화된 통신을 함으로써 안전한 구조를 가져갈 수 있지만, 공개키 암호화와 복호화 과정은 많은 비용을 수반한다.
따라서 HTTPS 통신은 HTTP 에 비해 느릴 수밖에 없으며, 보통 선택적으로 사용하게 된다.

예를들어 금융정보 및 기밀 또는 민감한 개인정보들의 경우에는 HTTPS 로, 그와 상관없는 UI 처리 및 일반 컨텐츠 관련 정보는 HTTP 로 처리하는게 정석적이다.


 

Spring AOP(Aspect Of Control) 란, DI(Dependency Injection), PSA(Portable Service Abstraction) 와 같이 Spring Framework 의 주요 Feature 이다.

 

AOP 란 공통된 관심사(Aspect)로 구분된 로직을 필요한 위치에 동적으로 삽입할 수 있게 해주는 기술로,

Advice, JoinPoint, PointCut, Advisor 등의 용어가 사용되며, 비즈니스 로직과 연계되어 공통적으로 사용하는 부분(Transaction 이나 Filter, Security 등의 Layer)을 코드를 특정시점에 코드에 삽입하는 기술이다.

 

이러한 핵심 로직 코드에의 적용을 Weaving 이라 하며 Compile , Class Loading , Runtime AOP의 구현이 가능하다.

 

다음은 몇가지 AOP 에 사용되는 용어들에 대한 정리이다.

 

- Aspect : 핵심기능에 부가될 수 있는 모듈을 말한다. 재사용 가능하며 핵심적인 기능에 부가되어 의미를 가질 수 있는 모듈이다.

 

- Advice : Aspect 에 대한 구현체가 된다. 주로 어느시점에 어떤 동작을 할지가 기술된다.

 

- Point Cut : 핵심 모듈을 분리할 선이자, 어드바이스를 적용할 시점(Join Point)을 정의하는 모듈이 된다.

 

- Proxy : 타겟은 프록시를 통해 호출되며 타겟 메서드 실행에 대한 전처리 후처리를 담당해줌과 동시에 AOP 추상화에 있어서 인터페이스를 제공한다.

 

- Weaving : 핵심 로직 코드에의 적용을 말하며, Aspect 가 적용됨으로써 새로운 Proxy 객체가 생성된다.

 

- Cross Cut : 공통 로직을 비즈니스 로직에서 추출해내는 것을 Cross Cutting 이라 한다.

 

하지만 위의 내용들은 사실 용어와 사용하는 기술들에 대한 내용으로 실제 Spring 에서 추구하는 AOP 의 개념 그 자체는 서버의 기능을 비즈니스 기능과 공통 기능으로 나누고, 공통 기능을 코드 밖에서 필요한 시점에 재사용 가능하도록 적용시켜 주겠다는 개념이다.

 

결국 공통 기능을 따로 분리해서 재사용하겠다는 관점을 말하는 것이다.

 

 

 

서버의 Scalability 를 관리하기 위한 방법은 굉장히 중요하다.

 

실 서비스의 아키텍처를 구조화할 때도 반드시 고려해야할 부분이고, 이 결정은 실제로 서비스에 큰 영향을 주게 된다.

 

가령 사용자가 갑자기 증가할 경우, 엄청난 수의 요청에 대한 처리를 어떻게 할 것인가는 Backend 에서 가장 중요하게 고려해야할 부분 중 하나이다.

 

Scaling 의 방법에는 크게 Scale Up 과 Scale Out 이 존재한다.

 

Scale Up : 서버 자체의 Spec 을 향상시킴으로써 성능을 향상시킨다. Vertical Scaling 이라 불리기도 한다. 서버 자체의 갱신이 빈번하여 정합성 유지가 어려운 경우(주로 OLTP 를 처리하는 RDB 서버의 경우) Scale Up 이 효과적이다.

 

성능 향상에 한계가 있으며 성능 증가에 따른 비용부담이 크다. 대신 관리 비용이나 운영 이슈가 Scale Out 에 비해 적어 난이도는 쉬운 편이다. 대신 서버 한대가 부담하는 양이 많이 때문에 다양한 이유(자연 재해를 포함한다...)로 서버에 문제가 생길 경우 큰 타격이 불가피하다.

 

Scale Out : 서버의 대수를 늘려 동시 처리 능력을 향상시킨다. Horizon Scaling 으로 불린다. 단순한 처리의 동시 수행에 있어 Load 처리가 버거운 경우 적합하다. API 서버나, 읽기 전용 Database, 정합성 관리가 어렵지않은 Database Engine 등에 적합하다.

특히 Sharding DB 를 Scale Out 하게 된다면 주의해야하는데, 기존의 샤딩 알고리즘과 충돌이 생길 수도 있고(샤드가 갯수에 영향을 받을 경우...) 원하는 대로 부하의 분산이 안생길 수 있으니 각별히 주의할 필요가 있다.

 

스케일 아웃은 일반적으로 저렴한 서버 여러 대를 사용하므로 가격에 비해 뛰어난 확장성 덕분에 효율이 좋지만 대수가 늘어날 수록 관리가 힘들어지는 부분이 있고, 아키텍처의 설계 단계에서부터 고려되어야 할 필요가 있다.

 

 

요즘은 클라우드를 사용하기 때문에 Scaling 에 있어서 큰 이점이 있으며, 서비스의 목표치에 알맞게 Scalability 를 설계하고 두 스케일링 방법을 모두 적용시키는 것이 일반적이다.

 

 

+ Recent posts