Initial import of Hugo site to Forgejo
This commit is contained in:
commit
cb1ba0317f
1259 changed files with 236349 additions and 0 deletions
508
public/categories/guides/index.xml
Normal file
508
public/categories/guides/index.xml
Normal file
|
|
@ -0,0 +1,508 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Guides on AlipourIm journeys</title><link>http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/categories/guides/</link><description>Recent content in Guides on AlipourIm journeys</description><generator>Hugo -- 0.146.0</generator><language>en</language><lastBuildDate>Tue, 09 Sep 2025 11:05:00 +0200</lastBuildDate><atom:link href="http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/categories/guides/index.xml" rel="self" type="application/rss+xml"/><item><title>Stealth Trojan VPN Behind Cloudflare Guide</title><link>http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/vpn/</link><pubDate>Tue, 09 Sep 2025 11:05:00 +0200</pubDate><guid>http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/vpn/</guid><description><h2 id="introduction">Introduction</h2>
|
||||
<p>So you want a VPN that <strong>doesn&rsquo;t scream &ldquo;I am a VPN&rdquo;</strong> to every censor and firewall out there?<br>
|
||||
Welcome to the world of <strong>Trojan over WebSocket + TLS behind Cloudflare</strong>.</p>
|
||||
<p>This guide not only shows you how to set it up but also sprinkles in some <strong>debugging magic</strong> so you can figure out why things break (and they <em>will</em> break, trust me).</p>
|
||||
<p>We’ll anonymise domains and secrets, so substitute with your own:</p></description><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
|
||||
<p>So you want a VPN that <strong>doesn’t scream “I am a VPN”</strong> to every censor and firewall out there?<br>
|
||||
Welcome to the world of <strong>Trojan over WebSocket + TLS behind Cloudflare</strong>.</p>
|
||||
<p>This guide not only shows you how to set it up but also sprinkles in some <strong>debugging magic</strong> so you can figure out why things break (and they <em>will</em> break, trust me).</p>
|
||||
<p>We’ll anonymise domains and secrets, so substitute with your own:</p>
|
||||
<ul>
|
||||
<li>VPN domain: <code>web.example.com</code></li>
|
||||
<li>Panel domain: <code>panel.example.com</code></li>
|
||||
<li>Secret WS path: <code>/stealth-path_abcd1234</code></li>
|
||||
<li>Password: <code><PASSWORD></code></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="architecture-at-a-glance">Architecture at a Glance</h2>
|
||||
<p>Think of it as a disguise party:</p>
|
||||
<ul>
|
||||
<li><strong>Trojan</strong> = the shy guest (your VPN protocol)</li>
|
||||
<li><strong>Nginx</strong> = the bouncer checking IDs (reverse proxy)</li>
|
||||
<li><strong>Cloudflare</strong> = the doorman who makes sure nobody sees who’s inside (CDN & proxy)</li>
|
||||
<li><strong>Your fake website</strong> = the mask (camouflage page)</li>
|
||||
</ul>
|
||||
<p>Traffic flow:</p>
|
||||
|
||||
|
||||
|
||||
<div class="goat svg-container ">
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
font-family="Menlo,Lucida Console,monospace"
|
||||
|
||||
viewBox="0 0 536 25"
|
||||
>
|
||||
<g transform='translate(8,16)'>
|
||||
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>C</text>
|
||||
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>i</text>
|
||||
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>n</text>
|
||||
<text text-anchor='middle' x='40' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'>→</text>
|
||||
<text text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'>C</text>
|
||||
<text text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'>u</text>
|
||||
<text text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'>d</text>
|
||||
<text text-anchor='middle' x='112' y='4' fill='currentColor' style='font-size:1em'>f</text>
|
||||
<text text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'>r</text>
|
||||
<text text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='160' y='4' fill='currentColor' style='font-size:1em'>(</text>
|
||||
<text text-anchor='middle' x='168' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'>3</text>
|
||||
<text text-anchor='middle' x='192' y='4' fill='currentColor' style='font-size:1em'>)</text>
|
||||
<text text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'>→</text>
|
||||
<text text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'>N</text>
|
||||
<text text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'>g</text>
|
||||
<text text-anchor='middle' x='240' y='4' fill='currentColor' style='font-size:1em'>i</text>
|
||||
<text text-anchor='middle' x='248' y='4' fill='currentColor' style='font-size:1em'>n</text>
|
||||
<text text-anchor='middle' x='256' y='4' fill='currentColor' style='font-size:1em'>x</text>
|
||||
<text text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'>(</text>
|
||||
<text text-anchor='middle' x='280' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'>3</text>
|
||||
<text text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'>)</text>
|
||||
<text text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'>→</text>
|
||||
<text text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'>T</text>
|
||||
<text text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'>r</text>
|
||||
<text text-anchor='middle' x='352' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='360' y='4' fill='currentColor' style='font-size:1em'>j</text>
|
||||
<text text-anchor='middle' x='368' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='376' y='4' fill='currentColor' style='font-size:1em'>n</text>
|
||||
<text text-anchor='middle' x='392' y='4' fill='currentColor' style='font-size:1em'>(</text>
|
||||
<text text-anchor='middle' x='400' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='408' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='416' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='424' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='432' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='440' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='448' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='456' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='464' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='472' y='4' fill='currentColor' style='font-size:1em'>:</text>
|
||||
<text text-anchor='middle' x='480' y='4' fill='currentColor' style='font-size:1em'>5</text>
|
||||
<text text-anchor='middle' x='488' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='496' y='4' fill='currentColor' style='font-size:1em'>3</text>
|
||||
<text text-anchor='middle' x='504' y='4' fill='currentColor' style='font-size:1em'>2</text>
|
||||
<text text-anchor='middle' x='512' y='4' fill='currentColor' style='font-size:1em'>1</text>
|
||||
<text text-anchor='middle' x='520' y='4' fill='currentColor' style='font-size:1em'>)</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<h2 id="step-1-panel-setup-panelexamplecom">Step 1: Panel Setup (<code>panel.example.com</code>)</h2>
|
||||
<ul>
|
||||
<li>Bind the 3x-ui panel to localhost (e.g., <code>127.0.0.1:46309</code>).</li>
|
||||
<li>Choose a funky <strong>web base path</strong> like <code>/panel-bananas_42/</code>.</li>
|
||||
<li>Proxy it through Nginx with HTTPS + Basic Auth.</li>
|
||||
<li>Test it at <code>https://panel.example.com/panel-bananas_42/</code>.</li>
|
||||
</ul>
|
||||
<p><strong>Pro tip:</strong> If you see a blank page → your base path is mismatched or Nginx is eating it. Check logs!</p>
|
||||
<hr>
|
||||
<h2 id="step-2-trojan-inbound">Step 2: Trojan Inbound</h2>
|
||||
<p>In 3x-ui, create a Trojan inbound:</p>
|
||||
<ul>
|
||||
<li>Local port: <code>54321</code></li>
|
||||
<li>Transport: WebSocket</li>
|
||||
<li>Path: <code>/stealth-path_abcd1234</code></li>
|
||||
<li>Security: none</li>
|
||||
<li>Password: <code><PASSWORD></code></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="step-3-nginx-for-vpn-domain-webexamplecom">Step 3: Nginx for VPN Domain (<code>web.example.com</code>)</h2>
|
||||
<p>Your Nginx is the gatekeeper. Sample config:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#ae81ff">443</span> <span style="color:#e6db74">ssl</span> <span style="color:#e6db74">http2</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">server_name</span> <span style="color:#e6db74">web.example.com</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate</span> <span style="color:#e6db74">/etc/letsencrypt/live/web.example.com/fullchain.pem</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate_key</span> <span style="color:#e6db74">/etc/letsencrypt/live/web.example.com/privkey.pem</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Fake website at root
|
||||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">root</span> <span style="color:#e6db74">/var/www/html</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">index</span> <span style="color:#e6db74">index.html</span>;
|
||||
</span></span><span style="display:flex;"><span> }
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#75715e"># Real VPN under secret WS path
|
||||
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#f92672">location</span> <span style="color:#e6db74">/stealth-path_abcd1234</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_pass</span> <span style="color:#e6db74">http://127.0.0.1:54321</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_http_version</span> <span style="color:#ae81ff">1</span><span style="color:#e6db74">.1</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Upgrade</span> $http_upgrade;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Connection</span> <span style="color:#e6db74">"upgrade"</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Host</span> $host;
|
||||
</span></span><span style="display:flex;"><span> }
|
||||
</span></span><span style="display:flex;"><span>}
|
||||
</span></span></code></pre></div><hr>
|
||||
<h2 id="step-4-firewall-rules">Step 4: Firewall Rules</h2>
|
||||
<p>Lock things down! Only Cloudflare should reach you:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ufw allow 22/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw allow 80/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw allow 443/tcp
|
||||
</span></span><span style="display:flex;"><span>ufw deny 54321/tcp
|
||||
</span></span></code></pre></div><hr>
|
||||
<h2 id="step-5-client-config">Step 5: Client Config</h2>
|
||||
<p>Trojan URI:</p>
|
||||
|
||||
|
||||
|
||||
<div class="goat svg-container ">
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
font-family="Menlo,Lucida Console,monospace"
|
||||
|
||||
viewBox="0 0 1160 25"
|
||||
>
|
||||
<g transform='translate(8,16)'>
|
||||
<text text-anchor='middle' x='0' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='8' y='4' fill='currentColor' style='font-size:1em'>r</text>
|
||||
<text text-anchor='middle' x='16' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='24' y='4' fill='currentColor' style='font-size:1em'>j</text>
|
||||
<text text-anchor='middle' x='32' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='40' y='4' fill='currentColor' style='font-size:1em'>n</text>
|
||||
<text text-anchor='middle' x='48' y='4' fill='currentColor' style='font-size:1em'>:</text>
|
||||
<text text-anchor='middle' x='56' y='4' fill='currentColor' style='font-size:1em'>/</text>
|
||||
<text text-anchor='middle' x='64' y='4' fill='currentColor' style='font-size:1em'>/</text>
|
||||
<text text-anchor='middle' x='72' y='4' fill='currentColor' style='font-size:1em'><</text>
|
||||
<text text-anchor='middle' x='80' y='4' fill='currentColor' style='font-size:1em'>P</text>
|
||||
<text text-anchor='middle' x='88' y='4' fill='currentColor' style='font-size:1em'>A</text>
|
||||
<text text-anchor='middle' x='96' y='4' fill='currentColor' style='font-size:1em'>S</text>
|
||||
<text text-anchor='middle' x='104' y='4' fill='currentColor' style='font-size:1em'>S</text>
|
||||
<text text-anchor='middle' x='112' y='4' fill='currentColor' style='font-size:1em'>W</text>
|
||||
<text text-anchor='middle' x='120' y='4' fill='currentColor' style='font-size:1em'>O</text>
|
||||
<text text-anchor='middle' x='128' y='4' fill='currentColor' style='font-size:1em'>R</text>
|
||||
<text text-anchor='middle' x='136' y='4' fill='currentColor' style='font-size:1em'>D</text>
|
||||
<text text-anchor='middle' x='144' y='4' fill='currentColor' style='font-size:1em'>></text>
|
||||
<text text-anchor='middle' x='152' y='4' fill='currentColor' style='font-size:1em'>@</text>
|
||||
<text text-anchor='middle' x='160' y='4' fill='currentColor' style='font-size:1em'>w</text>
|
||||
<text text-anchor='middle' x='168' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='176' y='4' fill='currentColor' style='font-size:1em'>b</text>
|
||||
<text text-anchor='middle' x='184' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='192' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='200' y='4' fill='currentColor' style='font-size:1em'>x</text>
|
||||
<text text-anchor='middle' x='208' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='216' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='224' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='232' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='240' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='248' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='256' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='264' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='272' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='280' y='4' fill='currentColor' style='font-size:1em'>:</text>
|
||||
<text text-anchor='middle' x='288' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='296' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='304' y='4' fill='currentColor' style='font-size:1em'>3</text>
|
||||
<text text-anchor='middle' x='312' y='4' fill='currentColor' style='font-size:1em'>?</text>
|
||||
<text text-anchor='middle' x='320' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='328' y='4' fill='currentColor' style='font-size:1em'>y</text>
|
||||
<text text-anchor='middle' x='336' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='344' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='352' y='4' fill='currentColor' style='font-size:1em'>=</text>
|
||||
<text text-anchor='middle' x='360' y='4' fill='currentColor' style='font-size:1em'>w</text>
|
||||
<text text-anchor='middle' x='368' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='376' y='4' fill='currentColor' style='font-size:1em'>&</text>
|
||||
<text text-anchor='middle' x='384' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='392' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='400' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='408' y='4' fill='currentColor' style='font-size:1em'>u</text>
|
||||
<text text-anchor='middle' x='416' y='4' fill='currentColor' style='font-size:1em'>r</text>
|
||||
<text text-anchor='middle' x='424' y='4' fill='currentColor' style='font-size:1em'>i</text>
|
||||
<text text-anchor='middle' x='432' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='440' y='4' fill='currentColor' style='font-size:1em'>y</text>
|
||||
<text text-anchor='middle' x='448' y='4' fill='currentColor' style='font-size:1em'>=</text>
|
||||
<text text-anchor='middle' x='456' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='464' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='472' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='480' y='4' fill='currentColor' style='font-size:1em'>&</text>
|
||||
<text text-anchor='middle' x='488' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='496' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='504' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='512' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='520' y='4' fill='currentColor' style='font-size:1em'>=</text>
|
||||
<text text-anchor='middle' x='528' y='4' fill='currentColor' style='font-size:1em'>w</text>
|
||||
<text text-anchor='middle' x='536' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='544' y='4' fill='currentColor' style='font-size:1em'>b</text>
|
||||
<text text-anchor='middle' x='552' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='560' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='568' y='4' fill='currentColor' style='font-size:1em'>x</text>
|
||||
<text text-anchor='middle' x='576' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='584' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='592' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='600' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='608' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='616' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='624' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='632' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='640' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='648' y='4' fill='currentColor' style='font-size:1em'>&</text>
|
||||
<text text-anchor='middle' x='656' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='664' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='672' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='680' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='688' y='4' fill='currentColor' style='font-size:1em'>=</text>
|
||||
<text text-anchor='middle' x='696' y='4' fill='currentColor' style='font-size:1em'>%</text>
|
||||
<text text-anchor='middle' x='704' y='4' fill='currentColor' style='font-size:1em'>2</text>
|
||||
<text text-anchor='middle' x='712' y='4' fill='currentColor' style='font-size:1em'>F</text>
|
||||
<text text-anchor='middle' x='720' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='728' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='736' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='744' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='752' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='760' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='768' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='776' y='4' fill='currentColor' style='font-size:1em'>-</text>
|
||||
<text text-anchor='middle' x='784' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='792' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='800' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='808' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='816' y='4' fill='currentColor' style='font-size:1em'>_</text>
|
||||
<text text-anchor='middle' x='824' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='832' y='4' fill='currentColor' style='font-size:1em'>b</text>
|
||||
<text text-anchor='middle' x='840' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='848' y='4' fill='currentColor' style='font-size:1em'>d</text>
|
||||
<text text-anchor='middle' x='856' y='4' fill='currentColor' style='font-size:1em'>1</text>
|
||||
<text text-anchor='middle' x='864' y='4' fill='currentColor' style='font-size:1em'>2</text>
|
||||
<text text-anchor='middle' x='872' y='4' fill='currentColor' style='font-size:1em'>3</text>
|
||||
<text text-anchor='middle' x='880' y='4' fill='currentColor' style='font-size:1em'>4</text>
|
||||
<text text-anchor='middle' x='888' y='4' fill='currentColor' style='font-size:1em'>&</text>
|
||||
<text text-anchor='middle' x='896' y='4' fill='currentColor' style='font-size:1em'>s</text>
|
||||
<text text-anchor='middle' x='904' y='4' fill='currentColor' style='font-size:1em'>n</text>
|
||||
<text text-anchor='middle' x='912' y='4' fill='currentColor' style='font-size:1em'>i</text>
|
||||
<text text-anchor='middle' x='920' y='4' fill='currentColor' style='font-size:1em'>=</text>
|
||||
<text text-anchor='middle' x='928' y='4' fill='currentColor' style='font-size:1em'>w</text>
|
||||
<text text-anchor='middle' x='936' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='944' y='4' fill='currentColor' style='font-size:1em'>b</text>
|
||||
<text text-anchor='middle' x='952' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='960' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='968' y='4' fill='currentColor' style='font-size:1em'>x</text>
|
||||
<text text-anchor='middle' x='976' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='984' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='992' y='4' fill='currentColor' style='font-size:1em'>p</text>
|
||||
<text text-anchor='middle' x='1000' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='1008' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='1016' y='4' fill='currentColor' style='font-size:1em'>.</text>
|
||||
<text text-anchor='middle' x='1024' y='4' fill='currentColor' style='font-size:1em'>c</text>
|
||||
<text text-anchor='middle' x='1032' y='4' fill='currentColor' style='font-size:1em'>o</text>
|
||||
<text text-anchor='middle' x='1040' y='4' fill='currentColor' style='font-size:1em'>m</text>
|
||||
<text text-anchor='middle' x='1048' y='4' fill='currentColor' style='font-size:1em'>#</text>
|
||||
<text text-anchor='middle' x='1056' y='4' fill='currentColor' style='font-size:1em'>M</text>
|
||||
<text text-anchor='middle' x='1064' y='4' fill='currentColor' style='font-size:1em'>y</text>
|
||||
<text text-anchor='middle' x='1072' y='4' fill='currentColor' style='font-size:1em'>S</text>
|
||||
<text text-anchor='middle' x='1080' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='1088' y='4' fill='currentColor' style='font-size:1em'>e</text>
|
||||
<text text-anchor='middle' x='1096' y='4' fill='currentColor' style='font-size:1em'>a</text>
|
||||
<text text-anchor='middle' x='1104' y='4' fill='currentColor' style='font-size:1em'>l</text>
|
||||
<text text-anchor='middle' x='1112' y='4' fill='currentColor' style='font-size:1em'>t</text>
|
||||
<text text-anchor='middle' x='1120' y='4' fill='currentColor' style='font-size:1em'>h</text>
|
||||
<text text-anchor='middle' x='1128' y='4' fill='currentColor' style='font-size:1em'>V</text>
|
||||
<text text-anchor='middle' x='1136' y='4' fill='currentColor' style='font-size:1em'>P</text>
|
||||
<text text-anchor='middle' x='1144' y='4' fill='currentColor' style='font-size:1em'>N</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<p>iOS clients: Shadowrocket, Stash, FoXray<br>
|
||||
Android clients: v2rayNG, Clash Meta, NekoBox</p>
|
||||
<hr>
|
||||
<h2 id="debugging-time-aka-why-the-heck-doesnt-it-work">Debugging Time (a.k.a. “Why the heck doesn’t it work?!”)</h2>
|
||||
<h3 id="symptom-520-unknown-error-cloudflare">Symptom: <strong>520 Unknown Error (Cloudflare)</strong></h3>
|
||||
<ul>
|
||||
<li>Likely cause: Nginx couldn’t talk to Trojan.</li>
|
||||
<li>Check Nginx error log:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>tail -n <span style="color:#ae81ff">50</span> /var/log/nginx/error.log
|
||||
</span></span></code></pre></div></li>
|
||||
<li>If you see <code>upstream sent no valid HTTP/1.0 header</code> → you’re mixing HTTPS/HTTP between Nginx and Trojan.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-526-invalid-ssl-certificate">Symptom: <strong>526 Invalid SSL certificate</strong></h3>
|
||||
<ul>
|
||||
<li>Cloudflare → Nginx cert mismatch.</li>
|
||||
<li>Run:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl s_client -connect web.example.com:443 -servername web.example.com -showcerts
|
||||
</span></span></code></pre></div></li>
|
||||
<li>Make sure CN = <code>web.example.com</code>. If not, fix your cert.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-blank-page-on-panel">Symptom: <strong>Blank page on panel</strong></h3>
|
||||
<ul>
|
||||
<li>Check if the base path matches exactly (case-sensitive, slash-sensitive).</li>
|
||||
<li>Watch for sneaky trailing spaces!</li>
|
||||
<li>Test locally:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -s -D- http://127.0.0.1:46309/panel-bananas_42/
|
||||
</span></span></code></pre></div></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-client-wont-connect">Symptom: <strong>Client won’t connect</strong></h3>
|
||||
<ul>
|
||||
<li>Run a WebSocket test:
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -i -k -H <span style="color:#e6db74">"Connection: Upgrade"</span> -H <span style="color:#e6db74">"Upgrade: websocket"</span> https://web.example.com/stealth-path_abcd1234
|
||||
</span></span></code></pre></div>Expect <code>101 Switching Protocols</code>. If not, check Nginx config.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3 id="symptom-censor-still-blocks-you">Symptom: <strong>Censor still blocks you</strong></h3>
|
||||
<ul>
|
||||
<li>Did you expose another service (like SSH, Matrix, or Minecraft) on the same IP?<br>
|
||||
→ They’ll find your origin IP. Use a second VPS or lock those ports down.</li>
|
||||
<li>Did you use an obvious path like <code>/ws</code>?<br>
|
||||
→ Use a random-looking one like <code>/cdn-assets-329df/</code>.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="pro-tips--fun-tricks">Pro Tips & Fun Tricks</h2>
|
||||
<ul>
|
||||
<li>Serve a fake blog or portfolio at root so your domain looks legit.</li>
|
||||
<li>Rotate WebSocket paths occasionally.</li>
|
||||
<li>Use Cloudflare <strong>Page Rules</strong> to disable Rocket Loader & Minify for your VPN domain.</li>
|
||||
<li>Make friends with your Nginx error.log — it will roast you but it tells the truth.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="conclusion">Conclusion</h2>
|
||||
<p>By putting Trojan behind Cloudflare, you’ve given your VPN a shiny new disguise:</p>
|
||||
<ul>
|
||||
<li>Looks like normal HTTPS.</li>
|
||||
<li>Hides your origin IP.</li>
|
||||
<li>Forces censors into a tough choice: block Cloudflare (and half the web) or let you pass.</li>
|
||||
</ul>
|
||||
<p>Congrats — you’ve built a VPN with both <strong>style</strong> and <strong>stealth</strong>. 🥷</p>
|
||||
]]></content:encoded></item><item><title>Self-Hosting HedgeDoc with Docker + Nginx + Let's Encrypt</title><link>http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/hedge_doc/</link><pubDate>Fri, 29 Aug 2025 00:00:00 +0000</pubDate><guid>http://fjthpp2h3mj2rup25r3psmqamutnkbvxbpltlohdthw6fscgo3t6bpad.onion/posts/hedge_doc/</guid><description><p>HedgeDoc is an open-source collaborative Markdown editor. Think <em>Google Docs for Markdown</em>: multiple people can edit the same note in real-time, with support for diagrams, math, polls, and slide decks. In this post we’ll walk through setting up your own instance on a server, secured with HTTPS.</p>
|
||||
<hr>
|
||||
<h2 id="prerequisites">Prerequisites</h2>
|
||||
<ul>
|
||||
<li>A Linux server with <strong>Docker</strong> and <strong>Docker Compose</strong></li>
|
||||
<li>A domain name pointing to your server (e.g. <code>notes.alipourimjourneys.ir</code>)</li>
|
||||
<li><strong>Nginx</strong> installed for reverse proxying</li>
|
||||
<li><strong>Certbot</strong> for Let’s Encrypt certificates</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="1-create-the-project-directory">1. Create the project directory</h2>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir ~/hedgedoc <span style="color:#f92672">&amp;&amp;</span> cd ~/hedgedoc</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="2-create-env">2. Create <code>.env</code></h2>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-env" data-lang="env"><span style="display:flex;"><span>POSTGRES_PASSWORD<span style="color:#f92672">=</span>ChangeThisStrongPassword
|
||||
</span></span><span style="display:flex;"><span>HD_DOMAIN<span style="color:#f92672">=</span>notes.alipourimjourneys.ir</span></span></code></pre></div>
|
||||
<p>Generate a strong password with:</p></description><content:encoded><![CDATA[<p>HedgeDoc is an open-source collaborative Markdown editor. Think <em>Google Docs for Markdown</em>: multiple people can edit the same note in real-time, with support for diagrams, math, polls, and slide decks. In this post we’ll walk through setting up your own instance on a server, secured with HTTPS.</p>
|
||||
<hr>
|
||||
<h2 id="prerequisites">Prerequisites</h2>
|
||||
<ul>
|
||||
<li>A Linux server with <strong>Docker</strong> and <strong>Docker Compose</strong></li>
|
||||
<li>A domain name pointing to your server (e.g. <code>notes.alipourimjourneys.ir</code>)</li>
|
||||
<li><strong>Nginx</strong> installed for reverse proxying</li>
|
||||
<li><strong>Certbot</strong> for Let’s Encrypt certificates</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2 id="1-create-the-project-directory">1. Create the project directory</h2>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir ~/hedgedoc <span style="color:#f92672">&&</span> cd ~/hedgedoc</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="2-create-env">2. Create <code>.env</code></h2>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-env" data-lang="env"><span style="display:flex;"><span>POSTGRES_PASSWORD<span style="color:#f92672">=</span>ChangeThisStrongPassword
|
||||
</span></span><span style="display:flex;"><span>HD_DOMAIN<span style="color:#f92672">=</span>notes.alipourimjourneys.ir</span></span></code></pre></div>
|
||||
<p>Generate a strong password with:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl rand -base64 <span style="color:#ae81ff">32</span></span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="3-create-docker-composeyml">3. Create <code>docker-compose.yml</code></h2>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">version</span>: <span style="color:#e6db74">"3.9"</span>
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span><span style="color:#f92672">services</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">db</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">image</span>: <span style="color:#ae81ff">postgres:16</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">environment</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">POSTGRES_USER</span>: <span style="color:#ae81ff">hedgedoc</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">POSTGRES_PASSWORD</span>: <span style="color:#ae81ff">${POSTGRES_PASSWORD}</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">POSTGRES_DB</span>: <span style="color:#ae81ff">hedgedoc</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumes</span>:
|
||||
</span></span><span style="display:flex;"><span> - <span style="color:#ae81ff">db:/var/lib/postgresql/data</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">restart</span>: <span style="color:#ae81ff">unless-stopped</span>
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">hedgedoc</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">image</span>: <span style="color:#ae81ff">quay.io/hedgedoc/hedgedoc:1.10.2</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">depends_on</span>:
|
||||
</span></span><span style="display:flex;"><span> - <span style="color:#ae81ff">db</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">environment</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_DB_URL</span>: <span style="color:#ae81ff">postgres://hedgedoc:${POSTGRES_PASSWORD}@db:5432/hedgedoc</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_DOMAIN</span>: <span style="color:#ae81ff">${HD_DOMAIN}</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_PROTOCOL_USESSL</span>: <span style="color:#e6db74">"true"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_URL_ADDPORT</span>: <span style="color:#e6db74">"false"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_PORT</span>: <span style="color:#e6db74">"3000"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_EMAIL</span>: <span style="color:#e6db74">"true"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_ALLOW_EMAIL_REGISTER</span>: <span style="color:#e6db74">"false"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumes</span>:
|
||||
</span></span><span style="display:flex;"><span> - <span style="color:#ae81ff">uploads:/hedgedoc/public/uploads</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ports</span>:
|
||||
</span></span><span style="display:flex;"><span> - <span style="color:#e6db74">"127.0.0.1:3000:3000"</span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">restart</span>: <span style="color:#ae81ff">unless-stopped</span>
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span><span style="color:#f92672">volumes</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">db</span>:
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">uploads:</span></span></span></code></pre></div>
|
||||
<p>Bring it up:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose up -d</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="4-get-a-lets-encrypt-certificate">4. Get a Let’s Encrypt certificate</h2>
|
||||
<p>Request a cert with a <strong>DNS challenge</strong>:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo certbot certonly --manual --preferred-challenges dns -d notes.alipourimjourneys.ir -m you@example.com --agree-tos --no-eff-email</span></span></code></pre></div>
|
||||
<p>Add the TXT record certbot asks for, wait for DNS to propagate, then continue.<br>
|
||||
Certificates will be in:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>/etc/letsencrypt/live/notes.alipourimjourneys.ir/</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="5-configure-nginx">5. Configure Nginx</h2>
|
||||
<p>Create <code>/etc/nginx/sites-available/notes.alipourimjourneys.ir</code>:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">server_name</span> <span style="color:#e6db74">notes.alipourimjourneys.ir</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#ae81ff">80</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:80</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">return</span> <span style="color:#ae81ff">301</span> <span style="color:#e6db74">https://</span>$host$request_uri;
|
||||
</span></span><span style="display:flex;"><span>}
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">server</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">server_name</span> <span style="color:#e6db74">notes.alipourimjourneys.ir</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#ae81ff">443</span> <span style="color:#e6db74">ssl</span> <span style="color:#e6db74">http2</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">listen</span> <span style="color:#e6db74">[::]:443</span> <span style="color:#e6db74">ssl</span> <span style="color:#e6db74">http2</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate</span> <span style="color:#e6db74">/etc/letsencrypt/live/notes.alipourimjourneys.ir/fullchain.pem</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ssl_certificate_key</span> <span style="color:#e6db74">/etc/letsencrypt/live/notes.alipourimjourneys.ir/privkey.pem</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">location</span> <span style="color:#e6db74">/</span> {
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_pass</span> <span style="color:#e6db74">http://127.0.0.1:3000</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Host</span> $host;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Real-IP</span> $remote_addr;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Forwarded-For</span> $proxy_add_x_forwarded_for;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">X-Forwarded-Proto</span> <span style="color:#e6db74">https</span>;
|
||||
</span></span><span style="display:flex;"><span>
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_http_version</span> <span style="color:#ae81ff">1</span><span style="color:#e6db74">.1</span>;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Upgrade</span> $http_upgrade;
|
||||
</span></span><span style="display:flex;"><span> <span style="color:#f92672">proxy_set_header</span> <span style="color:#e6db74">Connection</span> <span style="color:#e6db74">"upgrade"</span>;
|
||||
</span></span><span style="display:flex;"><span> }
|
||||
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
|
||||
<p>Enable the config and reload Nginx:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo ln -s /etc/nginx/sites-available/notes.alipourimjourneys.ir /etc/nginx/sites-enabled/
|
||||
</span></span><span style="display:flex;"><span>sudo nginx -t <span style="color:#f92672">&&</span> sudo systemctl reload nginx</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="6-create-users">6. Create users</h2>
|
||||
<p>Because we disabled self-registration, create accounts manually:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose exec hedgedoc ./bin/manage_users --add alice@example.com</span></span></code></pre></div>
|
||||
<p>You’ll be prompted for a password.<br>
|
||||
To reset a password later:</p>
|
||||
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose exec hedgedoc ./bin/manage_users --reset alice@example.com</span></span></code></pre></div>
|
||||
<hr>
|
||||
<h2 id="7-done">7. Done!</h2>
|
||||
<p>Visit <a href="https://notes.alipourimjourneys.ir">https://notes.alipourimjourneys.ir</a> and log in with the user you created. You now have your own collaborative Markdown editor 🎉</p>
|
||||
<hr>
|
||||
<p><strong>Extras:</strong></p>
|
||||
<ul>
|
||||
<li>Backups: dump the PostgreSQL database and save the <code>uploads</code> volume.</li>
|
||||
<li>Upgrades: <code>docker pull quay.io/hedgedoc/hedgedoc:latest && docker compose up -d</code>.</li>
|
||||
<li>Integrations: HedgeDoc supports S3/MinIO image storage, GitHub/GitLab/Google login, and more.</li>
|
||||
</ul>
|
||||
]]></content:encoded></item></channel></rss>
|
||||
Loading…
Add table
Add a link
Reference in a new issue