Windows (GUI) 에서 Ubuntu (CLI)로 SSH 기반 원격 백엔드를 구축.
쉽게 말하면, Windows Codex/Claude GUI에서 Ubuntu Codex/Claude CLI로 원격 작업하는 구조.
원격 Ubuntu 환경을 구축하는 이유는..
`1. Codex 환경에서 Powershell 7으로 작업해도 초반에 읽기 문제 여러 번 발생함 -> 토큰 낭비가 심함`
`2. Windows 환경에서 Codex와 Claude가 지원하는 기능들이 뭔가 나사가 한두개씩 빠져있음`
`ex. Codex에서 config.toml 설정할 때도 오류 있고, browser-use 쓸 때 경로 문제도 발생함`
`3. Windows 환경과 에이전트 실행 권한을 분리하기 좋음`
-> 단점이 없음.
---
# 1. Ubuntu Setup (1)
Ubuntu는 GUI 환경이 아닌 CLI로 설치해도 큰 문제 없음. Ubuntu Server 24.04 LTS로 다운로드 및 설치.
1) Ubuntu Install
- Language : English
- Update to the new installer
- Layout / Variant : Korean
- Choose the base for the installation : Ubuntu Server
- SSH configuration : Install OpenSSH server
2) 1회용 기본 설정
```bash
sudo apt update && sudo apt -y full-upgrade
sudo apt -y install build-essential curl ca-certificates git ripgrep fd-find unzip tmux jq bubblewrap
timedatectl # NTP 활성 확인
```
3) 네트워크 설정, 시간 설정
```bash
ls /etc/netplan
> 50-cloud-init.yaml
```
```bash
sudo nano/etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
enp6s18:
dhcp4: false
addresses:
- 192.168.50.30/24
routes:
- to: default
via: 192.168.50.1
nameservers:
addresses:
- 192.168.50.1
```
`ctrl x, y, enter`
```bash
timedatectl
sudo timedatectl set-timezone Asia/Seoul
```
# 2. Windows Setup (1)
1) Powershell 에서 Winget 설치
```Powershell
Install-PackageProvider -Name NuGet -Force | Out-Null
Install-Module -Name Microsoft.WinGet.Client -Force -Repository PSGallery | Out-Null
Repair-WinGetPackageManager -Force -Latest
```
2) 사전 도구 설치
```Powershell
winget upgrade --id Microsoft.AppInstaller
winget install --id Git.Git -e
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
winget install --id Microsoft.WindowsTerminal -e # 선택
```
3) SSH 키 생성 + ~/.ssh/config
```Powershell
ssh-keygen -t ed25519 -C "win10" # 기본 경로 사용, 비밀번호는 선택
notepad $HOME\.ssh\config
```
`config` *(주의 : config.txt가 아닌 config으로 저장해야 함)*
```Notepad
Host ubuntu-code
HostName 192.168.50.XX # Ubuntu IP
User user_name # Ubuntu Username
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3
```
4) 공개키를 Ubuntu로 전송
```Powershell
Get-Content $HOME\.ssh\id_ed25519.pub | ssh
[email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
```
5) 확인
```Powershell
ssh ubuntu-code # 비밀번호 없이 로그인되면 OK
```
# 3. Ubuntu Setup (2)
1) SSH 키 등록 (Windows에서 공개키 생성 후)
```bash
mkdir -p ~/.ssh && chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys # 공개키 한 줄 붙여넣기
chmod 600 ~/.ssh/authorized_keys
```
2) SSH 서버 하드닝
```bash
sudo nano /etc/ssh/sshd_config.d/10-hardening.conf
PasswordAuthentication yes
PermitRootLogin no
KbdInteractiveAuthentication no
```
```bash
sudo systemctl reload ssh
```
# 4. Ubuntu Setup (3)
[1-A] Node.js 22 LTS 설치 (Codex/Claude Code 공통 의존성)
apt 기본 노드(v18)는 너무 낡았고, nvm은 SSH 비대화식 셸에서 PATH에 잡히지 않아
Claude Code Desktop / Codex Desktop의 SSH-Remote 기능을 깨트린다.
**NodeSource 기반 시스템 Node**를 사용한다.
```bash
# Node 22 LTS 설치 (NodeSource APT 저장소)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# 확인 — /usr/bin/node 에 설치되어 기본 PATH에 잡힘
which node && node -v && npm -v
```
이 방식의 핵심은 `node`/`npm`이 `/usr/bin/` 에 들어간다는 것이다.
`/usr/bin`은 SSH 비대화식 셸(`ssh host "command"` 형태)의 기본 PATH에 포함되어 있어
GUI 앱이 원격에서 명령을 띄울 때 즉시 찾을 수 있다.
이어지는 §2-7, §2-8에서 글로벌 설치할 `claude`·`codex`도 동일한 디렉터리에 배치되므로
심볼릭 링크나 별도 PATH 설정이 필요 없다.
> **이후 : 시스템 Node에서는 글로벌 npm 설치가 root 권한을 요구한다.
> - `npm install -g @openai/codex` → `sudo npm install -g @openai/codex`
> - `npm install -g @anthropic-ai/claude-code` → `sudo npm install -g @anthropic-ai/claude-code`
>
> 인증 명령(`codex login`, `claude login`)은 사용자 홈에 자격증명을 쓰므로 `sudo` 없이 그대로 실행한다.
[1-B] Node.js 22 LTS 설치 (Codex/Claude Code 공통 의존성)
```bash
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
exec $SHELL
nvm install --lts
nvm alias default lts/*
node -v && npm -v # v22.x 이상 확인
```
[2] Codex CLI 설치 및 로그인
```bash
sudo npm install -g @openai/codex
codex --version
codex login --device-auth
```
--device-auth 출력에 "ChatGPT 보안 설정에서 디바이스 코드 인증 활성화 필요" 메시지가 뜨면:
1. Windows 브라우저로 https://chatgpt.com/#settings/Security 접속
2. nable device code authentication for Codex 토글 ON
3. Ubuntu에서 codex login --device-auth 재실행
4. 출력된 URL(https://auth.openai.com/codex/device)과 코드를 Windows 브라우저에서 입력 → 승인
5. codex login status로 성공 확인
[3] Claude Code CLI 설치 및 로그인
```bash
sudo npm install -g @anthropic-ai/claude-code
claude --version
claude login
```
[4-1] 작업 디렉터리 + Samba 공유
```
mkdir -p ~/code # 임의로 생성. 본 문서에서는 code 폴더로 설정
```
[4-2] Samba 설치 및 공유 설정
```
sudo apt -y install samba
# Samba 사용자 등록 (리눅스 계정과 같은 이름으로 등록 권장)
# $USER 해도 되는데, root로 되는 경우도 있어서 직접 입력.
sudo smbpasswd -a user_name # 새 SMB 비밀번호 설정 (리눅스 비밀번호와 별개)
sudo smbpasswd -e user_name
```
[4-3] `/etc/samba/smb.conf` 끝에 다음 추가 (user_name은 실제 사용자명으로 교체)
```
sudo nano /etc/samba/smb.conf
[code]
path = /home/user_name/code
browseable = yes
read only = no
create mask = 0644
directory mask = 0755
valid users = user_name
force user = user_name
```
```
sudo testparm # 설정 문법 검증
sudo systemctl restart smbd nmbd
sudo systemctl enable smbd nmbd
```
[4-4] 방화벽 (UFW) : 같은 서브넷(Windows VM 1)에서만 SSH/SMB 허용. 절대 `0.0.0.0`에 열지 말 것. (외부로 공유기 포트 노출 한거 아니면 안해도 됨.)
```
# Windows VM이 속한 서브넷을 192.168.50.0/24 라고 가정
sudo ufw allow from 192.168.50.0/24 to any port 22 proto tcp
sudo ufw allow from 192.168.50.0/24 to any port 445 proto tcp
sudo ufw allow from 192.168.50.0/24 to any port 139 proto tcp
sudo ufw enable
sudo ufw status verbose
```
[4-5] (권장) tmux로 장기 세션 보존
```
sudo apt -y install tmux
```
# 5. Windows (2)
[1] Codex Desktop - SSH 연결
```powershell
notepad $HOME\.codex\config.toml
[features]
remote_connections = true
```
앱 재시작 → **Settings → Connections → Add SSH host** → `ubuntu-code` 선택
[2] Claude Code Desktop - SSH 연결
# Troubleshooting
`Windows + Codex GUI에서 SSH connection failed : OpenSSH_for_windows_9.5p1, LibreSSL 3.8.2
[email protected]: Permission denied (publickey,password) 오류 발생 시`
: SSH Key에 Password를 설정해서 생기는 문제이다.
1. 관리자 권한 PowerShell에서 실행
```powershell
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
```
2. 그다음 일반 PowerShell에서
```
ssh-add $env:USERPROFILE\.ssh\id_ed25519
```
3. 등록 확인
```
ssh-add -l
```