Skip to content

C#/net8 Gemini/Spartan/Titan server with CGI, vhost and docker support - zero dependencies

License

Notifications You must be signed in to change notification settings

Alumniminium/atlas

Repository files navigation

Atlas

the launch rocket of the gemini capsule

  • C# / NET 8
  • zero dependencies
  • Linux and Windows - x86, x64 and ARM

Features

  • Docker Support
  • Automatic certificate generation
  • Analythics
  • Server-side animations on supported clients (eg. Lagrange) DEMO: gemini://her.st/
  • Built-in special tokens (see below)
  • vhosts
    • Per Location Configuration
      • directory listing
    • JSON config file
  • Configurable Default Mime Types
  • tsv Mimetype map
  • gemini:// with titan:// file uploads*
  • spartan:// file uploads and downloads*
  • CGI interface compatible with jetforce
    • CGI streaming (for things like gemini://chat.mozz.us/)

*Still WIP

Built-in Special Tokens

Token Replaced With
%%{sub}%% Gemini: Subject Name of the Client Cert (without CN=) - if any - otherwise 'Anon'. For Spartan it always returns 'Spartan'
%%{host}%% FQDN - eg: her.st
%%{path}%% requested path - eg: /index.gmi
%%{scheme}%% protocol of request - eg: spartan / gemini
%%{date}%% YYYY-MM-DD - eg: 2024-03-30
%%{time}%% HH:mm:ss - eg: 21:04:25
%%{datetime}%% YYYY-MM-DD HH-mm-ss - eg: 2024-03-30 21:04:25
%%{rendertime}%% Milliseconds - eg: 0.59
%%{ls}%% Create Directory Index

Example

Gemtext Rendered
Sub: %%{sub}%% Sub: Alumniminium
Host: %%{host}%% Host: localhost
Path: %%{path}%% Path: /index.gmi
Scheme: %%{scheme}%% Scheme: gemini
Date: %%{date}%% Date: 2024-04-01
Time: %%{time}%% Time: 11:32:41
Datetime: %%{datetime}%% Datetime: 2024-04-01 11:32:41
Render Time: %%{rendertime}%% Render Time: 4564.80
%%{ls}%% => gemini://localhost//index.gmi 2024-04-01 | 0.00mb | index.gmi
=> gemini://localhost//localhost.pfx 2024-03-30 | 0.00mb | localhost.pfx

Atlas Statistics

You can always access Atlas Stats on the following URL: gemini://yourserver.tld/atlas.stats

Stats Screenshot Stats Screenshot

Roadmap (in no particular order)

  • FastCGI
  • Use single Docker volume
  • Caching
  • certificate validation DONE IN v0.3 (April 1st 2024)
  • rate limiting
  • proper networking with SocketAsyncEventArgs
  • Inline Server Sided Scripts using %%{exec scriptname}%%
  • Assign "Owner" Cert in Capsule config to allow editing of files via TITAN:// in-client

Sample configuration with all options

A minimal config file will be autogenerated if none is found. this one is just an advanced example

{
  "GeminiPort": 1965,
  "SpartanPort": 300,

  "SlowMode": true, // animations, currently only for gemini
  "SlowModeMaxMilliSeconds": 2000, // max time for animations in ms

  "Capsules": {
    
    "allsafe.net": {
      "AbsoluteRootPath": "/srv/gemini/allsafe.net/",
      "AbsoluteTlsCertPath": "/srv/gemini/allsafe.net/allsafe.net.pfx",
      "FQDN": "allsafe.net",
      "Index": "index.gmi",

      "Locations": 
      [
        {
          "AbsoluteRootPath": "/srv/gemini/allsafe.net/",
          "Index": "index.gmi",
        }
      ]

    },

    "evilcorp.net": {
      "FQDN": "evilcorp.net",
      "AbsoluteRootPath": "/srv/gemini/evilcorp.net/",
      "AbsoluteTlsCertPath": "",// will be automatically created and placed at AbsoluteRootPath/FQDN.pfx
      "Index": "index.gmi",
      "MaxUploadSize": 4194304, // global max upload size (bytes)
      
      "Locations": [
        {
          "AbsoluteRootPath": "/srv/gemini/evilcorp.net/",
          "Index": "index.gmi",
        },

        {
          "AbsoluteRootPath": "/srv/gemini/evilcorp.net/cgi/",
          "Index": "script.csx",
          "CGI": true,
          "RequireClientCert": true,  // disables access for spartan protocol due to lack of support
        },

        {
          "AbsoluteRootPath": "/srv/gemini/evilcorp.net/textfiles/",
          "Index": "index.gmi",
          "DirectoryListing": true, 
          "AllowFileUploads": true, // public Titan/Spartan  uploads in this location
          "MaxUploadSize": 100000, // override max upload size (bytes)
          "DefaultMimeType": "text/plain", // default mimetype for files without or unknown extension

          "AllowedMimeTypes": {
            "text/*": { // whitelist all text files
              "MaxSizeBytes": 1048576 // override max upload size for text files
            },
          }
        }
      ]

    }

  }
}

CGI Interface

The CGI interface provides the following environment variables:

Variable Description Default
DOTNET_CLI_HOME Required for .NET assemblies to execute ~/.dotnet
GATEWAY_INTERFACE CGI Version CGI/1.1
SERVER_PROTOCOL Either Gemini or Spartan GEMINI / SPARTAN
SERVER_PORT Gemini or Spartan Port according to config.json 1965 / 300
SERVER_SOFTWARE atlas/version string atlas/0.2b
URL URL of the Request gemini://evil.corp/cgi/binary?queryString=value#fragment&token
SCRIPT_NAME the CGI script name binary
PATH_INFO See CGI documentation Hopefully correct
QUERY_STRING Query from the URL ?queryString=value#fragment&token
SERVER_NAME the FQDN of the vhost evil.corp
REMOTE_HOST The IP of the client sending the request 127.0.0.1
REMOTE_ADDR as above as above
TLS_VERSION Gemini Only 1.3
REMOTE_USER TLS Cert Subject without CN= trbl
TLS_CLIENT_SUBJECT as above as above
TLS_CLIENT_VALID Certificate is not expired true
TLS_CLIENT_TRUSTED Certificate issued by atlas false
TLS_CLIENT_HASH The Certificate Thumbprint 0baf2asdb23i02..
TLS_CLIENT_NOT_BEFORE Certificate Valid From Time 08/28/2022 18:26:30
TLS_CLIENT_NOT_AFTER Certificate Valid To Time 08/28/3000 18:26:30
TLS_CLIENT_SERIAL_NUMBER The Certificate Serial Number
AUTH_TYPE CERTIFICATE or NONE NONE

sample CGI script

Commenting on Articles atlas-comments