라벨이 security인 게시물 표시

Byzantine Fault Tolerance 시스템에서 N = 3f + 1인 이유

분산환경 시스템에서는 다른 노드가 보낸 메시지가 정상적이라고 보장할 수 없다. 이때 잘못된 노드가 모두에게 틀린 메시지를 보낸다면 문제가 쉽게 풀린다. 틀린 메시지를 보내는 노드를 차단하면 된다. 하지만 일부 노드에게는 잘못된 메시지를 보내고, 일부 노드에게는 제대로 된 메시지를 보내는 경우는 문제 상황을 찾기 힘들다. 분산 시스템에서 각 노드는 다른 노드의 상태를 모르기 때문이다. 이런 식으로 일부 노드에게만 틀린 메시지를 보내는 노드를 가정하는 모델을 byzantine failure model이라고 부른다. Byzantine failure model은 네트워크에서 가장 풀기 어려운 모델임과 동시에 실제 네트워크에서 반드시 해결해야 하는 문제다. 특히 다른 노드를 신뢰할 수 없는 p2p에서는 반드시 Byzantine failure model을 가정하고 예외 상황을 처리해야 한다. 그렇다고 인증된 노드만으로 구성된 분산 시스템이라고 byzantine failure model을 가정하지 않아도 된다는 것은 아니다. 노드 자체는 신뢰할 수 있는 사람이 관리하더라도 해킹당했을 수도 있고, 버그로 잘못된 메시지를 보낼 수도 있고, 하드웨어에 문제가 발생할 수도 있다. Byzantine failure model에서도 정상적으로 돌아가는 시스템을 byzantine fault tolerance (a.k.a. BFT)라고 말한다. 당연히 BFT라고 해도 무한히 많은 faulty 노드에 대해서 동작하지는 않는다. 그래서 보통 어떤 시스템이 BFT라고 말할 때 전체 노드 중 몇 개의 노드에 문제가 있을 때까지 동작하는지를 같이 말한다. 예를 들어 N = 5f라고 말하면, 전체 노드 중 1/5가 byzantine failure일 때 정상 동작하는 시스템이고 N = 3 f + 1이라고 말하면, 전체 노드 중 1/3이 byzantine failure일 때까지는 문제없이 돌아가는 시스템을 말한다. 같은 BFT라고 한다면, 감당할 수 있는 faulty 노드의 비

2018년 15번째 주

이미지
이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다. 보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다. 실제로 git 을 사용하면서 단순히 커맨드를 외워서 사용하는 사람들을 많이 봤다. 보통 그 이유로 크게 두 가지를 든다. 첫 번째로 git의 mental model 이 복잡하다는 것이다. git에서 변경된 내용은 크게 다음 상태 중 하나가 된다. 리모트에 존재하는 상태 로컬 브랜치에 있는 상태 브랜치에 머지되지 않았지만 add 돼 있는 상태 변경은 있지만 add 되지는 않은 상태 stash에 들어있는 상태 예전에 커밋했었지만 지금은 브랜치로 따라갈 수 없는 상태 이 중에서 내가 수정했던 내용이 어떤 상태인지 모르는 것이 헷갈리게 하는 첫 번째 이유다. 하지만 반대로 왜 이렇게 많은 상태를 가지게 됐을지 생각해보면 git을 사용하는 데 도움이 된다. 이것들은 전부 그냥 추가된 것이 아니다. 애초에 git을 처음 만든 사람은 Linus Torvalds 다. 그의 성격상 쓸모없는 것은 추가되지 않았다. 전부 제각각의 목적을 가지고 있다. 이 목적을 이해하는 것이 중요한데 아쉽게도 글로 잘 설명할 자신이 없다. 사실 이걸 이해하는 가장 빠르고 확실한 방법은 svn 을 써보는 것이다. 쓰다 보면 불편한 부분들이 자주 생기는데, git에서는 위에서 말한 것들을 이용해 이를 쉽고 빠르게 해결할 수 있다. 사람들이 git을 어려워하는 두 번째 이유는 명령어가 복잡하다는 것이다. 이건 어쩔 수 없다. 사실 git의 명령어는 규칙성 없이 만들어졌다. 그래서 외우는 수밖에 없다. 하지만 어떤 상황에서 어떤 명령어를 써야 한다는 식으로 외우면 끝이 없다. 그보다는 각 명령어가 어떤 상태와 연관이 있는지를 보는

