mysite/public/categories/guides/index.xml

508 lines
No EOL
45 KiB
XML
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.

<?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>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>So you want a VPN that &lt;strong>doesn&amp;rsquo;t scream &amp;ldquo;I am a VPN&amp;rdquo;&lt;/strong> to every censor and firewall out there?&lt;br>
Welcome to the world of &lt;strong>Trojan over WebSocket + TLS behind Cloudflare&lt;/strong>.&lt;/p>
&lt;p>This guide not only shows you how to set it up but also sprinkles in some &lt;strong>debugging magic&lt;/strong> so you can figure out why things break (and they &lt;em>will&lt;/em> break, trust me).&lt;/p>
&lt;p>Well anonymise domains and secrets, so substitute with your own:&lt;/p></description><content:encoded><![CDATA[<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>Well 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>&lt;PASSWORD&gt;</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&rsquo;s inside (CDN &amp; 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>&lt;PASSWORD&gt;</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">&#34;upgrade&#34;</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'>&lt;</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'>&gt;</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'>&amp;</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'>&amp;</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'>&amp;</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'>&amp;</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 doesnt it work?!”)</h2>
<h3 id="symptom-520-unknown-error-cloudflare">Symptom: <strong>520 Unknown Error (Cloudflare)</strong></h3>
<ul>
<li>Likely cause: Nginx couldnt 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> → youre 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 wont 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">&#34;Connection: Upgrade&#34;</span> -H <span style="color:#e6db74">&#34;Upgrade: websocket&#34;</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>
→ Theyll 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 &amp; 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 &amp; 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, youve 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 — youve 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>&lt;p>HedgeDoc is an open-source collaborative Markdown editor. Think &lt;em>Google Docs for Markdown&lt;/em>: multiple people can edit the same note in real-time, with support for diagrams, math, polls, and slide decks. In this post well walk through setting up your own instance on a server, secured with HTTPS.&lt;/p>
&lt;hr>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;ul>
&lt;li>A Linux server with &lt;strong>Docker&lt;/strong> and &lt;strong>Docker Compose&lt;/strong>&lt;/li>
&lt;li>A domain name pointing to your server (e.g. &lt;code>notes.alipourimjourneys.ir&lt;/code>)&lt;/li>
&lt;li>&lt;strong>Nginx&lt;/strong> installed for reverse proxying&lt;/li>
&lt;li>&lt;strong>Certbot&lt;/strong> for Lets Encrypt certificates&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="1-create-the-project-directory">1. Create the project directory&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>mkdir ~/hedgedoc &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> cd ~/hedgedoc&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;hr>
&lt;h2 id="2-create-env">2. Create &lt;code>.env&lt;/code>&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-env" data-lang="env">&lt;span style="display:flex;">&lt;span>POSTGRES_PASSWORD&lt;span style="color:#f92672">=&lt;/span>ChangeThisStrongPassword
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>HD_DOMAIN&lt;span style="color:#f92672">=&lt;/span>notes.alipourimjourneys.ir&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>Generate a strong password with:&lt;/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 well 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 Lets 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>
<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">&#34;3.9&#34;</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">&#34;true&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_URL_ADDPORT</span>: <span style="color:#e6db74">&#34;false&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_PORT</span>: <span style="color:#e6db74">&#34;3000&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_EMAIL</span>: <span style="color:#e6db74">&#34;true&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">CMD_ALLOW_EMAIL_REGISTER</span>: <span style="color:#e6db74">&#34;false&#34;</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">&#34;127.0.0.1:3000:3000&#34;</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 Lets 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">&#34;upgrade&#34;</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">&amp;&amp;</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>Youll 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 &amp;&amp; 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>