핵심 요약
이 글은 같은 네트워크에서 project-dev-server 사용 준비를 마친 뒤, 외부 PC와 Ubuntu 개발 서버를 Tailscale로 연결하는 방법을 설명합니다.
Tailscale을 사용하면 공유기의 SSH 포트를 인터넷에 직접 공개하지 않고도 승인된 장치끼리 사설 네트워크처럼 통신할 수 있습니다. 인터넷 회선의 공인 IP 주소가 바뀌거나 CGNAT 환경이더라도 일반적인 공유기 포트 전달 없이 연결할 수 있습니다.

외부 PC의 Windows 11
-> Tailscale 암호화 연결
-> 승인된 Tailnet 장치
-> project-dev-server의 tailscale0 인터페이스
-> 기존 OpenSSH 22/TCP와 공개 키 인증
이 문서는 Tailscale의 네트워크 연결 위에서 기존 OpenSSH를 사용하는 구성입니다. Tailscale이 SSH 인증까지 대신 처리하는 Tailscale SSH는 활성화하지 않습니다.
“Tailscale은 네트워크 연결 통로로만 사용하고, 실제 SSH 로그인과 인증은 기존 OpenSSH가 담당한다”는 뜻입니다.
조금 더 자세히 설명하면 다음과 같습니다.
Tailscale을 설치하면 두 컴퓨터가 인터넷상에서 서로 떨어져 있어도, 마치 같은 사설 네트워크 안에 있는 것처럼 연결할 수 있습니다. 예를 들어 서버의 일반 내부 IP가 192.168.1.10이고 Tailscale IP가 100.x.x.x라면, 외부에 있는 Windows PC에서도 Tailscale을 통해 그 100.x.x.x 주소로 서버에 접근할 수 있습니다.
이때 SSH 자체는 Ubuntu에 이미 설치되어 있는 OpenSSH Server가 처리합니다. 따라서 접속 명령도 일반 SSH와 거의 같습니다.
ssh username@100.x.x.x
또는 MagicDNS를 사용한다면:
ssh username@server-name
여기서 역할을 나누면 이해하기 쉽습니다.
- Tailscale → 두 컴퓨터 사이에 안전한 전용 네트워크 통로를 만들어 줌
- OpenSSH → SSH 접속 요청을 받고 사용자 인증을 처리함
- SSH Key → OpenSSH가 사용자를 확인할 때 사용하는 인증 방법
- Tailscale SSH → 별도의 기능으로, OpenSSH의 일반적인 SSH 인증 대신 Tailscale의 사용자·장치 인증 체계를 이용할 수 있게 하는 기능
이 글이 필요한 경우
- 외부 PC에서
project-dev-server에 접속하되 공유기 포트 전달을 사용하고 싶지 않은 경우 - 인터넷 회선이 CGNAT이거나 공인 IP 주소를 직접 사용할 수 없는 경우
- DuckDNS와 외부 SSH 포트를 별도로 관리하지 않고 서버에 접속하려는 경우
- Tailnet 관리자가 승인한 장치만 서버와 통신하게 하려는 경우
- 기존 OpenSSH 공개 키와 VS Code
Remote - SSH구성을 계속 사용하려는 경우
시작하기 전에
사용 환경의 명칭
| 명칭 | 의미 |
|---|---|
project-dev-server |
집이나 사무실에 있는 Ubuntu 개발 서버 |
| Windows 관리 PC | 서버와 같은 네트워크에서 초기 설정과 복구에 사용하는 Windows PC |
| 외부 PC | 서버와 다른 네트워크에서 접속할 Windows 11 PC |
| Tailnet | 같은 Tailscale 계정과 정책으로 관리되는 사설 네트워크 |
| 장치 승인 | Tailnet 관리자가 새 장치를 검토한 뒤 통신을 허용하는 기능 |
| Tailscale IP | Tailnet 안에서 장치에 할당되는 100.x.x.x 형태의 주소 |
| MagicDNS | Tailscale IP 대신 장치 이름으로 접속할 수 있게 하는 기능 |
예시 구성 값
| 항목 | 예시 값 |
|---|---|
| 서버 호스트 이름 | project-dev-server |
| 서버 사용자 이름 | apple2ne1 |
| 서버 Tailscale IP | 100.101.102.103 |
| Windows SSH 별칭 | project-dev-server-tailnet |
| 서버 SSH 포트 | 22/TCP |
100.101.102.103은 설명을 위한 예시입니다. Tailscale이 실제로 할당한 주소를 확인하여 사용하며 사용자가 임의로 정하지 않습니다.
준비 사항
- 서버 콘솔 또는 기존에 검증된 내부 SSH 연결
- Ubuntu 서버에서 사용할 수 있는 인터넷 연결
- Windows 11 외부 PC의 관리자 권한
- 개인용 Tailscale 계정 또는 직접 관리할 수 있는 Tailnet
- Tailnet의
Owner,Admin또는IT admin권한 - 서버에 등록된 외부 PC의 SSH 공개 키
검증 환경
- 기준 서버: Ubuntu Server 26.04 LTS, 호스트 이름
project-dev-server - 기준 클라이언트: Windows 11, Windows OpenSSH Client
- 서버 SSH 포트:
22/TCP - 연결 방식: Tailscale Tailnet과 기존 OpenSSH 공개 키 인증
- 장치 관리: Tailscale
Device approval활성화 - 작성 기준일: 2026년 8월 19일
- 직접 수행 여부: Windows·Linux 장치 설치와 승인, Tailscale IP를 사용한 OpenSSH 및 VS Code 연결 화면 확인; UFW와 실제 외부 네트워크 전체 절차는 추가 검증 필요
1. 포트 전달 방식과 Tailscale 비교
| 항목 | Tailscale | SSH 직접 공개 |
|---|---|---|
| 공유기 포트 전달 | 불필요 | 필요 |
| 공인 IPv4 | 불필요 | 외부에서 도달 가능한 주소 필요 |
| CGNAT | 연결 가능 | 일반적인 포트 전달로는 연결하기 어려움 |
| DDNS | 보통 불필요 | 유동 공인 IP라면 필요 |
| 접속 대상 | 승인되고 정책이 허용한 Tailnet 장치 | 외부 포트를 아는 인터넷의 모든 클라이언트 |
| SSH 인증 | 기존 OpenSSH 공개 키 사용 | 기존 OpenSSH 공개 키 사용 |
| 외부 서비스 의존 | Tailscale 제어 서비스와 필요시 중계 서버 | DDNS를 사용한다면 DDNS 서비스 |
공인 IP와 공유기 포트 전달로 project-dev-server에 접속하는 방법은 Tailscale을 사용할 수 없거나 외부 서비스를 사용하지 않는 구성이 필요할 때 비교합니다.
두 방식을 동시에 사용할 수 있는가?
공유기 포트 전달과 Tailscale은 서로 다른 네트워크 경로를 사용하므로 동시에 구성할 수 있습니다.
공유기 포트 전달
외부 PC -> 공인 IP:40222 -> 공유기 -> project-dev-server:22
Tailscale
승인된 외부 PC -> Tailnet -> tailscale0 -> project-dev-server:22
공유기의 외부 포트 40222와 서버가 실제로 수신하는 22/TCP는 역할이 다르므로 Tailscale이 같은 서버의 22/TCP에 연결해도 포트 충돌은 발생하지 않습니다.
두 방식을 함께 유지하는 구성은 Tailscale로 전환하거나 장애 복구 경로를 시험할 때 유용합니다. 그러나 공유기 포트 전달이 활성화되어 있으면 Tailscale을 설치한 뒤에도 인터넷에 공개된 SSH 공격 표면은 그대로 남습니다. Tailscale 외부 접속을 실제 네트워크에서 검증한 뒤에는 공유기 포트 전달과 전체 출발지의 UFW SSH 허용 규칙을 비활성화하는 구성을 권장합니다.
# Tailscale 인터페이스의 OpenSSH만 허용
sudo ufw allow in on tailscale0 to any port 22 proto tcp
# 비교용: 직접 공개 구성에서 사용될 수 있는 전체 허용 규칙
sudo ufw allow 22/tcp
두 번째 규칙이 남아 있고 공유기 포트 전달도 활성화되어 있으면 인터넷 경로를 통한 SSH 연결이 계속 서버에 도달할 수 있습니다. 실제 UFW 규칙은 9단계와 13단계에서 확인하고 정리합니다.
2. Tailnet과 장치 승인 구조 이해하기
Tailscale 클라이언트에 로그인한 장치는 같은 Tailnet의 Machines 목록에 등록됩니다. Device approval을 활성화하면 새 장치는 Needs approval 상태로 표시되며 관리자가 승인하기 전까지 Tailnet 트래픽을 보내거나 받을 수 없습니다.
이 글의 완료 상태는 다음과 같습니다.
개인 Tailscale 계정과 Tailnet
├── project-dev-server 승인됨
└── 외부 Windows PC 승인됨
3. Tailscale 계정과 장치 승인 준비
3-1. 개인 Tailnet 확인
- Tailscale 관리 콘솔에 접속합니다.

