| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
Bin Pastebin Nix Flake
This flake provides a Nix package and NixOS module for 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:
{
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:
{
services.bin = {
enable = true;
port = 6162;
address = "127.0.0.1";
};
}
Complete Configuration Example
{
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:
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:
# 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:
# 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:
nnoremap <leader>p :!pst %<CR>
Security Considerations
The NixOS module implements several security measures:
- Systemd Hardening: The service runs with strict sandboxing
- Separate User: Runs under a dedicated system user
- Filesystem Isolation: Only the upload directory is writable
- Network Restrictions: Limited to IPv4/IPv6 address families
- System Call Filtering: Restricted to necessary system calls
Maintenance
Viewing Logs
# View service logs
sudo journalctl -u bin -f
# View nginx logs (if using reverse proxy)
sudo journalctl -u nginx -f
Managing Uploads
# 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
# 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:
{
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:
{
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:
{
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
- Check logs:
sudo journalctl -u bin -e - Verify permissions:
ls -la /var/lib/bin - Check port availability:
sudo ss -tlnp | grep 6162
Upload Errors
- Check file size limits in configuration
- Verify disk space:
df -h /var/lib/bin - Check nginx client_max_body_size if using reverse proxy
SSL Certificate Issues
- Ensure domain points to your server
- Check ACME logs:
sudo journalctl -u acme-paste.yourdomain.com - Verify ports 80/443 are accessible
Development
To work on the bin source code:
# 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
# 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:
# Build for aarch64-linux on x86_64-linux
nix build .#packages.aarch64-linux.bin
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Test your changes thoroughly
- 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/