Ubuntu에서 Claude Code가 sudo를 사용하게 설정하기 (a terminal is required 해결)
Claude Code CLI가 apt·systemctl 같은 root 명령을 쓰려다 만나는 'sudo: a terminal is required' 에러를, NOPASSWD 없이 timestamp_timeout + !tty_tickets로 안전하게 푸는 설정.
Claude Code CLI로 apt install·systemctl 같은 root 명령을 돌리면 sudo: a terminal is required to read the password 에러가 난다. NOPASSWD 없이 안전하게 푸는 설정.
TL;DR
# /etc/sudoers (sudo visudo) — Defaults 섹션에 추가
Defaults timestamp_timeout=60 # 비밀번호 입력 후 60분 캐시
Defaults !tty_tickets # 모든 tty에서 credential 공유 (이게 핵심)
# 실행: 먼저 credential 캐시 후 Claude Code 기동
sudo -v && claude --dangerously-skip-permissionsClaude Code에서 sudo whoami → root 나오면 성공. 60분 지나면 sudo -v로 갱신.
왜 이 방식인가
Claude Code의 bash 세션은 interactive terminal이 아니라 비밀번호를 입력할 수 없다. 그래서 sudo가 막힌다.
가장 쉬운 우회는 yohan ALL=(ALL) NOPASSWD: ALL인데 쓰지 마라. 계정이 탈취되면 공격자가 즉시 root를 얻는다(이 설정으로 서버 털린 사례 많다). 대신 비밀번호 인증은 유지하고 credential 캐싱으로 편의만 확보한다.
핵심은 !tty_tickets다. 기본값은 tty별로 credential이 분리돼서, 터미널에서 sudo -v를 해도 Claude Code의 bash 세션엔 적용되지 않는다. !tty_tickets로 tty 간 공유를 켜야 터미널에서 캐시한 credential을 Claude Code가 물려받는다.
보안 비교
| 방식 | 공격자 침입 시 | 시간 제한 |
|---|---|---|
NOPASSWD: ALL | 즉시 root 탈취 | 없음 (영구) |
timestamp_timeout + !tty_tickets | 비밀번호 필요 | 60분 후 만료 |
캐시된 60분 안에 침입당하면 위험한 건 맞다. 하지만 "문을 항상 열어두는 것"과 "잠깐 열었다 닫는 것"의 차이다. 더 보수적으로 가려면 timestamp_timeout=15로 줄인다.
배운 것
sudo: a terminal is required의 원인은 sudo 설정이 아니라 비대화형 셸이다 — credential을 미리 캐시해두는 걸로 푼다.!tty_tickets가 진짜 스위치다. 이게 없으면sudo -v를 해도 Claude Code 세션엔 안 먹는다.- 편의(NOPASSWD)와 보안은 양자택일이 아니다. 캐시 + 만료로 둘 다 잡는다.