<?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>DreamServer Blog - DreamServer</title><link>https://dreamserver.ro/en/blog/</link><description>Technical articles, tutorials and announcements from DreamServer - dedicated servers, VDS, networking, applications and platforms, plus promotions and new features. on DreamServer</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 20 Apr 2026 10:00:00 +0300</lastBuildDate><atom:link href="https://dreamserver.ro/en/blog/" rel="self" type="application/rss+xml"/><item><title>CloudPanel: a free server panel that does not feel cheap</title><link>https://dreamserver.ro/en/blog/cloudpanel-free-server-control-panel/</link><pubDate>Mon, 20 Apr 2026 10:00:00 +0300</pubDate><author>Cristian Trusca</author><guid isPermaLink="true">https://dreamserver.ro/en/blog/cloudpanel-free-server-control-panel/</guid><description>A practical look at CloudPanel, the free open-source server control panel from MGT-COMMERCE: what is in the box, how it installs on a Debian or Ubuntu VPS, and where it stops short.</description><content:encoded><![CDATA[<p>If you have ever priced cPanel for a small fleet of VPSes, you already know the math is unkind. The per-account license, on top of the OS license if you went RHEL, on top of the server itself, turns a 5 EUR VPS into a 25 EUR VPS before you have served a single request. Plesk is in the same neighbourhood. The free alternatives have a habit of being either ten years behind on UI or quietly suspect about telemetry, which leaves a real gap for &ldquo;modern panel, free, hosted on my own box&rdquo;.</p>
<p><a href="https://www.cloudpanel.io/" rel="nofollow">CloudPanel</a>
, the open-source panel from MGT-COMMERCE, has been settling into that gap for the last couple of years. The community edition is the only edition, which is a refreshing change from the freemium pattern. As of v2.5.3 (December 2025) it sits at roughly 1.8k stars on <a href="https://github.com/cloudpanel-io/cloudpanel-ce" rel="nofollow">GitHub</a>
 and ships cloud images for every major hyperscaler. We have been running it on a <a href="/en/virtual-servers/vps/">VPS in our Bucharest datacenter</a>
 for several weeks. This is the field report.</p>
