initial echo project website (rust + axum + askama)
This commit is contained in:
commit
899040a319
11 changed files with 1480 additions and 0 deletions
40
templates/base.html
Normal file
40
templates/base.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}echoIRCd{% endblock %}</title>
|
||||
<meta name="description" content="echoIRCd — a modern IRC network built from scratch in Rust: TLS 1.3, full IRCv3, SASL, and native services.">
|
||||
<meta property="og:title" content="echoIRCd">
|
||||
<meta property="og:description" content="A modern IRC network, built from scratch in Rust.">
|
||||
<meta property="og:type" content="website">
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="nav">
|
||||
<a class="brand" href="/">echo<span class="dot">IRCd</span></a>
|
||||
<nav class="navlinks">
|
||||
<a href="/"{% if active == "home" %} class="on"{% endif %}>Home</a>
|
||||
<a href="/features"{% if active == "features" %} class="on"{% endif %}>Features</a>
|
||||
<a href="/connect"{% if active == "connect" %} class="on"{% endif %}>Connect</a>
|
||||
<a href="https://git.devtronic.pro/echo/echoIRCd" class="ext">Source ↗</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer class="foot">
|
||||
<div class="foot-in">
|
||||
<div>echoIRCd — native Rust IRC daemon & services · <span class="mono">#![forbid(unsafe_code)]</span></div>
|
||||
<div class="foot-links">
|
||||
<a href="https://git.devtronic.pro/echo/echoIRCd">echoIRCd</a>
|
||||
<a href="https://git.devtronic.pro/echo/echo">services</a>
|
||||
<a href="https://git.devtronic.pro/echo/website">website</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
58
templates/connect.html
Normal file
58
templates/connect.html
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Connect — echoIRCd{% endblock %}
|
||||
{% block content %}
|
||||
<section class="page-head">
|
||||
<h1>Connect</h1>
|
||||
<p class="lede">Point any IRC client at the network — or open it in your browser.</p>
|
||||
</section>
|
||||
|
||||
<section class="wrap">
|
||||
<table class="detail">
|
||||
<tr><th>Server</th><td class="mono">irc.echoircd.org</td></tr>
|
||||
<tr><th>TLS (recommended)</th><td class="mono">6697</td></tr>
|
||||
<tr><th>Plaintext</th><td class="mono">6667</td></tr>
|
||||
<tr><th>Network</th><td class="mono">echoiRCd</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="webchat">
|
||||
<span>Prefer the browser?</span>
|
||||
<a class="btn" href="https://orbit.devtronic.pro">Open the web client ↗</a>
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">Client quick-start</h2>
|
||||
<div class="block">
|
||||
<p>Most clients accept a one-line server string. The leading <span class="mono">+</span> on the
|
||||
port means TLS.</p>
|
||||
<pre class="code">/server irc.echoircd.org +6697
|
||||
/join #echoircd</pre>
|
||||
<table class="detail">
|
||||
<tr><th>HexChat</th><td class="mono">Network list → Add → irc.echoircd.org/+6697 → tick "Use SSL"</td></tr>
|
||||
<tr><th>WeeChat</th><td class="mono">/server add echo irc.echoircd.org/6697 -tls</td></tr>
|
||||
<tr><th>irssi</th><td class="mono">/connect -tls irc.echoircd.org 6697</td></tr>
|
||||
<tr><th>mIRC</th><td class="mono">/server irc.echoircd.org +6697</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">Register your nick</h2>
|
||||
<div class="block">
|
||||
<p>Registering lets you keep your nickname, found channels, and log in with SASL.</p>
|
||||
<pre class="code">/msg NickServ REGISTER <password> <email>
|
||||
/msg NickServ IDENTIFY <password></pre>
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">Log in with a key (ECDSA)</h2>
|
||||
<div class="block">
|
||||
<p>Instead of a password you can authenticate with a NIST P-256 key. The server sends a
|
||||
challenge, your client signs it, and the signature is checked against the key on your
|
||||
account — nothing secret crosses the wire.</p>
|
||||
<pre class="code"># generate a key and read its public half
|
||||
ecdsatool keygen ~/.ecdsa.pem
|
||||
ecdsatool pubkey ~/.ecdsa.pem
|
||||
|
||||
# store it on your account, then use ECDSA-NIST256P-CHALLENGE for SASL
|
||||
/msg NickServ SET PUBKEY <printed-public-key></pre>
|
||||
<p class="hint">Point your client's SASL settings at the same key file and pick the
|
||||
<span class="mono">ECDSA-NIST256P-CHALLENGE</span> mechanism.</p>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
85
templates/features.html
Normal file
85
templates/features.html
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Features — echoIRCd{% endblock %}
|
||||
{% block content %}
|
||||
<section class="page-head">
|
||||
<h1>Features</h1>
|
||||
<p class="lede">Everything below is original, native Rust — the InspIRCd protocol and API are a
|
||||
reference for wire compatibility, never a source of code.</p>
|
||||
</section>
|
||||
|
||||
<section class="wrap prose">
|
||||
<div class="block">
|
||||
<h2>The daemon</h2>
|
||||
<ul>
|
||||
<li><strong>Safe by construction</strong> — <span class="mono">#![forbid(unsafe_code)]</span> across the whole tree, enforced in CI.</li>
|
||||
<li><strong>Reactor core</strong> — a single core thread with a mio/epoll reactor pool; zero-copy broadcast lines and parallel large-channel fan-out.</li>
|
||||
<li><strong>Full mode set</strong> — every standard channel and user mode, host cloaking, and custom prefixes.</li>
|
||||
<li><strong>Operators</strong> — an InspIRCd-style privilege model: command grants, named privileges, and a usermode/chanmode allow-list per oper type.</li>
|
||||
<li><strong>Edge</strong> — connection classes, per-class flood / fakelag, RFC 1413 ident, and PROXY protocol v1/v2 (with TLS TLVs).</li>
|
||||
<li><strong>Observability</strong> — a metrics endpoint, structured JSON logging, and native syslog.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<h2>Transport & TLS</h2>
|
||||
<ul>
|
||||
<li><strong>6697</strong> direct TLS, <strong>7799</strong> WebSocket-over-TLS (wss), <strong>6667</strong> plaintext.</li>
|
||||
<li>Two interchangeable backends — <strong>OpenSSL</strong> and <strong>rustls</strong> — both serving TLS 1.3.</li>
|
||||
<li>With OpenSSL 3.5 the handshake negotiates post-quantum <span class="mono">X25519MLKEM768</span> key exchange.</li>
|
||||
<li>Per-host <strong>SNI</strong> certificates, reloaded live on rehash.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<h2>IRCv3</h2>
|
||||
<p>Capabilities advertised to clients:</p>
|
||||
<div class="chips">
|
||||
<span>server-time</span><span>message-tags</span><span>account-tag</span><span>account-notify</span>
|
||||
<span>extended-join</span><span>chghost</span><span>multi-prefix</span><span>away-notify</span>
|
||||
<span>invite-notify</span><span>setname</span><span>echo-message</span><span>userhost-in-names</span>
|
||||
<span>batch</span><span>labeled-response</span><span>standard-replies</span><span>extended-monitor</span>
|
||||
<span>draft/chathistory</span><span>draft/event-playback</span><span>draft/message-redaction</span>
|
||||
<span>draft/multiline</span><span>draft/metadata-2</span><span>draft/read-marker</span>
|
||||
<span>draft/webpush</span><span>draft/account-registration</span><span>sts</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<h2>SASL</h2>
|
||||
<ul>
|
||||
<li><strong>PLAIN</strong> — classic username/password.</li>
|
||||
<li><strong>EXTERNAL</strong> — authenticate by TLS client-certificate fingerprint.</li>
|
||||
<li><strong>SCRAM-SHA-256</strong> — challenge/response, no password on the wire.</li>
|
||||
<li><strong>ECDSA-NIST256P-CHALLENGE</strong> — sign a server challenge with a NIST P-256 key; the private key never leaves your client.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<h2>Services</h2>
|
||||
<ul>
|
||||
<li><strong>NickServ</strong> — registration, grouped nicks, certificates, public keys, vhosts, profile metadata.</li>
|
||||
<li><strong>ChanServ</strong> — founder/access, auto-op, akick, topic and mode locks.</li>
|
||||
<li><strong>OperServ / MemoServ / more</strong> — network administration, offline messaging, and games.</li>
|
||||
<li><strong>Event-sourced</strong> — every change is an appended event, replayed to rebuild state.</li>
|
||||
<li><strong>SASL over S2S</strong> — the daemon relays mechanisms mechanism-agnostically; the services layer holds the credentials.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="block">
|
||||
<h2>Security</h2>
|
||||
<ul>
|
||||
<li>A native anti-abuse engine in the core — not a bolt-on module.</li>
|
||||
<li>Connection-flood and nick-flood detection, mass-join screening.</li>
|
||||
<li>Behavioral and content heuristics with computed-pattern mining.</li>
|
||||
<li>A DEFCON state machine and policy, plus DNSBL / MX-blacklist screening via a native async resolver.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="connect-strip">
|
||||
<div class="cs-in">
|
||||
<div><h2>Ready?</h2><p>See how to connect and register.</p></div>
|
||||
<a class="btn primary" href="/connect">Connect & register</a>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
93
templates/index.html
Normal file
93
templates/index.html
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}echoIRCd — a modern IRC network in Rust{% endblock %}
|
||||
{% block content %}
|
||||
<section class="hero">
|
||||
<div class="badge-row">
|
||||
<span class="badge">100% safe Rust</span>
|
||||
<span class="badge">TLS 1.3 · post-quantum</span>
|
||||
<span class="badge">Full IRCv3</span>
|
||||
<span class="badge">SASL</span>
|
||||
</div>
|
||||
<h1>A modern IRC network,<br>built from scratch in <span class="accent">Rust</span>.</h1>
|
||||
<p class="lede">echoIRCd is an original IRC daemon and services suite — no forks, no C, no
|
||||
<span class="mono">unsafe</span>. Full IRCv3, modern TLS, server-to-server linking, and a
|
||||
complete services stack with accounts, channels, and SASL.</p>
|
||||
<div class="cta">
|
||||
<a class="btn primary" href="/connect">Connect now</a>
|
||||
<a class="btn" href="/features">Explore features</a>
|
||||
</div>
|
||||
<div class="connectline mono">/server irc.echoircd.org +6697</div>
|
||||
</section>
|
||||
|
||||
<section class="split">
|
||||
<div class="card">
|
||||
<h3>echoIRCd <span class="tag">the daemon</span></h3>
|
||||
<p>A single-threaded core with an epoll reactor pool and a module-per-file architecture.
|
||||
The full channel and user mode set, host cloaking, connection classes, PROXY protocol,
|
||||
ident, and an InspIRCd-style operator privilege system.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>echo <span class="tag">the services</span></h3>
|
||||
<p>NickServ, ChanServ, OperServ, MemoServ and more, linked over a standard server-to-server
|
||||
protocol. Account registration, vhosts, grouped nicks, memos and SASL — all backed by an
|
||||
event-sourced store.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="wrap">
|
||||
<h2 class="section-title">What's inside</h2>
|
||||
<div class="grid">
|
||||
<div class="feat">
|
||||
<div class="ico">🔒</div>
|
||||
<h4>Modern TLS</h4>
|
||||
<p>Direct TLS on 6697 and WebSocket (wss) on 7799. OpenSSL <em>and</em> rustls backends,
|
||||
TLS 1.3 with post-quantum X25519MLKEM768, and per-host SNI certificates.</p>
|
||||
</div>
|
||||
<div class="feat">
|
||||
<div class="ico">⚡</div>
|
||||
<h4>Full IRCv3</h4>
|
||||
<p>server-time, message-tags, account-tag, extended-join, batch, labeled-response,
|
||||
chathistory, multiline, setname, standard-replies, metadata and more.</p>
|
||||
</div>
|
||||
<div class="feat">
|
||||
<div class="ico">🔑</div>
|
||||
<h4>SASL</h4>
|
||||
<p>PLAIN, EXTERNAL (certificate fingerprint), SCRAM-SHA-256, and
|
||||
ECDSA-NIST256P-CHALLENGE — sign a challenge with your key, no password on the wire.</p>
|
||||
</div>
|
||||
<div class="feat">
|
||||
<div class="ico">🤖</div>
|
||||
<h4>Services</h4>
|
||||
<p>Accounts, channels, vhosts, memos and games over a standard S2S link, with SASL relayed
|
||||
mechanism-agnostically to the services layer.</p>
|
||||
</div>
|
||||
<div class="feat">
|
||||
<div class="ico">🛡</div>
|
||||
<h4>Anti-abuse</h4>
|
||||
<p>A native security subsystem: connection and nick-flood detection, behavioral and content
|
||||
heuristics, DEFCON states, and DNSBL / MX screening.</p>
|
||||
</div>
|
||||
<div class="feat">
|
||||
<div class="ico">🌐</div>
|
||||
<h4>Localized</h4>
|
||||
<p>Server-wide locale catalogs translate numerics and service replies at a single chokepoint.
|
||||
English stays zero-cost; switch locales on rehash.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="connect-strip">
|
||||
<div class="cs-in">
|
||||
<div>
|
||||
<h2>Jump in.</h2>
|
||||
<p>Point any IRC client at the network and say hello.</p>
|
||||
</div>
|
||||
<table class="mini">
|
||||
<tr><td>Server</td><td class="mono">irc.echoircd.org</td></tr>
|
||||
<tr><td>TLS</td><td class="mono">6697</td></tr>
|
||||
<tr><td>WebSocket</td><td class="mono">7799 (wss)</td></tr>
|
||||
<tr><td>Network</td><td class="mono">echoiRCd</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue