라즈베리파이5 AI 머신 세팅 2: SSH·Tailscale 보안과 Codex 설치
윈도우에서 SSH 키를 만들고 라즈베리파이5에 등록한 뒤, Tailscale 원격 접속·SSH 잠금·UFW 방화벽·시스템 업데이트·Codex CLI 설치까지 실제 화면으로 진행합니다.
왜 필요한가 · 라즈베리파이5를 집 밖에서도 안전하게 관리하고 Codex CLI를 실행하려면, 공유기 포트포워딩보다 먼저 SSH 키·Tailscale·방화벽·로그인 제한을 순서대로 구성해야 하기 때문입니다.
누구에게 · Ubuntu Server와 SSD 부팅까지 마친 뒤 윈도우 PC에서 라즈베리파이5에 원격 접속하고 AI CLI 환경을 만들려는 입문자
읽고 나면 · 윈도우 SSH 키로만 로그인하고, Tailscale IP를 이용해 외부에서 접속하며, UFW와 OpenSSH 보안 설정을 적용한 뒤 Codex CLI 로그인까지 완료할 수 있습니다.
핵심 요약
- 먼저 윈도우에서 ED25519 SSH 키를 만들고, 같은 공유기 안에서 라즈베리파이의 로컬 IP를 확인해 공개 키를 등록합니다.
- SSH config에 사용자·IP·개인 키 경로를 저장하면 긴 접속 명령 대신 짧은 별칭으로 접속할 수 있습니다.
- Tailscale은 윈도우와 라즈베리파이를 같은 계정에 연결해 공유기 포트포워딩 없이 암호화된 사설망을 만듭니다.
- Tailscale IP를 통한 새 SSH 접속을 확인한 뒤에만 비밀번호·root 로그인을 끄고, UFW에서 tailscale0의 22번 포트만 허용합니다.
- 마지막으로 시스템을 업데이트하고 nvm·Node.js·npm을 준비해 Codex CLI를 설치한 뒤 device-auth로 로그인합니다.
1편에서는 라즈베리파이5를 홈서버와 원격 AI 머신으로 사용하기 위한 가장 밑바탕을 만들었습니다.
- 라즈베리파이가 어떤 소형 컴퓨터인지 간단히 살펴봤습니다.
- Raspberry Pi Imager로 USB 메모리에 Ubuntu Server 이미지를 기록했습니다.
- USB로 먼저 부팅해 계정과 네트워크가 정상인지 확인했습니다.
- USB 시스템을 NVMe SSD에 복사한 뒤 USB를 제거했습니다.
- 재부팅 후 NVMe 파티션이 실제 루트 파일시스템으로 사용되는지 확인했습니다.
즉, 1편의 마지막 상태는 라즈베리파이5가 SSD의 Ubuntu Server로 정상 부팅되는 단계입니다. 아직 여기까지 진행하지 않았다면 아래 1편부터 완료하세요.
이번 2편에서 진행할 것
이제 SSD에서 부팅되는 Ubuntu Server를 모니터 없이 관리하고, 집 밖에서도 안전하게 접속하며, Codex를 실행할 수 있는 AI 서버로 바꿉니다. 진행 순서는 다음과 같습니다.
- 윈도우에서 SSH 키를 만듭니다.
- Ubuntu의 로컬 IP를 확인하고 공개 키를 등록합니다.
- 윈도우에서 SSH로 접속하고
config에 별칭을 저장합니다. - Tailscale 계정을 준비하고 윈도우와 라즈베리파이에 설치합니다.
- Tailscale IP로 원격 SSH 접속을 확인합니다.
- SSH 비밀번호 로그인과 root 로그인을 차단합니다.
- UFW에서 Tailscale을 거친 SSH만 허용합니다.
- Ubuntu 시스템을 업데이트하고 재부팅 후 상태를 확인합니다.
- Node.js와 Codex CLI를 설치하고 device-auth 로그인을 완료합니다.
완료하면 공유기 포트포워딩 없이 Tailscale로 접속하고, SSH 키로만 로그인하며, 터미널에서 Codex를 실행할 수 있는 서버가 됩니다.
중요: 비밀번호 로그인이나 방화벽을 먼저 잠그면 원격 접속이 끊길 수 있습니다. 각 단계에서 새 터미널로 접속을 확인하고 다음 단계로 넘어가세요. 가능하면 초기 설정 동안에는 라즈베리파이에 모니터와 키보드를 연결해 복구 수단을 남겨 두는 편이 안전합니다.
Tailscale을 사용하므로 공유기의 22번 포트를 인터넷에 직접 열지 않습니다. 외부 접속을 위해 공유기 포트포워딩부터 설정하는 방식보다 초보자가 관리할 부분이 적습니다.
시작 전 준비 사항
- 1편을 마치고 SSD에서 정상 부팅되는 라즈베리파이5
- 라즈베리파이의 Ubuntu 사용자명과 현재 비밀번호
- 처음 설정할 때 라즈베리파이와 같은 공유기에 연결된 윈도우 10·11 PC
- 윈도우의 OpenSSH Client
- 미리 가입한 Tailscale 계정
- ChatGPT 계정 또는 Codex를 사용할 수 있는 인증 수단
윈도우 PowerShell에서 다음 명령이 동작하는지 확인합니다.
Get-Command ssh, ssh-keygen
ssh -V
두 프로그램의 경로와 SSH 버전이 출력되면 준비된 상태입니다. 명령을 찾지 못하면 윈도우 설정 → 시스템 → 선택적 기능에서 OpenSSH Client를 설치한 뒤 다시 확인하세요.
1. 윈도우에서 SSH 키 만들기
윈도우 PowerShell을 열고 ED25519 방식의 키를 만듭니다.
ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\id_ed25519_pi"
저장 위치를 별도로 지정했기 때문에 다음 두 파일이 만들어집니다.
id_ed25519_pi: 개인 키 — 윈도우 PC에만 보관id_ed25519_pi.pub: 공개 키 — 라즈베리파이에 등록