<h2 id="what-cloudpanel-actually-is">What CloudPanel actually is</h2>
<p>Architecturally, CloudPanel is <strong>a thin management layer over a hardened Nginx, PHP-FPM, MySQL or MariaDB stack</strong>. It is not its own web server, not its own database, not a Docker swarm or a Kubernetes wrapper. The panel writes Nginx vhosts, manages PHP-FPM pools per site, provisions Linux users so each site is isolated at the OS level, and exposes a UI to do all of that without you remembering the exact <code>php-fpm</code> config knob you wanted last Tuesday.</p>
<p>If that sounds dull, that is the point. The interesting design decision in CloudPanel is what it does <em>not</em> try to be: it is not a hosting reseller platform, not a billing system, not a mail server, not a DNS authoritative server. Those omissions are deliberate, and they are also the first thing to understand before you adopt it.</p>
<h3 id="the-stack-you-get">The stack you get</h3>
<ul>
<li><strong>Web tier</strong>: Nginx, configured as the front for every site. There is no Apache option.</li>
<li><strong>PHP</strong>: multiple versions installed in parallel (7.x and 8.x), switchable per site with a click. Running an old PrestaShop on 7.4 next to a Laravel 11 app on 8.3 on the same box is a non-event.</li>
<li><strong>Databases</strong>: MySQL 8.4, 8.0, 5.7 or MariaDB 11.8, 11.4, 10.11, 10.6. You pick one at install time via a <code>DB_ENGINE</code> variable, the rest are not installed.</li>
<li><strong>Application types</strong>: PHP, Node.js, Python, static sites, and reverse-proxy passthroughs (handy for putting a panel-managed Nginx in front of an app you run elsewhere).</li>
<li><strong>TLS</strong>: Let&rsquo;s Encrypt baked in, with HTTP-01 validation and auto-renewal.</li>
</ul>
<p>The control plane itself is a Symfony PHP app behind its own Nginx vhost on port 8443. That single port is the entire management surface; close it to the world and the only people who can touch the panel are people on your management network.</p>
<h2 id="what-you-get-out-of-the-box">What you get out of the box</h2>
<p>The community edition (which, again, is the only edition) ships with:</p>
<ul>
<li><strong>Site isolation</strong> at the OS level. Each site gets its own Linux user, its own PHP-FPM pool, its own home directory. A compromised WordPress on site A does not have read access to site B&rsquo;s files. This is the single feature that matters most for shared environments.</li>
<li><strong>Free Let&rsquo;s Encrypt SSL</strong>, one click per site, auto-renewed by cron.</li>
<li><strong>UFW firewall</strong> management with a sane default policy and a UI to add rules.</li>
<li><strong>Two-factor authentication</strong> for the panel admin, TOTP based.</li>
<li><strong>IP and Bot blocker</strong>, which lets you blacklist user agents and IP ranges without dropping into Nginx config.</li>
<li><strong>Cloudflare integration</strong>, primarily for trusting the right <code>X-Forwarded-For</code> chain so your access logs are not full of Cloudflare edge IPs.</li>
<li><strong>Vhost templates</strong> per app type, pre-configured for WordPress, Magento, Symfony, Node, generic PHP, and so on. The templates are sensible (gzip, brotli, security headers) and editable.</li>
<li><strong>Per-site cron</strong>, FTP, file manager, and database management UI.</li>
<li><strong>Backup destinations</strong> to S3-compatible buckets, including MinIO and Backblaze B2, configurable per site.</li>
</ul>
<p>What it does <em>not</em> ship: a mail server, a DNS authoritative server, a billing/customer portal, a one-click app installer like Softaculous, or any kind of multi-server clustering. If your mental model of a control panel is &ldquo;cPanel feature parity&rdquo;, CloudPanel will feel sparse. If your mental model is &ldquo;the smallest thing that lets me stop hand-editing Nginx vhosts&rdquo;, it will feel right-sized.</p>
<h2 id="installing-cloudpanel-on-a-vps">Installing CloudPanel on a VPS</h2>
<p>The install path is genuinely a one-liner and the docs do not pretend otherwise. Minimum sane resources are <strong>1 vCPU, 2 GB RAM, 10 GB disk</strong>. Supported OSes are Debian 11, 12, 13 and Ubuntu 22.04, 24.04 LTS, on x86_64 or arm64. Anything older than Debian 11 is not supported and you should not try.</p>
<p>On a fresh server, log in as root and update the base packages first:</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>apt update <span style="color:#f92672">&amp;&amp;</span> apt -y upgrade <span style="color:#f92672">&amp;&amp;</span> apt -y install curl wget sudo
</span></span></code></pre></div><p>Then run the installer. The exact command from the official docs (with sha256 verification, which you should not skip):</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>curl -sS https://installer.cloudpanel.io/ce/v2/install.sh -o install.sh; <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>echo <span style="color:#e6db74">&#34;6eac061df80f08b75224fcd7fce2f115e201696d8a6122e31abf7259a813b462 install.sh&#34;</span> | <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>sha256sum -c <span style="color:#f92672">&amp;&amp;</span> sudo DB_ENGINE<span style="color:#f92672">=</span>MYSQL_8.4 bash install.sh
</span></span></code></pre></div><p>Pick the <code>DB_ENGINE</code> value that matches your needs. Common choices are <code>MYSQL_8.4</code>, <code>MYSQL_8.0</code>, <code>MARIADB_11.8</code>, <code>MARIADB_10.11</code>. If you want MariaDB because your app stack assumes it, decide now, the database engine is not swappable post-install without manual surgery.</p>
<p>The script will install Nginx, PHP, the chosen database, the panel itself, and the supporting cron jobs. It takes 3 to 6 minutes on a 1 vCPU VPS, longer on slow disks.</p>
<p>Once it finishes, the management UI is at <code>https://&lt;your-server-ip&gt;:8443/</code>. The first request lands on a setup wizard where you create the admin user, <strong>and that is the moment of risk</strong>: between the install finishing and you completing the wizard, anyone who can reach port 8443 can claim the admin account. The official guidance is to access the panel &ldquo;as fast as possible&rdquo;. The better guidance is to firewall port 8443 down to your own IP before you even start the install:</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 from YOUR_OFFICE_IP to any port <span style="color:#ae81ff">8443</span>
</span></span><span style="display:flex;"><span>ufw deny <span style="color:#ae81ff">8443</span>
</span></span></code></pre></div><p>If you are running this on a <a href="/en/virtual-servers/vps/">DreamServer VPS</a>
, put the same rule in your provider-side network firewall too. Host-level rules are fine, network-level rules are better, both is correct.</p>
<p>After the wizard, turn on TOTP two-factor for the admin account from <strong>Account</strong> &gt; <strong>Security</strong>. There is no excuse not to.</p>
<h2 id="adding-a-real-php-site-with-ssl">Adding a real PHP site with SSL</h2>
<p>The mental model is: every site is an isolated user with a dedicated docroot under <code>/home/&lt;sitename&gt;/htdocs/&lt;domain&gt;/</code>. You do not edit Nginx vhosts by hand, the panel does that for you when you create or modify a site.</p>
<p>In the UI, <strong>Sites</strong> &gt; <strong>Add site</strong>:</p>
<ul>
<li><strong>Site type</strong>: pick the closest match (WordPress, Magento, Symfony, generic PHP, Node.js, static, reverse proxy). The template prefills sensible defaults for that app type.</li>
<li><strong>Domain</strong>: <code>example.com</code> plus any aliases. Wildcard subdomains are supported via DNS-01 if you wire it up to Cloudflare or Route53; otherwise stick to explicit names.</li>
<li><strong>PHP version</strong>: 7.4 through 8.3 in the dropdown. Switchable later.</li>
<li><strong>Site user</strong>: the Linux user that will own this site. Defaults to a sane derivation of the domain.</li>
</ul>
<p>Save, point your A/AAAA records at the panel host, then come back and click <strong>SSL/TLS</strong> &gt; <strong>Let&rsquo;s Encrypt</strong>. The panel does the HTTP-01 dance, drops the cert into <code>/etc/nginx/ssl/</code>, and reloads. Sixty seconds, no manual certbot.</p>
<p>To verify the site is actually live:</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>curl -I https://example.com
</span></span></code></pre></div><p>You should see a <code>200</code> (or your app&rsquo;s redirect) and a <code>server: nginx</code> header. If you see Apache or anything other than Nginx, something is wrong with your DNS, not with CloudPanel.</p>
<h2 id="configuration-patterns-worth-knowing">Configuration patterns worth knowing</h2>
<p>A few patterns we have found useful beyond the defaults.</p>
<h3 id="use-the-per-site-php-settings-not-phpini">Use the per-site PHP settings, not php.ini</h3>
<p>CloudPanel exposes <code>memory_limit</code>, <code>max_execution_time</code>, <code>upload_max_filesize</code>, and friends per site in the UI. Use those. Editing the global <code>/etc/php/8.3/fpm/php.ini</code> works exactly once, until your next package update wipes it.</p>
<h3 id="vhost-custom-snippets-not-direct-edits">Vhost custom snippets, not direct edits</h3>
<p>Every site has a <strong>Vhost</strong> &gt; <strong>Custom snippets</strong> field where you can paste extra Nginx directives. Use that for cache rules, redirects, security headers. Do not edit the panel-generated vhost file directly; the next save through the UI will overwrite your edits.</p>
<h3 id="cron-over-web-cron">Cron over web cron</h3>
<p>For WordPress in particular, disable WP-Cron in <code>wp-config.php</code> (<code>define('DISABLE_WP_CRON', true);</code>) and add a real cron entry in the panel&rsquo;s <strong>Cron Jobs</strong> tab. WP-Cron firing on every page load is one of the more common reasons a small WordPress site feels slow under modest load.</p>
<h3 id="backups-panel--filesystem-both">Backups: panel + filesystem, both</h3>
<p>CloudPanel&rsquo;s S3 backups are good for application files and databases. They are not a substitute for a full-VM backup. We pair the panel&rsquo;s backups with <a href="/en/services/proxmox-backup/">Proxmox Backup Server</a>
 snapshots at the hypervisor level, so a &ldquo;rebuild this VPS from scratch&rdquo; recovery is a single restore instead of a panel-reinstall plus a per-site restore.</p>
