# 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 p :!pst % ``` ## 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/