키 생성 도중 passphrase를 입력할 수 있습니다. 입력하면 개인 키 파일이 유출돼도 한 번 더 보호할 수 있어 권장합니다. 빈 값으로 만들면 접속은 편하지만 개인 키 파일 자체를 더 철저히 보호해야 합니다.
.pub가 붙지 않은id_ed25519_pi는 개인 키입니다. 메신저·블로그·Git 저장소에 올리거나 라즈베리파이로 복사하지 마세요.
2. Ubuntu IP 확인 후 공개 키 등록하기
라즈베리파이의 로컬 IP 확인
라즈베리파이에 연결된 터미널에서 다음 명령을 실행합니다.
hostname -I
여러 주소가 보이면 192.168.x.x 또는 10.x.x.x처럼 현재 공유기에서 받은 IPv4 주소를 찾습니다. 인터페이스 이름까지 같이 보고 싶다면 다음 명령이 편합니다.
ip -br address
- 유선 연결은 보통
eth0 - Wi-Fi는 보통
wlan0 127.0.0.1은 자기 자신을 가리키므로 원격 접속 주소로 쓰지 않음
화면 예시에서는 wlan0의 192.168.0.8을 사용했습니다. 독자의 주소는 반드시 다르게 나올 수 있습니다.
윈도우에서 공개 키 전송
윈도우 PowerShell에서 실제 Ubuntu 사용자명과 방금 확인한 IP를 변수에 넣습니다.
$UbuntuUser = "calvin"
$UbuntuIP = "192.168.0.8"
이제 공개 키 내용을 라즈베리파이의 ~/.ssh/authorized_keys에 추가합니다.
Get-Content "$env:USERPROFILE\.ssh\id_ed25519_pi.pub" | ssh "$UbuntuUser@$UbuntuIP" "umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys"
접속이 안 될 때: Ubuntu에서 SSH 서버 활성화
위 명령을 실행했을 때 PowerShell에서 라즈베리파이에 접속할 수 없다면, Ubuntu에서 외부 접속을 받는 SSH 서버가 실행 중인지 확인합니다. 라즈베리파이에 모니터와 키보드를 연결해 Ubuntu 터미널을 열고 다음 명령을 실행하세요.
sudo apt update
sudo apt install openssh-server -y
Ubuntu에는 접속을 시도하는 SSH 클라이언트가 있어도, 외부 접속을 받는 openssh-server는 기본 설치되지 않았을 수 있습니다.
설치 후 SSH 서비스를 바로 시작하고, 재부팅 후에도 자동으로 실행되도록 설정합니다.
sudo systemctl enable --now ssh
정상적으로 실행 중인지 확인합니다.
sudo systemctl status ssh
출력에 다음 상태가 포함되면 정상입니다.
Active: active (running)
상태 화면에서 빠져나오려면 q를 누릅니다. 이제 윈도우 PowerShell에서 공개 키 전송 명령을 다시 실행하세요.
처음 연결할 때 호스트 지문을 신뢰할지 묻는다면, 주소와 장치가 맞는지 확인한 뒤 yes를 입력합니다. 이어서 Ubuntu 비밀번호를 한 번 입력합니다.

