<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>apiscp — LowEndSpirit</title>
        <link>https://lowendspirit.com/index.php?p=/</link>
        <pubDate>Sat, 06 Jun 2026 03:36:28 +0000</pubDate>
        <language>en</language>
            <description>apiscp — LowEndSpirit</description>
    <atom:link href="https://lowendspirit.com/index.php?p=/discussions/tagged/apiscp/feed.rss" rel="self" type="application/rss+xml"/>
    <item>
        <title>Reinventing the ApisCP WAF</title>
        <link>https://lowendspirit.com/index.php?p=/discussion/9700/reinventing-the-apiscp-waf</link>
        <pubDate>Sat, 21 Jun 2025 01:34:00 +0000</pubDate>
        <category>Technical</category>
        <dc:creator>nem</dc:creator>
        <guid isPermaLink="false">9700@/index.php?p=/discussions</guid>
        <description><![CDATA[<p>Long time since I've posted, and this one's a fun one. I'd like to pick your brains.</p>

<p>ApisCP based its original WAF on <a rel="nofollow" href="https://github.com/jzdziarski/mod_evasive">mod_evasive</a>. It's a simple counter that tracks inbound requests per process. Evasive is easily circumvented if keep-alives are disabled or the client explicitly closes a connection. A "200 OK" CSS request is just as significant as a 404 that flows through to a dispatcher, like WordPress, and serves out a dynamic - fully loaded - WordPress site. As of late, I've seen changes in bot request patterns that makes this solution inadequate.</p>

<p><a rel="nofollow" href="https://forums.apiscp.com/t/mod-shield-next-gen-http-dos-protection-early-testing/859">mod_shield</a> rethinks this approach. It's a full rewrite of Evasive.</p>

<h3>Features</h3>

<ul>
<li><p><strong>Hits are shared across processes</strong></p>

<ul>
<li>Records are fixed at 176 bytes allowing for 3k unique hits over a 2 minute window at 512 KB</li>
<li>Autoexpire, autoeviction w/ LRU policy</li>
<li>Cache resizable</li>
<li>Can be stored to <a rel="nofollow" href="https://httpd.apache.org/docs/2.4/mod/mod_socache_memcache.html">memcached</a> or <a rel="nofollow" href="https://httpd.apache.org/docs/trunk/mod/mod_socache_redis.html">Redis</a> providers to share hits across servers</li>
</ul></li>
<li><p><strong>HTTP statuses and page loads are scorable</strong></p>

<ul>
<li>Status points may penalize 404s allowing for faster blacklisting of random probes</li>
<li>Works with custom HTTP status codes, e.g. returning 499 from backend could score 10000000 resulting in immediate block.</li>
<li>Fast loads remove decrease points while slow loads may add to point total</li>
<li>Complex scoring is possible, e.g. 1s &lt; load &lt; 2s = 5 pts, 2s &lt;= x &lt; 10s = 7 pts, load &gt;= 10s = 10 pts</li>
<li>Addresses DoS situations where bots hit database-heavy requests, like search</li>
</ul></li>
<li><p><strong>Blocks counted per event</strong></p>

<ul>
<li>For each block application, the duration may be longer than previously applied</li>
<li>Counted for life of system service process</li>
<li>Both <a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.3">RFC7231</a> "Retry-After" + <a rel="nofollow" href="https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/">RateLimit</a> headers are sent to guide a compliant client</li>
</ul></li>
<li><p><strong>Proxy support</strong></p>

<ul>
<li>Pierces Cloudflare's tunnel in which the edge address cannot be blocked without disrupting Cloudflare usage</li>
<li>Works with any other downstream proxy as defined using <a rel="nofollow" href="https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html">mod_remoteip</a></li>
</ul></li>
<li><p><strong>Fast, Minimal Overhead</strong></p>

<ul>
<li>Occurs early in processing axis, ~13% faster than mod_evasive <img src="https://lowendspirit.com/plugins/emojiextender/emoji/twitter/blush.png" title=":blush:" alt=":blush:" height="18" /></li>
<li>Requires 3 separate memory chunks for per-site, per-page, and active-blocks.</li>
</ul></li>
<li><p><strong>Improved logging</strong></p>

<ul>
<li><p>Status handler executive summary<br />
<img src="https://futz.net/5f7332fb641d327b18f97446cc3f2ec6b116a54b.png" alt="epsilon-status-handler|669x500" /></p></li>
<li><p>Diagnostics, get a better idea of how things score and why. Doubles as a telemetry module without blocking.</p></li>
</ul></li>
</ul>

<pre><code>    [Fri Jun 20 17:27:18.044384 2025] [shield:info] [pid 2241388:tid 2241454] [client 35.196.24.130:58136] Request status 301 flagged with score 25
    [Fri Jun 20 17:27:18.626983 2025] [shield:info] [pid 2241388:tid 2241452] [client 35.196.24.130:58136] Request status 404 flagged with score 50
    [Fri Jun 20 17:27:22.265283 2025] [shield:info] [pid 2241388:tid 2241455] [client 35.196.24.130:60824] blocking period started for IP: 35.196.24.130 (expiry: 1750541242264768)
    [Fri Jun 20 17:31:46.372136 2025] [shield:info] [pid 2246513:tid 2246541] [client 103.205.211.78:47894] Request status 302 flagged with score 25
    [Fri Jun 20 17:31:47.559982 2025] [shield:info] [pid 2246566:tid 2246607] [client 103.205.211.78:40392] Request status 301 flagged with score 25, referer: http://x.com/xmlrpc.php
    [Fri Jun 20 17:31:48.719776 2025] [shield:info] [pid 2246513:tid 2246539] [client 103.205.211.78:40530] Request status 404 flagged with score 50, referer: https://x.com/xmlrpc.php
    [Fri Jun 20 17:32:03.948083 2025] [shield:info] [pid 2241389:tid 2241464] [client 138.117.18.67:52430] Request status 404 flagged with score 50
    [Fri Jun 20 17:39:03.452497 2025] [shield:info] [pid 2246566:tid 2246607] [client 193.203.10.164:32349] Request status 404 flagged with score 50
    [Fri Jun 20 17:41:51.467151 2025] [shield:info] [pid 2246513:tid 2246540] [client 177.10.34.242:13784] Request status 404 flagged with score 50
    [Fri Jun 20 17:43:28.093184 2025] [shield:info] [pid 2246513:tid 2246535] [client 177.204.39.240:58988] Request status 404 flagged with score 50
    [Fri Jun 20 18:18:46.574231 2025] [shield:notice] [pid 2241388:tid 2241446] [client 114.119.128.58:36383] Request round-trip 1069 ms exceeds limit 1000 ms. Scoring 1 /dsc_hdr-copy/ (proto: HTTP/1.1), referer: https://x.com/dsc_hdr-copy/
</code></pre>

<hr />

<h3>Ideas so far</h3>

<ul>
<li><p><strong>GeoIP blocking</strong></p>

<ul>
<li>I'm not a fan, works contrary that this firewall works adaptively based upon malicious traffic. Bad actors should be blocked organically.</li>
</ul></li>
<li><p><strong>JS challenge to unblock</strong></p>

<ul>
<li>Will be added in a later release. For now, blocks can be done within ApisCP's panel.</li>
</ul></li>
</ul>

<p>What else would you like to see added?</p>

<p>Running ApisCP already? You can swap to Shield today: <br />
<code>dnf --enablerepo=apnscp-testing update -y mod_shield</code></p>

<p>Module is RC stage. It'll be part of the next major ApisCP release <img src="https://lowendspirit.com/plugins/emojiextender/emoji/twitter/+1.png" title=":+1:" alt=":+1:" height="18" /></p>
]]>
        </description>
    </item>
    <item>
        <title>ApisCP 18 year anniversary sale! And updates!</title>
        <link>https://lowendspirit.com/index.php?p=/discussion/2316/apiscp-18-year-anniversary-sale-and-updates</link>
        <pubDate>Thu, 24 Dec 2020 18:04:08 +0000</pubDate>
        <category>Offers</category>
        <dc:creator>nem</dc:creator>
        <guid isPermaLink="false">2316@/index.php?p=/discussions</guid>
        <description><![CDATA[<p><a rel="nofollow" href="https://apiscp.com/">ApisCP</a> turns 18 on <a rel="nofollow" href="https://old.apisnetworks.com/apnscp.php">December 26th</a>, which is a great milestone as the codebase can now buy fireworks, purchase spray paint, and get tattoos without parental consent.</p>

<p>To kick the celebration off and help everyone move past 2020, I'm bringing back the popular 50% off discount (coupon code:  <strong>ANNIVERSARY</strong> ) valid on all <a rel="nofollow" href="https://my.apiscp.com/">lifetime licenses</a>. This discount is valid until January 1 or reseller support officially launches, whichever happens later.</p>

<p><strong>Pro</strong>  licenses (no domain limit) are $249,  <strong>Startup</strong>  (30 domain limit) is $79, and  <strong>Mini</strong>  (10 domain limit) is $49. These are all one-time costs. Licenses may be revoked and reissued as needed via the licensing portal, <a rel="nofollow" href="https://my.apiscp.com/">my.apiscp.com</a>.</p>

<p>It's an excellent excuse to move past cPanel's price creep and myriad third-party licenses with single one-time license for all. Plus, ApisCP handles <a rel="nofollow" href="https://docs.apiscp.com/admin/Migrations%20-%20cPanel/">cPanel migrations</a> with excellent fidelity.</p>

<hr />

<p>On to interesting developments over the last month.</p>

<h1>CentOS Stream</h1>

<p>As we know by now  <strong>CentOS is flipping upstream</strong>  to RHEL instead of downstream. I've shared <a rel="nofollow" href="https://hq.apiscp.com/future-of-centos-in-apiscp/">my thoughts</a> on this and logged a few days of build hours on <a rel="nofollow" href="https://api.ara.apiscp.com/?label=c8s">E2E tests</a>. Unless something catastrophic happens by July, ApisCP will continue to focus on the Red Hat/CentOS ecosystem to produce the maximum integration afforded by this distro. Having faster release cycles for crucial software like systemd allows me to build more cohesive platforms with less overhead. It's a win.</p>

<h1>Reseller support</h1>

<p>Technology helps accomplish tasks with better precision.  <strong>Reseller system</strong> , which is next to launch now that the <a rel="nofollow" href="https://docs.apiscp.com/admin/Panel%20proxy">panel proxy</a> is done, uses project quotas and cgroup subtrees to allow overselling with online resource enforcement. Resellers can allocate beyond their package allowances to sites, but the sum of all resources can never exceed the total on the reseller; unlike prevailing reseller systems this is enforced realtime by the OS.</p>

<p>Given the ambitious approach to reseller support, ApisCP will only support resellers on  <strong>CentOS 8 or Stream with xfs</strong>  filesystems. ext4 supports project quotas on 4.x kernels; however, I've not explored it to the same extent as xfs project/group/user quotas.</p>

<h1>Panel proxy</h1>

<p>Lastly,  <strong>panel proxy</strong>  as touched on earlier allows one to run multiple ApisCP nodes from a single login portal. It's been part of the magic behind Hostineer for the last 5 years and now it's cleaned up for a wider audience. Several great minds in the <a rel="nofollow" href="https://discord.gg/wDBTz6V">ApisCP Discord</a> have helped move this along. It's as simple as a couple <a rel="nofollow" href="https://docs.apiscp.com/admin/Panel%20proxy/#configuration">configuration settings</a> on each node. Panel proxy is broken down into 3 separate components to enhance security. Each component can be run off a free DNS-only license issued via <a rel="nofollow" href="https://my.apiscp.com/">my.apiscp.com</a>. After reseller is implemented, I'll expand upon this to allow admin to jump locations from a single login.</p>

<p><img src="https://docs.apiscp.com/assets/img/proxy-server-topology-basic.e065c483.svg" alt="" /></p>
]]>
        </description>
    </item>
   </channel>
</rss>