2018년 14번째 주

이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다. 보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다. Why you should pick strong consistency, whenever possible 지난번 글 에서 CP와 AP 중에서 CP를 AP보다 더 선호해야 한다고 썼었다. 이렇게 생각한 사람이 나만 있는 건 아닌 것 같다. 구글 클라우드 플랫폼 팀에서 발표한 Spanner 라는 데이터베이스는 external consistency 를 보장한다. 이 포스트는 Spanner가 external consistency를 사용한 이유에 관한 글인데 제목은 strong consistency 라고 나와 있지만, 이는 strong consistency가 더 일반적으로 사용되는 용어이기 때문에 제목을 이렇게 쓴 것이지 Spanner는 언제나 최신 데이터를 읽을 것을 보장하는 external consistency를 보장한다. MantisTek GK2's Keylogger Is A Warning Against Cheap Gadgets 중국 키보드에서 키로거가 검출됐다고 한다. 개인적으로 전자제품 살 때 알리익스프레스를 많이 사용한다. 같은 사양의 제품을 10분의 1도 안 되는 가격으로 살 수 있기 때문이다. 그때마다 친구들과 이거 전부 해킹당하고 있는거 아닌가라는 농담 하면서 구매하고 몇일은 외부로 나가는 네트워크를 감시하고 그랬는데 실제로 키로거 하는 제품이 있었다. There's a biological reason you're bored at work 회사 생활에 질리고 권태감이 드는 게 생물학적으로 당연하다고 한다. 사람의 뇌는 언제나 새로운 것을 추구하도록 진화됐다고 한다. 이는 사

[보안] Alice와 Bob

네트워크 프로토콜을 설명하는 글을 읽으면 Alice 와 Bob, Carol , Eve , Mallory 등 많은 이름이 등장한다. 보통 이 이름들은 일정한 규칙을 가지고 부여되기 때문에 각 이름이 무슨 의미를 가지는지 안다면 그 프로토콜이 무엇을 어떻게 풀려고 하는지 조금은 더 이해하기 쉬워진다. 이번 글에서는 많이 네트워크 프로토콜에서 많이 사용되는 이름들이 무슨 의미를 가지는지 간략하게 정리해보았다. 네트워크 참여자 - Alice , Bob 보통 Alice 와 Bob 은 서로 통신하려는 사람을 의미한다. 이때 통신하는 메시지는 보통 암호화하여 통신하는 메시지를 의미하는데 비대칭 키를 사용할지, 대칭 키를 사용할지는 그때그때 다르다. 다자 간 통신 참여자 - Carol , Dave , Erin , Frank , Gray Carol 과 Dave 는 Alice 와 Bob 과 함께 통신에 참여하는 경우 사용된다. Carol 과 Dave 말고도 Charlie 나 David 같은 이름을 사용하기도 하지만 보통 Carol 과 Dave 를 많이 사용한다. 5명 이상의 참여자가 필요한 프로토콜을 묘사할 때는, E, F, G로 시작하는 이름들을 사용한다. 보통 Erin , Frank , Gray 등의 이름이 사용되는데 어떤 이름을 사용할지는 딱히 정해져 있지 않다. 다른 용도로 사용되는 Eve 와 Faythe , Grace 등을 제외하고 아무 이름이나 사용된다. 공격자 - Eve , Mallory , Oscar , Trudy Eve 는 보통 네트워크를 감시하여 패킷을 도청하는 공격자를 의미한다. 다만 Eve 는 능동적으로 공격을 하지는 않고 Alice 와 Bob 이 주고받는 대화를 도청하여 무슨 대화를 주고받는지 알아내는 공격자에게 붙이는 이름이다. 이름의 유래는 eavesdrop에서 나왔다. Trudy 라는 이름은 Eve 보다 조금 더 적극적인 공격자를 지칭할 때 사용된다. Alice 와 Bob 사이에 끼어들어 Alice 와 Bob 의