같은 명령을 여러 번 실행하면 동일한 공개 키가 중복될 수 있습니다. 등록이 끝났다면 다음 단계에서 실제 키 로그인이 되는지 확인합니다.
3. 윈도우에서 SSH 접속하고 config에 저장하기
개인 키를 지정해 첫 접속 확인
ssh -i "$env:USERPROFILE\.ssh\id_ed25519_pi" "$UbuntuUser@$UbuntuIP"
Ubuntu 로그인 화면과 셸 프롬프트가 나오면 공개 키 등록이 정상입니다.

접속 후 다음 명령으로 사용자명과 장치 이름을 확인할 수 있습니다.
whoami
hostname
SSH config에 별칭 저장
매번 사용자명·IP·키 경로를 길게 입력하지 않도록 윈도우 SSH 설정 파일을 메모장에서 수정합니다.
- 파일 탐색기를 열고 주소 표시줄에
%USERPROFILE%\.ssh를 입력한 뒤 Enter를 누릅니다. - 탐색기 상단의 보기 → 표시 → 파일 확장명을 켭니다.
config파일이 있으면 마우스 오른쪽 버튼을 눌러 연결 프로그램 → 메모장으로 엽니다.- 파일이 없다면 메모장을 직접 열고 아래 설정을 입력한 다음 파일 → 다른 이름으로 저장을 선택합니다.
- 저장 위치를
C:\Users\윈도우계정\.ssh폴더로 지정합니다. - 파일 이름에는
"config"처럼 큰따옴표까지 입력하고, 파일 형식은 모든 파일로 선택해 저장합니다.
파일 이름은 확장자 없는 config 파일이어야 합니다. config.txt로 저장되면 OpenSSH가 해당 설정을 읽지 못합니다.
Host pi-office-local
HostName 192.168.0.8
User calvin
IdentityFile ~/.ssh/id_ed25519_pi
IdentitiesOnly yes
HostName과 User는 자신의 값으로 바꿉니다. 저장 후에는 다음처럼 짧게 접속할 수 있습니다.
ssh pi-office-local
문제가 생기면 상세 로그를 확인합니다.
ssh -v pi-office-local
로그에서 Offering public key와 Authenticated to가 보이면 지정한 키가 사용된 것입니다.
4. Tailscale 가입·설치하기
Tailscale은 여러 장치를 암호화된 사설망인 tailnet으로 묶어 줍니다. 공유기에서 포트포워딩하지 않아도, 같은 tailnet의 윈도우와 라즈베리파이가 서로의 Tailscale IP로 통신할 수 있습니다.
먼저 Tailscale 계정과 윈도우 앱 준비
- Tailscale 공식 사이트에서 계정을 만듭니다.
- Windows용 Tailscale을 설치합니다.
- 작업 표시줄의 Tailscale 아이콘을 열고 같은 계정으로 로그인합니다.

라즈베리파이5에 Tailscale 설치
라즈베리파이의 Ubuntu 터미널에서 공식 설치 스크립트를 실행합니다.
curl -fsSL https://tailscale.com/install.sh | sh
설치가 끝나면 tailnet 연결을 시작합니다.
sudo tailscale up
터미널에 https://login.tailscale.com/... 형식의 일회용 인증 주소가 표시됩니다. 주소를 윈도우 브라우저에서 열고, 앞에서 준비한 Tailscale 계정으로 장치를 승인합니다.

인증이 끝나면 터미널에 Success.가 표시됩니다.

