본문 바로가기
C.W.K.
Stream
Lesson 05 of 05 · published

자가 Lockout 복구 — 네가 자기 lockout 시키는 날

~15 min · recovery, self-lockout, runbook

Level 0Greenhorn
0 XP0/53 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

언젠가 넌 스스로 잠길 거야. 그런 일 생겨. 새 폰, 굵은 손가락, 오래 안 쓰다가 PIN 을 잊는 것. 일요일 밤 11시에 네 admin 패널에서 blacklist 된 채로가 아니라, *지금* 복구 계획을 짜.

세 복구 경로

경로전제 조건사용 시점
1. Local-IP unlockLOCAL_BYPASS 의 host 에 물리적 접근집에 있고 dev 맥이 bypass list 에 있음
2. 비밀 토큰 admin URL1Password 에 일회용 복구 토큰을 넣어둠밖에 있고 bypass IP 에 못 닿을 때
3. SSH + sqlite3host SSH 접근 (PIN 깨져도 작동)최후의 수단. 다른 게 다 막혔을 때

복구 경로 3 — 언제나 열려 있는 비상구

PIN 을 잊고 blacklist 가 네 IP 로 가득 차 있어도 SSH 에 SQL 한 줄이면 풀려. SSH 는 그 자체로 인증돼 있고 (key-only 라면). SSH 가 되는 사람은 이미 host 에서 뭐든 할 수 있어. security DB 도 결국 파일 하나고. 이 복구 경로를 적어둔다고 공격 면이 늘어나는 게 아니야. 미래의 패닉만 줄어들지.

복구 경로 2 — 복구 토큰

밖에 있는데 SSH 마저 막혔을 때 (또는 노트북이 없을 때) 쓰는 길이야. PIN 을 설정할 때 길고 무작위한 복구 토큰을 만들어서 비밀번호 매니저에 넣어둬.

Code

SSH + sqlite3 복구·bash
# 1. host 에 SSH
ssh me@my-mac

# 2. security DB 열기
sqlite3 ~/app/security.db

# 3. 자기 IP 의 blacklist 와 attempt counter wipe
DELETE FROM security_blacklist WHERE ip = '100.64.0.7';
DELETE FROM security_attempts  WHERE ip = '100.64.0.7';

# 4. 선택: PIN 자체 reset (Python 으로 새 거 bcrypt)
# 다른 터미널:
python3 -c "import bcrypt; print(bcrypt.hashpw(b'1234', bcrypt.gensalt(12)).decode())"
# sqlite3 에서:
UPDATE security_config SET pin_hash = 'NEW_HASH' WHERE id = 1;
.exit
복구 토큰 엔드포인트·python
RECOVERY_TOKEN = secrets.token_urlsafe(48)   # 한 번 생성, 1Password 저장
# security_config 에 hash 로 저장

@app.post("/recover")
async def recover(request: Request, token: str = Form(...), new_pin: str = Form(...)):
    cfg = load_config()
    if not bcrypt.checkpw(token.encode(), cfg["recovery_hash"]):
        return Response("Forbidden", status_code=403)
    db.execute("UPDATE security_config SET pin_hash = ?", (hash_pin(new_pin),))
    db.execute("DELETE FROM security_blacklist")
    db.execute("DELETE FROM security_attempts")
    db.commit()
    return Response("PIN reset, blacklist cleared")

External links

Exercise

복구 토큰을 만들어. python -c "import secrets; print(secrets.token_urlsafe(48))". bcrypt hash 를 security_config 에 저장 (recovery_hash 컬럼 추가). plaintext 토큰을 1Password 에 'Solo Auth Quest — Recovery Token' 으로 저장. /recover 엔드포인트 추가. 일부러 lockout 을 일으켜서 한 번 테스트해봐. 이제 빠져나갈 문이 생긴 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.