Compare commits
2 Commits
09cdb088af
...
176c6bb1c2
| Author | SHA1 | Date | |
|---|---|---|---|
| 176c6bb1c2 | |||
| b7c621f294 |
16
README.md
16
README.md
@ -164,16 +164,22 @@ curl -fsSL https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/bran
|
||||
|
||||
Windows PC에서 **한 번의 복사 붙여넣기**로 팜큐 네트워크 연결:
|
||||
|
||||
### 기본 설치 (권장)
|
||||
### 기본 설치 (권장) - 인코딩 문제 해결됨
|
||||
```powershell
|
||||
# 관리자 PowerShell에서 복사 붙여넣기
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
# 관리자 PowerShell에서 복사 붙여넣기 (English version - 한글 깨짐 해결)
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### 기존 Tailscale 있는 경우 (강제 재등록)
|
||||
```powershell
|
||||
# 기존 연결을 자동으로 해제하고 재등록
|
||||
$ForceInstall = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
# 기존 연결을 자동으로 해제하고 재등록 (English version)
|
||||
$Force = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### 한글 버전 (인코딩 문제 발생 가능)
|
||||
```powershell
|
||||
# 한글이 깨져 보일 수 있음 - 위 English 버전 권장
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
```
|
||||
|
||||
### 실행 방법
|
||||
|
||||
@ -4,17 +4,28 @@ Windows PC를 팜큐 네트워크에 **30초만에** 연결하는 방법입니
|
||||
|
||||
## 🎯 복사 붙여넣기 전용 명령어
|
||||
|
||||
### 📋 기본 설치 (가장 많이 사용)
|
||||
### 📋 기본 설치 (가장 많이 사용) - 인코딩 문제 해결됨 ✅
|
||||
|
||||
**복사할 명령어:**
|
||||
**복사할 명령어 (권장 - English 버전):**
|
||||
```powershell
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### 📋 강제 재설치 (기존 Tailscale이 있는 경우)
|
||||
|
||||
**복사할 명령어:**
|
||||
**복사할 명령어 (권장 - English 버전):**
|
||||
```powershell
|
||||
$Force = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### 📋 한글 버전 (인코딩 문제 발생 가능)
|
||||
|
||||
**한글이 깨져서 나올 수 있습니다 - 위 English 버전을 사용하세요:**
|
||||
```powershell
|
||||
# 기본 설치 (한글 깨짐 가능)
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
|
||||
# 강제 재설치 (한글 깨짐 가능)
|
||||
$ForceInstall = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
```
|
||||
|
||||
@ -37,52 +48,52 @@ $ForceInstall = $true; iex ((New-Object System.Net.WebClient).DownloadString('ht
|
||||
## 📺 실행 화면 예시
|
||||
|
||||
```powershell
|
||||
PS C:\WINDOWS\system32> iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
PS C:\WINDOWS\system32> iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
|
||||
============================================
|
||||
팜큐(FARMQ) Headscale Windows 원클릭 설치
|
||||
FARMQ Headscale Windows One-Click Installation
|
||||
============================================
|
||||
|
||||
🔧 시스템 요구사항 확인 중...
|
||||
✅ 시스템 요구사항 확인 완료
|
||||
[*] Checking system requirements...
|
||||
[+] System requirements check completed
|
||||
|
||||
🔧 Tailscale 클라이언트 확인 중...
|
||||
📋 Windows용 Tailscale 설치 중...
|
||||
🔧 Tailscale 다운로드 중...
|
||||
🔧 Tailscale 설치 중... (잠시 기다려주세요)
|
||||
✅ Tailscale 설치 완료
|
||||
[*] Checking Tailscale installation...
|
||||
[i] Installing Tailscale for Windows...
|
||||
[*] Downloading Tailscale...
|
||||
[*] Installing Tailscale... (please wait)
|
||||
[+] Tailscale installation completed
|
||||
|
||||
🔧 Tailscale 서비스 시작 중...
|
||||
✅ Tailscale 서비스가 실행 중입니다.
|
||||
[*] Starting Tailscale service...
|
||||
[+] Tailscale service is running.
|
||||
|
||||
🔧 Headscale 서버에 등록 중...
|
||||
📋 Headscale 서버: https://head.0bin.in
|
||||
📋 Pre-auth Key: 8b3df41d***************
|
||||
🔧 등록 명령 실행 중...
|
||||
✅ Headscale 등록 성공!
|
||||
[*] Registering with Headscale server...
|
||||
[i] Headscale Server: https://head.0bin.in
|
||||
[i] Pre-auth Key: 8b3df41d***************
|
||||
[*] Executing registration command...
|
||||
[+] Headscale registration successful!
|
||||
|
||||
🔧 방화벽 설정 확인 중...
|
||||
✅ 방화벽 설정 완료
|
||||
[*] Configuring firewall settings...
|
||||
[+] Firewall configuration completed
|
||||
|
||||
🔧 연결 상태 확인 중...
|
||||
✅ Headscale 네트워크 연결 완료!
|
||||
📋 할당된 IPv4: 100.64.0.15
|
||||
📋 할당된 IPv6: fd7a:115c:a1e0::15
|
||||
[*] Verifying network connection...
|
||||
[+] Headscale network connection completed!
|
||||
[i] Assigned IPv4: 100.64.0.15
|
||||
[i] Assigned IPv6: fd7a:115c:a1e0::15
|
||||
|
||||
🔧 네트워크 연결 테스트 중...
|
||||
✅ 팜큐 네트워크(100.64.0.0/10) 연결 정상!
|
||||
[*] Testing network connectivity...
|
||||
[+] FARMQ network (100.64.0.0/10) connection successful!
|
||||
|
||||
============================================
|
||||
팜큐 Headscale Windows 설치 완료!
|
||||
FARMQ Headscale Windows Installation Complete!
|
||||
============================================
|
||||
|
||||
🎉 설치가 성공적으로 완료되었습니다!
|
||||
Installation completed successfully!
|
||||
|
||||
📋 시스템 정보:
|
||||
컴퓨터명: PHARMACY-PC01
|
||||
System Information:
|
||||
Computer Name: PHARMACY-PC01
|
||||
Tailscale IP: 100.64.0.15
|
||||
OS: Windows 10.0
|
||||
Headscale 서버: https://head.0bin.in
|
||||
Headscale Server: https://head.0bin.in
|
||||
```
|
||||
|
||||
## ❓ 자주 묻는 질문 (FAQ)
|
||||
@ -98,9 +109,16 @@ Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
- `Windows 키 + X` → `Windows PowerShell(관리자)`
|
||||
|
||||
### Q: 이미 Tailscale이 설치되어 있어요
|
||||
**A: 강제 재설치 명령어를 사용하세요:**
|
||||
**A: 강제 재설치 명령어를 사용하세요 (English 버전):**
|
||||
```powershell
|
||||
$ForceInstall = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install.ps1'))
|
||||
$Force = $true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### Q: 한글이 깨져서 나와요
|
||||
**A: English 버전을 사용하세요 (인코딩 문제 해결됨):**
|
||||
```powershell
|
||||
# 기본 설치 (English 버전)
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/thug0bin/headscale-tailscale-replacement/raw/branch/feature/working-headscale-setup/farmq-install-en.ps1'))
|
||||
```
|
||||
|
||||
### Q: 설치 후 어떻게 확인하나요?
|
||||
|
||||
481
farmq-install-en.ps1
Normal file
481
farmq-install-en.ps1
Normal file
@ -0,0 +1,481 @@
|
||||
# FARMQ Headscale Windows One-Click Installation Script
|
||||
# Usage: Run in Administrator PowerShell
|
||||
# iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install-en.ps1'))
|
||||
|
||||
param(
|
||||
[switch]$Force,
|
||||
[string]$HeadscaleServer = "https://head.0bin.in",
|
||||
[string]$PreAuthKey = "8b3df41d37cb158ea39f41fc32c9af46e761de817ad06038",
|
||||
[string]$FarmqNetwork = "100.64.0.0/10"
|
||||
)
|
||||
|
||||
# Set console to support Unicode characters
|
||||
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
|
||||
if ($PSVersionTable.PSVersion.Major -ge 6) {
|
||||
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Color Output Functions
|
||||
# ================================
|
||||
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-Host "[*] $Message" -ForegroundColor Blue
|
||||
}
|
||||
|
||||
function Write-Success {
|
||||
param([string]$Message)
|
||||
Write-Host ""
|
||||
Write-Host "[+] $Message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Error {
|
||||
param([string]$Message)
|
||||
Write-Host ""
|
||||
Write-Host "[!] ERROR: $Message" -ForegroundColor Red
|
||||
}
|
||||
|
||||
function Write-Warning {
|
||||
param([string]$Message)
|
||||
Write-Host ""
|
||||
Write-Host "[!] WARNING: $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Write-Info {
|
||||
param([string]$Message)
|
||||
Write-Host ""
|
||||
Write-Host "[i] $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# ================================
|
||||
# System Requirements Check
|
||||
# ================================
|
||||
function Test-Requirements {
|
||||
Write-Status "Checking system requirements..."
|
||||
|
||||
# Check administrator privileges
|
||||
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
||||
|
||||
if (-NOT $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||
Write-Error "This script requires administrator privileges."
|
||||
Write-Info "Please restart using one of these methods:"
|
||||
Write-Info "1. Windows Key + X -> 'Windows PowerShell (Admin)'"
|
||||
Write-Info "2. Right-click PowerShell -> 'Run as Administrator'"
|
||||
Write-Host ""
|
||||
Read-Host "Press any key to exit..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check Windows version
|
||||
$osVersion = [System.Environment]::OSVersion.Version
|
||||
if ($osVersion.Major -lt 10) {
|
||||
Write-Warning "Windows 10 or later recommended. Current: Windows $($osVersion.Major).$($osVersion.Minor)"
|
||||
}
|
||||
|
||||
# Check internet connection
|
||||
try {
|
||||
Test-Connection "8.8.8.8" -Count 1 -Quiet | Out-Null
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Please check your internet connection."
|
||||
}
|
||||
|
||||
Write-Success "System requirements check completed"
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Install Tailscale
|
||||
# ================================
|
||||
function Install-Tailscale {
|
||||
Write-Status "Checking Tailscale installation..."
|
||||
|
||||
# Check existing installation
|
||||
$tailscalePath = Get-Command "tailscale" -ErrorAction SilentlyContinue
|
||||
if ($tailscalePath) {
|
||||
$version = & tailscale version 2>$null | Select-Object -First 1
|
||||
Write-Info "Tailscale is already installed."
|
||||
Write-Info "Current version: $version"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Info "Installing Tailscale for Windows..."
|
||||
|
||||
# Temporary download path
|
||||
$tempPath = "$env:TEMP\tailscale-setup.exe"
|
||||
$downloadUrl = "https://pkgs.tailscale.com/stable/tailscale-setup.exe"
|
||||
|
||||
try {
|
||||
Write-Status "Downloading Tailscale..."
|
||||
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempPath -UseBasicParsing
|
||||
|
||||
Write-Status "Installing Tailscale... (please wait)"
|
||||
Start-Process -FilePath $tempPath -ArgumentList "/S" -Wait
|
||||
|
||||
# Refresh PATH environment variable
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
|
||||
# Verify installation
|
||||
Start-Sleep -Seconds 3
|
||||
$tailscaleInstalled = Get-Command "tailscale" -ErrorAction SilentlyContinue
|
||||
if (-not $tailscaleInstalled) {
|
||||
# Try direct path
|
||||
$tailscaleExe = "C:\Program Files\Tailscale\tailscale.exe"
|
||||
if (Test-Path $tailscaleExe) {
|
||||
# Add Tailscale to PATH
|
||||
$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 installation completed"
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error "Tailscale installation failed: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Start Tailscale Service
|
||||
# ================================
|
||||
function Start-TailscaleService {
|
||||
Write-Status "Starting Tailscale service..."
|
||||
|
||||
try {
|
||||
# Start Tailscale service
|
||||
$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 service is running."
|
||||
} else {
|
||||
Write-Warning "Tailscale service not found. Attempting manual start..."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Failed to start service: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Register with Headscale
|
||||
# ================================
|
||||
function Register-Headscale {
|
||||
Write-Status "Registering with Headscale server..."
|
||||
|
||||
# Find Tailscale executable path
|
||||
$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 executable not found."
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
$tailscalePath = $tailscaleCmd.Source
|
||||
|
||||
# Check existing connection
|
||||
try {
|
||||
$status = & $tailscalePath status 2>$null
|
||||
if ($LASTEXITCODE -eq 0 -and $status) {
|
||||
Write-Warning "Already connected to Tailscale/Headscale network."
|
||||
|
||||
# Show current connection status
|
||||
Write-Info "Current connection status:"
|
||||
$status | Select-Object -First 5 | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
|
||||
# Check force registration option
|
||||
if ($Force) {
|
||||
Write-Warning "Force registration option is enabled."
|
||||
Write-Info "Disconnecting existing connection and re-registering..."
|
||||
} else {
|
||||
$response = Read-Host "Disconnect existing connection and register with FARMQ Headscale? (Y/n)"
|
||||
if ($response -eq "" -or $response -match "^[Yy]") {
|
||||
Write-Info "Disconnecting existing connection..."
|
||||
} else {
|
||||
Write-Info "Skipping registration."
|
||||
return $true
|
||||
}
|
||||
}
|
||||
|
||||
# Disconnect existing connection
|
||||
try {
|
||||
& $tailscalePath logout 2>$null
|
||||
Start-Sleep -Seconds 3
|
||||
Write-Success "Existing connection disconnected."
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Error during disconnection, but continuing..."
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# Not connected (normal)
|
||||
}
|
||||
|
||||
Write-Info "Headscale Server: $HeadscaleServer"
|
||||
Write-Info "Pre-auth Key: $($PreAuthKey.Substring(0,8))***************"
|
||||
|
||||
# Attempt Headscale registration
|
||||
Write-Status "Executing registration command..."
|
||||
|
||||
try {
|
||||
$arguments = @(
|
||||
"up",
|
||||
"--login-server=$HeadscaleServer",
|
||||
"--authkey=$PreAuthKey",
|
||||
"--accept-routes",
|
||||
"--accept-dns=false"
|
||||
)
|
||||
|
||||
& $tailscalePath $arguments
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Success "Headscale registration successful!"
|
||||
return $true
|
||||
} else {
|
||||
Write-Error "Automatic registration failed."
|
||||
Write-Info "Manual registration command:"
|
||||
Write-Host "tailscale up --login-server=`"$HeadscaleServer`" --authkey=`"$PreAuthKey`""
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Registration error: $($_.Exception.Message)"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Configure Firewall
|
||||
# ================================
|
||||
function Configure-Firewall {
|
||||
Write-Status "Configuring firewall settings..."
|
||||
|
||||
try {
|
||||
# Add Windows Defender firewall exception
|
||||
$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 firewall exceptions added."
|
||||
}
|
||||
|
||||
Write-Success "Firewall configuration completed"
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Firewall configuration error: $($_.Exception.Message)"
|
||||
Write-Info "Please manually allow Tailscale through Windows firewall."
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Verify Connection
|
||||
# ================================
|
||||
function Test-Connection {
|
||||
Write-Status "Verifying network connection..."
|
||||
|
||||
Start-Sleep -Seconds 5
|
||||
|
||||
# Find Tailscale executable path
|
||||
$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 executable not found."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$tailscalePath = $tailscaleCmd.Source
|
||||
|
||||
try {
|
||||
$status = & $tailscalePath status 2>$null
|
||||
if ($LASTEXITCODE -ne 0 -or -not $status) {
|
||||
Write-Error "Tailscale connection issue detected."
|
||||
return
|
||||
}
|
||||
|
||||
# Get IP addresses
|
||||
$ipv4 = & $tailscalePath ip -4 2>$null
|
||||
$ipv6 = & $tailscalePath ip -6 2>$null
|
||||
|
||||
Write-Success "Headscale network connection completed!"
|
||||
Write-Info "Assigned IPv4: $(if($ipv4){$ipv4}else{'N/A'})"
|
||||
Write-Info "Assigned IPv6: $(if($ipv6){$ipv6}else{'N/A'})"
|
||||
|
||||
# Network connectivity test
|
||||
Write-Status "Testing network connectivity..."
|
||||
|
||||
try {
|
||||
Test-Connection "100.64.0.1" -Count 2 -Quiet | Out-Null
|
||||
Write-Success "FARMQ network ($FarmqNetwork) connection successful!"
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Network test failed. Please check firewall settings."
|
||||
}
|
||||
|
||||
# Show connected nodes
|
||||
Write-Info "Network status:"
|
||||
$status | Select-Object -First 10 | ForEach-Object {
|
||||
Write-Host " $_" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Connection verification failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Cleanup
|
||||
# ================================
|
||||
function Complete-Installation {
|
||||
Write-Status "Completing installation..."
|
||||
|
||||
# Clean temporary files
|
||||
Get-ChildItem "$env:TEMP\tailscale*" -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Success "Cleanup completed"
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Show Final Information
|
||||
# ================================
|
||||
function Show-FinalInfo {
|
||||
Write-Header "FARMQ Headscale Windows Installation Complete!"
|
||||
|
||||
# System information
|
||||
$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-Host "Installation completed successfully!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "System Information:" -ForegroundColor Cyan
|
||||
Write-Host " Computer Name: $computerName"
|
||||
Write-Host " Tailscale IP: $(if($tailscaleIP){$tailscaleIP}else{'N/A'})"
|
||||
Write-Host " OS: Windows $($osVersion.Major).$($osVersion.Minor)"
|
||||
Write-Host " Headscale Server: $HeadscaleServer"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Useful Commands:" -ForegroundColor Yellow
|
||||
Write-Host " tailscale status # Check connection status"
|
||||
Write-Host " tailscale ip # Show assigned IP"
|
||||
Write-Host " tailscale ping <node> # Test connection to other nodes"
|
||||
Write-Host " tailscale logout # Disconnect from network"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "FARMQ Management Pages:" -ForegroundColor Magenta
|
||||
Write-Host " http://192.168.0.151:5002"
|
||||
Write-Host " http://192.168.0.151:5002/vms (VM Management)"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "If you encounter issues, check:" -ForegroundColor White
|
||||
Write-Host " 1. Windows Firewall settings"
|
||||
Write-Host " 2. Antivirus software exceptions"
|
||||
Write-Host " 3. Corporate network policies"
|
||||
|
||||
Write-Header "Installation Complete - You can now use FARMQ network!"
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Main Function
|
||||
# ================================
|
||||
function Main {
|
||||
# Stop on errors
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Header "FARMQ Headscale Windows One-Click Installation"
|
||||
|
||||
try {
|
||||
# Installation process
|
||||
Test-Requirements
|
||||
Install-Tailscale
|
||||
Start-TailscaleService
|
||||
$registerSuccess = Register-Headscale
|
||||
|
||||
if ($registerSuccess) {
|
||||
Configure-Firewall
|
||||
Test-Connection
|
||||
Complete-Installation
|
||||
Show-FinalInfo
|
||||
} else {
|
||||
Write-Warning "Registration failed but Tailscale is installed."
|
||||
Write-Info "Please complete registration manually."
|
||||
}
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error "Installation error occurred: $($_.Exception.Message)"
|
||||
Write-Info "If the problem persists, please contact administrator."
|
||||
Write-Host ""
|
||||
Read-Host "Press any key to exit..."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# ================================
|
||||
# Script Execution
|
||||
# ================================
|
||||
|
||||
# Handle parameters
|
||||
if ($args -contains "--help" -or $args -contains "-h") {
|
||||
Write-Host "FARMQ Headscale Windows Installation Script"
|
||||
Write-Host ""
|
||||
Write-Host "Usage:"
|
||||
Write-Host " iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install-en.ps1'))"
|
||||
Write-Host ""
|
||||
Write-Host "Options:"
|
||||
Write-Host " -Force Force disconnect existing connection and re-register"
|
||||
Write-Host " -HeadscaleServer Server address (default: https://head.0bin.in)"
|
||||
Write-Host ""
|
||||
Write-Host "Examples:"
|
||||
Write-Host " # Force re-registration"
|
||||
Write-Host " `$Force = `$true; iex ((New-Object System.Net.WebClient).DownloadString('https://git.0bin.in/.../farmq-install-en.ps1'))"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Handle Force parameter from URL or variable
|
||||
if ($MyInvocation.MyCommand.Path -like "*force=1*" -or (Get-Variable -Name "ForceInstall" -ErrorAction SilentlyContinue)) {
|
||||
$Force = $true
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
Main
|
||||
Loading…
Reference in New Issue
Block a user