Awesome
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
- Per Location Configuration
- 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
Roadmap (in no particular order)
- FastCGI
- Use single Docker volume
- Caching
certificate validationDONE 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