[Luna] 이중 서명 발생에 대한 보고서

3 분 소요

[Luna] 이중 서명 발생에 대한 보고서

2019-07-16
nonce - LunaWhale.com
English : Doc | Github
Korean : Doc | Github

1. 요약

1-1. 문제

  • Date : 7/11/2019 01:40 UTC-Zero
  • Block height : 474404
  • 문제 : 이중 서명(double sign) 발생
  • 해당 검증자 : “nonce - LunaWhale.com” (“15626A98542EE659662EA5B4431F48328045619F”)

1-2. 패널티

  • 검증자는 474407번 블록부터 검증자로서의 권한을 상실함.
  • 총 위임 지분의 1% (102,466 Luna)가 삭감(Slashing) 됨.

1-3. 처벌 사유(Slashing Cause)

  • 기록 : 474405번 블록 기록에 의거 아래의 내역이 확인 됨.
  • 동일한 검증자가 동일 높이의 2개 블록에 모두 서명
    • 첫번째 블록 : “2A8FD8728530B1C5190321B31889C1E9748B5BD86B020884344F10DE52883E91” (2019-07-11T01:40:55.988225325Z)
    • 두번째 블록 : “C1CCCAC31C21F8D08918B5450F2B45A90046F87EDDEFC68AEB9AE30B2FACEC00” (2019-07-11T01:40:56.07990156Z)
  • 투표 결과 첫번째 블록이 474404번 블록으로 인정 됨.

2. 문제 발생의 배경

사건발생 3일전 검증자 Node가 비정상적으로 종료되는 현상이 파악됨

01

(File descriptor 문제로 3시간 가량 Node가 중지 됨)

2-1. 비정상적 종료의 원인

  • Terra demon에서 제공하는 REST-API Server 운용시 File descriptor 관리 문제 발생.
  • 결과, terrad 프로세스가 강제 종료 됨

2-2. 상황

  • Linux System의 soft limit(1024) 초과가 log로 확인되었음.
  • REST-API를 통해 제공되는 Web service(LunaWhale.com)로 인해 초과된 것으로 예상

2-3. 조치

  • 임시 조치 : Validator node 의 fd_max 를 4096으로 증가함
  • 근본 조치 : 서버 분리를 위해 REST API 호출용 노드를 별도 구성

3. 문제 발생

3-1. 새 노드 구축시, 문제 발생 방지를 위한 내부 검토 진행

  • 잔액(Balance)를 예치하지 않음을 통한 Voting Power Down.
  • Validator Transaction을 전송하지 않음
  • 새로운 노드에서 Luna Validator Operator Key를 신규 생성함
  • Validator 요건을 충족되지 않음으로, 문제가 없을 것으로 예상