연결 상태와 라즈베리파이의 Tailscale IPv4 주소를 확인합니다.
tailscale status
tailscale ip -4
Tailscale IP는 일반적으로 100.x.y.z 형태입니다.
Windows에서 라즈베리파이 주소 찾기
작업 표시줄의 Tailscale 메뉴에서 Network devices를 열면 같은 tailnet에 연결된 라즈베리파이가 보입니다.

장치를 선택하면 Tailscale IP를 클립보드로 복사할 수 있습니다. 게시 이미지에서는 실제 tailnet 주소를 가렸습니다.

5. Tailscale 주소로 SSH 접속하기
여기서 사용하는 방식은 Tailscale 사설망 위의 일반 OpenSSH 접속입니다. 별도의 Tailscale SSH 서버 기능을 켜지 않습니다.
sudo tailscale up --ssh로 Tailscale SSH 기능을 켜면 Tailscale이 tailnet에서 들어오는 22번 포트를 별도로 처리하며, Ubuntu의 sshd_config와 authorized_keys를 사용하는 흐름과 달라집니다. 이번 글에서는 이 옵션을 실행하지 않습니다. 다음 단계에서 OpenSSH의 비밀번호 로그인을 직접 잠글 것이므로 sudo tailscale up만 사용합니다.
윈도우 PowerShell에서 복사한 Tailscale IP로 접속합니다.
$TailscaleIP = "100.x.y.z"
ssh -i "$env:USERPROFILE\.ssh\id_ed25519_pi" "$UbuntuUser@$TailscaleIP"
100.x.y.z는 예시이므로 실제 복사한 주소로 바꿔야 합니다. 집과 다른 네트워크에서도 접속을 확인하려면 윈도우를 휴대폰 핫스팟 등에 연결해 테스트할 수 있습니다.
SSH config에도 원격 접속 별칭을 추가합니다.
Host pi-office
HostName 100.x.y.z
User calvin
IdentityFile ~/.ssh/id_ed25519_pi
IdentitiesOnly yes
이후에는 다음 한 줄이면 됩니다.
ssh pi-office
이 접속이 새 PowerShell 창에서 성공하기 전에는 비밀번호 로그인을 끄거나 UFW를 활성화하지 마세요.
6. SSH 비밀번호와 root 로그인 차단하기
Tailscale IP와 SSH 키로 새 접속이 성공했다면 OpenSSH를 잠급니다. 현재 접속한 터미널은 닫지 않은 상태로 유지하세요. 설정이 잘못돼도 기존 창에서 되돌릴 수 있습니다.
현재 Ubuntu 로그인 사용자명을 확인합니다.
whoami
설정 조각 파일을 만듭니다.
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
다음 내용을 입력합니다.
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
AllowUsers calvin
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no

