728x90

지난주 후반부, 한국 뿐만 아니라 전세계가 시끌시끌했습니다. 
사실상의 서버측 로깅 표준으로 자리잡힌 log4j 로깅 모듈의 보안 취약점이 발견되었고
공격방법이 인터넷에 고개되면서 Zero Day Vulnerability 가 발생했기 때문입니다.

대략 이런 흐름! (출처 : CloudFlare Blog)

 

취약점을 간단히 요약하자면,
"로그로 기록되어야 하는 문자열에 악의적인 내용을 집어넣어 원격지에서 서버의 코드, 명령을 실행할 수 있는 취약점이 있었음"
입니다.

취약점을 통해 외부에 노출되지 않은 LDAP 서버 등으로 악의적인 코드가 담긴 자바 클래스를 전송하고 
log4j 를 통해 이 클래스를 메모리에 로딩하는 방식으로 서버에 침투하게 됩니다. 
이번 취약점은 오래전 SSL 프로토콜의 취약점으로 명성을 날렸던 하트블리드(heartbleed)급으로 알려졌습니다.

패스틀리 블로그의 이 정리가 가장 깔끔하고 명료합니다!


취약점에 대한 대응은 크게 두가지 방식으로 진행되었습니다. 
1. 취약점이 패치된 log4j 가 배포되기 전까지는 코드 인젝션이 발생할 수 있는 JNDI 의 옵션을 끈다
2. 취약점 패치 버전 (2.15.0+) 가 배포된 후에는 새로운 log4j 로 교체한다

이런 대응이 여러 회사의 개발조직 중심으로 대응되는 동안 
물들어올때 노를 저어야 한다는 것을 잘 알고 있는 클라우드 벤더들은 
열심히 관련된 포스팅을 날리며 자사의 보안 솔루션들을 홍보하기 시작했습니다. 

클라우드 플레어

 

아카마이

 

패스틀리

 

아마존

 


간만에 글로벌 초대형 급의 취약점으로 주말이 시끌시끌 했습니다. 
아직까지 취약점은 현재 진행형이기 때문에 두눈 부릅뜨고
log4j 를 쓰는 곳이 없는지 살펴봐야 하겠습니다!

728x90
728x90

스크래치 Scratch 를 비롯한 드래그 앤 드랍 방식의 코딩 도구들이 아이들 코딩 교육에 많이 쓰입니다.
스크래치 이후 등장한 엔트리 entry 등 수많은 도구들은 스크래치가 제안한 블록 코딩을 철저히(?) 따르고 있기도 합니다.
성인들의 세계에서는 블록 코딩은 아니지만 노코드 No code 개발이 하나의 트랜드가 된 것 같습니다.

구글에서 내놓은 앱시트 AppSheet 역시 노코드를 표방하는 개발 도구입니다.
단순히 노코드를 하는 것을 넘어서 데이터 기반으로 개발한다는 것을 강조하고 있습니다. 
파이어베이스 Firebase 류의 Pass Storage를 바탕으로 개발 작업을 할 때 느꼈던 감성을 
앱시트를 사용한 개발에서도 느낄 수 있는 것인가, 하는 기대감이 생기게 되더군요. 

 

 

사실 원래부터 모든 어플리케이션, 소프트웨어, 서비스는 데이터 중심이었죠. 
데이터가 없으면 잘 만든 UI도 아무짝에 쓸모 없습니다. 
근래에는 데이터하면 결국 AI, ML로 이어지니 이런 맥락에서 앱시트는 포지셔닝을 하는 느낌입니다. 
쉽고 빠르게 필요한 것을 데이터 기반으로 만들고 거기서 또 데이터를 추출해낸다?

 

가령 구글 시트에 위와 같은 간단한 테이블을 만들어 두고
앱시트를 통해서 Form 중심으로 CRUD 를 할 수 있는 앱을 만든다가 기본적인 컨셉입니다.
어차피 대부분의 어플리케이션이 DB에 대한 CRUD 라는 것에서 착안한 듯 합니다.
특히나 기업에서 사용하는 In-House 도구에서는 무척 유용할 것 같네요

 