- 개인 계정으로 로그인합니다.
- 화면 상단이나 계정 메뉴에서 현재 Tailnet 이름을 확인합니다.

- 오른쪽의 Add device를 선택한 뒤 서버에 접속할 Client device를 선택합니다.

- Add device에서 현재 외부 PC로 사용할 Windows를 선택하고 설치 프로그램 링크를 전달할 방법을 선택합니다.

- 복사한 링크를 웹 브라우저에서 열어 Windows용 Tailscale 설치 프로그램을 내려받습니다.

- 내려받은 설치 프로그램을 실행합니다.

- 사용권 계약에 동의하고 설치합니다.

- Sign in to your network를 선택합니다.

- 처음 등록한 Tailnet 관리 계정으로 로그인합니다.

- 장치와 Tailnet 계정을 확인한 뒤 Connect를 선택합니다.

- Machines 목록에서 추가된 장치와 Tailscale IP를 확인합니다. Tailscale의
100.x.x.x주소는 각 장치에 할당되는 전용 IP이며, 같은 장치가 같은 Tailnet에 등록되어 있는 동안에는 일반적으로 유지됩니다.

회사 계정으로 만든 Tailnet은 회사 관리자가 장치, 사용자와 접근 정책을 관리할 수 있습니다. 개인 개발 서버에는 본인이 계속 관리할 수 있는 개인 계정을 사용합니다.
3-2. Device approval 활성화
Device approval은 새 장치가 Tailnet에 연결되기 전에 관리자가 장치를 한 번 더 확인하고 승인하는 기능입니다. Device approval이 꺼져 있으면, Tailnet에 로그인할 권한이 있는 사용자가 새 PC에 Tailscale을 설치하고 로그인했을 때 그 장치가 비교적 바로 Tailnet에 등록될 수 있습니다.
- 관리 콘솔에서 Settings → Device management 페이지를 엽니다.

- Device approval을 활성화합니다.

- 설정이 저장되었는지 다시 확인합니다.
이 기능을 활성화하려면 Tailnet의 Owner, Admin 또는 IT admin 권한이 필요합니다.
4. Ubuntu 서버에 Tailscale 설치
4-1. 기존 연결과 복구 수단 유지
Tailscale 연결이 완전히 검증될 때까지 서버 콘솔과 기존 내부 SSH 연결을 닫지 않습니다. 공유기의 기존 포트 전달 규칙도 이 단계에서는 삭제하지 않습니다.
Ubuntu 서버에서 설치 전 상태를 확인합니다.
command -v curl
systemctl is-active ssh
sudo ufw status verbose

