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에서 **한 번의 복사 붙여넣기**로 팜큐 네트워크 연결:
|
Windows PC에서 **한 번의 복사 붙여넣기**로 팜큐 네트워크 연결:
|
||||||
|
|
||||||
### 기본 설치 (권장)
|
### 기본 설치 (권장) - 인코딩 문제 해결됨
|
||||||
```powershell
|
```powershell
|
||||||
# 관리자 PowerShell에서 복사 붙여넣기
|
# 관리자 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.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 있는 경우 (강제 재등록)
|
### 기존 Tailscale 있는 경우 (강제 재등록)
|
||||||
```powershell
|
```powershell
|
||||||
# 기존 연결을 자동으로 해제하고 재등록
|
# 기존 연결을 자동으로 해제하고 재등록 (English version)
|
||||||
$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'))
|
||||||
|
```
|
||||||
|
|
||||||
|
### 한글 버전 (인코딩 문제 발생 가능)
|
||||||
|
```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
|
```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이 있는 경우)
|
### 📋 강제 재설치 (기존 Tailscale이 있는 경우)
|
||||||
|
|
||||||
**복사할 명령어:**
|
**복사할 명령어 (권장 - English 버전):**
|
||||||
```powershell
|
```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'))
|
$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
|
```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 클라이언트 확인 중...
|
[*] Checking Tailscale installation...
|
||||||
📋 Windows용 Tailscale 설치 중...
|
[i] Installing Tailscale for Windows...
|
||||||
🔧 Tailscale 다운로드 중...
|
[*] Downloading Tailscale...
|
||||||
🔧 Tailscale 설치 중... (잠시 기다려주세요)
|
[*] Installing Tailscale... (please wait)
|
||||||
✅ Tailscale 설치 완료
|
[+] Tailscale installation completed
|
||||||
|
|
||||||
🔧 Tailscale 서비스 시작 중...
|
[*] Starting Tailscale service...
|
||||||
✅ Tailscale 서비스가 실행 중입니다.
|
[+] Tailscale service is running.
|
||||||
|
|
||||||
🔧 Headscale 서버에 등록 중...
|
[*] Registering with Headscale server...
|
||||||
📋 Headscale 서버: https://head.0bin.in
|
[i] Headscale Server: https://head.0bin.in
|
||||||
📋 Pre-auth Key: 8b3df41d***************
|
[i] Pre-auth Key: 8b3df41d***************
|
||||||
🔧 등록 명령 실행 중...
|
[*] Executing registration command...
|
||||||
✅ Headscale 등록 성공!
|
[+] Headscale registration successful!
|
||||||
|
|
||||||
🔧 방화벽 설정 확인 중...
|
[*] Configuring firewall settings...
|
||||||
✅ 방화벽 설정 완료
|
[+] Firewall configuration completed
|
||||||
|
|
||||||
🔧 연결 상태 확인 중...
|
[*] Verifying network connection...
|
||||||
✅ Headscale 네트워크 연결 완료!
|
[+] Headscale network connection completed!
|
||||||
📋 할당된 IPv4: 100.64.0.15
|
[i] Assigned IPv4: 100.64.0.15
|
||||||
📋 할당된 IPv6: fd7a:115c:a1e0::15
|
[i] Assigned IPv6: fd7a:115c:a1e0::15
|
||||||
|
|
||||||
🔧 네트워크 연결 테스트 중...
|
[*] Testing network connectivity...
|
||||||
✅ 팜큐 네트워크(100.64.0.0/10) 연결 정상!
|
[+] FARMQ network (100.64.0.0/10) connection successful!
|
||||||
|
|
||||||
============================================
|
============================================
|
||||||
팜큐 Headscale Windows 설치 완료!
|
FARMQ Headscale Windows Installation Complete!
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
🎉 설치가 성공적으로 완료되었습니다!
|
Installation completed successfully!
|
||||||
|
|
||||||
📋 시스템 정보:
|
System Information:
|
||||||
컴퓨터명: PHARMACY-PC01
|
Computer Name: PHARMACY-PC01
|
||||||
Tailscale IP: 100.64.0.15
|
Tailscale IP: 100.64.0.15
|
||||||
OS: Windows 10.0
|
OS: Windows 10.0
|
||||||
Headscale 서버: https://head.0bin.in
|
Headscale Server: https://head.0bin.in
|
||||||
```
|
```
|
||||||
|
|
||||||
## ❓ 자주 묻는 질문 (FAQ)
|
## ❓ 자주 묻는 질문 (FAQ)
|
||||||
@ -98,9 +109,16 @@ Set-ExecutionPolicy Bypass -Scope Process -Force
|
|||||||
- `Windows 키 + X` → `Windows PowerShell(관리자)`
|
- `Windows 키 + X` → `Windows PowerShell(관리자)`
|
||||||
|
|
||||||
### Q: 이미 Tailscale이 설치되어 있어요
|
### Q: 이미 Tailscale이 설치되어 있어요
|
||||||
**A: 강제 재설치 명령어를 사용하세요:**
|
**A: 강제 재설치 명령어를 사용하세요 (English 버전):**
|
||||||
```powershell
|
```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: 설치 후 어떻게 확인하나요?
|
### 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