Add Windows PowerShell one-click installation script

- Complete PowerShell script with colorful output and error handling
- Auto-detect existing Tailscale installations
- Smart handling of existing connections (like Linux version)
- Administrator privilege checking with clear instructions
- Automatic Tailscale download and silent installation
- Windows Defender firewall configuration
- Network connectivity testing and verification
- Comprehensive final status report

Features:
- One-line web execution support
- Force reinstall option (-Force parameter)
- Detailed system information display
- Graceful error handling and cleanup
- Windows-native user experience

🚀 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
시골약사 2025-09-11 00:54:13 +09:00
parent f69ee95443
commit ea11f92070
2 changed files with 938 additions and 0 deletions

View File

@ -0,0 +1,455 @@
# 🪟 Windows용 팜큐 Headscale 원클릭 설치 패키지 기획서
## 🎯 목표
Windows 클라이언트에서 **단 한 번의 실행**으로 Tailscale 설치부터 팜큐 Headscale 네트워크 연결까지 완전 자동화
## 🔍 현재 Windows 상황 분석
### 기존 연결된 Windows 클라이언트들
```
100.79.125.82 upharm-1 thug0bin@ windows offline
100.76.226.63 upharm thug0bin@ windows offline
100.93.4.146 prox-win10-kiosk thug0bin@ windows offline
100.109.121.8 desktop-06t3j0m thug0bin@ windows offline
100.70.5.37 desktop-9a1aurp thug0bin@ windows offline
100.126.213.6 desktop-m445evd thug0bin@ windows offline
```
### Windows 특성
- **관리자 권한** 필요 (UAC)
- **PowerShell** 스크립트 실행 정책
- **GUI 설치 마법사** 선호
- **레지스트리** 설정 관리
- **서비스** 자동 시작 설정
## 💡 Windows 설치 패키지 방안 (5가지)
## 방안 1: PowerShell 원클릭 스크립트 (권장)
### 개념도
```
[사용자] → [PowerShell 스크립트] → [Tailscale MSI 설치] → [Headscale 등록] → [완료]
우클릭 "관리자로 실행" 자동 다운로드/설치 자동 서버 설정
```
### 구현 방법
#### 1.1 PowerShell 스크립트 생성
```powershell
# farmq-headscale-installer.ps1
param(
[switch]$Force,
[string]$HeadscaleServer = "https://head.0bin.in",
[string]$PreAuthKey = "8b3df41d37cb158ea39f41fc32c9af46e761de817ad06038"
)
# 관리자 권한 확인
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "❌ 관리자 권한이 필요합니다." -ForegroundColor Red
Write-Host "우클릭 → '관리자로 실행'을 사용해주세요." -ForegroundColor Yellow
pause
exit 1
}
Write-Host "🚀 팜큐 Headscale Windows 설치 시작..." -ForegroundColor Green
```
#### 1.2 웹 실행 방법
```powershell
# 관리자 PowerShell에서
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1'))
# 또는 강제 재등록
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1?force=1'))
```
### 장점
- ✅ 단일 명령어로 실행 가능
- ✅ 기존 Linux 스크립트와 유사한 UX
- ✅ 웹에서 바로 실행 가능
- ✅ 버전 관리 용이
### 단점
- ❌ PowerShell 실행 정책 문제
- ❌ 일반 사용자에게 복잡함
- ❌ UAC 프롬프트 필요
---
## 방안 2: MSI 설치 패키지 (GUI 방식)
### 개념도
```
[사용자] → [farmq-headscale-installer.msi 실행] → [설치 마법사] → [완료]
더블클릭 GUI 단계별 진행
```
### 구현 방법
#### 2.1 WiX Toolset으로 MSI 제작
```xml
<!-- farmq-installer.wxs -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="팜큐 Headscale 클라이언트" Language="1042"
Version="1.0.0" Manufacturer="팜큐" UpgradeCode="...">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine"/>
<!-- Tailscale MSI 번들링 -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="FarmQ Headscale"/>
</Directory>
</Directory>
<!-- 사용자 정의 액션 -->
<CustomAction Id="InstallTailscale"
FileKey="TailscaleMSI"
ExeCommand="msiexec /i tailscale-windows.msi /quiet"/>
<CustomAction Id="RegisterHeadscale"
FileKey="RegisterScript"
ExeCommand="powershell.exe -ExecutionPolicy Bypass -File register-headscale.ps1"/>
</Product>
</Wix>
```
#### 2.2 설치 마법사 UI
```
┌─────────────────────────────────┐
│ 팜큐 Headscale 클라이언트 설치 │
├─────────────────────────────────┤
│ [ ] 기본 설치 (권장) │
│ [ ] 기존 연결 해제 후 재설치 │
│ │
│ 서버: https://head.0bin.in │
│ 네트워크: 100.64.0.0/10 │
│ │
│ [< 이전] [다음 >] [취소] │
└─────────────────────────────────┘
```
### 장점
- ✅ Windows 사용자에게 친숙한 GUI
- ✅ 제어판에서 제거 가능
- ✅ 디지털 서명 가능
- ✅ 그룹 정책 배포 가능
### 단점
- ❌ 개발 복잡도 높음
- ❌ 코드 서명 인증서 필요
- ❌ 업데이트 배포 복잡
---
## 방안 3: 실행 파일 (EXE) + 내장 리소스
### 개념도
```
[사용자] → [farmq-installer.exe 실행] → [콘솔/GUI 선택] → [완료]
단일 실행 파일 모든 리소스 내장
```
### 구현 방법
#### 3.1 Go/C#으로 네이티브 실행파일
```go
// farmq-installer.go
package main
import (
"embed"
"fmt"
"os"
"os/exec"
)
//go:embed resources/tailscale-windows.msi
//go:embed resources/register-script.ps1
var resources embed.FS
func main() {
fmt.Println("🚀 팜큐 Headscale Windows 설치")
// 관리자 권한 확인
if !isAdmin() {
fmt.Println("❌ 관리자 권한으로 다시 실행해주세요")
return
}
// Tailscale MSI 추출 및 설치
installTailscale()
// Headscale 등록
registerHeadscale()
}
```
#### 3.2 배포 형태
- **farmq-installer.exe** (단일 파일, ~50MB)
- Tailscale MSI 포함
- PowerShell 스크립트 포함
- 모든 의존성 내장
### 장점
- ✅ 단일 파일로 배포 간편
- ✅ 오프라인 설치 가능
- ✅ 의존성 문제 없음
- ✅ 콘솔/GUI 하이브리드 가능
### 단점
- ❌ 파일 크기 큼 (50MB+)
- ❌ 네이티브 개발 필요
- ❌ Tailscale 업데이트 시 재빌드
---
## 방안 4: 웹 기반 설치 (브라우저)
### 개념도
```
[사용자] → [웹페이지 방문] → [원클릭 다운로드] → [자동 실행] → [완료]
설치 가이드 페이지 맞춤형 설치파일 브라우저 실행
```
### 구현 방법
#### 4.1 웹 설치 페이지
```html
<!-- https://install.farmq.network -->
<!DOCTYPE html>
<html>
<head>
<title>팜큐 Headscale Windows 설치</title>
</head>
<body>
<h1>🪟 Windows용 팜큐 네트워크 설치</h1>
<div class="install-options">
<button onclick="downloadInstaller('basic')">
🚀 기본 설치
</button>
<button onclick="downloadInstaller('force')">
🔄 강제 재설치
</button>
</div>
<script>
function downloadInstaller(type) {
const url = `https://install.farmq.network/download?type=${type}`;
window.location.href = url;
}
</script>
</body>
</html>
```
#### 4.2 동적 설치파일 생성
```python
# Flask 서버에서 실시간 생성
@app.route('/download')
def download_installer():
install_type = request.args.get('type', 'basic')
# 사용자 맞춤형 PowerShell 스크립트 생성
script = generate_powershell_script(
force=install_type=='force',
preauth_key=get_current_preauth_key(),
server_url="https://head.0bin.in"
)
response = make_response(script)
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = 'attachment; filename=farmq-install.ps1'
return response
```
### 장점
- ✅ 최신 설정 항상 반영
- ✅ 사용자별 맞춤 설치
- ✅ 통계 수집 가능
- ✅ 웹 기반으로 접근성 좋음
### 단점
- ❌ 인터넷 연결 필수
- ❌ 웹 서버 인프라 필요
- ❌ 브라우저 보안 정책 제약
---
## 방안 5: 배치 파일 (BAT) 스크립트
### 개념도
```
[사용자] → [farmq-install.bat 실행] → [Windows CMD 명령] → [완료]
우클릭 "관리자로 실행" 전통적인 배치 방식
```
### 구현 방법
#### 5.1 배치 스크립트
```batch
@echo off
:: farmq-install.bat
title 팜큐 Headscale Windows 설치
:: 관리자 권한 확인
net session >nul 2>&1
if %errorLevel% neq 0 (
echo ❌ 관리자 권한이 필요합니다.
echo 우클릭으로 "관리자로 실행"해주세요.
pause
exit /b 1
)
echo 🚀 팜큐 Headscale Windows 설치 시작...
:: Tailscale 다운로드 및 설치
echo 📦 Tailscale 다운로드 중...
powershell -Command "Invoke-WebRequest -Uri 'https://pkgs.tailscale.com/stable/tailscale-setup.exe' -OutFile 'tailscale-setup.exe'"
echo 🔧 Tailscale 설치 중...
tailscale-setup.exe /S
:: Headscale 등록
echo 🌐 Headscale 서버 등록 중...
"C:\Program Files\Tailscale\tailscale.exe" up --login-server=https://head.0bin.in --authkey=8b3df41d37cb158ea39f41fc32c9af46e761de817ad06038
echo ✅ 설치 완료!
pause
```
### 장점
- ✅ 개발 간단
- ✅ Windows 네이티브 지원
- ✅ 의존성 없음
- ✅ 디버깅 용이
### 단점
- ❌ 기능 제한적
- ❌ 에러 처리 복잡
- ❌ 사용자 경험 떨어짐
---
## 🎯 권장 구현 우선순위
### 1단계: PowerShell 스크립트 (즉시 구현 가능)
**기간**: 1-2일
**난이도**: 하
```powershell
# 사용자 실행 방법
# 1. 관리자 PowerShell 열기
# 2. 다음 명령 실행
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1'))
```
### 2단계: 실행 파일 (EXE) 방식
**기간**: 3-5일
**난이도**: 중
- Go언어로 크로스 컴파일
- 단일 실행파일로 배포
- GUI 옵션 포함
### 3단계: MSI 설치 패키지
**기간**: 1주일
**난이도**: 상
- 전문적인 설치 경험
- 제어판 등록
- 그룹 정책 배포 지원
## 📋 PowerShell 스크립트 구현 명세서
### 기본 기능
```powershell
# 1. 시스템 확인
- Windows 버전 체크 (Windows 10/11 지원)
- 관리자 권한 확인
- 인터넷 연결 확인
# 2. Tailscale 설치
- 기존 설치 확인
- 최신 버전 다운로드
- 자동 설치 (Silent Install)
- 서비스 시작
# 3. Headscale 등록
- 기존 연결 확인 및 해제
- Pre-auth key로 자동 등록
- 연결 상태 확인
# 4. 방화벽 설정
- Windows Defender 예외 추가
- 필요한 포트 허용
# 5. 완료 확인
- IP 주소 할당 확인
- 네트워크 연결 테스트
- 상태 출력
```
### 사용자 시나리오
```
1. 약국 직원이 새 PC 설정
2. 관리자 PowerShell 실행
3. 원클릭 명령어 붙여넣기
4. 자동 설치 진행 (2-3분)
5. 팜큐 네트워크 연결 완료
```
## 🔧 즉시 구현 가능한 MVP
### 파일 구조
```
farmq-windows-installer/
├── farmq-install.ps1 # 메인 설치 스크립트
├── modules/
│ ├── system-check.ps1 # 시스템 확인
│ ├── tailscale-installer.ps1 # Tailscale 설치
│ ├── headscale-register.ps1 # Headscale 등록
│ └── network-verify.ps1 # 네트워크 확인
├── resources/
│ └── farmq-logo.ico # 아이콘
└── README-windows.md # Windows 설치 가이드
```
### 웹 실행 명령어
```powershell
# 기본 설치
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/main/farmq-install.ps1'))
# 강제 재설치
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/main/farmq-install.ps1?force=1'))
```
## 📊 예상 사용 통계
### 대상 사용자
- **팜큐 약국**: ~100개 약국 × 2-3대 PC = 200-300대
- **신규 PC**: 월 10-20대 추가
- **재설치**: 월 5-10건
### 성공 지표
- ✅ **설치 성공률**: 95% 이상
- ✅ **설치 시간**: 3분 이내
- ✅ **사용자 만족도**: 5점 만점 4점 이상
- ✅ **지원 요청**: 월 5건 이하
## 🚀 결론 및 추천
**즉시 구현 권장**: PowerShell 원클릭 스크립트
1. **개발 용이성** ⭐⭐⭐⭐⭐
2. **사용자 편의성** ⭐⭐⭐⭐
3. **유지보수성** ⭐⭐⭐⭐⭐
4. **배포 편의성** ⭐⭐⭐⭐⭐
**다음 단계**: PowerShell 스크립트 구현 → EXE 파일 → MSI 패키지 순으로 단계적 발전
---
**목표**: "Linux처럼 Windows에서도 한 줄 명령어로 팜큐 네트워크 연결!" 🎯

483
farmq-install.ps1 Normal file
View File

@ -0,0 +1,483 @@
# 팜큐(FARMQ) Headscale Windows 원클릭 설치 스크립트
# 사용법: 관리자 PowerShell에서 실행
# iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1'))
param(
[switch]$Force,
[string]$HeadscaleServer = "https://head.0bin.in",
[string]$PreAuthKey = "8b3df41d37cb158ea39f41fc32c9af46e761de817ad06038",
[string]$FarmqNetwork = "100.64.0.0/10"
)
# ================================
# 색상 출력 함수
# ================================
function Write-ColorOutput {
param(
[string]$Message,
[string]$ForegroundColor = "White"
)
Write-Host $Message -ForegroundColor $ForegroundColor
}
function Write-Header {
param([string]$Text)
Write-Host ""
Write-Host "============================================" -ForegroundColor Magenta
Write-Host $Text -ForegroundColor White
Write-Host "============================================" -ForegroundColor Magenta
Write-Host ""
}
function Write-Status {
param([string]$Message)
Write-Host ""
Write-ColorOutput "🔧 $Message" "Blue"
}
function Write-Success {
param([string]$Message)
Write-Host ""
Write-ColorOutput "$Message" "Green"
}
function Write-Error {
param([string]$Message)
Write-Host ""
Write-ColorOutput "$Message" "Red"
}
function Write-Warning {
param([string]$Message)
Write-Host ""
Write-ColorOutput "⚠️ $Message" "Yellow"
}
function Write-Info {
param([string]$Message)
Write-Host ""
Write-ColorOutput "📋 $Message" "Cyan"
}
# ================================
# 시스템 요구사항 확인
# ================================
function Test-Requirements {
Write-Status "시스템 요구사항 확인 중..."
# 관리자 권한 확인
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
if (-NOT $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Error "이 스크립트는 관리자 권한으로 실행해야 합니다."
Write-Info "다음 방법으로 다시 실행해주세요:"
Write-Info "1. Windows 키 + X → 'Windows PowerShell(관리자)' 클릭"
Write-Info "2. 스크립트 명령어 다시 실행"
Write-Host ""
Read-Host "아무 키나 누르세요..."
exit 1
}
# Windows 버전 확인
$osVersion = [System.Environment]::OSVersion.Version
if ($osVersion.Major -lt 10) {
Write-Warning "Windows 10 이상을 권장합니다. 현재: Windows $($osVersion.Major).$($osVersion.Minor)"
}
# 인터넷 연결 확인
try {
Test-Connection "8.8.8.8" -Count 1 -Quiet | Out-Null
}
catch {
Write-Warning "인터넷 연결을 확인해주세요."
}
Write-Success "시스템 요구사항 확인 완료"
}
# ================================
# Tailscale 설치
# ================================
function Install-Tailscale {
Write-Status "Tailscale 클라이언트 확인 중..."
# 기존 설치 확인
$tailscalePath = Get-Command "tailscale" -ErrorAction SilentlyContinue
if ($tailscalePath) {
$version = & tailscale version 2>$null | Select-Object -First 1
Write-Info "Tailscale이 이미 설치되어 있습니다."
Write-Info "현재 버전: $version"
return
}
Write-Info "Windows용 Tailscale 설치 중..."
# 임시 다운로드 경로
$tempPath = "$env:TEMP\tailscale-setup.exe"
$downloadUrl = "https://pkgs.tailscale.com/stable/tailscale-setup.exe"
try {
Write-Status "Tailscale 다운로드 중..."
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempPath -UseBasicParsing
Write-Status "Tailscale 설치 중... (잠시 기다려주세요)"
Start-Process -FilePath $tempPath -ArgumentList "/S" -Wait
# PATH 환경변수 새로고침
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# 설치 확인
Start-Sleep -Seconds 3
$tailscaleInstalled = Get-Command "tailscale" -ErrorAction SilentlyContinue
if (-not $tailscaleInstalled) {
# 직접 경로 시도
$tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe"
if (Test-Path $tailscaleExe) {
# PATH에 Tailscale 경로 추가
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($currentPath -notlike "*Tailscale*") {
[Environment]::SetEnvironmentVariable("Path", "$currentPath;C:\Program Files\Tailscale", "Machine")
$env:Path = "$env:Path;C:\Program Files\Tailscale"
}
}
}
Remove-Item $tempPath -Force -ErrorAction SilentlyContinue
Write-Success "Tailscale 설치 완료"
}
catch {
Write-Error "Tailscale 설치 실패: $($_.Exception.Message)"
throw
}
}
# ================================
# Tailscale 서비스 시작
# ================================
function Start-TailscaleService {
Write-Status "Tailscale 서비스 시작 중..."
try {
# Tailscale 서비스 시작
$service = Get-Service -Name "Tailscale" -ErrorAction SilentlyContinue
if ($service) {
if ($service.Status -ne "Running") {
Start-Service -Name "Tailscale"
Start-Sleep -Seconds 3
}
Write-Success "Tailscale 서비스가 실행 중입니다."
} else {
Write-Warning "Tailscale 서비스를 찾을 수 없습니다. 수동 시작을 시도합니다."
}
}
catch {
Write-Warning "서비스 시작에 실패했습니다: $($_.Exception.Message)"
}
}
# ================================
# Headscale 등록
# ================================
function Register-Headscale {
Write-Status "Headscale 서버에 등록 중..."
# Tailscale 실행파일 경로 확인
$tailscaleCmd = Get-Command "tailscale" -ErrorAction SilentlyContinue
if (-not $tailscaleCmd) {
$tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe"
if (Test-Path $tailscaleExe) {
$tailscaleCmd = @{Source = $tailscaleExe}
} else {
Write-Error "Tailscale 실행파일을 찾을 수 없습니다."
return $false
}
}
$tailscalePath = $tailscaleCmd.Source
# 기존 연결 확인
try {
$status = & $tailscalePath status 2>$null
if ($LASTEXITCODE -eq 0 -and $status) {
Write-Warning "이미 Tailscale/Headscale에 연결되어 있습니다."
# 현재 연결 상태 표시
Write-Info "현재 연결 상태:"
$status | Select-Object -First 5 | ForEach-Object { Write-Host " $_" }
# 강제 등록 옵션 확인
if ($Force) {
Write-Warning "강제 재등록 옵션이 활성화되었습니다."
Write-Info "기존 연결을 해제하고 재등록합니다..."
} else {
$response = Read-Host "기존 연결을 해제하고 팜큐 Headscale로 등록하시겠습니까? (Y/n)"
if ($response -eq "" -or $response -match "^[Yy]") {
Write-Info "기존 연결을 해제합니다..."
} else {
Write-Info "등록을 건너뜁니다."
return $true
}
}
# 기존 연결 해제
try {
& $tailscalePath logout 2>$null
Start-Sleep -Seconds 3
Write-Success "기존 연결이 해제되었습니다."
}
catch {
Write-Warning "연결 해제 중 오류가 발생했지만 계속 진행합니다."
}
}
}
catch {
# 연결되어 있지 않음 (정상)
}
Write-Info "Headscale 서버: $HeadscaleServer"
Write-Info "Pre-auth Key: $($PreAuthKey.Substring(0,8))***************"
# Headscale 등록 시도
Write-Status "등록 명령 실행 중..."
try {
$arguments = @(
"up",
"--login-server=$HeadscaleServer",
"--authkey=$PreAuthKey",
"--accept-routes",
"--accept-dns=false"
)
& $tailscalePath $arguments
if ($LASTEXITCODE -eq 0) {
Write-Success "Headscale 등록 성공!"
return $true
} else {
Write-Error "자동 등록에 실패했습니다."
Write-Info "수동 등록 명령어:"
Write-Host "tailscale up --login-server=`"$HeadscaleServer`" --authkey=`"$PreAuthKey`""
return $false
}
}
catch {
Write-Error "등록 중 오류 발생: $($_.Exception.Message)"
return $false
}
}
# ================================
# 방화벽 설정
# ================================
function Configure-Firewall {
Write-Status "방화벽 설정 확인 중..."
try {
# Windows Defender 방화벽 예외 추가
$ruleName = "Tailscale-FarmQ"
$existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
if (-not $existingRule) {
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Protocol UDP -LocalPort 41641 -Action Allow -Profile Any | Out-Null
New-NetFirewallRule -DisplayName "$ruleName-Outbound" -Direction Outbound -Protocol UDP -LocalPort 41641 -Action Allow -Profile Any | Out-Null
Write-Info "Windows Defender 방화벽 예외를 추가했습니다."
}
Write-Success "방화벽 설정 완료"
}
catch {
Write-Warning "방화벽 설정 중 오류 발생: $($_.Exception.Message)"
Write-Info "수동으로 방화벽에서 Tailscale을 허용해주세요."
}
}
# ================================
# 연결 상태 확인
# ================================
function Test-Connection {
Write-Status "연결 상태 확인 중..."
Start-Sleep -Seconds 5
# Tailscale 실행파일 경로 확인
$tailscaleCmd = Get-Command "tailscale" -ErrorAction SilentlyContinue
if (-not $tailscaleCmd) {
$tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe"
if (Test-Path $tailscaleExe) {
$tailscaleCmd = @{Source = $tailscaleExe}
} else {
Write-Error "Tailscale 실행파일을 찾을 수 없습니다."
return
}
}
$tailscalePath = $tailscaleCmd.Source
try {
$status = & $tailscalePath status 2>$null
if ($LASTEXITCODE -ne 0 -or -not $status) {
Write-Error "Tailscale 연결에 문제가 있습니다."
return
}
# IP 주소 확인
$ipv4 = & $tailscalePath ip -4 2>$null
$ipv6 = & $tailscalePath ip -6 2>$null
Write-Success "Headscale 네트워크 연결 완료!"
Write-Info "할당된 IPv4: $(if($ipv4){$ipv4}else{'N/A'})"
Write-Info "할당된 IPv6: $(if($ipv6){$ipv6}else{'N/A'})"
# 네트워크 테스트
Write-Status "네트워크 연결 테스트 중..."
try {
Test-Connection "100.64.0.1" -Count 2 -Quiet | Out-Null
Write-Success "팜큐 네트워크($FarmqNetwork) 연결 정상!"
}
catch {
Write-Warning "네트워크 테스트 실패. 방화벽을 확인해주세요."
}
# 연결된 노드 확인
Write-Info "네트워크 상태:"
$status | Select-Object -First 10 | ForEach-Object {
Write-Host " $_" -ForegroundColor Gray
}
}
catch {
Write-Error "연결 상태 확인 실패: $($_.Exception.Message)"
}
}
# ================================
# 정리 작업
# ================================
function Complete-Installation {
Write-Status "설치 완료 작업 중..."
# 임시 파일 정리
Get-ChildItem "$env:TEMP\tailscale*" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
Write-Success "정리 작업 완료"
}
# ================================
# 최종 정보 출력
# ================================
function Show-FinalInfo {
Write-Header "팜큐 Headscale Windows 설치 완료!"
# 시스템 정보
$computerName = $env:COMPUTERNAME
$tailscaleCmd = Get-Command "tailscale" -ErrorAction SilentlyContinue
if (-not $tailscaleCmd) {
$tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe"
if (Test-Path $tailscaleExe) {
$tailscaleCmd = @{Source = $tailscaleExe}
}
}
if ($tailscaleCmd) {
$tailscaleIP = & $tailscaleCmd.Source ip -4 2>$null
}
$osVersion = [System.Environment]::OSVersion.Version
Write-ColorOutput "🎉 설치가 성공적으로 완료되었습니다!" "Green"
Write-Host ""
Write-ColorOutput "📋 시스템 정보:" "Cyan"
Write-Host " 컴퓨터명: $computerName"
Write-Host " Tailscale IP: $(if($tailscaleIP){$tailscaleIP}else{'N/A'})"
Write-Host " OS: Windows $($osVersion.Major).$($osVersion.Minor)"
Write-Host " Headscale 서버: $HeadscaleServer"
Write-Host ""
Write-ColorOutput "🔧 유용한 명령어:" "Yellow"
Write-Host " tailscale status # 연결 상태 확인"
Write-Host " tailscale ip # 할당된 IP 확인"
Write-Host " tailscale ping <node> # 다른 노드와 연결 테스트"
Write-Host " tailscale logout # 네트워크에서 해제"
Write-Host ""
Write-ColorOutput "🌐 팜큐 관리자 페이지:" "Magenta"
Write-Host " http://192.168.0.151:5002"
Write-Host " http://192.168.0.151:5002/vms (VM 관리)"
Write-Host ""
Write-ColorOutput "문제가 있을 경우 다음을 확인하세요:" "White"
Write-Host " 1. Windows 방화벽 설정"
Write-Host " 2. 바이러스 백신 프로그램 예외 설정"
Write-Host " 3. 회사 네트워크 정책 확인"
Write-Header "설치 완료 - 팜큐 네트워크를 사용할 수 있습니다!"
}
# ================================
# 메인 함수
# ================================
function Main {
# 에러 발생 시 중단
$ErrorActionPreference = "Stop"
Write-Header "팜큐(FARMQ) Headscale Windows 원클릭 설치"
try {
# 설치 과정
Test-Requirements
Install-Tailscale
Start-TailscaleService
$registerSuccess = Register-Headscale
if ($registerSuccess) {
Configure-Firewall
Test-Connection
Complete-Installation
Show-FinalInfo
} else {
Write-Warning "등록에 실패했지만 Tailscale은 설치되었습니다."
Write-Info "수동으로 등록을 완료해주세요."
}
}
catch {
Write-Error "설치 중 오류가 발생했습니다: $($_.Exception.Message)"
Write-Info "문제가 지속되면 관리자에게 문의하세요."
Write-Host ""
Read-Host "아무 키나 누르세요..."
exit 1
}
}
# ================================
# 스크립트 실행
# ================================
# 파라미터 처리
if ($args -contains "--help" -or $args -contains "-h") {
Write-Host "팜큐 Headscale Windows 설치 스크립트"
Write-Host ""
Write-Host "사용법:"
Write-Host " iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1'))"
Write-Host ""
Write-Host "옵션:"
Write-Host " -Force 기존 연결을 강제로 해제하고 재등록"
Write-Host " -HeadscaleServer 서버 주소 (기본값: https://head.0bin.in)"
Write-Host ""
Write-Host "예시:"
Write-Host " # 강제 재등록"
Write-Host " iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install.ps1?force=1'))"
exit 0
}
# Force 파라미터 URL에서 처리
if ($MyInvocation.MyCommand.Path -like "*force=1*") {
$Force = $true
}
# 메인 함수 실행
Main