<h3 id="trust-the-bot-blocker-more-than-your-gut">Trust the bot blocker more than your gut</h3>
<p>The IP and Bot blocker has a curated list of known scrapers and credential stuffers. Turn it on for any public site and check the access logs a week later. The number of requests it silently drops, mostly stale WordPress brute-force toolkits, is consistently higher than people expect.</p>
<h2 id="cloudpanel-vs-the-alternatives">CloudPanel vs the alternatives</h2>
<p>For completeness:</p>
<ul>
<li><strong>cPanel/WHM</strong>: the industry default, mature, expensive, RHEL-centric. If you bill clients per cPanel account and need feature parity with the rest of the cPanel ecosystem (CageFS, JetBackup, WHMCS integration), it is still the right answer. CloudPanel is not trying to compete here.</li>
<li><strong>Plesk</strong>: similar pricing tier to cPanel, friendlier UI, runs on more OSes. If you are already paying for Plesk and it works, there is no reason to switch.</li>
<li><strong>aaPanel</strong>: free, broad feature set, Chinese-origin with an opaque telemetry story that has made some operators nervous. The UI is dense in a way that CloudPanel deliberately is not.</li>
<li><strong>HestiaCP</strong>: free, fork of VestaCP, ships with mail and DNS, more &ldquo;do everything&rdquo; in scope. Older codebase, more rough edges, but the right pick if you specifically need bundled mail and DNS.</li>
<li><strong>CyberPanel</strong>: free community edition, OpenLiteSpeed-centric, optimized for LiteSpeed cache. Good if you have already committed to the LiteSpeed ecosystem; otherwise Nginx is more portable.</li>
</ul>
<p>CloudPanel ended up being the cleanest fit for &ldquo;I want a modern panel that manages Nginx, PHP and databases for a small number of sites, without giving me features I will not use&rdquo;. Your weights might be different.</p>
<h2 id="where-cloudpanel-is-not-the-right-answer">Where CloudPanel is not the right answer</h2>
<p>Worth being honest about the limits.</p>
<ul>
<li><strong>No mail server.</strong> If you need IMAP/SMTP hosting on the same panel, CloudPanel will not give it to you. You will run a separate mail box (or, more sensibly, route mail through a managed provider).</li>
<li><strong>No authoritative DNS.</strong> The panel does not run BIND/PowerDNS for you. You manage DNS at your registrar, at Cloudflare, or on a separate authoritative service. For our customers this is usually fine because we provide DNS at the <a href="/en/lir-services/">LIR/network layer</a>
 anyway.</li>
