Finger, gopher and Gemini
Three small servers tell the world about the BBS. Finger shows who is on and who a user is. Gopher serves the system's own gopherspace, with the message and file areas the sysop opens to it. Gemini serves the same capsule, and finger's users, over TLS. Each is off unless its section is in the configuration.
Finger's and gopher's usual ports are below 1024, so either run the BBS with
AmbientCapabilities=CAP_NET_BIND_SERVICE (see
bbs.service.sample),
or use another port.
Finger¶
[finger]
address = :79
online = yes ; "finger @bbs.example.org": who is on
users = yes ; "finger alice@bbs.example.org": the user
max_clients = 16
max_per_ip = 4
$ finger @bbs.example.org
D-Modem BBS: 2 callers on
Node User Via On Doing
1 sysop telnet 12m Chatting in main
2 alice modem 26400 3m Reading mail
$ finger alice@bbs.example.org
User: alice
From: Zürich
Member since: 2026-10-01
Last call: on now, node 2: Reading mail
Calls: 14
Posts: 5
Finger never shows addresses, caller IDs or anything about locked
accounts, and it forwards nothing (user@otherhost is refused).
online = no and users = no turn off its two halves.
Gopher¶
[gopher]
address = :70
hostname = bbs.example.org ; what the menus say to come back to
port = 70 ; and on which port (behind NAT, a forward)
areas = general,announcements ; message areas anyone may read (a wildmat)
files = no ; yes: file areas listed and downloadable
max_clients = 32
max_per_ip = 8
The root menu has About this system (name, location, sysop, number of users and the message of the day), Who's online, and, if the sysop has opened them, Message areas and File areas. An area lists its messages 50 at a time (oldest first, with More...). A message is served as text, and a file as it is (type 9, or as an image for GIF, PNG and JPEG).
Gopher has no login, so everything it shows, it shows to anyone. That is
why it shows no message areas and no files by default, and bbs check
warns when areas or files is set. areas matches area names in any
case (* matches all of them), and an area that does not match cannot be
reached, whatever is asked. Selectors are not paths: they name records in
the BBS's database, and nothing on the server's disk can be reached.
Gemini¶
[gemini]
address = :1965
hostname = bbs.example.org ; offered by bbs gemini cert
;cert_file = /etc/bbs/gemini-cert.pem ; or neither, for bbs gemini cert's
;key_file = /etc/bbs/gemini-key.pem
areas = general,announcements ; as gopher's
files = no
users = yes ; /users: look up a user, as finger does
max_clients = 32
max_per_ip = 8
Gemini is gopher's younger cousin: one
request a connection, always over TLS, pages in gemtext. The capsule is
gopher's: the home page links About this system, Who's online, Look
up a user (it asks for a name and shows what finger would) and, if the
sysop opened them, Message areas and File areas. gemini://host/~alice
goes straight to a user. A message is a gemtext page with its headers
first; its lines are shown as text, so a line in a message cannot become
a link or a heading. A file goes as it is, typed by its name
(application/octet-stream if the name says nothing).
Gemini clients trust a capsule's certificate the first time they see it
and warn if it ever changes, so self-signed certificates are the usual
thing. The BBS never makes one by itself: with no cert_file and
key_file, make one with bbs gemini cert before starting it. It asks
what goes in the certificate, shows it, and makes it only when you say
yes:
$ bbs -config /etc/bbs/bbs.conf gemini cert
A certificate for the Gemini server, made here and signed by itself.
Clients trust it the first time they connect and warn if it ever changes:
make it once, and keep it (and its key) with your backups.
Host names callers use, by commas [bbs.example.org]: bbs.example.org, gemini.example.org
Organization (- for none) [D-Modem BBS]:
Years it is good for [20]:
For: bbs.example.org, gemini.example.org
Org: D-Modem BBS
Until: 2046-11-09
Files: /var/lib/bbs/gemini-cert.pem, /var/lib/bbs/gemini-key.pem
Make it? (yes/no) [no]: yes
Made: bbs.example.org, gemini.example.org until 2046-11-09, SHA-256 3F2A...
The first host name is the certificate's common name; addresses (IPv4 or
IPv6) can be listed too. The files go beside the database
(gemini-cert.pem, gemini-key.pem). Keep them with your backups: a new
certificate makes every client that has been before warn, which is why
bbs gemini cert will not replace one without -force (and then keeps
the old one as .old). bbs check shows the certificate's names, expiry
and SHA-256 fingerprint, or that there is none yet; without one, bbs
serve stops and says to make it. A certificate from a certificate
authority (Let's Encrypt's, say) works too: set cert_file and
key_file.
What gopher shows anyone, Gemini shows anyone: no areas and no files by
default, bbs check warns when areas or files is set, and file areas
with a download requirement are never shown. users = no turns off the
user lookup. Port 1965 is above 1024 and needs no privilege.
$ amfora gemini://bbs.example.org
$ printf 'gemini://bbs.example.org/areas\r\n' | openssl s_client -quiet -connect bbs.example.org:1965
See also: Configuration, Security