commit 4f3ee338ae4c861f5a91944df8c7aeacc74d7fc0 Author: cpinte Date: Mon Jan 19 10:11:49 2026 +0100 first commit diff --git a/socks-browser.config.psd1 b/socks-browser.config.psd1 new file mode 100644 index 0000000..7bd6d12 --- /dev/null +++ b/socks-browser.config.psd1 @@ -0,0 +1,16 @@ +@{ + # ========================= + # 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" + +} \ No newline at end of file diff --git a/socks-browser.ico b/socks-browser.ico new file mode 100644 index 0000000..f74d443 Binary files /dev/null and b/socks-browser.ico differ diff --git a/socks-browser.ps1 b/socks-browser.ps1 new file mode 100644 index 0000000..b3219ab --- /dev/null +++ b/socks-browser.ps1 @@ -0,0 +1,314 @@ +$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 à l'écran + Write-Host $logEntry -ForegroundColor DarkGray + + # É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'é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é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 écoute sur le port $LocalPort" + return $true + } + Start-Sleep 1 + } + + return $false +} + +function Stop-SshTunnelByPort { + param ([int]$LocalPort) + + Write-DebugLog "Arrê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ê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éé : $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é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 à chaque exé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à utilisé par $procName" + } + + if (-not (Start-SshTunnel -SshExe $config.SshExe -LocalPort $config.LocalPort -HostAlias $config.HostAlias -AskPassExe $config.AskPassExe)) { + throw "Échec de l'é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ée (PID $browserProcessId)" + + Wait-ForProcessExit -ProcessId $browserProcessId + Write-Output "Navigateur temporaire fermé" + + Remove-TemporaryProfile -ProfilePath $tempProfile + Stop-SshTunnelByPort -LocalPort $config.LocalPort + + Write-Output "Tunnel SSH arrêté 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 +} \ No newline at end of file