<li><strong>No multi-server.</strong> One panel manages one server. There is no concept of a cluster, no shared filesystem story, no failover. If you have more than a handful of servers, you are looking at orchestration tooling, not a panel.</li>
<li><strong>No customer billing.</strong> This is not a hosting-reseller platform. If you need to sell hosting plans with invoicing, you bolt the panel onto a separate billing system.</li>
<li><strong>Self-hosting is still self-hosting.</strong> You patch the OS, you watch the disk fill up, you deal with the occasional MySQL surprise. If your team does not want that, <a href="/en/services/server-administration/">a managed service</a>
 is cheaper in operator hours than free software is in your time.</li>
</ul>
<h2 id="so-should-you-run-it">So, should you run it?</h2>
<p>If you self-host a handful of PHP, Node or Python sites on a VPS or dedicated server, and you have been hand-editing Nginx vhosts long enough to be bored of it, CloudPanel is worth a Sunday afternoon. The install is a single command, the UI gets out of your way, and the per-site Linux user model means a compromised plugin on one site is not a panel-wide incident.</p>
<p>If you are running it in production, put it on a server with a real backup story (Proxmox Backup, snapshots, your call), firewall the management port, and treat the panel as critical infrastructure. The Nginx and PHP configs the panel writes are easy to rebuild; the database of site definitions and users is what you would actually miss.</p>
<p>We run CloudPanel ourselves in front of a few internal sites and recommend it to customers who ask for &ldquo;something between bare Nginx and cPanel&rdquo;. If you want to try it on infrastructure you do not have to build first, our <a href="/en/virtual-servers/vps/">VPS plans</a>
 start small enough to make the experiment cheap, and our <a href="/en/services/server-administration/">server administration service</a>
 covers the install and tuning if you would rather skip the learning curve. If something does not fit, <a href="/en/contact/">get in touch</a>
 and we will tell you honestly whether it is the right tool for the job.</p>