AllowUsers calvin의 calvin은 예시입니다. 반드시 whoami 결과로 바꿔야 합니다. 잘못된 사용자명을 입력하면 정상 계정도 로그인할 수 없습니다.
Ubuntu는 /etc/ssh/sshd_config.d/*.conf 설정 조각을 지원합니다. OpenSSH는 대부분의 항목에서 먼저 읽힌 값을 사용하므로 00-hardening.conf처럼 앞쪽 이름을 사용하면 배포판이 만든 뒤쪽 설정보다 우선 적용되는지 관리하기 쉽습니다. 그래도 최종 적용값은 반드시 sshd -T로 확인합니다.
설정 문법 검사
sudo sshd -t
아무것도 출력되지 않으면 문법 오류가 없는 것입니다. 오류가 나오면 reload하지 말고 파일을 다시 확인합니다.
설정 적용
sudo systemctl reload ssh
재시작이 아니라 reload를 사용하면 기존 연결은 유지하면서 새 연결부터 설정을 적용할 수 있습니다.
실제 적용값 확인
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|maxauthtries'
출력 결과에는 다음 항목과 값이 포함되어 있어야 합니다. Ubuntu·OpenSSH 버전이나 다른 설정 파일에 따라 이 항목들 외의 결과가 함께 표시될 수 있으므로, 출력 전체가 아래 다섯 줄과 완전히 같을 필요는 없습니다.
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
maxauthtries 3
중요한 것은 출력 줄의 개수가 아니라 위 다섯 설정의 최종값이 각각 no, yes, no, no, 3으로 적용됐는지 확인하는 것입니다.
현재 창을 닫지 말고 새 창에서 재접속
윈도우의 새 PowerShell 창을 열고 다시 접속합니다.
ssh pi-office
또는 전체 명령으로 확인합니다.
ssh -i "$env:USERPROFILE\.ssh\id_ed25519_pi" "calvin@100.x.y.z"
새 창에서도 접속되면 SSH 잠금 설정이 끝났습니다. 실패하면 기존에 열어 둔 Ubuntu 세션에서 설정을 수정합니다. 급히 되돌려야 할 때는 다음처럼 설정 조각을 치우고 reload할 수 있습니다.
sudo mv /etc/ssh/sshd_config.d/00-hardening.conf ~/00-hardening.conf.disabled
sudo sshd -t
sudo systemctl reload ssh
7. UFW로 Tailscale 경유 OpenSSH만 허용하기
UFW는 Uncomplicated Firewall의 약자로, Ubuntu에서 네트워크 연결을 허용하거나 차단하는 규칙을 비교적 간단한 명령으로 관리하게 해 주는 방화벽 도구입니다. SSH 설정이 “누가 어떤 방식으로 로그인할지”를 정한다면, UFW는 “어떤 네트워크 인터페이스와 포트로 서버에 들어올 수 있는지”를 제한합니다.
이번 설정에서는 외부에서 들어오는 연결을 기본적으로 차단하고, Tailscale이 만든 tailscale0 인터페이스를 거쳐 들어오는 SSH의 TCP 22번 포트만 허용합니다. 따라서 공유기나 일반 네트워크 인터페이스를 통해 22번 포트에 직접 접근하는 경로를 줄일 수 있습니다.
먼저 Tailscale 인터페이스가 있는지 확인합니다.
ip link show tailscale0
그다음 정책과 SSH 허용 규칙을 추가합니다.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow in on tailscale0 to any port 22 proto tcp
활성화 전에 규칙을 확인합니다.
sudo ufw show added
현재 Tailscale SSH 세션을 유지한 상태에서 UFW를 켭니다.
sudo ufw enable
sudo ufw status verbose

정상이라면 기본 정책은 deny (incoming), allow (outgoing)이고, 허용 목록에는 다음과 비슷한 항목이 보입니다.
22/tcp on tailscale0 ALLOW IN Anywhere
22/tcp (v6) on tailscale0 ALLOW IN Anywhere (v6)
예전에 sudo ufw allow 22/tcp로 모든 인터페이스에 SSH를 열어 둔 적이 있다면 다음 명령으로 규칙 번호를 확인합니다.
sudo ufw status numbered
불필요한 전체 허용 규칙은 Tailscale 접속 검증 후 sudo ufw delete 규칙번호로 지울 수 있습니다. 번호를 잘못 삭제하지 않도록 한 번에 하나씩 확인하세요.
이 설정 이후에는
192.168.x.x로컬 IP의 SSH가 차단될 수 있습니다. 이 글은 원격 관리 경로를 Tailscale로 통일하는 구성입니다. 로컬 SSH도 유지하려면 자신의 LAN 대역만 별도로 허용해야 합니다.
UFW 적용 후에도 새 PowerShell에서 ssh pi-office가 되는지 다시 확인합니다.
8. Ubuntu 시스템 업데이트하기
접속과 보안 경로가 안정된 뒤 시스템 패키지를 업데이트합니다.
sudo apt update
sudo apt full-upgrade -y
sudo reboot
full-upgrade는 필요하면 패키지를 추가하거나 제거하면서 의존성을 맞출 수 있습니다. 실행 전에 제거 예정 패키지가 예상보다 많다면 무조건 진행하지 말고 목록을 확인하세요.
재부팅되면 잠시 기다린 뒤 윈도우에서 다시 접속합니다.
ssh pi-office
서버에서 다음 상태도 확인합니다.
tailscale status
sudo ufw status verbose
systemctl is-active ssh
세 명령에서 Tailscale 연결, UFW 활성화, SSH 서비스 실행 상태를 확인한 뒤 Codex 설치로 넘어갑니다.
9. 라즈베리파이5에 Codex CLI 설치하기
Codex CLI는 현재 터미널의 작업 폴더를 읽고 파일 수정·명령 실행을 도와주는 AI 코딩 도구입니다. 라즈베리파이를 원격 AI 머신으로 쓰려면 먼저 Node.js와 npm을 준비합니다.
기본 패키지와 bubblewrap 설치
sudo apt update
sudo apt install -y curl git ca-certificates bubblewrap
bubblewrap은 Linux에서 Codex가 명령 실행 범위를 격리하는 샌드박스 구성 요소입니다. 설치하지 않아도 버전에 따라 번들된 bubblewrap으로 대체될 수 있지만, 첫 화면에 PATH 경고가 보일 수 있으므로 Ubuntu 패키지를 먼저 설치했습니다.
nvm 설치
Node.js 버전을 사용자 계정 단위로 관리하기 위해 nvm을 사용합니다. 이 글은 확인된 v0.40.5 설치 스크립트를 사용합니다.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
source ~/.bashrc
설치가 끝나면 LTS Node.js를 설치하고 기본 버전으로 지정합니다.
nvm install --lts
nvm alias default 'lts/*'
nvm use default
버전을 확인합니다.
node --version
npm --version
두 명령에서 버전 숫자가 출력되면 준비됐습니다.
Codex 설치와 버전 확인
npm install --global @openai/codex
codex --version
ChatGPT 계정으로 device-auth 로그인
라즈베리파이 서버에는 웹브라우저가 없으므로 기기 인증 방식을 사용합니다.
codex login --device-auth
터미널에 공식 인증 주소와 15분 동안 유효한 일회용 코드가 표시됩니다.

- 윈도우 브라우저에서 화면에 표시된 공식 주소를 엽니다.
- ChatGPT 계정으로 로그인합니다.
- 라즈베리파이 터미널에 표시된 일회용 코드를 입력합니다.
- 인증이 완료될 때까지 터미널을 유지합니다.
일회용 코드는 비밀번호처럼 취급하고 다른 사람에게 보내거나 캡처에 그대로 노출하지 마세요. 이 글의 이미지에서도 실제 코드를 가렸습니다.
인증 후 작업 폴더를 만든 뒤 Codex를 실행합니다.
mkdir -p ~/projects
cd ~/projects
codex

화면 상단에 Codex 버전과 모델, 현재 디렉터리가 표시되면 원격 AI 머신의 기본 구성이 끝난 것입니다. 캡처에는 bubblewrap PATH 경고가 보이지만, 앞에서 sudo apt install -y bubblewrap을 실행했다면 같은 경고가 사라지는지 다음 실행에서 확인할 수 있습니다.
AI가 돌아가는 서버 기본 세팅 완료
여기까지 오면 SSD의 Ubuntu Server 위에 원격 접속 경로와 SSH 보안, UFW 방화벽, Node.js, Codex CLI가 모두 준비된 상태입니다. Codex 로그인과 첫 실행까지 확인했으므로 AI가 실제로 돌아가는 라즈베리파이 서버의 기본 세팅은 끝났습니다.
아직은 윈도우에서 SSH로 접속해 직접 Codex를 실행하는 방식입니다. 다음 단계에서는 이 서버에 Hermes Agent를 설치하고 Gateway를 설정해, 외부 채널에서 라즈베리파이에 작업을 요청하고 결과를 받을 수 있는 구조로 확장합니다.
마지막 점검 체크리스트
- 윈도우에서
ssh pi-office로 Tailscale IP에 접속된다. - 비밀번호가 아니라 지정한 개인 키로 로그인된다.
-
sudo sshd -T에서 root·password·keyboard-interactive 로그인이 꺼져 있다. -
sudo ufw status verbose에서tailscale0의 22번만 허용된다. - 재부팅 후에도 Tailscale과 SSH가 정상 동작한다.
-
node --version,npm --version,codex --version이 모두 출력된다. -
codex login --device-auth인증 후 Codex 첫 화면이 열린다.
💡 Tip
보안 명령을 한꺼번에 붙여 넣기보다, 키 접속과 Tailscale 접속을 새 창에서 확인한 뒤 한 단계씩 잠갔습니다. 특히 비밀번호 로그인 차단과 UFW 활성화 전에는 기존 SSH 창을 닫지 않았습니다. AI에게 설정을 맡기더라도 “새 연결 확인 후 다음 단계 진행”을 작업 조건에 넣는 편이 안전합니다.
출처
- Microsoft Learn — OpenSSH 키 기반 인증
- Ubuntu Server — OpenSSH 서버 설정
- Ubuntu Server — UFW 방화벽
- Tailscale — Linux 설치
- Tailscale — Ubuntu 서버 잠그기
- Tailscale — Tailscale SSH와 일반 SSH의 차이
- nvm 공식 저장소
- OpenAI Codex — 빠른 시작
- OpenAI Codex — Linux 샌드박스
정리
라즈베리파이5를 원격 AI 머신으로 만드는 순서는 먼저 접속 경로를 만들고, 새 접속을 검증한 뒤, 마지막에 잠그는 것이 핵심입니다.
윈도우에서 SSH 키를 만들고 로컬 IP로 공개 키를 등록한 뒤, Tailscale IP 접속까지 확인했습니다. 그다음 OpenSSH에서 비밀번호와 root 로그인을 차단하고 UFW가 Tailscale의 SSH만 받도록 제한했습니다. 시스템 업데이트와 재부팅 검증을 마친 뒤 Node.js와 Codex CLI를 설치해 device-auth 로그인까지 완료했습니다.
이제 라즈베리파이5는 공유기 포트포워딩 없이 외부에서 접속하고, 터미널에서 AI 작업을 맡길 수 있는 기본 원격 머신이 됐습니다.
다음 글: Hermes Agent와 Gateway로 외부에서 제어하기
3편에서는 라즈베리파이5에 Hermes Agent를 설치하고 Discord Gateway를 설정하는 과정을 진행합니다. Gateway를 실행 서비스로 구성하고 Discord Bot과 연결한 뒤, 외부 채널에서 작업을 요청하고 라즈베리파이의 응답을 확인합니다.
자주 묻는 질문
- 이 글에서 사용하는 방식이 Tailscale SSH 기능인가요?
- 아닙니다. 이 글은 Tailscale이 만든 사설망 위에서 Ubuntu의 일반 OpenSSH 서버에 접속합니다. 따라서 authorized_keys와 sshd_config 보안 설정이 그대로 적용됩니다. 별도의 Tailscale SSH 기능을 켜는 sudo tailscale up --ssh 명령은 사용하지 않습니다.
- SSH 키 접속을 확인하기 전에 비밀번호 로그인을 꺼도 되나요?
- 안 됩니다. 공개 키 등록이나 경로가 잘못되면 서버에 접속할 수 없게 됩니다. 기존 SSH 창을 유지한 채 새 창에서 키 로그인을 먼저 확인하고, Tailscale IP 접속까지 성공한 후 비밀번호 로그인을 차단하세요.
- Tailscale을 사용하면 공유기 포트포워딩이 필요한가요?
- 이 구성에서는 필요하지 않습니다. 윈도우와 라즈베리파이 양쪽이 같은 tailnet에 로그인되어 있으면 Tailscale IP로 접속할 수 있습니다. 공유기의 22번 포트를 인터넷에 직접 공개하지 않습니다.
- UFW를 켠 뒤 로컬 IP로 SSH 접속이 안 됩니다. 정상인가요?
- 이 글의 규칙은 tailscale0 인터페이스의 22번 포트만 허용하므로 192.168.x.x 같은 로컬 IP 접속은 차단될 수 있습니다. Tailscale IP 접속을 먼저 확인하고 적용해야 하며, 로컬 접속도 유지하려면 자신의 LAN 대역을 제한적으로 허용하는 별도 규칙이 필요합니다.
- Codex device code가 만료됐습니다. 어떻게 하나요?
- 일회용 코드는 화면에 표시된 시간 동안만 유효합니다. 라즈베리파이 터미널에서 codex login --device-auth를 다시 실행해 새 코드를 발급받으면 됩니다. 코드는 다른 사람에게 공유하지 마세요.
이 글은 입문자 기준으로 이해하기 쉽게 정리했으며, 내용은 운영 과정에서 순차적으로 보완될 수 있습니다. 환경에 따라 화면이나 명령이 다르게 보일 수 있으니, 막히는 부분이 있으면 isense2021@gmail.com 로 알려주세요.