이더리움과 Eclipse attack

p2p 네트워크는 많은 취약점을 가지고 있는데 대표적인 것이 Eclipse attack 이다. Eclipse attack은 네트워크 전체를 공격하는 것이 아니라 목표로 하는 노드의 Routing table을 공격하여 목표로 하는 노드와 전체 네트워크 사이에 악의적인 노드를 집어넣는 공격이다. Routing table을 공격하는 방법이기 때문에 routing-table poisoning이라고도 불린다. 이더리움도 p2p 네트워크를 사용하여 메시지를 주고받기 때문에 eclipse attack이 가능하리라 생각은 했는데 지난 3월 1일 발표 된 페이퍼 에 따르면 단 2개의 노드만으로 하나의 노드를 완전히 고립시키는 것이 가능하다고 한다. 이 페이퍼는 올해 1월 진행됐던 바운티 프로그램에서 나온 문제점들을 정리한 페이퍼로 크게 세 가지 공격방법으로 나눌 수 있다. 우선 첫 번째 문제는 이해하기 위해 이더리움이 p2p 네트워크를 어떻게 관리하는지 이해해야 한다. 네트워크 그래프 구성에 가장 중요한 것은 다른 노드를 어떻게 찾을 것인가 하는 것이다. 이를 흔히 node discovery라고 하는데 이더리움은 node discovery를 위해 DHT( Distributed Hash Table ) 프로토콜 중 하나인 Kademlia 의 일부를 수정해서 사용한다. Kademlia가 다른 DHT와 다른 가장 큰 특징은 노드 간의 거리를 XOR distance로 측정한다는 것이다. XOR distance의 거리는 symmetric 하므로 노드 아이디만 알고 있으면, 노드 A가 생각하는 노드 B까지의 거리나, 노드 B가 생각하는 노드 A까지의 거리나, 노드 C가 생각하는 노드 A와 노드 B 사이의 거리가 같다. 따라서 각 노드는 자신이 알고 있는 노드 중에서 자신과 가까운 노드들과만 통신하면 적은 연결 수로도 큰 네트워크를 구성할 수 있다는 장점이 있다. Kademlia 페이퍼에는 대략 노드의 개수를 N 이라고 할 때 각 노드는 O(log(N)) 개의 연결만 유지하면 된

2018년 9번째 주

이 포스팅은 그냥 지난 한 주간 읽었던 것들을 정리하는 포스트입니다. 그냥 예전에 봤던 글 중 나중에 필요한데 뭐였는지 기억 안 나는 글들이 있어서 쓰기 시작했습니다. 보통 하는 일과 관련된 글들이 올라오겠지만 딱히 정해둔 주제는 없고, 그때그때 관심 있었던 것을 읽었기 때문에 지난주에 쓰인 글일 수도 있고 몇 년 전에 쓰인 글일 수도 있습니다. Lifetime Safety: Preventing Leaks and Dangling Herb Sutter 와 Neil MacIntosh가 쓴 C++에서 memory leak 과 dangling pointer 를 어떻게 없앨 수 있는지에 관한 글이다. 일반적으로 C++의 포인터는 매우 강력하기 때문에, memory leak이나 dangling pointer를 없애기 위해서 C++의 기능을 일부 제한하거나 새로운 문법을 추가하거나 한다. 하지만 이 글에서는 언어를 바꾸지 않으면서 런타임 오버헤드 없이 컴파일 타임에 분석할 수 있는 알고리즘을 제시한다. 특히 이 알고리즘은 프로그램 전체를 분석하는 것이 아니라 함수 단위, 정확히는 블록 단위로 적용할 수 있고, 변수 재사용 등 많은 스타일 가이드에서 권하지 않지만 실제로는 많이 사용되는 패턴들에 대해서도 고려돼있기 때문에 레거시 코드에 적용하기도 좋다. 기계적인 작업이기 때문에 툴을 만드는 것이 가장 좋을 것이다. 하지만 툴을 만들 여유가 없더라도 포인터나 레퍼런스를 어떻게 써야 안전한지 보여주는 좋은 글이기 때문에 일단 읽어보는 것을 추천한다. GitHub DDoS 공격당함 지난 2018년 2월 28일, GitHub 이 Distributed Denial-of-Service(a.k.a. DDoS) 공격을 당해 약 10분 정도 서비스가 멈췄었다. 이 공격은 memcached 를 이용한 공격으로 중국의 0kee team이 찾은 Deluge 라는 기법을 이용한 공격이었다. Deluge는 다른 서버에 설치된 memcached에 데이터를 요청할 때 sourc