<p>The code is on <a href="https://github.com/cloudpanel-io/cloudpanel-ce" rel="nofollow">GitHub</a>
, the install is one command, and you will know within an hour whether it earns a spot in your stack.</p>
]]></content:encoded><category>Control Panels</category><category>Hosting</category></item><item><title>SafeLine WAF: a serious open-source firewall for your web apps</title><link>https://dreamserver.ro/en/blog/safeline-waf-open-source-self-hosted/</link><pubDate>Sun, 19 Apr 2026 10:00:00 +0300</pubDate><author>Cristian Trusca</author><guid isPermaLink="true">https://dreamserver.ro/en/blog/safeline-waf-open-source-self-hosted/</guid><description>A hands-on look at SafeLine, the self-hosted WAF from Chaitin Tech: semantic detection engine, install on a VPS in five minutes, real configuration examples and the limits to know before you put it in front of production.</description><content:encoded><![CDATA[<p>If you have ever stared at a 5xx graph at 3 AM while a botnet pokes every login form you own, you already know why a Web Application Firewall matters. The honest question is which one to put in front of your stack without paying Cloudflare Enterprise money or fighting ModSecurity rulesets for a weekend.</p>
<p><a href="https://github.com/chaitin/SafeLine" rel="nofollow">SafeLine</a>
, the open-source WAF maintained by <a href="https://www.chaitin.com/" rel="nofollow">Chaitin Tech</a>
, has been quietly building momentum around that exact gap. As of v9.3.4 (released 17 April 2026) it sits at 21k+ stars on GitHub, runs on more than 180,000 installations and is licensed under GPL-3.0. We have been testing it on a VPS in our Bucharest datacenter for a few weeks. This post is the field report.</p>
<h2 id="what-safeline-actually-is">What SafeLine actually is</h2>
<p>Architecturally, SafeLine is a <strong>reverse proxy with a detection engine in front of your origin</strong>. Traffic hits SafeLine on ports 80/443, gets inspected, and either passes through to your upstream application or is challenged, throttled, or blocked. The reverse proxy is built on a hardened Tengine fork (Tengine being Alibaba&rsquo;s nginx derivative), with detection logic implemented as native modules in C++ and Lua. The management plane is a Go service backed by PostgreSQL.</p>
<p>If that sounds a lot like nginx + ModSecurity, the comparison is fair on paper and unfair in practice. The interesting part is what happens between request arrival and the upstream call.</p>
<h3 id="why-the-detection-engine-is-different">Why the detection engine is different</h3>
<p>Most open-source WAFs you have probably touched, ModSecurity with the OWASP Core Rule Set being the canonical example, are fundamentally regex engines. They match patterns in the request and decide. The trade-off is well known: tighten the rules and you start blocking legitimate users, loosen them and attacks slip through. Anyone who has ever paranoia-mode&rsquo;d ModSecurity in front of a WordPress site knows the false-positive tax.</p>
<p>SafeLine takes a different route. It parses the request as a syntactic structure (SQL grammar for query parameters that look database-shaped, JS AST for script content, shell parser for command patterns) and then evaluates whether the parsed result has the <em>semantic shape</em> of an attack. A query with quotes is not automatically suspicious; a query whose parsed form would change SQL execution flow is. The Chaitin team publishes benchmark numbers around 99.4% true-positive accuracy in their balance mode, which is in the range of commercial offerings.</p>
<p>You should still verify on your own traffic, all WAF benchmarks have a strong &ldquo;tested on the dataset we built&rdquo; flavour, but in practice the false-positive rate on our test workloads has been substantially lower than ModSecurity with CRS at paranoia level 2. That alone changes the operational story: a WAF you do not have to constantly whitelist around is a WAF that stays on.</p>
<h2 id="what-you-get-out-of-the-box">What you get out of the box</h2>
<p>The community edition (which is what we are talking about, the Pro edition is announced but not generally available at the time of writing) ships with:</p>
<ul>
<li><strong>Web attack detection</strong> for the OWASP-canonical categories: SQL injection, XSS, command and code injection, XXE, SSRF, path traversal, deserialization patterns.</li>
<li><strong>Rate limiting</strong> per IP, per path, per session, with configurable windows and burst behaviour.</li>
<li><strong>Anti-bot challenge</strong>, a JavaScript proof-of-work that legitimate browsers solve transparently and headless scrapers stumble on.</li>
<li><strong>Authentication challenge</strong>, a separate gate you can put in front of admin panels (think: a captcha-like step before reaching <code>/wp-admin/</code>).</li>
<li><strong>Dynamic HTML/JS encryption</strong>, which mangles client-side identifiers per request so scrapers and credential-stuffing tools cannot easily target form fields.</li>
<li><strong>Geo blocking</strong> by country, useful for sites with no business outside a specific region.</li>
<li><strong>Logging and analytics dashboard</strong>, which is genuinely useful (more on this below).</li>
</ul>
<p>What it does not do: it is not a CDN. It does not cache static assets, does not give you POPs around the world, does not protect against L3/L4 volumetric DDoS at the network edge. SafeLine is a layer-7 application firewall. If you are taking 100 Gbit of UDP reflection, you need network-layer mitigation upstream, the kind we run at AS57050 with <a href="/en/network/">our own RTBH and sFlow setup</a>
, before the traffic ever reaches your VPS.</p>
<h2 id="installing-safeline-on-a-vps">Installing SafeLine on a VPS</h2>
<p>This is the part where most &ldquo;open source WAF&rdquo; projects make you regret the decision. SafeLine genuinely does not. The official one-liner does the right thing on a clean Debian or Ubuntu box.</p>
<p>Minimum sane resources: <strong>2 vCPU, 4 GB RAM, 10 GB free disk</strong>. The script will warn under 5 GB free. SSSE3 CPU instructions are required (any x86 CPU made in the last 15 years has them, but if you are running on something exotic, check <code>/proc/cpuinfo</code>). Both x86_64 and arm64 are supported.</p>
<p>On a fresh server:</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>bash -c <span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>curl -fsSLk https://waf.chaitin.com/release/latest/setup.sh<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span>
</span></span></code></pre></div><p>The script will:</p>
<ol>
<li>Install Docker and the Compose plugin if they are missing.</li>
<li>Drop a docker-compose stack at <code>/data/safeline/</code>.</li>
<li>Pick an unused private subnet (it tries <code>172.22.222.0/24</code>, <code>169.254.222.0/24</code>, <code>192.168.222.0/24</code> in order).</li>
<li>Generate a random 32-char Postgres password.</li>
<li>Pull and start four containers: <code>safeline-pg</code>, <code>safeline-mgt</code>, <code>safeline-detector</code>, <code>safeline-tengine</code>.</li>
</ol>
<p>Once it finishes, the management UI is at <code>https://&lt;your-server-ip&gt;:9443/</code> with a self-signed certificate. To grab the initial admin credentials:</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 exec safeline-mgt resetadmin
</span></span></code></pre></div><p>That command prints a one-time username and password you can use for the first login. Change the password immediately after you are in. While you are at it, restrict port 9443 with a firewall rule, the management plane should not be exposed to the internet:</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 from YOUR_OFFICE_IP to any port <span style="color:#ae81ff">9443</span>
</span></span><span style="display:flex;"><span>ufw deny <span style="color:#ae81ff">9443</span>
</span></span></code></pre></div><p>If you are running this on a <a href="/en/virtual-servers/vps/">DreamServer VPS</a>
, the same rule belongs in your provider&rsquo;s network firewall too, do not rely on host-level rules alone for management interfaces.</p>
<h2 id="putting-a-real-site-behind-it">Putting a real site behind it</h2>
<p>Adding a protected site is straightforward but the mental model takes a minute to click. SafeLine becomes the public-facing endpoint; your real application becomes an internal upstream that only SafeLine talks to.</p>
<p>In the management UI, <strong>Sites</strong> &gt; <strong>Add site</strong>:</p>
<ul>
<li><strong>Domain</strong>: <code>example.com</code> (and any aliases you serve).</li>
<li><strong>Port</strong>: <code>80</code> for plain HTTP, <code>443</code> for HTTPS, both if you want SafeLine to do the redirect.</li>
<li><strong>Upstream</strong>: the IP and port of your origin, for example <code>10.0.0.5:8080</code>. If your origin lives on the same box, use the docker bridge gateway (typically <code>172.17.0.1</code> or whatever the script picked) and the port your application listens on.</li>
<li><strong>TLS certificate</strong>: paste a cert and key, or upload a Let&rsquo;s Encrypt-issued one. SafeLine does not currently auto-issue certificates, you bring your own.</li>
</ul>
<p>Save, then point your domain&rsquo;s A/AAAA records at the SafeLine host. Within a few seconds the site shows up under <strong>Detection logs</strong> and you can watch live traffic flow through.</p>
<p>The first thing to verify is that SafeLine is genuinely inline. Send a deliberately bad request:</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>curl -k <span style="color:#e6db74">&#34;https://example.com/?id=1&#39; OR &#39;1&#39;=&#39;1&#34;</span>
</span></span></code></pre></div><p>You should get a SafeLine block page (HTML body, HTTP 403 by default) and a corresponding entry in the detection log. If the request goes through to your application, your DNS or upstream config is wrong, fix that before you trust anything else.</p>
<h2 id="configuration-patterns-worth-knowing">Configuration patterns worth knowing</h2>
<p>A few patterns we have found genuinely useful beyond the defaults.</p>
<h3 id="whitelisting-health-checks">Whitelisting health checks</h3>
<p>If your monitoring system pings <code>/health</code> from a known IP, do not let SafeLine score those requests. Add an <strong>Allow rule</strong> at the top of the policy chain matching source IP and path, with action &ldquo;skip detection&rdquo;. The point is not to save CPU, it is to keep your detection logs uncluttered with traffic you trust.</p>
<h3 id="rate-limit-before-block">Rate limit before block</h3>
<p>When you turn on rate limiting for a login endpoint, prefer <strong>challenge</strong> over <strong>block</strong> for the first threshold. A bot that runs into a challenge silently dies; a human who fat-fingered their password three times in a row gets through. Reserve the block action for the second threshold (say, 30 requests per 5 minutes from a single IP).</p>
<h3 id="anti-bot-for-the-entire-site-not-just-login">Anti-bot for the entire site, not just login</h3>
<p>Counter-intuitive but useful: turn on the JS challenge sitewide for low-value paths (the homepage, the blog) on a small percentage of traffic. The bots that fail the challenge there are the same ones that would later try your login form. You learn a lot about what is hitting you before any sensitive endpoint sees the traffic.</p>
<h3 id="authentication-challenge-for-admin-paths">Authentication challenge for admin paths</h3>
<p>For anything matching <code>/admin*</code>, <code>/wp-admin*</code>, <code>/phpmyadmin*</code>, add an authentication challenge layer. SafeLine implements this as an extra gate that requires solving a CAPTCHA-style challenge before the request reaches your application. It does not replace your application&rsquo;s auth, it just stops automated tools from ever knocking on the door.</p>
<h3 id="read-the-logs">Read the logs</h3>
<p>The dashboard at <strong>Statistics</strong> &gt; <strong>Detection logs</strong> shows every blocked request with the parsed reason: which engine triggered (semantic SQLi, regex XSS, anti-bot), the request body, the score. Spend an hour going through it the day after you turn SafeLine on. You will find that most of your &ldquo;weird traffic&rdquo; looks the same: a handful of mass-scanning toolkits hitting the same WordPress admin paths and the same exposed <code>.env</code> URLs.</p>
<h2 id="where-safeline-is-not-the-right-answer">Where SafeLine is not the right answer</h2>
<p>It is worth being honest about the limits.</p>
<ul>
<li><strong>Not a CDN.</strong> No caching, no edge POPs. If your performance story depends on edge proximity, you still need a CDN in front of (or beside) SafeLine.</li>
<li><strong>Not for sub-millisecond paths.</strong> Every request goes through detection. Median overhead in our tests was 1 to 3 ms on warm caches, which is fine for almost any web app, but if you are running an HFT API, this is not your tool.</li>
<li><strong>Pro features are not all open.</strong> Some of the more sophisticated dynamic-protection features and the multi-node clustering are clearly aimed at the upcoming Pro edition. The community edition is generous, but if you are protecting a fleet of dozens of sites with HA requirements, plan for that.</li>
<li><strong>Self-hosting is not free.</strong> You are running another stateful service that needs backups, OS patching, and the occasional Postgres babysitting. If your team does not want that, a managed WAF will be cheaper in operator hours.</li>
</ul>
<h2 id="alternatives-we-considered">Alternatives we considered</h2>
<p>For completeness: we also looked at <a href="https://github.com/bunkerity/bunkerweb" rel="nofollow">BunkerWeb</a>
 (nginx-based, very approachable, weaker semantic detection), <a href="https://coraza.io/" rel="nofollow">Coraza</a>
 (a Go-native ModSecurity reimplementation, great if you want to embed WAF logic directly in a service mesh), and the OWASP CRS on a stock nginx with <code>ngx_security_module</code> (battle-tested, infinitely tunable, false positives are your hobby now).</p>
