geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

geomyidae.8 (15593B)


      1 .\" geomyidae.8 handcrafted in GNU groff -mdoc using nvi
      2 .\"
      3 .Dd March 17, 2021
      4 .Dt GEOMYIDAE 8
      5 .Os
      6 .
      7 .Sh NAME
      8 .Nm geomyidae
      9 .Nd a gopher daemon for Linux/BSD
     10 .
     11 .Sh SYNOPSIS
     12 .Nm
     13 .Bk -words
     14 .Op Fl 4
     15 .Op Fl 6
     16 .Op Fl c
     17 .Op Fl d
     18 .Op Fl e
     19 .Op Fl n
     20 .Op Fl s
     21 .Op Fl y
     22 .Op Fl l Ar logfile
     23 .Op Fl v Ar loglevel
     24 .Op Fl b Ar base
     25 .Op Fl p Ar port
     26 .Op Fl o Ar sport
     27 .Op Fl u Ar user
     28 .Op Fl g Ar group
     29 .Op Fl h Ar host
     30 .Op Fl i Ar interface ...
     31 .Op Fl t Ar keyfile certfile
     32 .Ek
     33 .
     34 .Sh DESCRIPTION
     35 .Bd -filled
     36 .Nm
     37 is a daemon for serving the protocol specified in
     38 .Em RFC 1436
     39 (Gopher). Under 1000 lines of C by design, it is lightweight yet supports
     40 dynamic content, automatic file/directory indexing, logging and privilege
     41 separation.
     42 .Ed
     43 .
     44 .Sh IMPLEMENTATION
     45 .Bd -filled
     46 Installation is straightforward: grab the zipped tar file, expand it in
     47 an appropriate temp directory, change to the
     48 .Qq "../geomyidae-x.xx"
     49 directory, tweak the Makefile if desired (installs in
     50 .Qq "/usr/bin"
     51 by default), then run the
     52 .Sq "make ; make install"
     53 commands.  The resulting executable should be run by root.
     54 .Ed
     55 .
     56 .Ss Basic Installation and Startup
     57 .Bd -literal
     58      $ wget ftp://bitreich.org/releases/geomyidae/geomyidae-$VERSION.tar.lz
     59      $ lzip -d geomyidae-$VERSION.tar.lz
     60      $ tar -xvf geomyidae-*.tar
     61      $ cd geomyidae-*
     62      $ make; sudo make install
     63      $ sudo mkdir -p /var/gopher
     64      $ sudo cp index.gph /var/gopher
     65      $ sudo geomyidae -l /var/log/geomyidae.log -b /var/gopher -p 70
     66      $ tail -f /var/log/geomyidae.log
     67 
     68      Use whatever gopher client you like (ie. sacc) to browse:
     69      $ sacc gopher://localhost
     70 .Ed
     71 .
     72 .Ss Running
     73 geomyidae should normally be started by root, although it can be started
     74 by a regular user provided that the base directory and its contents are owned
     75 by the same user.  geomyidae will only serve content within the base directory
     76 tree and will drop privileges to the
     77 .Fl u Ar user
     78 and
     79 .Fl g Ar group
     80 values if set.  See
     81 .Ic OPTIONS
     82 below for specifics.  Launching geomyidae automatically is best done via a UNIX
     83 run-time (rc.d) script; several sample rc.d scripts are included in the
     84 geomyidae source archive. Logging in geomyidae can be done through either
     85 logfiles or syslog.
     86 .
     87 .Sh OPTIONS
     88 geomyidae options and default settings:
     89 .Bl -tag -width Ds
     90 .
     91 .It Fl 4
     92 Only use IPv4.
     93 .
     94 .It Fl 6
     95 Only use IPv6.
     96 .
     97 .It Fl c
     98 Use
     99 .Xr chroot 2
    100 for the
    101 .Ar base
    102 directory (by default off).
    103 .
    104 .It Fl d
    105 Don't fork into background. If no log file is given, this implies logging to
    106 the standard output.
    107 .
    108 .It Fl e
    109 Disable execution of any CGI or DCGI script.
    110 .
    111 .It Fl n
    112 Don't perform reverse lookups.
    113 .
    114 .It Fl s
    115 Log using syslog for logging.
    116 .
    117 .It Fl y
    118 Enable HAProxy support.
    119 .
    120 .It Fl l Ar logfile
    121 Specify file where log output is written (no default).
    122 .
    123 .It Fl v Ar loglevel
    124 Set the logging level (default: 47).
    125 .
    126 .Bd -literal
    127 Loglevels:
    128         0  - no logging
    129         1  - served plain files
    130         2  - directory listings
    131         4  - HTTP redirects
    132         8  - errors (e.g., not found)
    133         16 - client connections
    134         32 - gopher+ redirects
    135   e.g.:
    136         1 + 2 + 4 + 8 + 32 = 47
    137         (files + directories + HTTP + errors + gopher+)
    138 .Ed
    139 .
    140 .It Fl b Ar base
    141 Root directory to serve (default: /var/gopher).
    142 .
    143 .It Fl p Ar port
    144 Port geomyidae should listen on (default: 70).
    145 .
    146 .It Fl o Ar sport
    147 Port geomyidae displays within base directory (default: 70).
    148 Use in conjunction with
    149 .Ic -p
    150 for obfuscating actual port geomyidae is running on.
    151 .
    152 .It Fl u Ar user
    153 Sets the user to which privileges drop when geomyidae is ready
    154 to accept network connections (default: user geomyidae runs as).
    155 Helps improve security by reducing privileges during request
    156 processing.
    157 .
    158 .It Fl g Ar group
    159 Sets the group to which privileges drop when geomyidae is ready
    160 to accept network connections (default: group geomyidae runs as).
    161 Helps improve security by reducing privileges during request
    162 processing.
    163 .
    164 .It Fl h Ar host
    165 Host to use in directory listings (default: localhost).
    166 .
    167 .It Fl i Ar interface
    168 Defines the interface to which geomyidae binds to (default: 0.0.0.0).
    169 Multiple interfaces can be given.
    170 .
    171 .It Fl t Ar keyfile certfile
    172 Activate gopher TLS and use the private key
    173 .Ar keyfile
    174 and the public key
    175 .Ar certfile
    176 for TLS connections (if the feature is compiled in.) See ENCRYPTION ONLY
    177 support below.
    178 .El
    179 .
    180 .Sh FORMATTING
    181 .Bd -filled
    182 Structured Gopher space(s) can be created with geomyidae through the
    183 use of special indexing files of the form
    184 .Ic <name>.gph
    185 which, if present, geomyidae uses to format and/or filter the contents of
    186 the base directory (/var/gopher by default) and create gopher menus.
    187 However, index files are
    188 .Em not
    189 required: if no index.gph, index.cgi or index.dcgi
    190 file is found, geomyidae simply lists the directory
    191 contents in alphanumeric order.  In addition, a directory can utilize
    192 multiple index files to create a layered gopher environment without the
    193 use of sub-directories: ie. pictures.gph, music.gph, documents.gph could
    194 be "directories" within main.gph, yet all reside in /var/gopher along with
    195 their respective files (*.jpg, *.mp3, *.pdf for example).
    196 .Ed
    197 .
    198 .Ss Anatomy of an index.gph file
    199 A gph file consists of informational text and links. A link has the form:
    200 .Bl -inset -offset indent
    201 .It Ic [<type>|<desc>|<path>|<host>|<port>]
    202 .El
    203 .Pp
    204 where,
    205 .Bl -inset -offset indent
    206 .It Ic <type>
    207 = A valid gopher Item Type.
    208 .Pp
    209 Some common Gopher Types as defined in
    210 .Em RFC 1436
    211 :
    212 .
    213 .Bd -literal
    214  0   Item is a file.
    215  1   Gopher directory.
    216  3   Error.
    217  7   Item is an Index-Search server.
    218  8   Item points to a text-based telnet session.
    219  9   Binary file. Client reads until TCP connection closes!
    220  g   GIF format graphics file.
    221  I   Indeterminate image file. Client decides how to display.
    222 .Ed
    223 .Pp
    224 In addition, geomyidae provides these:
    225 .Bd -literal
    226  h   Item is a hypertext (HTTP) link.
    227  i   Informational Item (used for descriptive purposes).
    228 .Ed
    229 .
    230 .Bd -filled
    231 Unknown file types default to Type "9" (binary).
    232 .Ed
    233 .
    234 .It Ic <desc>
    235 = description of gopher item. Most printable characters should work.
    236 .
    237 .It Ic <path>
    238 = full or relative path to gopher item (base value is
    239 .Qq "/"
    240 ). Use the
    241 .Qq "Err"
    242 path for items not intended to be served.
    243 .
    244 .It Ic <host>
    245 = hostname or IP hosting the gopher item. Must be resolvable for the
    246 intended clients. If this is set to
    247 .Qq "server"
    248 , the server's hostname is used.
    249 .
    250 .It Ic <port>
    251 = TCP port number (usually 70).
    252 .
    253 If this is set to
    254 .Qq "port"
    255 , the default port of the server is used.
    256 .El
    257 .
    258 .Bd -filled
    259 Note: geomyidae doesn't require "informational" text to be formally
    260 Typed as "[i|...]"; any line
    261 .Em not
    262 beginning with "[" is treated as informational, greatly simplifying the
    263 formatting of index.gph files. If you want to display some informational
    264 text beginning with "[" you can use the special case of an empty item
    265 type. "[|[some link" will be shortened to "[some link". For dynamically
    266 generated content it may be desirable to either formally type
    267 informational text or run it through a filter to prepend "[|" - .ie sed 's,^[,[|&,' .
    268 .Ed
    269 .Bd -filled
    270 Note 2: You can escape a pipe ("|") character in for example a
    271 .Em <desc>
    272 field by prepending a slash ("\\").
    273 .Ed
    274 .Bd -filled
    275 Note 3: The gph parser is very forgiving. If the link structure is not parsed
    276 correctly, then the original line is printed.
    277 .Ed
    278 .
    279 .Ss index.gph Example
    280 A root.gph file for a server running on host=frog.bog, port=70.  Note use
    281 of optional [i]nformational Item (line 2) for vertical space insertion:
    282 .Bd -literal -offset indent
    283 Welcome to Frog.bog
    284 [i||Err||]
    285 [0|About this server|about.txt|frog.bog|70]
    286 [0|Daily Log|/dtail.cgi|frog.bog|70]
    287 [1|Phlog: like a blog, but not|/PHLOG|frog.bog|70]
    288 [9|Some binary file|widget.exe|frog.bog|70]
    289 [I|Snowflake picture|snowflake.jpg|frog.bog|70]
    290 ttry our snowflakes!
    291 
    292 Links and Searches
    293 [1|Go to R-36.net|/|gopher.r-36.net|70]
    294 [h|Go to NetBSD.org|URL:http://netbsd.org|frog.bog|70]
    295 [7|Query US Weather by Zipcode|/weather.cgi?|frog.bog|70]
    296 [7|Search Veronica II|/v2/vs|gopher.floodgap.com|70]
    297 [8|Telnet to SDF Public Access Unix System|null|freeshell.org|23]
    298 .Ed
    299 .
    300 .Pp
    301 The above looks something like this in a text-based gopher client:
    302 .Pp
    303 .Bl -tag -width ".It Ic WIDTHS" -compact -offset indent
    304 .It Ic Welcome to Frog.bog
    305 .Pp
    306 .It Ic (FILE)
    307 About this server
    308 .It Ic (FILE)
    309 Daily Log
    310 .It Ic (DIR)
    311 Phlog: like a blog, but not
    312 .It Ic (BIN)
    313 Some binary file
    314 .It Ic (IMG)
    315 Snowflake picture
    316 .Pp
    317 try our snowflakes!
    318 .El
    319 .Pp
    320 .Bl -tag -width ".It Ic WIDTHS" -compact -offset indent
    321 .It Ic Links and Searches
    322 .It Ic (DIR)
    323 Go to R-36.net
    324 .It Ic (HTML)
    325 Go to NetBSD.org
    326 .It Ic (?)
    327 Query US Weather by Zipcode
    328 .It Ic (?)
    329 Search Veronica II
    330 .It Ic (TEL)
    331 Telnet to SDF Public Access Unix System
    332 .El
    333 .Sh DYNAMIC CONTENT (gopher CGI)
    334 There are two options provided for dynamic content creation: standard CGI (
    335 .Ic .cgi
    336 ) and dynamic CGI
    337 (
    338 .Ic .dcgi
    339 ). Despite the names, both can accept input and generate dynamic content;
    340 the only difference is the latter re-formats it's output so it appears to
    341 the server as a standard geomyidae index (.gph) file. This makes the
    342 creation of on-the-fly gopher directories much easier (see examples).
    343 All scripts must be under the gopher root directory and be executable by
    344 the same user:group running geomyidae.  Consequently, it is best to use
    345 the -u and -g server options to avoid running as root.
    346 .Pp
    347 Both .cgi and .dcgi scripts have the same argument call structure (as seen by geomyidae):
    348 .Bd -literal -offset indent
    349 executable.[d]cgi $search $arguments $host $port
    350 .Ed
    351 .Pp
    352 where
    353 .Bd -literal -offset indent
    354 search = query string (type 7) or "" (type 0)
    355 arguments = string after "?" in the path, the remaining path or ""
    356 host = server's hostname ("localhost" by default)
    357 port = server's port ("70" by default)
    358 .Ed
    359 .Pp
    360 All terms are tab-separated (per gopher protocol) which can cause some
    361 surprises depending on how a script is written.  See the CGI file (included
    362 in the geomyidae source archive) for further elaboration.
    363 .Pp
    364 For a special REST path case for the arguments, see the CGI file for the
    365 description.
    366 .Pp
    367 QUIRK: The original gopher client tried to be too intelligent. It is using
    368 gopher+ when you request some resource. When "search" is just the value "+",
    369 "!", "$" or empty, geomyidae will display a gopher+ redirect instead of
    370 invoking the script. Be careful to design your search script so the user is
    371 unlikely to enter those values. The designers of gopher+ did not think of
    372 classic gopher to survive. It survived gopher+.
    373 .Pp
    374 Additionally to the above arguments several environment variables are set.
    375 .Bd -literal -offset indent
    376 GATEWAY_INTERFACE = `CGI/1.1'
    377 PATH_INFO = script which is executed
    378 PATH_TRANSLATED = absolute path with script which is executed
    379 QUERY_STRING = arguments (See above.)
    380 SELECTOR = arguments (For backwards compatibility.)
    381 REQUEST = arguments (For backwards compatibility.)
    382 REMOTE_ADDR = IP of the client
    383 REMOTE_HOST = REMOTE_ADDR
    384 REQUEST_METHOD = `GET'
    385 SCRIPT_NAME = script which is executed
    386 SERVER_NAME = server's hostname
    387 SERVER_PORT = server's port
    388 SERVER_LISTEN_NAME = ip the server received the connection on
    389 SERVER_PROTOCOL = `gopher/1.0'
    390 SERVER_SOFTWARE = `geomyidae'
    391 X_GOPHER_SEARCH = search (See above.)
    392 SEARCHREQUEST = search (For backwards compatibility.)
    393 HTTPS and GOPHERS = set, if TLS is used
    394 .Ed
    395 .
    396 .Ss Some CGI Examples
    397 Note: these are a very simple examples with no fitness checks with respect
    398 to safety/security.
    399 .Pp
    400 ex. uptime.cgi - standard CGI, no queries
    401 .
    402 .Bd -literal -offset indent
    403 #!/bin/sh
    404 #  uptime.cgi - prints system uptime(1)
    405 /usr/bin/uptime
    406 exit 0
    407 .Ed
    408 .
    409 .Pp
    410 Call the above with the following index.gph entry:
    411 .Pp
    412 .D1 [0|System Uptime|/uptime.cgi|frog.bog|70]
    413 .Pp
    414 A search query request must have an item Type of "7" to be called
    415 from an index.gph file.  It also needs a "?" suffix in the <path>
    416 field:
    417 .Pp
    418 ex. hello.cgi - standard CGI with query
    419 .
    420 .Bd -literal -offset indent
    421 #!/bin/sh
    422 #  hello.cgi - welcome user
    423 NAME=$1
    424 HOSTNAME=$2
    425 echo ""
    426 echo Hello $NAME - welcome to $HOSTNAME
    427 exit 0
    428 .Ed
    429 .
    430 .Pp
    431 Call the above with the following index.gph entry:
    432 .Pp
    433 .D1 [7|Hello You - Please enter your name|/hello.cgi?FROG.bog|frog.bog|70]
    434 .
    435 .Pp
    436 And do a simple
    437 .Xr snarf 1
    438 query (note the inserted TAB):
    439 .Pp
    440 .D1 % snarf Qo gopher://frog.bog/7/hello.cgi?FROG.bog[TAB]Christoph Qc -
    441 .D1 Hello Christoph - welcome to FROG.bog
    442 .
    443 .Pp
    444 Dynamic CGI entries are similar to above except that the script
    445 needs to create output as described in the
    446 .Ic FORMATTING
    447 section:
    448 .Pp
    449 ex. jughead.dcgi - dynamic CGI script with query
    450 .
    451 .Bd -literal -offset indent
    452 #!/bin/sh
    453 # jughead.dcgi - jughead-like local gopher search
    454 KWRD="$1"
    455 ARCHIVE="/var/gopher/textfiles/"
    456 echo "[i|Search results for \\"${KWRD}\\":|Err||]"
    457 echo "[i||Err||]"
    458 # grep(1) recursive, case-insensitive KWRD search of ARCHIVE:
    459 for RESULT in $(/usr/bin/grep -i -l -m1 ${KWRD} -r $ARCHIVE)
    460 do
    461         DESC=$(/usr/bin/basename ${RESULT})
    462         PATH=$(echo "$RESULT" | /usr/bin/sed 's/^\\/var\\/gopher//')
    463         echo "[0|${DESC}|${PATH}|frog.bog|70]"
    464 done
    465 exit 0
    466 .Ed
    467 .
    468 .Pp
    469 Call the above with the following index.gph entry:
    470 .Pp
    471 .D1 [7|Search this Gopher|/jughead.dcgi?|frog.bog|70]
    472 .Pp
    473 A successful query might look like this:
    474 .Pp
    475 .Bl -tag -width Ds -compact -offset indent
    476 .It Search results for Qo fubar Qc :
    477 .Pp
    478 .It Ic (FILE)
    479 How_Things_Break.txt
    480 .It Ic (FILE)
    481 Origins_of_Words.txt
    482 .It Ic (FILE)
    483 Phrases_of_the_Ages.txt
    484 .El
    485 .
    486 .Pp
    487 Care should to be exercised to avoid creating miss-Typed entries, unwanted
    488 recursions, and/or unintended writes in the working directory.
    489 .Sh HAPROXY SUPPORT
    490 Geomyidae has
    491 .Em HAProxy
    492 support. It can be enabled using the -y parameter.
    493 .
    494 .Sh LOG FILES
    495 The log file (ie. /var/log/gopherd.log) has the following structure:
    496 .
    497 .Pp
    498 .Ic [<date>|<IP/Host>|<port>|<status>] <item path>
    499 .
    500 .Pp
    501 where,
    502 .
    503 .Bl -inset
    504 .It Ic <date>
    505 = access date and time (std 'date' format)
    506 .Pp
    507  ex.
    508 .Qq "2018-01-31 14:18:34 +0000"
    509 .It Ic <IP/Host>
    510 = client IP/Host served
    511 .Pp
    512 ex.
    513 .Qq "104.23.33.1"
    514 .It Ic <port>
    515 = client port served
    516 .Pp
    517 ex.
    518 .Qq "16857"
    519 .It Ic <status>
    520 = status of client request
    521 .Pp
    522 ex. - some common status entries:
    523 .It Qo serving Qc
    524 => a successful request
    525 .It Qo not found Qc
    526 => an unsuccessful request
    527 .It Qo HTTP redirect Qc
    528 => web link redirect (Type h)
    529 .It Qo dir listing Qc
    530 => unindexed directory listing
    531 .It Ic <item path>
    532 = full path to item served
    533 .Pp
    534 ex.
    535 .D1 Qo "/PICS/simple2.jpg" Qc for an image file
    536 .D1 Qo "/PICS" Qc for a directory access
    537 .El
    538 .
    539 .Sh ENCRYPTION ONLY
    540 If you set the sticky bit (chmod +t) on some file or directory, geomyidae
    541 will only serve it over an encrypted connection. There is the special
    542 case, that when the sticky bit is set on the
    543 .Ar base
    544 directory, all content will only be served over tls.
    545 .
    546 .Sh FILES
    547 README, LICENSE, CGI, index.gph, rc.d/, LINKS, gph/
    548 .
    549 .Sh SEE ALSO
    550 Links for further information on gopher:
    551 .Pp
    552 .D1 Pa gopher://gopher.floodgap.com
    553 .D1 Pa gopher://gopherproject.org
    554 .Sh STANDARDS
    555 .Em Internet RFC 1436
    556 .
    557 .Sh HISTORY
    558 .Bd -filled
    559 geomyidae started as a Linux/BSD port of the Plan 9 gopherd_P9 server.
    560 Originally called gopherd_BSD, the name was later changed to Geomyidae
    561 (latin), the taxonomic family of burrowing rodents known as "pocket
    562 gophers" which are in fact the true gophers. Due to inconsistencies
    563 and the UNIX culture, the name was changed to lowercase in 2010.
    564 .Ed
    565 .
    566 .Sh AUTHORS
    567 See LICENSE file for authors in the distribution.
    568 .
    569 .Sh LICENSE
    570 geomyidae is released under the MIT/X Consortium License.
    571 .
    572 .Sh BUGS
    573 Dynamic content functionality may vary across gopher clients.
    574 .
    575 .Ss "Reporting Bugs"
    576 Report bugs to:
    577 .An "Christoph Lohmann" Aq 20h@R-36.net