curl이 없다면 설치합니다.
sudo apt update
sudo apt install curl
4-2. 공식 설치 스크립트 실행
Tailscale 공식 Linux 설치 문서의 명령을 실행합니다.
curl -fsSL https://tailscale.com/install.sh | sh

설치 결과를 확인합니다.
tailscale version
systemctl is-active tailscaled
systemctl is-enabled tailscaled

tailscaled가 active인지 확인합니다. 자동 시작이 비활성화되어 있다면 원인을 확인한 뒤 필요한 경우에만 활성화합니다.
sudo systemctl enable --now tailscaled
5. Ubuntu 서버를 Tailnet에 등록하고 승인
5-1. 서버 로그인 주소 생성
Ubuntu 서버에서 실행합니다.
sudo tailscale up

터미널에 표시된 https://login.tailscale.com/a/... 형식의 project-dev-server 인증 주소를 복사합니다. 이 주소는 공개하거나 문서에 기록하지 않습니다.
- Windows 관리 PC의 웹 브라우저에서 인증 주소를 열고, 3단계에서 확인한 개인 Tailscale 계정으로 로그인합니다.

- 아래 화면에서 Open in admin console 을 선택합니다.

- 연결할 Tailnet과 장치 이름을 확인합니다.
- 화면에 표시된 승인 버튼을 선택해도,
Device approval이 활성화 되어 있어,Need approved표시가 없어지지 않습니다.

인증에 사용한 웹 브라우저의 장치가 Tailnet에 자동으로 등록되는 것은 아닙니다. 인증한 계정과 Tailnet이 중요합니다.
5-2. 서버 장치 승인
Device approval이 활성화되어 있으면 서버는 아직 통신할 수 없고 Needs approval 상태로 표시됩니다.
- 관리 콘솔의 Machines 페이지를 엽니다.

project-dev-server와 운영체제, 등록 사용자 정보를 확인합니다.- 장치 오른쪽의 줄임표 메뉴를 열어, Approve를 선택합니다.

Needs approval표시가 사라졌는지 확인합니다.

이름이 같은 장치가 여러 개라면 등록 시간, 운영체제와 Tailscale IP를 함께 확인합니다. 확신할 수 없는 장치는 승인하지 않습니다.
- 승인이 끝나면 서버 터미널에
Success.가 표시됩니다.

5-3. 서버 상태와 주소 확인
Ubuntu 서버에서 실행합니다.
tailscale status
tailscale ip -4
ip -br address show tailscale0

확인 항목은 다음과 같습니다.
tailscale status에 서버와 승인된 Tailnet 장치가 표시됨tailscale ip -4에100.x.x.x주소가 표시됨tailscale0인터페이스가 존재함
Tailscale IP와 관리 콘솔의 장치 이름을 기록하되 로그인 주소나 인증정보는 기록하지 않습니다.
6. 추가 Windows PC 설치와 장치 승인
6-1. 추가 Windows용 Tailscale 설치
- 외부 PC에 Tailscale을 추가로 설치하려면 Tailscale Windows 설치 페이지에서 공식
.exe설치 파일을 내려받습니다. - 내려받은 설치 파일의 게시자가 Tailscale인지 확인합니다.
- 설치 파일을 실행합니다.
- 설치가 끝나면 Windows 작업 표시줄의 시스템 트레이에서 Tailscale 아이콘을 찾습니다.
- 아이콘을 열고 Log in을 선택합니다.
- Ubuntu 서버를 등록한 것과 같은 개인 Tailscale 계정으로 로그인합니다.
6-2. 외부 PC 승인
관리 콘솔의 Machines 페이지에서 새 Windows 장치를 확인합니다.
- 장치 이름, Windows 운영체제, 등록 사용자와 시간을 확인합니다.
- 줄임표 메뉴에서 Approve를 선택합니다.
- Windows Tailscale 앱에서 연결 상태가 정상인지 확인합니다.
승인하기 전에 알 수 없는 장치가 함께 나타나면 해당 장치를 승인하지 말고 계정 로그인 기록과 Tailnet 사용자를 먼저 확인합니다.
6-3. Windows에서 Tailnet 상태 확인
새 PowerShell 창을 열고 실행합니다.
tailscale status
tailscale ping project-dev-server
tailscale ping 결과에 서버의 Tailscale IP와 응답 시간이 표시되는지 확인합니다. 처음에는 DERP 중계를 사용하다가 직접 연결로 전환될 수 있습니다.
7. Linux 서버끼리 연결하는 경우
Windows 외부 PC 대신 다른 Linux 서버를 SSH 클라이언트로 사용할 수도 있습니다. 두 장치가 모두 Linux여도 Tailscale 설치, Tailnet 등록과 장치 승인 원리는 같습니다.
Linux 서버 A
-> Tailscale 암호화 연결
-> 승인된 Tailnet 장치와 접근 정책
-> Linux 서버 B의 tailscale0 인터페이스
-> 기존 OpenSSH 22/TCP
이 예시에서는 Linux 서버 A가 접속을 시작하는 SSH 클라이언트이고 project-dev-server가 연결을 받는 Linux 서버 B입니다.
7-1. 두 Linux 서버 설치와 승인
두 Linux 서버에서 각각 Tailscale을 설치하고 Tailnet에 등록합니다.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
각 명령에 표시된 인증 주소를 신뢰할 수 있는 웹 브라우저에서 열고 같은 Tailnet에 연결합니다. Device approval이 활성화되어 있다면 관리 콘솔의 Machines 페이지에서 서버 A와 서버 B를 개별적으로 검토하고 승인합니다.
두 장치의 상태와 Tailscale IP를 각각 확인합니다.
tailscale status
tailscale ip -4
이미 Ubuntu 서버 B에서 4단계와 5단계를 완료했다면 서버 B를 다시 등록하지 않고 Linux 서버 A만 같은 절차로 추가합니다.
7-2. Linux 서버 A에서 연결 확인
Linux 서버 A에서 서버 B의 MagicDNS 이름으로 연결을 확인합니다.
tailscale ping project-dev-server
ssh apple2ne1@project-dev-server
MagicDNS를 사용하지 않으면 서버 B에서 확인한 실제 Tailscale IP를 사용합니다.
ssh apple2ne1@100.101.102.103
이 문서는 기존 OpenSSH 공개 키 인증을 사용합니다. Linux 서버 A에서 만든 개인 키는 서버 B로 복사하지 않고, 서버 A의 공개 키만 신뢰된 연결을 통해 서버 B 사용자의 ~/.ssh/authorized_keys에 등록합니다.
7-3. 대상 Linux 서버 B의 방화벽
SSH 연결을 받는 서버 B에서만 tailscale0의 22/TCP 허용 여부를 확인합니다.
sudo ufw status numbered
sudo ufw allow in on tailscale0 to any port 22 proto tcp comment 'OpenSSH over Tailscale'
sudo ufw status numbered
이 절에서 서버 B에 규칙을 추가했다면 9단계에서 같은 tailscale0 SSH 규칙을 중복으로 추가하지 않고 기존 규칙이 정확한지만 확인합니다.
서버 A도 다른 장치의 SSH 연결을 받아야 한다면 서버 A에 같은 원칙의 별도 규칙이 필요합니다. 접속을 시작하기만 하는 서버 A에는 수신 SSH 규칙을 이유 없이 추가하지 않습니다.
Tailscale이 SSH 인증까지 처리하는 Tailscale SSH를 사용하려면 별도 정책과 tailscale set --ssh 설정이 필요합니다. 이 문서의 기존 OpenSSH 방식과 한 절차에서 혼합하지 않습니다.
8. MagicDNS 이름 확인
MagicDNS를 사용하면 Tailscale IP 대신 project-dev-server라는 장치 이름으로 접속할 수 있습니다. 2022년 10월 20일 이후 만들어진 Tailnet은 MagicDNS가 기본으로 활성화되지만 실제 설정을 관리 콘솔에서 확인합니다.
- 관리 콘솔의 DNS 페이지를 엽니다.
- MagicDNS가 활성화되어 있는지 확인합니다.

