Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Alumniminium/atlas

C#/net8 Gemini/Spartan/Titan server with CGI, vhost and docker support - zero dependencies
https://github.com/Alumniminium/atlas

cgi gemini gemini-protocol gemini-server net8 netcore spartan-protocol spartan-server titan-protocol titan-server vhost

Last synced: 3 days ago
JSON representation

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

Awesome Lists containing this project

README

        

# 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/](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](https://github.com/michael-lazar/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-1.jpg?raw=true "Stats screenshot")
![Stats Screenshot](/stats-2.jpg?raw=true "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

```json
{
"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](https://github.com/Alumniminium/atlas-comments)