435 lines
No EOL
10 KiB
Markdown
435 lines
No EOL
10 KiB
Markdown
# Bin Pastebin Nix Flake
|
|
|
|
This flake provides a Nix package and NixOS module for [bin](https://github.com/wantguns/bin), a minimal pastebin service that accepts binary files like images and PDFs.
|
|
|
|
## Features
|
|
|
|
- **Minimal and fast**: Written in Rust using the Rocket framework
|
|
- **Binary file support**: Upload images, PDFs, and other binary files
|
|
- **Multiple clients**: Web UI, CLI, and Vim integration
|
|
- **Self-contained**: No external database required
|
|
- **Security hardened**: Systemd service with strict security policies
|
|
- **Nginx integration**: Built-in reverse proxy configuration with SSL support
|
|
|
|
## Quick Start
|
|
|
|
### Using the Flake in Your NixOS Configuration
|
|
|
|
Add the flake to your `flake.nix` inputs:
|
|
|
|
```nix
|
|
{
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
bin-flake.url = "path:/path/to/this/flake";
|
|
# Or from GitHub (once published):
|
|
# bin-flake.url = "github:yourusername/bin-flake";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, bin-flake, ... }: {
|
|
nixosConfigurations.yourhost = nixpkgs.lib.nixosSystem {
|
|
system = "x86_64-linux";
|
|
modules = [
|
|
bin-flake.nixosModules.default
|
|
./configuration.nix
|
|
];
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
### Basic Configuration
|
|
|
|
In your NixOS configuration:
|
|
|
|
```nix
|
|
{
|
|
services.bin = {
|
|
enable = true;
|
|
port = 6162;
|
|
address = "127.0.0.1";
|
|
};
|
|
}
|
|
```
|
|
|
|
### Complete Configuration Example
|
|
|
|
```nix
|
|
{
|
|
services.bin = {
|
|
enable = true;
|
|
|
|
# Network settings
|
|
address = "127.0.0.1";
|
|
port = 6162;
|
|
openFirewall = false; # Set to true if not using nginx
|
|
|
|
# Storage settings
|
|
uploadDir = "/var/lib/bin/upload";
|
|
binaryUploadLimit = 100; # MiB
|
|
|
|
# UI settings
|
|
clientDescription = true; # Show CLI client info on landing page
|
|
|
|
# Custom environment variables
|
|
environmentFile = pkgs.writeText "bin-env" ''
|
|
BIN_LIMITS={form="16 MiB"}
|
|
BIN_WORKERS=8
|
|
BIN_IDENT=false
|
|
BIN_KEEP_ALIVE=5
|
|
BIN_LOG_LEVEL=normal
|
|
'';
|
|
|
|
# Nginx reverse proxy
|
|
nginx = {
|
|
enable = true;
|
|
domain = "paste.yourdomain.com";
|
|
enableSSL = true; # Uses Let's Encrypt
|
|
};
|
|
};
|
|
|
|
# Ensure nginx and ACME are configured
|
|
services.nginx.enable = true;
|
|
security.acme = {
|
|
acceptTerms = true;
|
|
defaults.email = "admin@yourdomain.com";
|
|
};
|
|
}
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
### Core Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `enable` | bool | false | Whether to enable the bin service |
|
|
| `package` | package | bin | The bin package to use |
|
|
| `user` | string | "bin" | User account under which bin runs |
|
|
| `group` | string | "bin" | Group under which bin runs |
|
|
|
|
### Network Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `address` | string | "127.0.0.1" | Address on which the webserver listens |
|
|
| `port` | int | 6162 | Port on which the webserver listens |
|
|
| `openFirewall` | bool | false | Whether to open the firewall for the service |
|
|
|
|
### Storage Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `uploadDir` | path | "/var/lib/bin/upload" | Directory where uploaded pastes are stored |
|
|
| `binaryUploadLimit` | int | 100 | Binary uploads file size limit (in MiB) |
|
|
|
|
### Feature Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `clientDescription` | bool | true | Whether to show the /client description on landing page |
|
|
| `extraArgs` | list of strings | [] | Extra command-line arguments to pass to bin |
|
|
| `environmentFile` | null or path | null | File containing environment variables for bin |
|
|
|
|
### Nginx Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `nginx.enable` | bool | false | Whether to enable nginx reverse proxy |
|
|
| `nginx.domain` | string | "paste.example.com" | Domain name for the bin service |
|
|
| `nginx.enableSSL` | bool | true | Whether to enable SSL (uses ACME/Let's Encrypt) |
|
|
|
|
## Environment Variables
|
|
|
|
The bin service supports additional configuration through environment variables. You can set these using the `environmentFile` option:
|
|
|
|
```nix
|
|
environmentFile = pkgs.writeText "bin-env" ''
|
|
# Rocket configuration
|
|
BIN_LIMITS={form="16 MiB"} # Form data size limit
|
|
BIN_WORKERS=8 # Number of worker threads
|
|
BIN_IDENT=false # Disable server identification
|
|
BIN_KEEP_ALIVE=5 # Keep-alive timeout in seconds
|
|
BIN_LOG_LEVEL=normal # Log level: off, critical, normal, debug
|
|
|
|
# Additional Rocket settings
|
|
BIN_SECRET_KEY=your-secret-key # For encrypted cookies (generate with openssl)
|
|
BIN_TLS={certs="path/to/certs",key="path/to/key"} # TLS configuration
|
|
'';
|
|
```
|
|
|
|
## Client Configuration
|
|
|
|
### Web Client
|
|
|
|
Access the web interface at `http://localhost:6162` (or your configured domain).
|
|
|
|
### CLI Client
|
|
|
|
The CLI client can be installed and configured:
|
|
|
|
```bash
|
|
# Download the client
|
|
curl -o ~/.local/bin/pst https://yourdomain.com/client
|
|
chmod +x ~/.local/bin/pst
|
|
|
|
# Or create your own client script
|
|
cat > ~/.local/bin/pst << 'EOF'
|
|
#!/bin/bash
|
|
URL="https://paste.yourdomain.com"
|
|
FILEPATH="$1"
|
|
FILENAME=$(basename -- "$FILEPATH")
|
|
EXTENSION="${FILENAME##*.}"
|
|
|
|
RESPONSE=$(curl --data-binary @${FILEPATH:-/dev/stdin} --url $URL)
|
|
PASTELINK="$URL$RESPONSE"
|
|
|
|
[ -z "$EXTENSION" ] && \
|
|
echo "$PASTELINK" || \
|
|
echo "$PASTELINK.$EXTENSION"
|
|
EOF
|
|
chmod +x ~/.local/bin/pst
|
|
```
|
|
|
|
Usage:
|
|
```bash
|
|
# Upload a file
|
|
pst somefile.txt
|
|
|
|
# Pipe content
|
|
echo "Hello, World!" | pst
|
|
|
|
# Upload an image
|
|
pst screenshot.png
|
|
```
|
|
|
|
### Vim Integration
|
|
|
|
Add to your `init.vim` or `.vimrc`:
|
|
|
|
```vim
|
|
nnoremap <leader>p :!pst %<CR>
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
The NixOS module implements several security measures:
|
|
|
|
1. **Systemd Hardening**: The service runs with strict sandboxing
|
|
2. **Separate User**: Runs under a dedicated system user
|
|
3. **Filesystem Isolation**: Only the upload directory is writable
|
|
4. **Network Restrictions**: Limited to IPv4/IPv6 address families
|
|
5. **System Call Filtering**: Restricted to necessary system calls
|
|
|
|
## Maintenance
|
|
|
|
### Viewing Logs
|
|
|
|
```bash
|
|
# View service logs
|
|
sudo journalctl -u bin -f
|
|
|
|
# View nginx logs (if using reverse proxy)
|
|
sudo journalctl -u nginx -f
|
|
```
|
|
|
|
### Managing Uploads
|
|
|
|
```bash
|
|
# View disk usage
|
|
du -sh /var/lib/bin/upload
|
|
|
|
# Clean old uploads (example: files older than 30 days)
|
|
find /var/lib/bin/upload -type f -mtime +30 -delete
|
|
|
|
# Backup uploads
|
|
tar -czf bin-uploads-$(date +%Y%m%d).tar.gz /var/lib/bin/upload
|
|
```
|
|
|
|
### Service Management
|
|
|
|
```bash
|
|
# Restart the service
|
|
sudo systemctl restart bin
|
|
|
|
# Check service status
|
|
sudo systemctl status bin
|
|
|
|
# Reload after configuration changes
|
|
sudo nixos-rebuild switch
|
|
```
|
|
|
|
## Advanced Usage
|
|
|
|
### Custom Nginx Configuration
|
|
|
|
If you need more control over the nginx configuration:
|
|
|
|
```nix
|
|
{
|
|
services.bin = {
|
|
enable = true;
|
|
nginx.enable = false; # Disable automatic nginx config
|
|
};
|
|
|
|
services.nginx.virtualHosts."paste.yourdomain.com" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:6162";
|
|
extraConfig = ''
|
|
client_max_body_size 100M;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# Custom headers
|
|
proxy_set_header X-Custom-Header "value";
|
|
|
|
# Rate limiting
|
|
limit_req zone=paste burst=5 nodelay;
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
### Running Multiple Instances
|
|
|
|
You can run multiple bin instances on different ports:
|
|
|
|
```nix
|
|
{
|
|
services.bin = {
|
|
enable = true;
|
|
port = 6162;
|
|
uploadDir = "/var/lib/bin/upload";
|
|
};
|
|
|
|
# Second instance (requires manual systemd service)
|
|
systemd.services.bin-private = {
|
|
description = "Private bin instance";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
ExecStart = "${pkgs.bin}/bin/bin --port 6163 --upload /var/lib/bin-private/upload";
|
|
User = "bin-private";
|
|
Group = "bin-private";
|
|
StateDirectory = "bin-private";
|
|
};
|
|
};
|
|
|
|
users.users.bin-private = {
|
|
isSystemUser = true;
|
|
group = "bin-private";
|
|
};
|
|
users.groups.bin-private = {};
|
|
}
|
|
```
|
|
|
|
### Integration with Monitoring
|
|
|
|
Example Prometheus/Grafana integration:
|
|
|
|
```nix
|
|
{
|
|
services.prometheus = {
|
|
enable = true;
|
|
scrapeConfigs = [{
|
|
job_name = "bin";
|
|
static_configs = [{
|
|
targets = [ "localhost:6162" ];
|
|
}];
|
|
}];
|
|
};
|
|
|
|
services.grafana.provision.dashboards = [{
|
|
options.path = ./dashboards;
|
|
# Add your bin dashboard JSON here
|
|
}];
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Service Won't Start
|
|
|
|
1. Check logs: `sudo journalctl -u bin -e`
|
|
2. Verify permissions: `ls -la /var/lib/bin`
|
|
3. Check port availability: `sudo ss -tlnp | grep 6162`
|
|
|
|
### Upload Errors
|
|
|
|
1. Check file size limits in configuration
|
|
2. Verify disk space: `df -h /var/lib/bin`
|
|
3. Check nginx client_max_body_size if using reverse proxy
|
|
|
|
### SSL Certificate Issues
|
|
|
|
1. Ensure domain points to your server
|
|
2. Check ACME logs: `sudo journalctl -u acme-paste.yourdomain.com`
|
|
3. Verify ports 80/443 are accessible
|
|
|
|
## Development
|
|
|
|
To work on the bin source code:
|
|
|
|
```bash
|
|
# Enter development shell
|
|
nix develop
|
|
|
|
# Run locally
|
|
cargo run -- --address 127.0.0.1 --port 6162
|
|
|
|
# Run tests
|
|
cargo test
|
|
|
|
# Format code
|
|
cargo fmt
|
|
|
|
# Lint
|
|
cargo clippy
|
|
```
|
|
|
|
## Building
|
|
|
|
### Build the package
|
|
|
|
```bash
|
|
# Build the bin package
|
|
nix build .#bin
|
|
|
|
# Build the Docker image
|
|
nix build .#docker
|
|
|
|
# Load Docker image
|
|
docker load < result
|
|
```
|
|
|
|
### Cross-compilation
|
|
|
|
The flake supports cross-compilation:
|
|
|
|
```bash
|
|
# Build for aarch64-linux on x86_64-linux
|
|
nix build .#packages.aarch64-linux.bin
|
|
```
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please:
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Test your changes thoroughly
|
|
4. Submit a pull request
|
|
|
|
## License
|
|
|
|
This flake is provided under the same license as the bin project (LGPL-3.0).
|
|
|
|
## Credits
|
|
|
|
- Original bin project: https://github.com/wantguns/bin
|
|
- Based on Rocket framework: https://rocket.rs/ |