- Machines 페이지에서 서버의 정확한 장치 이름을 확인합니다.

Windows PowerShell에서 확인합니다.
ping project-dev-server

tailscale ping project-dev-server

장치 이름이 중복되거나 짧은 이름이 해석되지 않으면 관리 콘솔에 표시된 전체 MagicDNS 이름 또는 tailscale ip -4로 확인한 Tailscale IP를 사용합니다.

9. UFW에서 Tailscale 인터페이스의 OpenSSH만 허용
서버에서 UFW 상태를 확인합니다.
sudo ufw status verbose
sudo ufw status numbered
UFW가 active라면 tailscale0 인터페이스에서 들어오는 OpenSSH만 허용합니다.
sudo ufw allow in on tailscale0 to any port 22 proto tcp comment 'OpenSSH over Tailscale'
sudo ufw status numbered
이 규칙은 인터넷 인터페이스 전체에 22/TCP를 공개하는 규칙이 아닙니다. Tailscale 인터페이스로 들어온 연결만 서버의 OpenSSH 포트로 전달합니다.
UFW가 inactive라면 이 글의 SSH 규칙만 보고 방화벽을 즉시 활성화하지 않습니다. 서버가 사용하는 다른 서비스와 기존 정책을 검토한 뒤 별도의 방화벽 절차로 설정합니다.
10. 기존 OpenSSH 공개 키로 접속
10-1. SSH 포트 연결 확인
외부 Windows PC의 PowerShell에서 실행합니다.
Test-NetConnection project-dev-server -Port 22

MagicDNS를 사용하지 않으면 실제 Tailscale IP를 지정합니다.
Test-NetConnection 100.101.102.103 -Port 22

TcpTestSucceeded : True가 표시되면 SSH 연결을 시작합니다.
10-2. 서버 Host Key 확인
Tailscale 이름이나 IP로 처음 접속하면 기존 내부 IP 접속과 별도로 Host Key 확인 메시지가 나타날 수 있습니다. 서버 콘솔 또는 이미 신뢰한 내부 연결에서 ED25519 Host Key 지문을 확인합니다.
서버의 ED25519 Host Key 지문 확인
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

외부 PC의 SSH 화면에 표시된 SHA256:... 지문과 정확히 일치할 때만 연결을 승인합니다. 자세한 원리는 SSH 공개 키 인증과 Host Key의 차이를 참조합니다.
10-3. 공개 키 인증 확인
Windows PowerShell에서 실행합니다.
ssh -i "$env:USERPROFILE\.ssh\id_ed25519" apple2ne1@project-dev-server

MagicDNS를 사용하지 않으면 실제 Tailscale IP를 사용합니다.
ssh -i "$env:USERPROFILE\.ssh\id_ed25519" apple2ne1@100.101.102.103

서버 계정 암호를 묻지 않고 접속되면 공개 키 인증이 동작한 것입니다. 개인 키의 Passphrase를 설정했다면 해당 Passphrase는 요구할 수 있습니다.
접속 후 서버에서 연결 정보를 확인합니다.
who
sudo journalctl -u ssh --since "15 minutes ago" --no-pager

10-4. 서버 Host Key로 접근할 수 없을 때
기존 IP 대신 Tailscale IP로 접속할 때 Host Key 경고가 발생하면 원인을 먼저 확인합니다. 주소 변경에 따른 기존 항목 충돌로 확인된 경우에만 known_hosts에서 기존 서버 IP 192.168.1.231 항목을 제거한 뒤 다시 접속합니다.

ssh-keygen -R 192.168.1.231
11. 외부용 SSH 별칭 만들기
Windows PowerShell에서 SSH 설정 파일을 엽니다.
notepad $env:USERPROFILE\.ssh\config
기존 내부 접속 별칭을 덮어쓰지 않고 다음 항목을 추가합니다.
Host project-dev-server-tailnet
HostName project-dev-server
User apple2ne1
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes

MagicDNS를 사용하지 않으면 HostName에 실제 Tailscale IP를 입력합니다.
적용값을 확인합니다.
ssh -G project-dev-server-tailnet | Select-String 'hostname|user|port|identityfile'

Windows PC에서 별칭으로 접속합니다.
ssh project-dev-server-tailnet

VS Code에서 별칭으로 접속합니다.
Windows PowerShell에서 SSH 설정 파일을 변경한 뒤 VS Code가 새 별칭을 표시하지 않으면 Remote Explorer를 새로고침합니다.

적용한 별칭 이름이 보입니다.


원격 호스트 운영체제로 Linux를 선택합니다.

Open Folder를 선택하여 원격 서버에서 작업할 시작 폴더를 지정합니다.

계속 진행합니다.

project-dev-server-tailnet 별칭으로 서버에 연결되었습니다.

12. 실제 외부 네트워크에서 검증
같은 공유기 안의 연결만으로 외부 접속을 완료 처리하지 않습니다. 외부 PC를 휴대전화 테더링이나 다른 장소의 네트워크에 연결합니다.
Windows PowerShell에서 다음 순서로 확인합니다.
tailscale status
tailscale ping project-dev-server
Test-NetConnection project-dev-server -Port 22
ssh project-dev-server-tailnet
성공 기준은 다음과 같습니다.
- Tailscale 앱이 연결 상태입니다.
tailscale ping이 서버의 Tailscale 이름과 주소로 응답합니다.TcpTestSucceeded : True가 표시됩니다.- SSH 공개 키 인증으로 로그인됩니다.
- 서버 Host Key 지문이 별도 경로로 확인한 값과 일치합니다.
13. 외부 Windows PC를 Tailscale에 등록한 화면 확인
13-1. Windows용 Tailscale 내려받기
Tailscale 공식 내려받기 페이지에서 Windows를 선택하고 설치 파일을 내려받습니다.

13-2. Tailscale 설치 시작
사용권 계약에 동의한 뒤 Install을 클릭하여 Windows용 Tailscale을 설치합니다.

13-3. Tailscale 시작 화면 열기
설치가 끝나면 Get Started를 클릭하여 장치 등록 절차를 시작합니다.

13-4. Tailnet 로그인 시작
Sign in to your network를 클릭하여 이 Windows PC를 Tailnet에 연결합니다.

13-5. 로그인 방법 선택
웹 브라우저에 열린 Tailscale 로그인 화면에서 사용할 계정 인증 방법을 선택합니다.

13-6. Google 계정 선택
Tailnet을 관리하는 Google 계정을 선택하여 Tailscale 인증을 계속합니다.

13-7. Windows PC 연결 승인 요청
연결할 장치와 Tailnet 계정을 확인한 뒤 Connect를 클릭합니다.

13-8. 관리자 승인 대기 확인
로그인은 완료되었지만 장치 승인이 필요하다는 안내가 표시되는지 확인합니다.

13-9. 승인 대기 장치 확인
관리 콘솔에서 새 Windows 장치가 Needs approval 상태인지 확인합니다.

13-10. Machines 메뉴 열기
관리 콘솔의 왼쪽 메뉴에서 Machines를 선택하여 Tailnet 장치 목록으로 이동합니다.

13-11. 등록할 Windows 장치 식별
Machines 목록에서 장치 이름, 운영체제와 Needs approval 상태를 대조하여 승인할 외부 Windows PC를 식별합니다.

13-12. Windows 장치 승인
정확한 장치의 줄임표 메뉴를 열고 Approve를 선택합니다.

14. 외부 Linux 서버 등록과 SSH·VS Code 연결 화면 확인
14-1. Linux 서버 사전 상태 확인
curl, OpenSSH 서비스와 UFW 상태를 확인하여 설치와 원격 접속에 필요한 조건을 점검합니다.

14-2. Linux 서버에 Tailscale 설치
Tailscale 공식 설치 스크립트를 실행하고 설치 완료 메시지와 다음 명령을 확인합니다.

14-3. 버전과 서비스 상태 확인
설치된 Tailscale 버전과 tailscaled 서비스의 실행·자동 시작 상태를 확인합니다.

14-4. Linux 서버 인증 주소 생성
sudo tailscale up을 실행하고 표시된 일회성 인증 주소를 웹 브라우저에서 엽니다.

14-5. Tailscale 로그인 방법 선택
Linux 서버 등록에 사용할 Tailnet 계정의 인증 방법을 선택합니다.

14-6. Google 계정 선택
Tailnet을 관리하는 Google 계정을 선택하여 Linux 서버 인증을 계속합니다.

14-7. Linux 서버 연결 요청
장치 이름과 Tailnet 계정을 확인한 뒤 Connect를 클릭합니다.

14-8. Linux 서버 승인 대기 확인
로그인은 완료되었지만 관리 콘솔 승인이 필요하다는 안내가 표시되는지 확인합니다.

14-9. 관리 콘솔의 Machines 열기
관리 콘솔의 왼쪽 메뉴에서 Machines를 선택합니다.

14-10. Linux 서버 승인
Machines 목록에서 project-server를 확인하고 줄임표 메뉴의 Approve를 선택합니다.

14-11. Linux 서버 등록 결과 확인
승인한 project-server가 기존 장치와 함께 정상 상태로 표시되는지 확인합니다.

14-12. tailscale up 완료 확인
Linux 서버 터미널로 돌아와 sudo tailscale up이 Success로 끝났는지 확인합니다.

14-13. Linux 서버에서 Tailscale IP로 SSH 접속
Linux 서버 터미널에서 대상 서버의 Tailscale IP로 SSH 접속하고 처음 표시된 Host Key를 확인합니다.

