4 releases
new 0.1.2 | Jan 22, 2025 |
---|---|
0.1.1 | Jan 22, 2025 |
0.1.0 | Jan 22, 2025 |
0.0.1 | Jan 22, 2025 |
#89 in Web programming
102 downloads per month
64KB
1K
SLoC
Bandurria
Bandurria is a self-hosted lightweight comment system for static websites and blogs. Built in Rust, takes a few MB of RAM. Can be included with a single line of JavaScript.
This project has been started after I used another similar comment system on my personal blog, named Schnack, that requires users to authenticate through OAuth (eg. via Google) before they can send their comment. I have noticed that requiring to OAuth to a Google or GitHub account to send a comment on a random blog (where user trust is possibly low), might discourage a lot of people from commenting. Bandurria comes as a lighter and even simpler alternative to Schnack (without the memory overhead of NodeJS and installing NPM dependencies).
Tested at Rust version: rustc 1.84.0 (9fc6b4312 2025-01-07)
🇨🇱 Crafted in Santiago, Chile.
Features
- Built-in spam control with Proof of Work anti-bot system and Magic Link email verification
- Email-based notifications and comment moderation (no complex Web admin UI)
- Zero-dependencies server runtime and lightweight JavaScript script
- Compatible with any static website or blog system (as long as your can add 1 line of JavaScript)
- Customize it in a few lines of CSS to match your website or blog style
Bandurria provides no administration interface. It solely relies on email notifications for moderation and Magic Links for identity verification. It also does not provide any CSS preset, only CSS classes in its injected HTML that you can freely style to match your blog or website style.
Spam is prevented by requiring user browsers to submit the result to a Proof of Work challenge (based on an improved variant of Hashcash), while the user is typing their comment. This spam prevention method is CAPTCHA-free and hassle-free, since the proof will already be computed when the user will be ready to submit their comment. Upon submission of their comment, the user will receive a Magic Link over email they will need to click on to confirm their identity and submit their comment. Then, you (the administrator) will receive the user comment over email for moderation. If the user has already sent approved comments in the past under the same email, then their comment will be auto-approved. If not, you will need to approve the comment which will also trust the user. Either way, Bandurria notifies people of new replies to their comments over email.
Oh and what about that name?! Well, the Bandurria name refers to the Bandurria Austral (Black-faced Ibis), which is a bird that can be found across Patagonia. It emits interesting metallic sounds.
End Goals
All goals might not have yet been implemented, but this is what Bandurria aims for:
- No social auth, no admin interface, no multiple notification channels, do it all over email notifications with magic links.
- Public users can write their comment, give a name and email and submit in a simple way (WordPress like).
- Proof of work anti spam mechanism, with progress bar (multiple parallel hash computation), with ability to configure difficulty.
- Upon sending a comment and passing the PoW, ask the user to click on a magic link sent over their email (double spam prevention and email verification to authenticate themselves).
- Admin user can manage comment and remove or allow them from the comment UI after logging in over magic link with email.
- Once an user first comment got approved then all further comments will be auto approved (unless the user gets banned by the admin).
- Notify admin of new comments over email, and notify of replies to user comments over email to users (enable engagement, which was an issue with other simple commenting systems since users didn’t get notified of replies to their own comments).
- Built in theme is to be generic and simple with no colors, it can be extended by the user by styling CSS classes in their own blog theme (CSS class names should be stable, and never use important rules).
- Provide ability to customize every action, button and input placeholder wordings, since there will be no internationalization, it will solely be done via configuring custom eg. button labels from the configuration file.
- Built with Rust, goal is to produce a 4MB binary using the same amount of RAM and distribute lightweight Docker images for all platforms.
- Upon sending the first comment for a given page, internally check that the blog page exists with a HTTP request (it should return 200), if the page already exists in database then no need to check again (this prevents inserting junk in the database).
- Upon submitting a comment and waiting for the user to confirm their identity over email with the magic link, store the pending comment in a temporary table, and purge it every day or so, if the user submits a comment but never validate anything over email (garbage collect periodically to ensure we do not store a growing list of pending comments, especially if spammers with fake emails manage to pass the PoW step).
- Store everything in a simple MySQL database.
- Verify origin of comments to be from the same domain as the site, and also prevent CORS (for security and anti-spam reasons).
How to use it?
Installation
Install from Docker Hub:
You might find it convenient to run Bandurria via Docker. You can find the pre-built Bandurria image on Docker Hub as valeriansaliou/bandurria.
First, pull the valeriansaliou/bandurria
image:
docker pull valeriansaliou/bandurria:v1.0.0
Then, provide a configuration file and run it (replace /path/to/your/bandurria/config.cfg
with the path to your configuration file):
docker run -p 8080:8080 -v /path/to/your/bandurria/config.cfg:/etc/bandurria.cfg valeriansaliou/bandurria:v1.0.0
In the configuration file, ensure that:
server.inet
is set to0.0.0.0:8080
(this lets Bandurria be reached from outside the container)assets.path
is set to./res/assets/
(this refers to an internal path in the container, as the assets are contained there)
Bandurria will be reachable from http://localhost:8080
.
Install from binary:
A pre-built binary of Bandurria is shared in the releases on GitHub. You can simply download the latest binary version from the releases page, and run it on your server.
You will still need to provide the binary with the configuration file, so make sure you have a Bandurria config.cfg
file ready somewhere.
The binary provided is statically-linked, which means that it will be able to run on any Linux-based server. Still, it will not work on MacOS or Windows machines.
👉 Each release binary comes with an .asc
signature file, which can be verified using @valeriansaliou GPG public key: 🔑valeriansaliou.gpg.pub.asc.
Install from Cargo:
If you prefer managing bandurria
via Rust's Cargo, install it directly via cargo install
:
cargo install bandurria
Ensure that your $PATH
is properly configured to source the Crates binaries, and then run Bandurria using the bandurria
command.
Install from source:
The last option is to pull the source code from Git and compile Bandurria via cargo
:
cargo build --release
You can find the built binaries in the ./target/release
directory.
Configuration
Use the sample config.cfg configuration file and adjust it to your own environment.
You can also use environment variables with string interpolation in your configuration file, eg. server.inet = ${BANDURRIA_INET}
.
Available configuration options are commented below, with allowed values:
[server]
log_level
(type: string, allowed:debug
,info
,warn
,error
, default:error
) — Verbosity of logging, set it toerror
in productioninet
(type: string, allowed: IPv4 / IPv6 + port, default:[::1]:8080
) — Host and TCP port the Bandurria server should listen on
[assets]
path
(type: string, allowed: UNIX path, default:./res/assets/
) — Path to Bandurria assets directory
[database]
uri
(type: string, allowed: MySQL connection URI, no default) — MySQL URI (ie.mysql://user:password@server:port/database
)
[email]
server_host
(type: string, allowed: hostname, IPv4, IPv6, default: no default) — SMTP host to connect toserver_port
(type: integer, allowed: TCP port, default:587
) — SMTP TCP port to connect toserver_starttls
(type: boolean, allowed:true
,false
, default:true
) — Whether to encrypt SMTP connection withSTARTTLS
or notserver_tls
(type: boolean, allowed:true
,false
, default:false
) — Whether to encrypt SMTP connection withTLS
or notauth_user
(type: string, allowed: any string, default: no default) — SMTP username to use for authentication (if any)auth_password
(type: string, allowed: any string, default: no default) — SMTP password to use for authentication (if any)
from_name
(type: string, allowed: any string, default:Comments
) — Name to send the emails fromfrom_email
(type: string, allowed: email address, default: no default) — Email to send the emails from
[site]
name
(type: string, allowed: any string, default: no default) — Name of the siteadmin_emails
(type: array[string], allowed: email addresses, default: no default) — Email addresses of site administratorssite_url
(type: string, allowed: URL, default: no default) — URL of the sitecomments_url
(type: string, allowed: URL, default: no default) — URL of the comment system
[security]
secret_key
(type: string, allowed: any hexadecimal string, default: auto-generated secret) — Secret key to use to sign all authenticated payloads (generate yours withopenssl rand -hex 32
)
Run Bandurria
Bandurria can be run as such:
./bandurria -c /path/to/config.cfg
You will also need to make sure the MySQL database fixtures are imported in your database.
🔥 Report A Vulnerability
If you find a vulnerability in Bandurria, you are more than welcome to report it directly to @valeriansaliou by sending an encrypted email to valerian@valeriansaliou.name. Do not report vulnerabilities in public GitHub issues, as they may be exploited by malicious people to target production servers running an unpatched Bandurria instance.
⚠️ You must encrypt your email using @valeriansaliou GPG public key: 🔑valeriansaliou.gpg.pub.asc.
Dependencies
~40–73MB
~1.5M SLoC