노코드는 앱 에서 뿐만 아니라 머신러닝 쪽에서도 대세로 자리잡는 느낌입니다.
코드를 써야하는 과제와 쓰지 않아도 되는 과제의 분리를 통해 
누구나 필요한 것을 만들어 쓸 수 있게 하는 방향성은 이제 대세가 된 것 같네요!

 

 

AppSheet Platform

AppSheet delivers a no-code application platform for people in any role to create the apps that adapt to their work, not the other way around.

solutions.appsheet.com

 

피쳐에 대해서 잘 정리된 블로그 하나 링크해 둡니다!
https://meir.tistory.com/m/89

728x90
728x90

AWS의 CDN 제품인 CloudFront는 원본 서버에서 제공하는 기본 오브젝트를 지정할 수 있는 기능을 제공하고 있습니다. 보통은 원본 서버에서 사용하는 웹 서버에서 기본 오브젝트를 지정하는 경우가 많지만 S3 등 다른 제품을 함께 사용할 때는 기본 오브젝트를 지정할 수 있는 방법이 없기 때문에 파일명을 지정할 수 있는 기능이 필요합니다.

기본 루트 오브젝트 설정 Set Default Root Object

CloudFront Distribution의 기본 설정 탭에서 기본 루트 오브젝트를 설정할 수 있습니다. Distribution 목록에서 작업하려는 Dist ID를 선택하여 상세 화면으로 진입합니다. 상단 탭중 첫번째 탭인 General 탭으로 이동합니다. Settings 섹션의 `Edit` 버튼을 눌러 상세 설정 화면으로 진입해 봅니다. 

Edit 화면의 중간 정도를 살펴보면 `Default root object - optional` 항목을 찾으실 수 있습니다. 이곳에 지정된 파일 이름이 CloudFront를 통해 접근시 사용되는 기본적인 파일 이름이 됩니다. 가령 www.iamnopd.com  이라는 도메인이 있다고 가정했을 때, 브라우저에 www.iamnopd.com  만 입력해도 알아서 index.html 을 찾아 사용자 브라우저로 응답을 하게 되는 거죠. 

 

다양한 경로에 대한 기본 오브젝트 설정 

그런데 문제가 있습니다. `Default root object`에 지정한 파일 이름은 진짜, 레알, 루트 경로에 대한 요청에 대해서만 적용되는 한계가 있습니다. 가령 원본이 S3 버킷이라고 했을 때, 버킷의 최상위 경로에도 index.html 이 있고, 버킷에 생성되어 있는 api 폴더의 하위에도 index.html 이 있다고 해봅시다.

아마도 여러분이 기대하는 것은 www.iamnopd.com  접근시에도 index.html 을 읽어들이고 www.iamnopd.com/api  접근시에도 index.html 을 읽어들여 사용자에게 제공되는 시나리오였을겁니다. 하지만 첫번째 케이스와 달리 두번째 api 경로에 대한 접근은 index.html 을 알아서 패칭해오지 않습니다. 반드시 www.iamnopd.com/api/index.html  로 호출을 해야 컨텐츠를 읽어오게 됩니다.

원본의 서로 다른 경로를 특정 사용자 Path의 루트로 바인딩 하기 위해서는 (아시겠지만) 아래와 같이 동일 원본을 Origin Path만 분기하여 등록하면 됩니다. 이 구성과 Default root object 의 조합은 /api 경로에 대해서 적용되지 않는다는 상황으로 이해하지면 될 것 같습니다. 그러면 어떻게 하면 될까요?

 

CloudFront Function을 이용한 경로 조작

S3에서 뭔가를 하면 되지 않을까? 하고 생각했을지도 모르지만 그것보다는 CloudFront Function을 쓰면 간단하게 구현할 수 있습니다. 아시겠지만 Lambda@Edge를 쓰는 것보다 CloudFront Function을 쓰는 것이 사용도 간편하고(=기능이 다소 적고) 비용도 저렴합니다. 묻지도 따지지도 말고 바로 코드를 보겠습니다.

function handler(event) {
    var pathFrom = /^\/api$/g
    var pathTo   = '/api/index.html'
    var pathDecided = '';   
	var request = event.request;
    pathDecided = request.uri;

	if (pathDecided.match(pathFrom) != null) {
    	pathDecided = pathDecided.replace(pathFrom, pathTo);
	}

    request.uri = pathDecided;
    return request;
}

코드는 무척 간단합니다. 간단한 Regex 를 이용하여 들어온 URI (request.uri)를 단순히 문자열 비교한 후에 실제로 원본이 받게될 URI 를 변경해서 return 해주는 코드입니다. 요청량이 많아도 크게 부담스러운 금액이 나오지는 않을것 같습니다. 간단하지만 Default root object가 단일 경로에 대해서만 적용되는 제약을 회피(?)하는 방법을 살펴봤습니다 :-)

테스트도 참 쉽죠? 원하는 결과를 테스트를 통해 얻었다면, 만든 함수를 적용하고자 하는 Distribution의 Behavior의 Viewer Request 함수로 지정하면 됩니다. 끝!

 

 

 

 

728x90
728x90

공식 문서의 taints 와 tolerations 에 대해서는 아래의 링크를 참고하면 된다. taints 는 노드에 적용되어 <수용 가능한 Pod 의 특성 정의>정도인 것 같고, tolerations 는 Pod 에 적용되어 <내가 동작할 수 있는 Node 를 선택하기 위한 특성 정의>라고 보면 될 것 같다.

 

테인트(Taints)와 톨러레이션(Tolerations)

노드 어피니티는 노드 셋을 (기본 설정 또는 어려운 요구 사항으로) 끌어들이는 파드의 속성이다. 테인트 는 그 반대로, 노드가 파드 셋을 제외할 수 있다. 톨러레이션 은 파드에 적용되며, 파드

kubernetes.io

 


노드에 설정된 taints 를 확인하기 위해서는 kubectl 에서 describe 옵션을 사용하면 된다.

$ kubectl describe node node01
Name:               node01
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
...
Annotations:        flannel.alpha.coreos.com/backend-data: null
                    flannel.alpha.coreos.com/backend-type: host-gw
...
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Mon, 25 Jan 2021 07:43:27 +0000
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  node01
  AcquireTime:     <unset>

 

특정 노드에 특정 key-value 와 effect 값을 지정하여 taints 를 설정. 아래는 spray 를 key 로, mortein 을 value 로, effect 는 NoSchedule 로 지정한 예임

$ kubectl taint nodes node01 spray=mortein:NoSchedule
node/node01 tainted

 

Pod 을 생성할 때 배치된 Node 가 없다면 (이 경우에는 Taints 로 특정한 값이 부여된 Node 밖에 없다) Pod 이 생성되지 못하고 Pending 상태로 머무르며, 상세 에러 내용이 taints 와 tolerations 에 대한 내용이 노출된다.

$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
mosquito   0/1     Pending   0          88s

$ kubectl describe pod mosquito
Name:         mosquito
Namespace:    default
Priority:     0
Node:         <none>
...
...
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age               From               Message
  ----     ------            ----              ----               -------
  Warning  FailedScheduling  6s (x3 over 92s)  default-scheduler  0/2 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 1 node(s) had taint {spray: mortein}, that the pod didn't tolerate.

 

Pod 을 Taints 가 지정된 Node 로 배포하기 위해서는 Pod 의 스펙에 관련된 값을 지정해 주어야 한다.

$ cat create_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: bee
spec:
  containers:
  - image: nginx
    name: bee
  tolerations:
  - key: spray
    value: mortein
    effect: NoSchedule
    operator: Equal
    
$ kubectl create -f create_pod.yaml
pod/bee created

 

노드에 할당되어 있는 taints 값의 변경은 아래의 명령으로 수행할 수 있다. 예시는 controlplane 노드에 대하여 값을 부여하고 삭제하는 예시임.

$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule
node/controlplane tainted
$
$ kubectl taint nodes controlplane node-role.kubernetes.io/master:NoSchedule-
node/controlplane untainted
728x90

+ Recent posts