14-14. 외부 Windows PC에서 Tailscale IP로 SSH 접속
외부 Windows PC의 PowerShell에서도 같은 Tailscale IP로 접속하여 Host Key 지문을 대조합니다.

14-15. Linux 서버 간 SSH 접속 확인
Host Key를 승인한 뒤 대상 Ubuntu 서버의 로그인 메시지와 셸 프롬프트가 표시되는지 확인합니다.

14-16. 외부 Windows PC의 SSH 접속 확인
PowerShell에서도 대상 Ubuntu 서버에 로그인되어 셸 프롬프트가 표시되는지 확인합니다.

14-17. Tailscale SSH 별칭 추가
Windows의 ~/.ssh/config를 열어 Tailscale용 Host, HostName, 사용자와 개인 키 경로를 추가합니다.

14-18. SSH 별칭으로 처음 접속
PowerShell에서 Tailscale SSH 별칭으로 접속하고 별칭이 가리키는 서버의 Host Key를 확인합니다.

14-19. SSH 별칭 접속 성공 확인
Host Key를 승인한 뒤 Tailscale SSH 별칭으로 Ubuntu 서버 로그인이 성공하는지 확인합니다.

14-20. VS Code Remote Explorer 새로고침
VS Code의 Remote Explorer에서 새로고침 아이콘을 클릭하여 추가한 SSH 별칭을 불러옵니다.

14-21. Tailscale SSH 호스트 선택
Remote Explorer에서 project-dev-server-tailnet을 선택하여 현재 창에서 연결을 시작합니다.

14-22. 원격 호스트 운영체제 선택
처음 연결할 때 표시되는 원격 호스트 운영체제 선택 화면에서 Linux를 선택합니다.

14-23. 원격 연결 뒤 폴더 열기
VS Code가 원격 서버에 연결되면 Open Folder를 선택합니다.

14-24. 원격 프로젝트 폴더 선택
서버의 실제 프로젝트 경로를 입력하거나 목록에서 선택한 뒤 OK를 클릭합니다.

14-25. Workspace Trust 확인
본인이 관리하고 내용을 신뢰하는 프로젝트인지 확인한 뒤 Trust Folder & Continue를 선택합니다.

14-26. 원격 프로젝트 연결 완료 확인
Explorer와 터미널에서 Tailscale SSH 별칭으로 열린 프로젝트 경로와 서버 프롬프트를 확인합니다.

14-27. Tailnet 장치 최종 확인
관리 콘솔의 Machines 목록에서 Windows PC와 두 Linux 서버가 모두 정상 상태인지 최종 확인합니다.

15. 직접 공개한 SSH 포트 정리
공유기 포트 전달 방식을 이미 사용하고 있었다면 Tailscale 외부 접속을 실제로 검증한 뒤 직접 공개 구성을 정리합니다.
15-1. 공유기 포트 전달 비활성화
- 공유기 관리 화면에서
project-dev-server-ssh규칙을 찾습니다. - 외부
40222/TCP가 내부192.168.1.231:22로 전달되는 규칙인지 확인합니다. - 먼저 규칙을 비활성화합니다.
- 외부 네트워크에서 Tailscale을 통한 OpenSSH 접속이 계속 성공하는지 확인합니다.
- 더 이상 복구에 필요하지 않다고 판단한 뒤에만 규칙 삭제를 검토합니다.
15-2. UFW의 전체 출발지 SSH 허용 규칙 정리
서버에서 현재 규칙 번호와 범위를 확인합니다.
sudo ufw status numbered
다음 규칙은 서로 역할이 다릅니다.
192.168.1.0/24에서22/TCP허용: 같은 네트워크의 Windows 관리 PC용tailscale0에서22/TCP허용: 승인된 Tailnet 장치용- 모든 출발지에서
22/TCP허용: 인터넷 직접 공개용으로 추가했을 수 있는 규칙
모든 출발지에서 22/TCP를 허용하는 규칙이 실제로 존재하고 더 이상 필요하지 않은지 확인한 뒤, 추가할 때 사용한 규칙과 같은 구문으로 삭제합니다.
sudo ufw delete allow 22/tcp
sudo ufw status numbered
이 명령은 tailscale0 인터페이스 규칙이나 192.168.1.0/24 출발지 규칙을 대신 삭제하는 명령이 아닙니다. sudo ufw status numbered 출력에 전체 출발지의 22/TCP 허용 규칙이 없거나 규칙의 의미를 확정할 수 없으면 실행하지 않습니다.
15-3. DuckDNS 자동 갱신 정리
Tailscale 접속에 DuckDNS는 필요하지 않습니다. 다른 서비스가 DuckDNS를 사용하지 않는 경우에만 사용자 Crontab에서 해당 갱신 줄을 제거합니다.
crontab -l
crontab -e

crontab -e는 현재 사용자에게 설정된 편집기로 Crontab을 엽니다.

crontab -r은 현재 사용자의 예약 작업 전체를 삭제하므로 사용하지 않습니다. DuckDNS 갱신 스크립트와 토큰 정리는 외부 네트워크에서 project-dev-server 사용 준비를 참조하여 별도로 진행합니다.
16. 연결 방식과 성능 확인
Tailscale은 먼저 중계 연결로 통신을 시작하고 가능한 경우 직접 연결로 전환합니다. 직접 연결이 불가능하면 DERP 또는 설정된 Peer Relay를 사용할 수 있습니다. 모든 방식의 장치 간 데이터는 WireGuard로 종단 간 암호화되지만 중계 연결은 성능이 낮을 수 있습니다.
| 연결 | 경로와 영향 |
|---|---|
direct |
장치끼리 직접 연결하며 일반적으로 지연이 가장 낮고 처리량이 높음 |
peer-relay |
Tailnet의 Peer Relay 장치를 거쳐 직접 연결보다 지연이 늘어날 수 있음 |
relay |
Tailscale DERP 서버를 경유하여 지연이 늘고 대용량 전송 속도가 낮아질 수 있음 |
WireGuard 암호화 처리로 CPU와 패킷 처리 부하가 조금 늘어날 수 있습니다. 일반적인 SSH 명령과 VS Code 원격 편집에서는 영향이 작을 수 있지만, 저사양 서버의 대용량 파일 전송이나 DERP 중계 환경에서는 차이가 커질 수 있으므로 실제 환경에서 측정합니다.
Windows 또는 Ubuntu에서 실행합니다.
tailscale ping project-dev-server
tailscale status
tailscale netcheck