3-2. REST-API 호출용 노드 구축

  • 신규 노드 설치 과정에서 제네시스/설정파일등의 문제로 Sync 불가 상태가 빈번히 발생
  • 문제를 피하기위해 기존 테라 노드 설정파일(~/.terrad/config/*)을 복사 하여 초기 Sync 문제 해결.
  • 약 3일 후 블록 싱크가 완료되는 시점에서 Double Sign 발생

3-3. 결과 : 문제 발생

  • Luna Validator로서의 조건은 충족되지 않은 상황.
  • 그러나, priv_validator_key.jsonpriv_validator_state.json 파일을 공통으로 사용하게 됨 으로서 Tendermint 합의과정에서는 Validator로서 구분 됨.
  • Double Sign 발생

4. 코드 분석

텐더민트 합의 알고리즘 소스코드가, 우리가 의도치 않게 재사용했던 priv_validator_key.jsonpriv_validator_state.json 파일을 어떻게 활용하는지 확인.

4-1. 의문 : Validator 가 아님에도 서명이 가능한가?

02

(Node Initialize with key files)

위 2개 파일(priv_validator_key.json and priv_validator_state.json)로 인해 텐더민트 검증인 키를 새로 생성하지 않고, 재사용 함.

노드가 시작될때 ConsensusState에 아래 두 파일을 파일을 참조하여 validator정보를 갱신한다.

03

따라서 우리가 새롭게 셋업한 테스트 노드는 기존 Validator노드의 검증인 키와 검증자 정보를 활용하여 동작하게 될 것이다.

04

(Node 셋업시 KeyFile 참조하는 코드)

이렇게 동작할 경우, Prevote Msg에 대해 아래와 같은 순서로 처리를 진행하게 된다.

05

(Validator’s Signing Sequence)

06

(Vote에 대한 서명을 진행하는 코드)

가장 중요한 함수는 ConsensusState 패키지의 signAddVote함수로서, 이 함수의 첫번째 줄의 조건문에서 서명을 할 것인지에 대한 여부를 결정한다.

이때 우리의 테스트 노드의 경우 cs.Validators.HasAddress(pubkey_addr) == true 이므로 (Validator 정보에 이미 등록이 되어 있음), signVote함수를 실행할 수 있게 되었다.

4-3. 어떤 상황에서 Double Sign 이 발생 되었는가?

474,404번 블록의 제안자(proposer)는 “nonce - LunaWhale.com” 차례였다. 모든 노드가 새로운 라운드마다 호출하는 consensus/state.go enterPropose()에서 노드는 자신이 현재 블록의 검증자 목록에 속하는지와 자신이 이번 블록의 제안자인지 확인한다. 자신이 현재 블록의 제안자인 경우 (defaultDecideProposal()) 유효한 블록이 없으면 블록 생성을 시도한다(createProposalBlock(), state/execution.go CreateProposalBlock()).

이렇게 “nonce - LunaWhale.com” 제안자 키로 동작하는 두 노드가 각자 다른 블록을 만들었다. 이후 두 노드가 자신이 만든 블록을 서명하여 이중 서명이 발생했다. 새로운 노드가 검증자를 만들지 않았고 새로운 노드의 CLI 계정이 루나를 보유하지 않았더라도, 새로운 노드는 기존 노드와 협의없이 독자로 검증자 역할을 수행한다.

07

(Proposer’s Signing Sequence)

4-4. 어떻게 발견되었는가?

VoteMsg가 전달 될 경우, LastCommit된 정보에 검증인의 투표정보를 추가하게 된다. 이때 이미 검증인의 투표정보가 존재하며, height 동일, round 동일, type 동일, validator address 동일, validator index 동일한 상태이나 block id가 서로 다르다면 Double sign Evidence를 생성한다.

08

(Evidence Generation)

09

즉, 루나 노드 실행시 자신의 검증자 주소가 현재 블록체인 상태의 검증자 목록에 포함 되어 있다면 검증자 역할을 수행한다. 노드의 운영자 키(operator key)가 다르고 그 운영자 키가 소유한 루나가 없더라도, 텐더민트 상에서는 여전히 검증자 역할을 수행이 가능한 것이다.

그 결과, 우리의 검증인 노드는 현재 Jail에 갇혀있다.

5. 개선 방안

5-1. 서버 구성

  • 서버/프로세스/노드 로그 모니터링 구성 필요
    • Uptime Slashing 방지
  • Sentry mode node 추가 운영하여 DDOS 공격 방어
    • https://cosmos.network/docs/cosmos-hub/validators/security.html
    • https://forum.cosmos.network/t/sentry-node-architecture-overview/454
  • 이중 서명 위험이 없는 노드 이중화 구성 필요

5-2. 운영 방안

  1. 신뢰할만한 검증자들과 persistent_peers 관계 유지하여 네트워크 반응성 개선
  2. 여러 Node 로 지분을 나누어 운영
    • Terraform Labs 사례 example (Terraform Labs - Ghost, Terraform Labs - Goliath, Terraform Labs - Marine, Terraform Labs - Wraith)
  3. 이중 서명을 유도하는 공격이 가능한지 살펴보고 대비책을 세운다
    • GoS(Game of Stakes) 사례 분석을 통한 개선
  4. Hardware Security Module(HSM)을 사용한 키관리 시스템
  5. Precommits Missed 문제 개선 필요
    • 네트워크 상황 분석 필요
    • 10

6. Conclusion

검증인으로서 우리를 믿고 소중한 자산을 위임해 준 위임자들에게 피해를 입힌 점에 대해 고개 숙여 사죄의 말씀을 드린다.

우리는 이번 경험을 통해 검증인 역할과 방향성에 대해 중대한 고민을 해야 했다.

그 결과, 우리는 커뮤니티 구성원들의 이익과 더 건강한 테라 생태계 조성을 위해 이번 경험을 공유하고, 다양한 연구를 통해 더 건강한 네트워크로 발전시키는 것만이 유일한 보답이라는 결론을 내렸다.

앞으로 Nonce-LunaWhale.com은 신뢰를 회복하는 검증인으로서, 더욱 더 견고한 시스템을 구축하여 노드를 운영 할 것이며, 우리의 노력을 통해 배운 경험에 대해 지속적으로 정보를 공유하도록 할 것이다.

2019-07-16 nonce - LunaWhale.com

카테고리: ,

업데이트:

댓글남기기