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