판정 기준은 다음과 같습니다.
direct: 장치끼리 직접 연결relay: DERP 중계 연결peer-relay: Tailnet의 Peer Relay 장치를 통한 연결
중계 연결이어도 보안 실패를 뜻하지 않습니다. SSH 응답 속도나 파일 전송 성능이 낮을 때 네트워크가 UDP 통신을 제한하는지 확인합니다.
함께 확인할 운영 문제
- 회사, 학교 또는 공공 네트워크가 UDP를 제한하면 직접 연결 대신 중계 연결이 사용될 수 있습니다.
- 다른 VPN 프로그램과 동시에 실행하면 네트워크 경로 또는 DNS 설정이 충돌할 수 있습니다.
- 장치 키가 만료되면 해당 장치를 다시 인증할 때까지 연결할 수 없습니다.
- MagicDNS 이름이 해석되지 않으면 실제 Tailscale IP로 연결하여 DNS 문제와 네트워크 문제를 구분합니다.
- Tailscale 제어 서비스 장애나 계정 인증 문제는 새 장치 등록, 정책 갱신과 재인증에 영향을 줄 수 있습니다.
Device approval을 사용해도 승인된 장치별 포트가 자동으로 제한되지는 않으므로 Tailnet 장치가 늘어나면Grants를 검토합니다.- Exit Node를 선택한 경우에는 일반 인터넷 트래픽도 해당 노드를 통과하여 지연과 대역폭 사용이 늘어날 수 있습니다. Exit Node를 선택하지 않은 기본 구성에서는 Tailnet 대상 트래픽만 Tailscale 경로를 사용합니다.
17. 장치 키 만료와 운영 점검
Tailscale 장치는 주기적으로 다시 인증해야 합니다. 새 도메인의 기본 키 만료 기간은 일반적으로 180일이지만 Tailnet 설정과 장치 상태에 따라 다를 수 있습니다.
관리 콘솔의 Machines 및 Device management 페이지에서 다음 항목을 확인합니다.
- 장치가
Connected또는 최근 연결 상태인지 - 키 만료 예정일
- 승인하지 않은 장치가 없는지
- 서버와 외부 PC의 운영체제 및 Tailscale 버전
Ubuntu 서버에서 확인합니다.
tailscale status
tailscale version
systemctl is-active tailscaled

