Add post: Replacing RDPGuard With IPBan (EN + ZH, og+banner)
Deploy / build (push) Successful in 22s
Deploy / build (push) Successful in 22s
Case study of migrating from paid RDPGuard 7.8.7 to open-source IPBan 4.1.0, covering the three undocumented traps: the uninstaller that would have silently unbanned 12 active attackers, the non-existent --install-service flag in v4.1.0, and ExpireTime vs BanTime. Also fixes an og-gen defect: the tag chip hardcoded KIND='DevOps', so every non-devops post carried a wrong label (e.g. "case-studies · DevOps" on the STT card). KIND now derives from the post category, and all 29 existing OG images are regenerated with correct badges.
This commit is contained in:
@@ -565,6 +565,26 @@ BANNERS['self-hosted-speech-to-text-api'] = {
|
||||
],
|
||||
};
|
||||
|
||||
BANNERS['replacing-rdpguard-with-ipban'] = {
|
||||
titlebar: 'root@win11 — ipban service',
|
||||
lines: [
|
||||
{ t: 'cmd', text: 'sc.exe qc IPBAN' },
|
||||
{ t: 'ok', text: 'START_TYPE : 2 AUTO_START ✓' },
|
||||
{ t: 'dim', text: 'RdpGuard 7.8.7 — paid, closed, 3 versions behind' },
|
||||
{ t: 'err', text: 'uninstall → rule rdpguard-… deleted → 12 bans LOST' },
|
||||
{ t: 'cmd', text: 'ban.txt → IPBan import (12 ipv4)' },
|
||||
{ t: 'ok', text: 'Updating firewall with 12 entries...' },
|
||||
{ t: 'err', text: "ipban --install-service → 'Unrecognized command'" },
|
||||
{ t: 'hl', text: '16 attackers blocked · zero protection gap' },
|
||||
],
|
||||
flow: [
|
||||
{ n: '1', label: 'export bans' },
|
||||
{ n: '2', label: 'sc.exe install' },
|
||||
{ n: '3', label: 'whitelist LAN' },
|
||||
{ n: '4', label: '16 blocked ✓' },
|
||||
],
|
||||
};
|
||||
|
||||
// ---------- read frontmatter ----------
|
||||
const postPath = join(ROOT, 'src', 'content', 'posts', `${slug}.md`);
|
||||
let category = 'devops';
|
||||
|
||||
@@ -176,6 +176,11 @@ TERMINALS['self-hosted-speech-to-text-api'] = `
|
||||
<div class="line"><span class="prompt"> </span><span class="err">connect ETIMEDOUT 192.168.1.123:20129 — bound to 127.0.0.1 only</span></div>
|
||||
<div class="line"><span class="prompt">$</span><span class="cmd">bind 0.0.0.0 · firewall LocalSubnet · n8n key gate</span><span class="fix">→ 130 wpm ✓</span></div>`;
|
||||
|
||||
TERMINALS['replacing-rdpguard-with-ipban'] = `
|
||||
<div class="line"><span class="prompt">$</span><span class="cmd">ipban --install-service</span></div>
|
||||
<div class="line"><span class="prompt"> </span><span class="err">Unrecognized command or argument '--install-service'</span></div>
|
||||
<div class="line"><span class="prompt">$</span><span class="cmd">sc.exe create IPBAN type= own start= auto binPath= ...</span><span class="fix">→ AUTO_START ✓</span></div>`;
|
||||
|
||||
const DEFAULT_TERMINAL = `
|
||||
<div class="line"><span class="prompt">$</span><span class="cmd">engineering · devops · self-hosting</span></div>
|
||||
<div class="line"><span class="prompt"> </span><span class="fix">read the full post →</span></div>`;
|
||||
@@ -227,12 +232,25 @@ const tagsHtml = tags.map((t) => `<span>#${esc(t)}</span>`).join('');
|
||||
|
||||
const logoPath = 'file:///' + join(ROOT, 'public', 'logo-square.png').replace(/\\/g, '/');
|
||||
|
||||
// the tag chip shows "<category> · <kind>"; kind is a human label for the section.
|
||||
// Were KIND to be hardcoded, every non-devops post would carry a wrong label.
|
||||
const KIND_BY_CATEGORY = {
|
||||
engineering: 'Engineering',
|
||||
devops: 'DevOps',
|
||||
ai: 'AI',
|
||||
web3: 'Web3',
|
||||
tutorials: 'Tutorials',
|
||||
'case-studies': 'Case Study',
|
||||
notes: 'Notes',
|
||||
};
|
||||
const kind = KIND_BY_CATEGORY[category] || category;
|
||||
|
||||
let tpl = readFileSync(join(__dirname, 'template.html'), 'utf8');
|
||||
tpl = tpl
|
||||
.replace('{{TITLE_SIZE}}', String(titleSize))
|
||||
.replace('{{LOGO_PATH}}', logoPath)
|
||||
.replace('{{CATEGORY}}', esc(category))
|
||||
.replace('{{KIND}}', 'DevOps')
|
||||
.replace('{{CATEGORY}}', esc(category === kind.toLowerCase() ? category : kind))
|
||||
.replace('{{KIND}}', '')
|
||||
.replace('{{TITLE_HTML}}', titleHtml)
|
||||
.replace('{{TERMINAL_HTML}}', terminalHtml)
|
||||
.replace('{{TAGS_HTML}}', tagsHtml);
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<div class="brand">Mr Hoelee <span class="domain">· blog.hoelee.com</span></div>
|
||||
</div>
|
||||
|
||||
<div class="tag"><span class="dot"></span>{{CATEGORY}} · {{KIND}}</div>
|
||||
<div class="tag"><span class="dot"></span>{{CATEGORY}}</div>
|
||||
|
||||
<div class="title">{{TITLE_HTML}}</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user