- Add hostname-based request routing for multiple capsules per server - Parse virtual host configs from TOML sections ([hostname]) - Implement per-host certificate and content isolation - Add comprehensive virtual host testing and validation - Update docs and examples for multi-host deployments This enables Pollux to serve multiple Gemini domains from one instance, providing the foundation for multi-tenant Gemini hosting.
177 lines
5.4 KiB
Markdown
177 lines
5.4 KiB
Markdown
# Pollux - A Simple Gemini Server
|
|
|
|
Pollux is a lightweight Gemini server for serving static files securely. It supports **virtual hosting**, allowing multiple Gemini capsules on a single server instance. Features include TLS encryption, hostname validation, directory serving, and comprehensive security protections.
|
|
|
|
## Requirements
|
|
|
|
Rust 1.70+ and Cargo.
|
|
|
|
## Building
|
|
|
|
Clone or download the source, then run:
|
|
|
|
```bash
|
|
cargo build --release
|
|
```
|
|
|
|
This produces the `target/release/pollux` binary.
|
|
|
|
## Virtual Hosting
|
|
|
|
Pollux supports **virtual hosting**, allowing you to serve multiple Gemini capsules from a single server. Each hostname can have its own root directory, certificates, and configuration.
|
|
|
|
### Configuration
|
|
|
|
Create a config file at `/etc/pollux/config.toml` or use `--config` to specify a path:
|
|
|
|
```toml
|
|
# Global settings (optional)
|
|
bind_host = "0.0.0.0"
|
|
port = 1965
|
|
log_level = "info"
|
|
max_concurrent_requests = 1000
|
|
|
|
# Virtual host configurations
|
|
["example.com"]
|
|
root = "/var/gemini/example.com"
|
|
cert = "/etc/ssl/example.com.crt"
|
|
key = "/etc/ssl/example.com.key"
|
|
|
|
["blog.example.com"]
|
|
root = "/var/gemini/blog"
|
|
cert = "/etc/ssl/blog.crt"
|
|
key = "/etc/ssl/blog.key"
|
|
|
|
["another-site.net"]
|
|
root = "/var/gemini/another"
|
|
cert = "/etc/ssl/another.crt"
|
|
key = "/etc/ssl/another.key"
|
|
port = 1966 # Optional per-host port override
|
|
```
|
|
|
|
### Features
|
|
|
|
- **Multiple hostnames** on a single server instance
|
|
- **Per-host TLS certificates** for proper security isolation
|
|
- **Automatic content isolation** - each host serves only its own files
|
|
- **Path security** - directory traversal attacks are blocked
|
|
- **Index file serving** - `index.gmi` files are served automatically
|
|
- **Hostname validation** - DNS-compliant hostname checking
|
|
|
|
### Request Routing
|
|
|
|
- `gemini://example.com/` → serves `/var/gemini/example.com/index.gmi`
|
|
- `gemini://blog.example.com/article.gmi` → serves `/var/gemini/blog/article.gmi`
|
|
- `gemini://unknown.com/` → returns status 53 "Proxy request refused"
|
|
|
|
### Single Host Mode (Legacy)
|
|
|
|
For backward compatibility, you can still use the old single-host format:
|
|
|
|
```toml
|
|
root = "/path/to/static/files"
|
|
cert = "/path/to/cert.pem"
|
|
key = "/path/to/key.pem"
|
|
hostname = "gemini.example.com"
|
|
bind_host = "0.0.0.0"
|
|
port = 1965
|
|
log_level = "info"
|
|
max_concurrent_requests = 1000
|
|
```
|
|
|
|
## Development Setup
|
|
|
|
### Quick Start with Self-Signed Certs
|
|
```bash
|
|
mkdir -p tmp
|
|
openssl req -x509 -newkey rsa:2048 \
|
|
-keyout tmp/key.pem \
|
|
-out tmp/cert.pem \
|
|
-days 365 \
|
|
-nodes \
|
|
-subj "/CN=localhost"
|
|
```
|
|
|
|
Update `config.toml`:
|
|
```toml
|
|
cert = "tmp/cert.pem"
|
|
key = "tmp/key.pem"
|
|
```
|
|
|
|
Run the server:
|
|
|
|
```bash
|
|
./pollux --config /path/to/config.toml
|
|
```
|
|
|
|
Access with a Gemini client like Lagrange at `gemini://yourdomain.com/`.
|
|
|
|
### Development Notes
|
|
|
|
- These certificates are for local testing only
|
|
- Browsers will show security warnings with self-signed certs
|
|
- Certificates in the `dev/` directory are gitignored for security
|
|
|
|
## Options
|
|
|
|
- `--config` (`-C`): Path to config file (default `/etc/pollux/config.toml`)
|
|
- `--no-tls`: Disable TLS for testing (uses raw TCP connections)
|
|
- `--test-processing-delay` (debug builds only): Add delay before processing requests (seconds) - for testing rate limiting
|
|
|
|
## Security
|
|
|
|
Pollux is designed with security as a priority:
|
|
|
|
- **Path traversal protection** - requests like `../../../etc/passwd` are blocked
|
|
- **TLS encryption** - all connections are encrypted with valid certificates
|
|
- **Content isolation** - virtual hosts cannot access each other's files
|
|
- **Request validation** - malformed requests are rejected
|
|
- **Rate limiting** - configurable concurrent request limits prevent abuse
|
|
|
|
### Best Practices
|
|
|
|
#### Virtual Hosting Setup
|
|
- Use separate TLS certificates for each hostname when possible
|
|
- Keep host root directories separate and properly permissioned
|
|
- Use DNS-compliant hostnames (no underscores, proper formatting)
|
|
- Monitor logs for unknown hostname attempts
|
|
|
|
#### Certificate Management
|
|
- Never commit certificate files to version control
|
|
- Use development certificates only for local testing
|
|
- Production certificates should be obtained via Let's Encrypt or your CA
|
|
- Rotate certificates regularly and restart the server
|
|
|
|
#### File Organization
|
|
- Create `index.gmi` files in directories for automatic serving
|
|
- Use `.gmi` extension for Gemini text files
|
|
- Store certificates outside web-accessible directories
|
|
- Use proper file permissions (readable by server user only)
|
|
|
|
### Limitations
|
|
|
|
- **No dynamic content** - Pollux serves only static files
|
|
- **Single certificate per server** - All hosts currently share the same TLS certificate (can be enhanced)
|
|
- **No CGI support** - No server-side processing or scripting
|
|
- **Memory usage** - All host configurations are loaded into memory
|
|
- **No HTTP support** - Gemini protocol only
|
|
|
|
## Examples
|
|
|
|
The `examples/` directory contains sample configuration files:
|
|
|
|
- `virtual-hosting.toml` - Multi-host setup with different certificates
|
|
- `single-host.toml` - Legacy single-host configuration
|
|
- `development.toml` - Local development with self-signed certificates
|
|
|
|
## Testing
|
|
|
|
Run `cargo test` for the full test suite, which includes comprehensive integration tests covering:
|
|
|
|
- Virtual hosting with multiple hostnames
|
|
- TLS certificate validation
|
|
- Path security and isolation
|
|
- Concurrent request handling
|
|
- Performance validation
|
|
|
|
**Note**: Some integration tests use Python 3 for Gemini protocol validation. If Python 3 is not available, certain tests will be skipped automatically.
|