[READ-ONLY] Mirror of https://github.com/andrioid/ublproxy. andrioid.github.io/ublproxy
adblock adblock-plus-list adblocker privacy-tools proxy-server self-hosted
Something went wrong. Try again.
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>ublproxy Setup</title><link rel="stylesheet" href="/static/shared.css"><style> .setup-main { max-width: 640px; margin: 0 auto; padding: 2rem 1rem; } .setup-header { text-align: center; margin-bottom: 0.5rem; } .setup-header h1 { font-size: 1.4rem; font-weight: 700; } .setup-header p { color: var(--color-text-muted); font-size: 0.9rem; margin-top: 0.25rem; }</style></head><body>
<main class="setup-main"> <div class="setup-header"> <h1>ublproxy Setup</h1> <p>Get your device connected in a few steps.</p> </div>
<!-- Progress dots --> <div class="wizard-progress" id="wizard-progress"></div>
<!-- Step 1: Install Certificate --> <div class="card wizard-card" id="step-cert"> <h2 class="card-title" style="margin-bottom:0.75rem">Install Certificate</h2> <p style="margin-bottom:1rem; font-size:0.9rem; color:var(--color-text-muted)" id="cert-intro"> Your device must trust the ublproxy CA certificate before the proxy can filter HTTPS traffic. Without it, every HTTPS request through the proxy will fail with a certificate error. </p>
<!-- Platform selector --> <div class="platform-selector" id="platform-selector"> <button class="platform-btn" data-platform="apple">iOS / macOS</button> <button class="platform-btn" data-platform="android">Android</button> <button class="platform-btn" data-platform="windows">Windows</button> <button class="platform-btn" data-platform="linux">Linux</button> <button class="platform-btn" data-platform="firefox">Firefox</button> </div>
<!-- Apple: .mobileconfig --> <div class="platform-instructions" data-platform="apple"> <a class="setup-download setup-download-primary" href="/ublproxy.mobileconfig"> Download Profile (.mobileconfig) </a> <p style="margin-top:0.75rem; font-size:0.85rem; color:var(--color-text-muted)"> This profile installs the CA certificate <strong>and</strong> configures proxy settings in one step. </p> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Download the profile above</li> <li><strong>iOS:</strong> Go to Settings → General → VPN & Device Management → tap the profile → Install</li> <li><strong>iOS:</strong> Go to Settings → General → About → Certificate Trust Settings → enable full trust for <strong>ublproxy CA</strong></li> <li><strong>macOS:</strong> Open the downloaded file → Keychain Access will prompt to install</li> </ol>
<div class="setup-or">or install manually</div>
<a class="setup-download setup-download-secondary" href="/ca.crt"> Download CA Certificate (.crt) </a> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li><strong>macOS:</strong> Open the .crt file → add to System keychain → find <strong>ublproxy CA</strong> → set Trust to <strong>Always Trust</strong></li> <li><strong>iOS:</strong> Download .crt → Settings → General → VPN & Device Management → install → then enable full trust under Certificate Trust Settings</li> <li>Restart your browser after installing</li> </ol> </div>
<!-- Android --> <div class="platform-instructions" data-platform="android"> <a class="setup-download setup-download-primary" href="/ca.crt"> Download CA Certificate </a> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Download the certificate above</li> <li>Go to <strong>Settings → Security → Encryption & Credentials → Install a certificate → CA certificate</strong></li> <li>Select the downloaded <strong>ublproxy-ca.crt</strong> file and confirm</li> </ol> <p style="margin-top:0.5rem; font-size:0.82rem; color:var(--color-text-muted)"> Menu paths vary by manufacturer (Samsung, Pixel, etc.). </p> </div>
<!-- Windows --> <div class="platform-instructions" data-platform="windows"> <a class="setup-download setup-download-primary" href="/ca.crt"> Download CA Certificate </a> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Download and double-click the certificate</li> <li>Click <strong>Install Certificate</strong></li> <li>Select <strong>Local Machine</strong>, then <strong>Place all certificates in the following store</strong></li> <li>Choose <strong>Trusted Root Certification Authorities</strong> and finish the wizard</li> <li>Restart your browser</li> </ol> </div>
<!-- Linux --> <div class="platform-instructions" data-platform="linux"> <a class="setup-download setup-download-primary" href="/ca.crt"> Download CA Certificate </a> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Copy the certificate:<br><code class="code-block">sudo cp ublproxy-ca.crt /usr/local/share/ca-certificates/</code></li> <li>Update the trust store:<br><code class="code-block">sudo update-ca-certificates</code></li> <li>Restart your browser</li> </ol> </div>
<!-- Firefox --> <div class="platform-instructions" data-platform="firefox"> <p style="margin-bottom:0.75rem; font-size:0.88rem; color:var(--color-text-muted)"> Firefox uses its own certificate store, separate from your OS. You may need to install the certificate here in addition to your OS trust store. </p> <a class="setup-download setup-download-primary" href="/ca.crt"> Download CA Certificate </a> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Open <strong>Settings → Privacy & Security → Certificates → View Certificates</strong></li> <li>Click <strong>Import</strong> and select the downloaded .crt file</li> <li>Check <strong>Trust this CA to identify websites</strong> and confirm</li> <li>Restart Firefox</li> </ol> </div>
<!-- QR code for mobile --> <div class="setup-qr" id="setup-qr"> <p>Scan to open this page on your phone:</p> <img src="/qr.png" alt="QR code to open setup page"> </div>
<div class="wizard-nav"> <div></div> <div class="wizard-actions"> <button class="btn btn-primary" onclick="wizardNext()">Next</button> </div> </div> </div>
<!-- Step 2: Configure Proxy --> <div class="card wizard-card" id="step-proxy"> <h2 class="card-title" style="margin-bottom:0.75rem">Configure Proxy</h2>
<div id="proxy-apple-skip" style="display:none"> <div class="verify-status success"> Proxy settings were included in the configuration profile. You can skip this step if you installed the .mobileconfig profile. </div> <div class="setup-or">or configure manually</div> </div>
<p style="margin-bottom:0.75rem; font-size:0.9rem; color:var(--color-text-muted)"> Use the automatic proxy configuration file (PAC) to route traffic through ublproxy. </p>
<!-- Desktop PAC --> <div id="proxy-desktop-section"> <h3 style="font-size:0.95rem; font-weight:600; margin-bottom:0.4rem">Desktop</h3> <p style="font-size:0.85rem; color:var(--color-text-muted); margin-bottom:0.4rem">PAC URL:</p> <code class="code-block" id="pac-url"></code>
<!-- Platform-specific proxy instructions --> <div class="platform-instructions" data-platform="apple" data-proxy> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Open <strong>System Settings → Network → Wi-Fi → Details → Proxies</strong></li> <li>Enable <strong>Automatic Proxy Configuration</strong></li> <li>Enter the PAC URL shown above</li> </ol> </div>
<div class="platform-instructions" data-platform="windows" data-proxy> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Open <strong>Settings → Network & Internet → Proxy</strong></li> <li>Under <strong>Automatic proxy setup</strong>, enable <strong>Use setup script</strong></li> <li>Enter the PAC URL shown above</li> </ol> </div>
<div class="platform-instructions" data-platform="linux" data-proxy> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Configure your browser's proxy settings to use the PAC URL above</li> <li>Or launch Chromium with:<br><code class="code-block" id="chrome-flag"></code></li> </ol> </div>
<div class="platform-instructions" data-platform="firefox" data-proxy> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Open <strong>Settings → General → Network Settings → Settings…</strong></li> <li>Select <strong>Automatic proxy configuration URL</strong></li> <li>Enter the PAC URL shown above</li> <li>Click <strong>OK</strong></li> </ol> </div> </div>
<!-- Mobile PAC --> <div id="proxy-mobile-section" style="margin-top:1.25rem"> <h3 style="font-size:0.95rem; font-weight:600; margin-bottom:0.4rem">Mobile</h3> <p style="font-size:0.85rem; color:var(--color-text-muted); margin-bottom:0.4rem"> Mobile devices use a separate PAC URL (plain HTTP proxy): </p> <code class="code-block" id="mobile-pac-url"></code>
<div class="platform-instructions" data-platform="apple" data-proxy-mobile> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Go to <strong>Settings → Wi-Fi</strong></li> <li>Tap the info button on your connected network</li> <li>Scroll to <strong>Configure Proxy</strong> and select <strong>Automatic</strong></li> <li>Enter the mobile PAC URL shown above</li> </ol> </div>
<div class="platform-instructions" data-platform="android" data-proxy-mobile> <ol style="margin-top:0.75rem; padding-left:1.5rem; font-size:0.88rem"> <li>Go to <strong>Settings → Wi-Fi</strong></li> <li>Tap the gear icon on your connected network</li> <li>Set <strong>Proxy</strong> to <strong>Proxy Auto-Config</strong></li> <li>Enter the mobile PAC URL shown above</li> </ol> </div>
<p style="margin-top:0.75rem; font-size:0.82rem; color:var(--color-text-faint)"> The desktop PAC routes traffic through the encrypted HTTPS proxy. The mobile PAC uses a plain HTTP proxy because iOS and Android do not support HTTPS proxy connections. HTTPS traffic is still filtered via MITM. </p> </div>
<div class="wizard-nav"> <button class="btn btn-secondary" onclick="wizardPrev()">Back</button> <div class="wizard-actions"> <button class="btn btn-primary" onclick="wizardNext()">Next</button> </div> </div> </div>
<!-- Step 3: Verify --> <div class="card wizard-card" id="step-verify"> <h2 class="card-title" style="margin-bottom:0.75rem">Verify Setup</h2> <p style="margin-bottom:1rem; font-size:0.9rem; color:var(--color-text-muted)"> Check that the CA certificate is installed and trusted by your browser. </p>
<div class="verify-status pending" id="verify-status"> <span class="verify-spinner"></span> <span id="verify-text">Checking certificate trust…</span> </div>
<div id="verify-detail" style="margin-top:0.75rem; font-size:0.85rem; color:var(--color-text-muted); display:none"></div>
<div class="wizard-nav"> <button class="btn btn-secondary" onclick="wizardPrev()">Back</button> <div class="wizard-actions"> <button class="btn btn-secondary" onclick="runVerify()">Check Again</button> <button class="btn btn-primary" onclick="wizardNext()">Next</button> </div> </div> </div>
<!-- Step 4: Done --> <div class="card wizard-card done-card" id="step-done"> <h2>Setup Complete</h2> <p style="color:var(--color-text-muted); margin-top:0.25rem"> Your device is ready to use ublproxy for ad-free browsing. </p> <p style="margin-top:1rem; font-size:0.88rem; color:var(--color-text-muted)"> Register a passkey on the management portal to create custom blocking rules and manage your blocklist subscriptions. </p> <div class="done-links"> <a class="btn btn-primary" id="portal-link" href="">Open Management Portal</a> <button class="btn btn-secondary" onclick="wizardGoTo(0)">Start Over</button> </div> </div></main>
<script>(function() { var portalURL = '{{.PortalURL}}'; var httpOrigin = '{{.HttpOrigin}}'; var transparentMode = {{.Transparent}};
var steps = transparentMode ? ['step-cert', 'step-verify', 'step-done'] : ['step-cert', 'step-proxy', 'step-verify', 'step-done']; var currentStep = 0;
// Populate dynamic values var pacURL = portalURL + '/proxy.pac'; var mobilePacURL = httpOrigin + '/mobile.pac'; var pacEl = document.getElementById('pac-url'); var mobilePacEl = document.getElementById('mobile-pac-url'); if (pacEl) pacEl.textContent = pacURL; if (mobilePacEl) mobilePacEl.textContent = mobilePacURL; document.getElementById('portal-link').href = portalURL; var chromeFlag = document.getElementById('chrome-flag'); if (chromeFlag) chromeFlag.textContent = 'chromium --proxy-pac-url=' + pacURL;
// In transparent mode, update intro text and hide proxy step if (transparentMode) { var intro = document.getElementById('cert-intro'); if (intro) { intro.textContent = 'This network uses a transparent proxy for ad-blocking. ' + 'Install the CA certificate below so your device trusts the proxy. ' + 'No proxy configuration is needed \u2014 traffic is intercepted automatically.'; } }
// Platform detection var ua = navigator.userAgent; var detectedPlatform = 'apple'; if (/Firefox/i.test(ua)) detectedPlatform = 'firefox'; else if (/Android/i.test(ua)) detectedPlatform = 'android'; else if (/Windows/i.test(ua)) detectedPlatform = 'windows'; else if (/Linux/i.test(ua) && !/Android/i.test(ua)) detectedPlatform = 'linux'; // apple covers iPhone, iPad, Macintosh
var activePlatform = detectedPlatform;
function selectPlatform(platform) { activePlatform = platform; // Update platform buttons var btns = document.querySelectorAll('.platform-btn'); for (var i = 0; i < btns.length; i++) { btns[i].classList.toggle('active', btns[i].getAttribute('data-platform') === platform); } // Show platform-specific instructions (cert step) var instructions = document.querySelectorAll('.platform-instructions:not([data-proxy]):not([data-proxy-mobile])'); for (var i = 0; i < instructions.length; i++) { instructions[i].classList.toggle('active', instructions[i].getAttribute('data-platform') === platform); } // Show platform-specific proxy instructions (proxy step) var proxyInstructions = document.querySelectorAll('.platform-instructions[data-proxy]'); for (var i = 0; i < proxyInstructions.length; i++) { proxyInstructions[i].classList.toggle('active', proxyInstructions[i].getAttribute('data-platform') === platform); } var proxyMobileInstructions = document.querySelectorAll('.platform-instructions[data-proxy-mobile]'); for (var i = 0; i < proxyMobileInstructions.length; i++) { var p = proxyMobileInstructions[i].getAttribute('data-platform'); proxyMobileInstructions[i].classList.toggle('active', p === platform); }
// Show/hide QR code (useful for mobile platforms) var qr = document.getElementById('setup-qr'); var isMobile = platform === 'apple' || platform === 'android'; qr.style.display = isMobile ? '' : 'none';
// Show apple skip message on proxy step var appleSkip = document.getElementById('proxy-apple-skip'); appleSkip.style.display = platform === 'apple' ? '' : 'none';
// Show/hide mobile proxy section var mobileSection = document.getElementById('proxy-mobile-section'); mobileSection.style.display = isMobile ? '' : 'none';
// Show/hide desktop proxy section based on platform var desktopSection = document.getElementById('proxy-desktop-section'); desktopSection.style.display = (platform !== 'android') ? '' : 'none';
sessionStorage.setItem('ublproxy_platform', platform); }
// Bind platform buttons var btns = document.querySelectorAll('.platform-btn'); for (var i = 0; i < btns.length; i++) { btns[i].addEventListener('click', function() { selectPlatform(this.getAttribute('data-platform')); }); }
// Restore or detect platform var savedPlatform = sessionStorage.getItem('ublproxy_platform'); selectPlatform(savedPlatform || detectedPlatform);
// Wizard navigation function renderProgress() { var container = document.getElementById('wizard-progress'); container.innerHTML = ''; for (var i = 0; i < steps.length; i++) { if (i > 0) { var conn = document.createElement('div'); conn.className = 'wizard-step-connector'; if (i <= currentStep) conn.classList.add('completed'); container.appendChild(conn); } var dot = document.createElement('div'); dot.className = 'wizard-step-dot'; if (i === currentStep) dot.classList.add('active'); else if (i < currentStep) dot.classList.add('completed'); container.appendChild(dot); } }
function showStep(index) { currentStep = index; for (var i = 0; i < steps.length; i++) { var el = document.getElementById(steps[i]); el.classList.toggle('active', i === index); } renderProgress(); sessionStorage.setItem('ublproxy_step', index);
if (steps[index] === 'step-verify') { runVerify(); } }
window.wizardNext = function() { if (currentStep < steps.length - 1) showStep(currentStep + 1); };
window.wizardPrev = function() { if (currentStep > 0) showStep(currentStep - 1); };
window.wizardGoTo = function(index) { showStep(index); };
// Verification window.runVerify = function() { var status = document.getElementById('verify-status'); var text = document.getElementById('verify-text'); var detail = document.getElementById('verify-detail');
status.className = 'verify-status pending'; text.textContent = 'Checking certificate trust\u2026'; detail.style.display = 'none'; // Re-add spinner var existingSpinner = status.querySelector('.verify-spinner'); if (!existingSpinner) { var spinner = document.createElement('span'); spinner.className = 'verify-spinner'; status.insertBefore(spinner, status.firstChild); }
fetch(portalURL + '/api/setup/verify', { mode: 'cors' }) .then(function(resp) { return resp.json(); }) .then(function(data) { var spinner = status.querySelector('.verify-spinner'); if (spinner) spinner.remove();
status.className = 'verify-status success'; text.textContent = 'CA certificate is trusted. Your browser can connect to the proxy.'; }) .catch(function(err) { var spinner = status.querySelector('.verify-spinner'); if (spinner) spinner.remove();
status.className = 'verify-status error'; text.textContent = 'Could not verify certificate trust.'; detail.style.display = ''; detail.innerHTML = 'The browser could not connect to <code>' + portalURL + '</code>. ' + 'This usually means the CA certificate is not yet installed or trusted. ' + 'Go back to step 1 and follow the instructions for your platform, then try again.'; }); };
// Restore step from session var savedStep = parseInt(sessionStorage.getItem('ublproxy_step'), 10); if (savedStep >= 0 && savedStep < steps.length) { showStep(savedStep); } else { showStep(0); }})();</script></body></html>