Cloudflare의 Flexible SSL을 쓰면 안 되는 이유

이미지
Cloudflare 의 서비스 중 Flexible SSL이라는 것이 있다. SSL 인증서가 없는 서버에 있는 웹페이지도 https 를 이용해 접근할 수 있도록 해주는 서비스다. 자신이 인증서를 설치할 수 없는 서버나 서비스를 사용할 때도 https를 사용할 수 있게 해주기 때문에 blogger처럼 커스텀 도메인에 https를 지원 안 하는 서비스를 이용하는 사람들이 많이 사용한다. 이 블로그도 blogger에서 custom domain을 이용하고 있기 때문에 https를 지원하려면 Cloudflare의 Flexible SSL이 사실상 유일한 옵션이다. 하지만 https를 포기하고 Flexible SSL을 사용하지 않고 있다. 왜냐하면, Flexible SSL이 아무런 이득이 없는, 오히려 위험하기만 한, 존재해서는 안 되는 서비스이기 때문이다. Flexible SSL을 엄청 디스한 것 같은데 어째서 그런지 Flexible SSL이 동작하는 방식을 보면 쉽게 이해할 수 있다. 위의 도표는 Flexible SSL이 어떻게 동작하는지를 그림으로 표현한 것이다. Cloudflare의 DNS 는 요청된 도메인에 대해서 원래 서버의 주소를 주지 않고, Cloudflare 서버의 주소를 준다. 그러면 클라이언트의 브라우저는 원래 서버가 아닌 Cloudflare의 서버로 접속한다. 그러면 Cloudflare의 서버는 원래 서버로 다시 요청을 보내고, 받은 결과를 클라이언트에게 돌려준다. 이때 클라이언트와 Cloudflare 사이의 통신은 암호화된 https로 이루어지고, Cloudflare와 원래 서버 사이의 통신은 암호화되지 않은 http로 이루어진다. 이를 보고 " 최소한 Cloudflare와 클라이언트 사이에는 https를 사용하기 때문에 안전하지 않은가 "라고 생각하는 사람도 있다. 하지만 아니다. 보안에서 자주 사용되는 격언에 " A chain is only as strong as its weakest link. "

Diffie-Hellman Key Exchange - 공개된 정보만으로 secret key 만들기

