314 lines
10 KiB
PowerShell
314 lines
10 KiB
PowerShell
|
|
$config = @{
|
|||
|
|
# =========================
|
|||
|
|
# SSH configuration
|
|||
|
|
# =========================
|
|||
|
|
SshExe = "C:\Windows\System32\OpenSSH\ssh.exe"
|
|||
|
|
AskPassExe = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\mingw64\bin\git-askpass.exe"
|
|||
|
|
HostAlias = "alamaison"
|
|||
|
|
LocalPort = 33333
|
|||
|
|
|
|||
|
|
# =========================
|
|||
|
|
# Browser configuration
|
|||
|
|
# =========================
|
|||
|
|
BrowserExe = "C:\Program Files\Mozilla Firefox\firefox.exe"
|
|||
|
|
BrowserProcessName = "firefox"
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# =========================
|
|||
|
|
# Configuration du script
|
|||
|
|
# =========================
|
|||
|
|
Set-StrictMode -Version Latest
|
|||
|
|
$script:DebugEnabled = $false
|
|||
|
|
#$script:ConfigFile = Join-Path $PSScriptRoot "socks-browser.config.psd1"
|
|||
|
|
$script:LogFile = Join-Path $env:TEMP "socks-browser.log"
|
|||
|
|
|
|||
|
|
# =========================
|
|||
|
|
# Fonction de journalisation
|
|||
|
|
# =========================
|
|||
|
|
|
|||
|
|
function Write-DebugLog {
|
|||
|
|
param (
|
|||
|
|
[Parameter(Mandatory)]
|
|||
|
|
[string]$Message
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if (-not $script:DebugEnabled) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|||
|
|
$logEntry = "[DEBUG $timestamp] $Message"
|
|||
|
|
|
|||
|
|
# Affiche <20> l'<27>cran
|
|||
|
|
Write-Host $logEntry -ForegroundColor DarkGray
|
|||
|
|
|
|||
|
|
# <20>crit dans le fichier de log (dans %TEMP%)
|
|||
|
|
try {
|
|||
|
|
$logEntry | Out-File -FilePath $script:LogFile -Encoding UTF8 -Append -ErrorAction SilentlyContinue
|
|||
|
|
} catch {
|
|||
|
|
# Ignore les erreurs d'<27>criture (ex: droits, disque plein)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# =========================
|
|||
|
|
# Fonctions principales
|
|||
|
|
# =========================
|
|||
|
|
#
|
|||
|
|
#function Get-Configuration {
|
|||
|
|
# if (-not (Test-Path $script:ConfigFile)) {
|
|||
|
|
# throw "Fichier de configuration introuvable : $script:ConfigFile"
|
|||
|
|
# }
|
|||
|
|
#
|
|||
|
|
# $config = Import-PowerShellDataFile $script:ConfigFile
|
|||
|
|
#
|
|||
|
|
# $requiredKeys = @(
|
|||
|
|
# "SshExe", "AskPassExe", "HostAlias",
|
|||
|
|
# "LocalPort", "BrowserExe", "BrowserProcessName"
|
|||
|
|
# )
|
|||
|
|
#
|
|||
|
|
# foreach ($key in $requiredKeys) {
|
|||
|
|
# if (-not $config.ContainsKey($key) -or [string]::IsNullOrWhiteSpace($config[$key])) {
|
|||
|
|
# throw "Valeur de configuration manquante ou vide : $key"
|
|||
|
|
# }
|
|||
|
|
# }
|
|||
|
|
#
|
|||
|
|
# return $config
|
|||
|
|
#}
|
|||
|
|
|
|||
|
|
function Test-PortAvailable {
|
|||
|
|
param ([int]$Port)
|
|||
|
|
|
|||
|
|
$existing = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue
|
|||
|
|
return (-not $existing)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Start-SshTunnel {
|
|||
|
|
param (
|
|||
|
|
[string]$SshExe,
|
|||
|
|
[int]$LocalPort,
|
|||
|
|
[string]$HostAlias,
|
|||
|
|
[string]$AskPassExe
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
$env:SSH_ASKPASS = $AskPassExe
|
|||
|
|
$env:SSH_ASKPASS_REQUIRE = "force"
|
|||
|
|
$env:DISPLAY = "dummy"
|
|||
|
|
|
|||
|
|
Write-DebugLog "D<EFBFBD>marrage du tunnel SSH : ssh -N -D $LocalPort $HostAlias"
|
|||
|
|
Start-Process $SshExe -ArgumentList "-N -D $LocalPort $HostAlias" -WindowStyle Hidden
|
|||
|
|
|
|||
|
|
for ($attempt = 0; $attempt -lt 10; $attempt++) {
|
|||
|
|
if (Get-NetTCPConnection -LocalPort $LocalPort -State Listen -ErrorAction SilentlyContinue) {
|
|||
|
|
Write-DebugLog "Le tunnel SSH <20>coute sur le port $LocalPort"
|
|||
|
|
return $true
|
|||
|
|
}
|
|||
|
|
Start-Sleep 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return $false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Stop-SshTunnelByPort {
|
|||
|
|
param ([int]$LocalPort)
|
|||
|
|
|
|||
|
|
Write-DebugLog "Arr<EFBFBD>t du tunnel SSH sur le port $LocalPort"
|
|||
|
|
|
|||
|
|
$sshProcessIds = Get-NetTCPConnection -LocalPort $LocalPort -State Listen -ErrorAction SilentlyContinue |
|
|||
|
|
Select-Object -ExpandProperty OwningProcess -Unique
|
|||
|
|
|
|||
|
|
foreach ($sshPid in $sshProcessIds) {
|
|||
|
|
try {
|
|||
|
|
$proc = Get-Process -Id $sshPid -ErrorAction Stop
|
|||
|
|
if ($proc.ProcessName -eq "ssh") {
|
|||
|
|
Write-DebugLog "Arr<EFBFBD>t du processus SSH PID $sshPid"
|
|||
|
|
Stop-Process -Id $sshPid -ErrorAction SilentlyContinue
|
|||
|
|
}
|
|||
|
|
} catch {}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for ($attempt = 0; $attempt -lt 5; $attempt++) {
|
|||
|
|
if (-not (Get-NetTCPConnection -LocalPort $LocalPort -State Listen -ErrorAction SilentlyContinue)) {
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
Start-Sleep 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Create-TemporaryBrowserProfile {
|
|||
|
|
param ([int]$LocalPort)
|
|||
|
|
|
|||
|
|
$tempProfile = Join-Path $env:TEMP ("browser-socks-" + [guid]::NewGuid())
|
|||
|
|
New-Item -ItemType Directory -Path $tempProfile | Out-Null
|
|||
|
|
|
|||
|
|
$userJs = @"
|
|||
|
|
user_pref("network.proxy.type", 1);
|
|||
|
|
user_pref("network.proxy.socks", "127.0.0.1");
|
|||
|
|
user_pref("network.proxy.socks_port", $LocalPort);
|
|||
|
|
user_pref("network.proxy.socks_version", 5);
|
|||
|
|
user_pref("network.proxy.socks_remote_dns", true);
|
|||
|
|
user_pref("network.proxy.no_proxies_on", "");
|
|||
|
|
user_pref("network.proxy.allow_hijacking_localhost", false);
|
|||
|
|
|
|||
|
|
user_pref("network.trr.mode", 3);
|
|||
|
|
user_pref("network.trr.uri", "https://hard.dnsforge.de/dns-query ");
|
|||
|
|
user_pref("network.trr.bootstrapAddress", "88.198.122.154");
|
|||
|
|
user_pref("network.trr.confirmationNS", "");
|
|||
|
|
|
|||
|
|
user_pref("media.peerconnection.enabled", false);
|
|||
|
|
user_pref("media.peerconnection.ice.default_address_only", true);
|
|||
|
|
user_pref("media.peerconnection.ice.no_host", true);
|
|||
|
|
|
|||
|
|
user_pref("geo.enabled", false);
|
|||
|
|
user_pref("geo.provider.network.url", "");
|
|||
|
|
user_pref("geo.provider.ms-windows-location", false);
|
|||
|
|
user_pref("geo.provider.use_corelocation", false);
|
|||
|
|
user_pref("geo.provider.use_gpsd", false);
|
|||
|
|
|
|||
|
|
user_pref("browser.search.suggest.enabled", false);
|
|||
|
|
user_pref("browser.urlbar.suggest.searches", false);
|
|||
|
|
user_pref("toolkit.telemetry.enabled", false);
|
|||
|
|
user_pref("datareporting.healthreport.uploadEnabled", false);
|
|||
|
|
user_pref("browser.ping-centre.telemetry", false);
|
|||
|
|
|
|||
|
|
user_pref("browser.tabs.loadInBackground", false);
|
|||
|
|
|
|||
|
|
user_pref("privacy.resistFingerprinting", true);
|
|||
|
|
user_pref("privacy.trackingprotection.enabled", true);
|
|||
|
|
user_pref("privacy.trackingprotection.pbmode.enabled", true);
|
|||
|
|
|
|||
|
|
user_pref("plugin.state.flash", 0);
|
|||
|
|
user_pref("plugin.state.java", 0);
|
|||
|
|
|
|||
|
|
user_pref("browser.privatebrowsing.autostart", true);
|
|||
|
|
user_pref("signon.rememberSignons", false);
|
|||
|
|
user_pref("browser.formfill.enable", false);
|
|||
|
|
user_pref("browser.sessionstore.resume_from_crash", false);
|
|||
|
|
user_pref("browser.sessionstore.max_tabs_undo", 0);
|
|||
|
|
user_pref("browser.sessionstore.max_windows_undo", 0);
|
|||
|
|
|
|||
|
|
user_pref("browser.cache.disk.enable", false);
|
|||
|
|
user_pref("browser.cache.disk.capacity", 0);
|
|||
|
|
user_pref("browser.cache.disk.smart_size.enabled", false);
|
|||
|
|
user_pref("browser.cache.offline.enable", false);
|
|||
|
|
|
|||
|
|
user_pref("app.update.auto", false);
|
|||
|
|
user_pref("app.update.enabled", false);
|
|||
|
|
|
|||
|
|
user_pref("extensions.autoDisableScopes", 15);
|
|||
|
|
user_pref("extensions.enabledScopes", 0);
|
|||
|
|
|
|||
|
|
user_pref("browser.privateWindowSeparation.enabled", true);
|
|||
|
|
|
|||
|
|
user_pref("browser.aboutwelcome.enabled", false);
|
|||
|
|
user_pref("startup.homepage_welcome_url", "");
|
|||
|
|
user_pref("startup.homepage_welcome_url.additional", "");
|
|||
|
|
"@
|
|||
|
|
|
|||
|
|
Set-Content -Path (Join-Path $tempProfile "user.js") -Value $userJs -Encoding ASCII
|
|||
|
|
Write-DebugLog "Profil temporaire cr<63><72> : $tempProfile"
|
|||
|
|
|
|||
|
|
return $tempProfile
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Launch-BrowserAndWaitForInstance {
|
|||
|
|
param (
|
|||
|
|
[string]$BrowserExe,
|
|||
|
|
[string]$BrowserProcessName,
|
|||
|
|
[string]$ProfilePath
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
$existingProcessIds = Get-Process -Name $BrowserProcessName -ErrorAction SilentlyContinue |
|
|||
|
|
Select-Object -ExpandProperty Id
|
|||
|
|
|
|||
|
|
Write-DebugLog "Lancement du navigateur avec profil temporaire"
|
|||
|
|
Start-Process $BrowserExe -ArgumentList "--no-remote --private-window --profile `"$ProfilePath`"" -WindowStyle Hidden
|
|||
|
|
|
|||
|
|
for ($attempt = 0; $attempt -lt 15; $attempt++) {
|
|||
|
|
Start-Sleep 1
|
|||
|
|
$currentProcessIds = Get-Process -Name $BrowserProcessName -ErrorAction SilentlyContinue |
|
|||
|
|
Select-Object -ExpandProperty Id
|
|||
|
|
$newProcessIds = $currentProcessIds | Where-Object { $_ -notin $existingProcessIds }
|
|||
|
|
if ($newProcessIds) {
|
|||
|
|
$tempBrowserProcessId = $newProcessIds | Select-Object -First 1
|
|||
|
|
Write-DebugLog "Instance temporaire d<>tect<63>e (PID $tempBrowserProcessId)"
|
|||
|
|
return $tempBrowserProcessId
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
throw "Impossible de d<>tecter l'instance temporaire du navigateur"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Wait-ForProcessExit {
|
|||
|
|
param ([int]$ProcessId)
|
|||
|
|
|
|||
|
|
while (Get-Process -Id $ProcessId -ErrorAction SilentlyContinue) {
|
|||
|
|
Start-Sleep 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Remove-TemporaryProfile {
|
|||
|
|
param ([string]$ProfilePath)
|
|||
|
|
|
|||
|
|
for ($attempt = 0; $attempt -lt 5; $attempt++) {
|
|||
|
|
try {
|
|||
|
|
if (Test-Path $ProfilePath) {
|
|||
|
|
Remove-Item -Recurse -Force $ProfilePath -ErrorAction Stop
|
|||
|
|
}
|
|||
|
|
break
|
|||
|
|
} catch {
|
|||
|
|
Start-Sleep 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# =========================
|
|||
|
|
# Orchestrateur principal
|
|||
|
|
# =========================
|
|||
|
|
try {
|
|||
|
|
# Ajouter une ligne de s<>paration dans le log <20> chaque ex<65>cution
|
|||
|
|
if ($script:DebugEnabled) {
|
|||
|
|
$separator = "=" * 60
|
|||
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|||
|
|
"[$timestamp] SESSION START" | Out-File -FilePath $script:LogFile -Encoding UTF8 -Append -ErrorAction SilentlyContinue
|
|||
|
|
$separator | Out-File -FilePath $script:LogFile -Encoding UTF8 -Append -ErrorAction SilentlyContinue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not (Test-PortAvailable -Port $config.LocalPort)) {
|
|||
|
|
$ownerPid = (Get-NetTCPConnection -LocalPort $config.LocalPort -State Listen).OwningProcess
|
|||
|
|
$ownerProc = Get-Process -Id $ownerPid -ErrorAction SilentlyContinue
|
|||
|
|
$procName = if ($ownerProc) { "$($ownerProc.Name) (PID $ownerPid)" } else { "PID $ownerPid" }
|
|||
|
|
throw "Le port $($config.LocalPort) est d<>j<EFBFBD> utilis<69> par $procName"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (-not (Start-SshTunnel -SshExe $config.SshExe -LocalPort $config.LocalPort -HostAlias $config.HostAlias -AskPassExe $config.AskPassExe)) {
|
|||
|
|
throw "<EFBFBD>chec de l'<27>tablissement du tunnel SSH"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Write-Output "Tunnel SSH actif sur 127.0.0.1:$($config.LocalPort)"
|
|||
|
|
|
|||
|
|
$tempProfile = Create-TemporaryBrowserProfile -LocalPort $config.LocalPort
|
|||
|
|
$browserProcessId = Launch-BrowserAndWaitForInstance -BrowserExe $config.BrowserExe -BrowserProcessName $config.BrowserProcessName -ProfilePath $tempProfile
|
|||
|
|
|
|||
|
|
Write-Output "Instance temporaire du navigateur d<>tect<63>e (PID $browserProcessId)"
|
|||
|
|
|
|||
|
|
Wait-ForProcessExit -ProcessId $browserProcessId
|
|||
|
|
Write-Output "Navigateur temporaire ferm<72>"
|
|||
|
|
|
|||
|
|
Remove-TemporaryProfile -ProfilePath $tempProfile
|
|||
|
|
Stop-SshTunnelByPort -LocalPort $config.LocalPort
|
|||
|
|
|
|||
|
|
Write-Output "Tunnel SSH arr<72>t<EFBFBD> proprement"
|
|||
|
|
|
|||
|
|
} catch {
|
|||
|
|
$errorMessage = "ERREUR: $($_.Exception.Message)"
|
|||
|
|
Write-Error $errorMessage
|
|||
|
|
|
|||
|
|
# Journaliser aussi l'erreur dans le fichier
|
|||
|
|
if ($script:DebugEnabled) {
|
|||
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|||
|
|
"[$timestamp] $errorMessage" | Out-File -FilePath $script:LogFile -Encoding UTF8 -Append -ErrorAction SilentlyContinue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
exit 1
|
|||
|
|
}
|