Files
Go-VPN-Client/internal/proxy/proxy_windows.go
arkonsadter b809e84220 feat: add security system with system-wide proxy, DNS protection and encryption
- System-wide proxy: automatic Windows proxy configuration for all apps
- DNS leak protection: force all DNS queries through VPN
- Config encryption: AES-256-GCM encryption for all config files
- File protection: strict access permissions for config directory
- Leak detection: built-in security check system
- Kill Switch: temporarily disabled (will be improved in next version)

Security features:
✓ Automatic system proxy setup
✓ DNS leak protection (optional)
✓ AES-256-GCM config encryption
✓ File and directory protection
✓ Security leak checker
⚠ Kill Switch disabled (caused internet blocking issues)

Emergency recovery scripts included:
- ОТКЛЮЧИТЬ_KILLSWITCH.bat
- EMERGENCY_FIX_INTERNET.bat
- ЕСЛИ_СЛОМАЛСЯ_ИНТЕРНЕТ.txt

Documentation:
- Markdown/SECURITY_GUIDE.md - full security guide
- БЕЗОПАСНОСТЬ_БЫСТРЫЙ_СТАРТ.md - quick start guide
- CHANGELOG_SECURITY.md - detailed changelog
2026-04-12 19:01:24 +06:00

210 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package proxy
import (
"fmt"
"os/exec"
"strings"
"syscall"
)
var (
wininet = syscall.NewLazyDLL("wininet.dll")
internetSetOptionW = wininet.NewProc("InternetSetOptionW")
INTERNET_OPTION_SETTINGS_CHANGED = 39
INTERNET_OPTION_REFRESH = 37
)
// EnableSystemProxy включает системный прокси в Windows для ВСЕХ приложений
func EnableSystemProxy(proxyAddr string) error {
// Включаем прокси через реестр
cmd := exec.Command("reg", "add",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyEnable",
"/t", "REG_DWORD",
"/d", "1",
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("ошибка включения прокси: %w", err)
}
// Устанавливаем адрес прокси (используем socks= для SOCKS5)
cmd = exec.Command("reg", "add",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyServer",
"/t", "REG_SZ",
"/d", fmt.Sprintf("socks=%s", proxyAddr),
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("ошибка установки адреса прокси: %w", err)
}
// Отключаем прокси для локальных адресов
cmd = exec.Command("reg", "add",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyOverride",
"/t", "REG_SZ",
"/d", "<local>;localhost;127.*;10.*;172.16.*;172.31.*;192.168.*",
"/f")
cmd.Run() // Игнорируем ошибку
// Применяем изменения немедленно через WinINet API
notifySystemProxyChange()
// Обновляем настройки Internet Explorer
refreshIESettings()
// Уведомляем систему о изменении настроек сети
notifyNetworkChange()
return nil
}
// DisableSystemProxy отключает системный прокси в Windows
func DisableSystemProxy() error {
// Отключаем прокси
cmd := exec.Command("reg", "add",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyEnable",
"/t", "REG_DWORD",
"/d", "0",
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("ошибка отключения прокси: %w", err)
}
// Очищаем адрес прокси
cmd = exec.Command("reg", "delete",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyServer",
"/f")
cmd.Run() // Игнорируем ошибку, если ключ не существует
// Обновляем настройки
refreshIESettings()
return nil
}
// GetSystemProxyStatus проверяет статус системного прокси
func GetSystemProxyStatus() (bool, string, error) {
// Проверяем, включен ли прокси
cmd := exec.Command("reg", "query",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyEnable")
output, err := cmd.Output()
if err != nil {
return false, "", nil
}
enabled := strings.Contains(string(output), "0x1")
// Получаем адрес прокси
cmd = exec.Command("reg", "query",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyServer")
output, err = cmd.Output()
proxyAddr := ""
if err == nil {
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if strings.Contains(line, "ProxyServer") {
parts := strings.Fields(line)
if len(parts) >= 3 {
proxyAddr = parts[len(parts)-1]
}
}
}
}
return enabled, proxyAddr, nil
}
func refreshIESettings() {
// Используем rundll32 для обновления настроек Internet Explorer
cmd := exec.Command("rundll32.exe", "inetcpl.cpl,ClearMyTracksByProcess", "8")
cmd.Run()
}
// notifySystemProxyChange уведомляет систему об изменении прокси через WinINet API
func notifySystemProxyChange() {
// Уведомляем об изменении настроек
internetSetOptionW.Call(
0,
uintptr(INTERNET_OPTION_SETTINGS_CHANGED),
0,
0,
)
// Обновляем настройки
internetSetOptionW.Call(
0,
uintptr(INTERNET_OPTION_REFRESH),
0,
0,
)
}
// notifyNetworkChange уведомляет систему об изменении сетевых настроек
func notifyNetworkChange() {
// Используем netsh для сброса кэша DNS и обновления настроек
exec.Command("ipconfig", "/flushdns").Run()
// Перезапускаем сетевые службы для применения изменений
exec.Command("net", "stop", "WinHttpAutoProxySvc").Run()
exec.Command("net", "start", "WinHttpAutoProxySvc").Run()
}
// EnableSystemProxyHTTP включает HTTP прокси (для совместимости с некоторыми приложениями)
func EnableSystemProxyHTTP(httpProxyAddr string) error {
// Устанавливаем HTTP прокси
cmd := exec.Command("reg", "add",
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyServer",
"/t", "REG_SZ",
"/d", fmt.Sprintf("http=%s;https=%s", httpProxyAddr, httpProxyAddr),
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("ошибка установки HTTP прокси: %w", err)
}
notifySystemProxyChange()
return nil
}
// SetProxyForAllUsers устанавливает прокси для всех пользователей (требует прав администратора)
func SetProxyForAllUsers(proxyAddr string) error {
// Устанавливаем в HKLM для всех пользователей
cmd := exec.Command("reg", "add",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyEnable",
"/t", "REG_DWORD",
"/d", "1",
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("требуются права администратора: %w", err)
}
cmd = exec.Command("reg", "add",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
"/v", "ProxyServer",
"/t", "REG_SZ",
"/d", fmt.Sprintf("socks=%s", proxyAddr),
"/f")
if err := cmd.Run(); err != nil {
return fmt.Errorf("ошибка установки прокси для всех пользователей: %w", err)
}
notifySystemProxyChange()
return nil
}