<p>SafeLine ended up being the cleanest fit for &ldquo;I want a real WAF in front of a small fleet of self-hosted sites without becoming a WAF specialist&rdquo;. Your weights might be different.</p>
<h2 id="so-should-you-run-it">So, should you run it?</h2>
<p>If you self-host PHP, Node, Python or Go web applications on a VPS or dedicated server and you have been meaning to &ldquo;do something about security headers and bot traffic&rdquo;, SafeLine is worth a Sunday afternoon. The install is genuinely fast, the detection works without you fighting it, and the dashboard tells you something true about your traffic.</p>
<p>If you are running it in production, put it on a server with a real backup story (Proxmox Backup, snapshots, your call) and treat the management plane as critical infrastructure. The detection containers can be rebuilt in a minute; the configuration in Postgres is what you would actually miss.</p>
<p>We run SafeLine ourselves in front of a couple of internal services and recommend it to customers who ask. If you want to try it on infrastructure you do not have to build first, our <a href="/en/virtual-servers/vps/">VPS plans</a>
 start at small enough sizes to make the experiment cheap, and our <a href="/en/services/server-administration/">server administration service</a>
 covers the install and tuning if you would rather skip the learning curve.</p>
<p>Either way, kicking the tires on SafeLine is a better way to spend an evening than reading another &ldquo;top 10 WAF&rdquo; listicle. The code is on GitHub, the install is one command, and you will know within an hour whether it earns a spot in your stack.</p>
]]></content:encoded><category>WAF</category><category>Security</category></item><item><title>Introducing the DreamServer Blog</title><link>https://dreamserver.ro/en/blog/introducing-the-dreamserver-blog/</link><pubDate>Sat, 18 Apr 2026 18:00:00 +0300</pubDate><author>Cristian Trusca</author><guid isPermaLink="true">https://dreamserver.ro/en/blog/introducing-the-dreamserver-blog/</guid><description>We are starting a blog to publish promotions, campaigns, tutorials, recommendations and technical articles about the hosting services we run - dedicated servers, VDS, VPS and everything around them.</description><content:encoded><![CDATA[<p>Welcome to the DreamServer blog.</p>
<p>This is where we will publish <strong>promotions, campaigns, tutorials, recommendations and technical articles</strong> about the hosting services we run. If it helps a customer configure, deploy or troubleshoot a dedicated server, VDS or VPS, we want to write it down here.</p>
<h2 id="what-to-expect">What to expect</h2>
<ul>
<li><strong>Promotions and campaigns</strong> - when we launch a deal, drop a price, bundle a service or open a new configuration, you will read it here first.</li>
<li><strong>Tutorials</strong> - step-by-step guides with commands you can paste and configuration files you can reuse, focused on getting your servers up and running the way you actually want them.</li>
<li><strong>Recommendations</strong> - platforms, control panels, operating systems and applications that work well on our infrastructure, and how to pick between the usual alternatives.</li>
<li><strong>Technical articles</strong> - dedicated server setup, VDS and VPS management, Linux administration, networking, storage, backups and security hardening - the same topics that come up in our support tickets, written up once so you can find the answer faster next time.</li>
</ul>
<h2 id="how-we-write">How we write</h2>
<p>Honest, source-linked, no fluff. When something needs proof we cite the documentation, the RFC or the vendor knowledge base. When we make a mistake we correct it inline with a dated note.</p>
<h2 id="stay-in-touch">Stay in touch</h2>
<ul>
<li><strong>RSS</strong> - subscribe in your feed reader at <a href="/en/blog/index.xml">/en/blog/index.xml</a>
.</li>
<li><strong>Email</strong> - <a href="mailto:contact@dreamserver.ro">contact@dreamserver.ro</a>
 for sales, <a href="mailto:noc@dreamserver.ro">noc@dreamserver.ro</a>
 for network operations, or open a ticket from the <a href="/client/">client area</a>
.</li>
<li><strong>Services</strong> - browse <a href="/en/dedicated-servers/bladeservers/">dedicated servers</a>
, <a href="/en/virtual-servers/vps/">VPS</a>
 and <a href="/en/virtual-servers/vds/">VDS</a>
.</li>
</ul>
<p>Thanks for stopping by. More posts coming soon.</p>
]]></content:encoded><category>Announcements</category></item></channel></rss>