18. 장치 연결 해제와 제거
일시적으로 연결 끄기
Ubuntu 서버에서 Tailscale 연결만 일시적으로 끕니다.
sudo tailscale down
다시 연결합니다.
sudo tailscale up
Tailnet에서 로그아웃하기
sudo tailscale logout
로그아웃하면 다시 tailscale up할 때 인증이 필요합니다. 원격 연결 중에는 실행하지 않습니다.
관리 콘솔에서 장치 제거
클라이언트 삭제만으로 장치가 Tailnet의 Machines 목록에서 자동 제거되지는 않습니다.
- 관리 콘솔의 Machines 페이지를 엽니다.
- 제거할 장치의 이름, 사용자와 운영체제를 확인합니다.
- 줄임표 메뉴에서 Remove를 선택합니다.
- 확인 창에서 Remove machine을 선택합니다.
장치를 제거하면 해당 장치는 Tailnet 자원과 즉시 연결할 수 없게 됩니다. 서버나 외부 PC를 잘못 선택하지 않도록 확인합니다.
완료 확인표
- [ ] 본인이 관리하는 개인 Tailnet을 사용한다.
- [ ]
Device approval이 활성화되어 있다. - [ ] Ubuntu 서버와 외부 Windows PC만 검토 후 승인했다.
- [ ] 알 수 없는 장치가 Machines 목록에 없다.
- [ ] 서버에서
tailscaled가active이다. - [ ] 서버에 실제 Tailscale IP와
tailscale0인터페이스가 표시된다. - [ ] MagicDNS 이름 또는 Tailscale IP로
tailscale ping이 성공한다. - [ ] UFW가
tailscale0의22/TCP만 필요한 범위로 허용한다. - [ ] 외부 네트워크에서 OpenSSH 공개 키 인증이 성공한다.
- [ ] 서버 Host Key 지문을 별도 경로로 확인했다.
- [ ] 공유기의 SSH 포트 전달 규칙을 비활성화했다.
- [ ] 전체 출발지의 불필요한 UFW SSH 규칙을 제거했다.
- [ ] 장치 키 만료일과 재인증 방법을 확인했다.
자주 발생하는 문제
장치가 Needs approval 상태로 남는다
Tailnet의 Owner, Admin 또는 IT admin 계정으로 관리 콘솔에 로그인했는지 확인합니다. Machines 페이지에서 정확한 장치를 선택하여 승인합니다.
tailscale status에 다른 장치가 보이지 않는다
- 두 장치가 같은 Tailnet에 로그인했는지 확인합니다.
- 두 장치가 모두 승인되었는지 확인합니다.
- Tailscale 앱과
tailscaled가 실행 중인지 확인합니다. - Tailnet 접근 정책이 장치 가시성과 연결을 허용하는지 확인합니다.
tailscale ping은 성공하지만 SSH가 실패한다
Ubuntu 서버에서 확인합니다.
systemctl is-active ssh
sudo ss -lntp | grep ':22'
sudo ufw status numbered
sudo journalctl -u ssh --since "15 minutes ago" --no-pager
Tailscale 네트워크 연결과 OpenSSH 서비스는 별개입니다. tailscale ping 성공은 SSH 인증 성공을 보장하지 않습니다.
TcpTestSucceeded : False가 표시된다
- 서버의 OpenSSH가
22/TCP에서 수신하는지 확인합니다. - UFW에
tailscale0의22/TCP허용 규칙이 있는지 확인합니다. - Tailnet 접근 정책이 연결을 허용하는지 확인합니다.
- 서버와 외부 PC가 모두 승인 상태인지 확인합니다.
MagicDNS 이름이 해석되지 않는다
- 관리 콘솔의 DNS 페이지에서 MagicDNS 활성화 상태를 확인합니다.
- Machines 페이지의 정확한 장치 이름을 사용합니다.
- 우선 실제 Tailscale IP로 연결을 시험합니다.
연결이 relay로만 표시된다
DERP 중계 연결은 연결 실패가 아니며 암호화 수준도 직접 연결과 같습니다. 속도가 느리면 tailscale netcheck로 UDP 사용 가능 여부와 가까운 DERP 지역을 확인합니다.
SSH Host Key 경고가 표시된다
기존 키를 즉시 삭제하지 않습니다. 서버 콘솔에서 현재 Host Key 지문을 확인하고 경고 원인을 판정합니다. 자세한 절차는 REMOTE HOST IDENTIFICATION HAS CHANGED 경고 이해와 해결을 참조합니다.
주의 사항과 한계
- Tailscale은 장치 간 데이터 통신을 WireGuard로 암호화하지만 장치 정보, IP 주소, 연결 상태와 같은 운영 메타데이터는 제어 서비스에서 처리할 수 있습니다.
- 직접 연결이 성립하지 않으면 DERP 또는 Peer Relay 중계 연결을 사용하여 성능이 낮아질 수 있습니다.
Device approval은 장치 가입 승인 기능이며 승인된 장치 사이의 세부 포트 정책을 대신하지 않습니다.- 기본 Tailnet 정책은 승인된 장치 사이의 통신을 넓게 허용할 수 있습니다. 장치나 사용자가 늘어나면
Grants를 사용한 최소 권한 정책을 별도로 설계합니다. - Tailscale IP와 MagicDNS 이름은 Tailnet 안에서 사용하는 주소이며 일반 인터넷에서 직접 접속하는 공개 주소가 아닙니다.
- 이 문서는 기존 OpenSSH를 사용합니다.
tailscale set --ssh를 실행하여 Tailscale SSH를 활성화하는 절차와 혼합하지 않습니다. - Tailscale 연결을 Exit Node로 사용하지 않는 한 일반 웹 트래픽 전체가 개발 서버를 통과하지 않습니다.
- 서버 콘솔 또는 같은 네트워크의 복구 수단을 유지합니다.
다음 단계 안내
Tailscale용 SSH 별칭으로 접속을 확인한 뒤 VS Code에서 project-dev-server-tailnet 별칭을 선택하면 기존 Remote - SSH 작업 흐름을 사용할 수 있습니다. 자세한 VS Code 절차는 Windows VS Code에서 Linux 서버 Remote – SSH 연결하기를 참조합니다.
작성 및 검증 정보
- 작성자: apple2ne1
- 검토자: apple2ne1
- 직접 수행 여부: Windows·Linux 장치 설치와 승인, Tailscale IP SSH 및 VS Code 연결 화면 확인; UFW와 외부 네트워크 전체 절차는 추가 검증 필요
- 마지막 검토일: 2026년 8월 22일
- 검증 방법: Windows·Linux 장치 등록 화면과 SSH·VS Code 연결 화면 확인, Tailscale 설치·장치 승인·MagicDNS·연결 방식·키 만료 공식 문서 및 Ubuntu OpenSSH·UFW 공식 문서 대조
- 추가 확인 항목: UFW의
tailscale0규칙, 실제 외부 네트워크에서 Tailscale 경로를 사용하는 OpenSSH 연결, 공유기 포트 전달 제거 전후의 복구 경로
참고 자료 및 출처
- Tailscale: Install on Linux — Linux 설치 스크립트,
tailscale up과 Machines 확인 절차 — 2026-08-22 - Tailscale: Install on Windows — Windows
.exe설치, 시스템 트레이와 로그인 절차 — 2026-08-22 - Tailscale: Device approval — 장치 승인 활성화, 권한과
Needs approval처리 — 2026-08-22 - Tailscale: Add a device — Tailnet 장치 추가와 장치 승인 조건 — 2026-08-22
- Tailscale: Device visibility — 기본 접근 정책과 Tailnet 장치 가시성 — 2026-08-22
- Tailscale: MagicDNS — 장치 이름 접속과 기본 활성화 시점 — 2026-08-22
- Tailscale: Connection types — 직접, DERP 및 Peer Relay 연결과 확인 방법 — 2026-08-22
- Tailscale: Key expiry — 기본 만료 기간, 재인증과 원격 강제 재인증 주의 사항 — 2026-08-22
- Tailscale: Remove a device — Machines 페이지에서 장치 제거와 영향 — 2026-08-22
- Ubuntu Server: OpenSSH server — 기존 OpenSSH 공개 키 인증과 서비스 확인 — 2026-08-22
- Ubuntu Server: Firewall — UFW 상태와 포트 허용·삭제 원칙 — 2026-08-22
- Ubuntu 26.04 Manpage: @@INLINE_0@@ — 인터페이스별 포트 허용과 기존 규칙 구문을 사용한 삭제 방법 확인 — 2026-08-22
관련 문서
- prepare-project-dev-server-on-local-network-ko
- prepare-project-dev-server-on-remote-network-ko
- windows-vscode-linux-remote-ssh-setup-ko
- ssh-public-key-and-host-key-ko
- ssh-port-basics-ko
- ssh-remote-host-identification-changed-ko
- Linux 서버 간 Tailscale 인증