네트워크상의 두 노드가 암호화된 통신을 하기 위해선 먼저 두 노드가 어떤 암호화 방식으로 어떤 키를 이용해서 암호화할지 합의해야 한다. 보통 암호화 방식은 사용하는 애플리케이션에 따라 고정된 방식을 사용하거나 두 노드가 처음 통신을 시작할 때 암호화하지 않은 패킷을 이용해 합의하거나 한다. 이후 패킷은 양쪽 노드밖에 모르는 암호키를 이용해 암호화할 것이기 때문에 암호화 방식은 암호화되지 않은 방식으로 합의를 해도 안전하다. 하지만 어떤 키를 사용할지는 암호화되지 않은 방식으로 합의해선 안 된다. 키가 공개되면, 이 비밀키를 이용해서 제삼자가 패킷을 위조할 수 있기 때문이다. 그렇다면 이 비밀키는 어떻게 안전하게 교환할 수 있을까? 이에 대한 해답으로 나온 것 중 하나가 Diffie-Hellman key exchange(a.k.a. DH) 다. 사실 이외에도 다른 방법들이 많이 있지만, 개인적으로 생각하기에 가장 범용적으로 안전하게 사용할 수 있는 것은 DH라고 생각한다. 또한, 이후 이것에 대해 많은 변종이 나왔지만, DH만 이해하면 나머지는 이해하는 데 별문제 되지 않는다. 그렇다면 DH는 어떻게 동작할까? 우선 DH가 성립하기 위해서는 특별한 수학적 성질을 만족하는 generator가 필요하다. 이 generator는 하나의 입력을 받아 하나의 출력을 내뱉는다. 이 generator가 g 라고 하고, 입력 x 에 대해서 출력 Y 를 내뱉는 Y = g ( x ) 가 있을 때, x 로부터 Y 를 가지고 오는 것은 빠르고 쉽게 계산할 수 있지만, Y 로부터 x 를 가지고 오는 것은 어려운 일이어야 한다. 즉, 수학적으로는 역함수가 없는 함수여야 하고, 결괏값의 스페이스가 매우 커서 brute-force로 찾는 것이 매우 힘들어야 한다. 사실 이외에도 만족해야 할 수학적 성질이 여러 개 있지만 이번 포스팅에서는 그에 대한 설명은 생략하고 넘어가겠다. DH가 처음으로 제시한 방법은 generator로 modular exponentiation 을 사용

file URI와 same-origin policy

modern web browser에는 보안을 위한 여러 가지 기능들이 들어있다. 그중 가장 대표적인 기능이 same-origin policy 다. same-origin policy 덕분에 (개발자 입장에서는 약간 짜증 나기는 하지만) 특별히 신경을 쓰지 않아도 보안에 관해 상당히 많은 부분을 커버할 수 있다. same-origin policy의 원칙은 매우 간단하다. 내 사이트가 다른 사이트에서 호스팅 되는 리소스에 의존하는 것을 금지해서, 내 사이트가 오염되거나 다른 사이트에 의해 공격당하는 것을 막는 것이다. same-origin인지 결정하는 것은 매우 간단한데 프로토콜, 호스트, 포트가 같은 URI 를 same-origin이라고 판단한다. 요새는 대부분 개인 서버와 개인 도메인을 사용하기 때문에, 프로토콜과 포트까지 같은지 판단하는 것은 너무 빡빡한 기준이라고 생각할 수도 있지만, 워크스테이션이나 공용 서버에서 작업하는 일도 많다는 것을 생각하면 포트와 프로토콜까지 고려하는 것은 역시 상식적인 판단이라고 할 수 있다. 브라우저에서 많이 쓰이는 http나 https에서는 이 규칙이 상식적이라고 할 수 있다. 문제는 file URI 에서의 동작이다. file URI에 대해서는 어떤 URI를 same-origin이라고 할 것인지 정해진 것이 없고, 브라우저마다 알아서 자신이 옳다고 생각하는 방식으로 구현했다. 우선 오페라 는 file URI도 다른 URI와 같은 정책으로 처리한다. 따라서 file URI로 접근한 페이지에서는 읽기 권한이 있는 모든 파일을 읽어서 리소스로 활용할 수 있다. 어차피 파일은 OS가 access list로 보호하고 있으니, 로컬 파일에 대한 보안을 OS에 맡겨 버린 것이라고 할 수 있겠다. 약간 무책임한 것 같지만, 오페라의 구현이 가장 웹서버 없이 웹 페이지를 테스트하기 편한 구현이다. 반면 크롬 은 modern browser 중에 가장 빡빡한 규칙을 적용한다. 크롬에서는 file URI로 들어오는 요청에 대해 무조

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API