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
This commit is contained in:
2026-04-12 19:01:24 +06:00
parent 20d24a3639
commit b809e84220
18 changed files with 2063 additions and 31 deletions

160
installer.iss Normal file
View File

@@ -0,0 +1,160 @@
; Скрипт Inno Setup для VPN Client (Go)
; Требуется Inno Setup 7
#define MyAppName "VPN Client Go"
#define MyAppVersion "1.0.0"
#define MyAppPublisher "VPN Client Team"
#define MyAppExeName "vpn-client-cli.exe"
[Setup]
AppId={{F8E7D6C5-B4A3-2109-8765-4321FEDCBA09}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppVerName={#MyAppName} {#MyAppVersion}
DefaultDirName={autopf}\VPNClientGo
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=installer_output
OutputBaseFilename=VPNClientGo-Setup-v{#MyAppVersion}
SetupIconFile=compiler:SetupClassicIcon.ico
UninstallDisplayIcon={app}\{#MyAppExeName}
Compression=lzma2/ultra64
SolidCompression=yes
LZMAUseSeparateProcess=yes
LZMANumBlockThreads=2
WizardStyle=modern
WizardSizePercent=100,100
DisableWelcomePage=no
MinVersion=10.0
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
PrivilegesRequired=admin
PrivilegesRequiredOverridesAllowed=commandline
[Languages]
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "Создать ярлык на рабочем столе"; GroupDescription: "Дополнительно:"; Flags: unchecked
[Files]
Source: "vpn-client-cli.exe"; DestDir: "{app}"; Flags: ignoreversion
[Dirs]
Name: "{app}\.vpn_client"; Permissions: users-full
Name: "{app}\logs"; Permissions: users-full
Name: "{app}\xray"; Permissions: users-full
Name: "{app}\v2ray"; Permissions: users-full
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Comment: "VPN Client"
Name: "{group}\Удалить {#MyAppName}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "Запустить {#MyAppName}"; Flags: nowait postinstall skipifsilent shellexec
[UninstallDelete]
Type: filesandordirs; Name: "{app}\.vpn_client"
Type: filesandordirs; Name: "{app}\logs"
Type: filesandordirs; Name: "{app}\xray"
Type: filesandordirs; Name: "{app}\v2ray"
[Messages]
russian.WelcomeLabel2=Программа установит [name/ver] на ваш компьютер.%n%nXray и V2Ray будут загружены во время установки (~20 МБ).
russian.FinishedLabel=Установка завершена.%n%nДля работы требуются права администратора.
english.WelcomeLabel2=This will install [name/ver] on your computer.%n%nXray and V2Ray will be downloaded during installation (~20 MB).
english.FinishedLabel=Installation complete.%n%nAdministrator privileges are required.
[Code]
function InitializeSetup(): Boolean;
begin
Result := True;
if not IsAdminLoggedOn then
begin
MsgBox('Требуются права администратора!', mbError, MB_OK);
Result := False;
end;
end;
function DownloadFile(const URL, FileName: String): Boolean;
var
ResultCode: Integer;
PSScript: String;
begin
Result := False;
PSScript := '[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ' +
'Invoke-WebRequest -Uri ''' + URL + ''' -OutFile ''' + FileName + ''' -UseBasicParsing';
if Exec('powershell.exe', '-NoProfile -ExecutionPolicy Bypass -Command "' + PSScript + '"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
Result := (ResultCode = 0) and FileExists(FileName);
end;
end;
function ExtractZip(const ZipFile, DestDir: String): Boolean;
var
ResultCode: Integer;
begin
Result := False;
if not FileExists(ZipFile) then Exit;
if not DirExists(DestDir) then CreateDir(DestDir);
if Exec('powershell.exe',
'-NoProfile -ExecutionPolicy Bypass -Command "Expand-Archive -Path ''' + ZipFile + ''' -DestinationPath ''' + DestDir + ''' -Force"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
Result := (ResultCode = 0);
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
XrayZip, V2RayZip, XrayDir, V2RayDir: String;
StatusLabel: TNewStaticText;
begin
if CurStep = ssInstall then
begin
XrayZip := ExpandConstant('{tmp}\xray.zip');
V2RayZip := ExpandConstant('{tmp}\v2ray.zip');
XrayDir := ExpandConstant('{app}\xray');
V2RayDir := ExpandConstant('{app}\v2ray');
StatusLabel := TNewStaticText.Create(WizardForm);
StatusLabel.Parent := WizardForm.InstallingPage;
StatusLabel.Left := WizardForm.ProgressGauge.Left;
StatusLabel.Top := WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + 20;
StatusLabel.Width := WizardForm.ProgressGauge.Width;
try
StatusLabel.Caption := 'Загрузка Xray...';
WizardForm.Update;
if DownloadFile('https://github.com/XTLS/Xray-core/releases/download/v24.12.18/Xray-windows-64.zip', XrayZip) then
begin
StatusLabel.Caption := 'Распаковка Xray...';
WizardForm.Update;
ExtractZip(XrayZip, XrayDir);
DeleteFile(XrayZip);
end;
StatusLabel.Caption := 'Загрузка V2Ray...';
WizardForm.Update;
if DownloadFile('https://github.com/v2fly/v2ray-core/releases/download/v5.22.0/v2ray-windows-64.zip', V2RayZip) then
begin
StatusLabel.Caption := 'Распаковка V2Ray...';
WizardForm.Update;
ExtractZip(V2RayZip, V2RayDir);
DeleteFile(V2RayZip);
end;
StatusLabel.Caption := 'Готово!';
finally
StatusLabel.Free;
end;
end;
end;