Skip to content

Deploying GNUnet

Introduction

GNUnet is a free software framework for decentralized, peer-to-peer networking that emphasizes privacy and security. Unlike traditional internet protocols, GNUnet provides secure peer-to-peer communication, anonymous file sharing, censorship-resistant messaging, and a distributed hash table (DHT) for decentralized data storage. Built on the principles of privacy by design, GNUnet encrypts all communication, provides resistance to traffic analysis, and offers a foundation for building privacy-respecting distributed applications.

Deploying GNUnet on Klutch.sh gives you a managed infrastructure for running privacy-focused peer-to-peer services with persistent storage for peer databases and shared files, automatic networking configuration, environment-based configuration management, and streamlined deployment workflows. Whether you’re building a privacy-focused file sharing network, experimenting with decentralized applications, or contributing to the GNUnet ecosystem, Klutch.sh handles the infrastructure complexity while you focus on the peer-to-peer networking aspects.

This comprehensive guide walks you through deploying GNUnet on Klutch.sh using a Dockerfile, configuring persistent volumes for data persistence, setting up peer discovery and networking, and implementing production-ready best practices for security and reliability.


Why Deploy GNUnet on Klutch.sh?

  • Privacy-First Infrastructure: Run peer-to-peer services without compromising privacy
  • Persistent Storage: Reliable volume storage for peer databases, shared files, and configuration
  • Automatic Networking: Simplified TCP/UDP configuration for peer-to-peer communication
  • Environment Management: Secure configuration through environment variables
  • Container Isolation: Run GNUnet services in isolated, reproducible containers
  • Easy Updates: Deploy new versions without manual server management
  • GitHub Integration: Automated deployments from your repository
  • Custom Domains: Expose GNUnet services with branded domains
  • Resource Scaling: Adjust compute resources as your peer network grows
  • Zero Downtime: Deploy updates without service interruption

Prerequisites

Before you begin, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your deployment
  • Basic understanding of Docker and peer-to-peer networking concepts
  • Familiarity with GNUnet concepts (peers, identities, DHT, file sharing)
  • Understanding of TCP/UDP networking for peer discovery

Understanding GNUnet Architecture

GNUnet is a comprehensive framework for secure peer-to-peer networking built on privacy-by-design principles:

Core Components:

  • Transport Layer: Handles peer-to-peer communication (TCP, UDP, HTTP, HTTPS, Bluetooth)
  • Core Service: Manages peer connections, routing, and topology maintenance
  • Distributed Hash Table (DHT): Provides decentralized key-value storage
  • File Sharing (FS): Anonymous, censorship-resistant file sharing with encoding
  • GNS: GNU Name System - decentralized, privacy-preserving DNS alternative
  • Identity Service: Manages pseudonymous identities for privacy
  • VPN Service: Tunnels IP traffic through the GNUnet overlay network
  • Messaging: Encrypted peer-to-peer chat and messaging

Key Features:

  • End-to-end encryption for all communications
  • Traffic obfuscation and resistance to traffic analysis
  • Decentralized peer discovery via DHT
  • Anonymous file sharing with configurable anonymity levels
  • Censorship resistance through multi-hop routing
  • Privacy-preserving name resolution (GNS)
  • Plugin architecture for extensibility

Network Architecture:

GNUnet uses multiple transport protocols for peer communication:

  • TCP/UDP: Primary protocols for peer connections
  • HTTP/HTTPS: Firewall-friendly transports
  • Bluetooth: Direct device-to-device communication

When deploying on Klutch.sh, we’ll configure GNUnet to use TCP transport for incoming peer connections while allowing outbound connections on all supported transports.

Preparing Your Repository

Step 1: Create Project Directory

Create a new directory for your GNUnet deployment:

Terminal window
mkdir gnunet-deploy
cd gnunet-deploy

Step 2: Understand GNUnet Requirements

GNUnet requires the following to run successfully:

  • Operating System: Linux (Debian/Ubuntu recommended)
  • Dependencies: libgcrypt, libcurl, SQLite3 or PostgreSQL/MySQL for data storage
  • Network Access: Ability to listen on TCP/UDP ports for peer connections
  • Storage: Persistent storage for peer database, shared files, and configuration
  • Memory: Minimum 512MB RAM, recommended 1GB+ for active file sharing

Step 3: Create the Dockerfile

Create a Dockerfile in your project root with a production-ready GNUnet setup:

FROM debian:bookworm-slim
# Install dependencies
RUN apt-get update && apt-get install -y \
gnunet \
gnunet-fuse \
sqlite3 \
curl \
netcat-traditional \
&& rm -rf /var/lib/apt/lists/*
# Create GNUnet user and directories
RUN useradd -m -s /bin/bash gnunet && \
mkdir -p /var/lib/gnunet/.local/share/gnunet && \
mkdir -p /var/lib/gnunet/.config/gnunet && \
mkdir -p /data/gnunet && \
chown -R gnunet:gnunet /var/lib/gnunet /data/gnunet
# Set working directory
WORKDIR /var/lib/gnunet
# Copy configuration files
COPY gnunet.conf /var/lib/gnunet/.config/gnunet/gnunet.conf
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh && \
chown gnunet:gnunet /var/lib/gnunet/.config/gnunet/gnunet.conf
# Switch to gnunet user
USER gnunet
# Expose ports for peer communication
# Port 2086 - TCP transport
# Port 2086 - UDP transport
# Port 8080 - HTTP REST API (optional)
EXPOSE 2086/tcp 2086/udp 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD gnunet-arm -I || exit 1
# Set environment variables
ENV GNUNET_HOME=/var/lib/gnunet
ENV GNUNET_DATA_HOME=/data/gnunet
# Start GNUnet services
CMD ["/usr/local/bin/start.sh"]

Dockerfile Explanation:

  • Base Image: Uses Debian Bookworm Slim with GNUnet from official repositories
  • Dependencies: Installs GNUnet core, FUSE support, SQLite, and networking tools
  • User Setup: Creates dedicated gnunet user for security
  • Directory Structure: Sets up config directories and persistent data location
  • Port Exposure: Opens TCP/UDP 2086 for peer connections, 8080 for REST API
  • Health Check: Monitors GNUnet ARM (Automatic Restart Manager) status
  • Startup Script: Launches GNUnet services with custom configuration

Step 4: Create GNUnet Configuration

Create gnunet.conf with optimized settings for containerized deployment:

[PATHS]
GNUNET_HOME = $GNUNET_HOME
GNUNET_RUNTIME_DIR = $GNUNET_HOME/.local/share/gnunet
GNUNET_USER_RUNTIME_DIR = $GNUNET_HOME/.local/share/gnunet
GNUNET_DATA_HOME = $GNUNET_DATA_HOME
[arm]
START_SYSTEM_SERVICES = YES
START_USER_SERVICES = YES
[transport-tcp]
PORT = 2086
ADVERTISED_PORT = 2086
BINDTO = 0.0.0.0
[transport-udp]
PORT = 2086
ADVERTISED_PORT = 2086
BINDTO = 0.0.0.0
[transport-http_server]
PORT = 8080
EXTERNAL_HOSTNAME = example-app.klutch.sh
ADVERTISED_PORT = 8080
[core]
USE_EPHEMERAL_KEYS = NO
TOTAL_QUOTA_IN = 50 MB
TOTAL_QUOTA_OUT = 50 MB
[datastore]
DATABASE = sqlite
QUOTA = 1 GB
BLOOMFILTER_K = 16
[fs]
START_ON_DEMAND = YES
CONTENT_CACHING = YES
CONTENT_PUSHING = YES
MAX_PENDING_REQUESTS = 65536
DELAY = 1000 ms
[dhtcache]
DATABASE = sqlite
QUOTA = 100 MB
[hostlist]
SERVERS = https://gnunet.org/hostlist
OPTIONS = -b -e
[topology]
FRIENDS = $GNUNET_DATA_HOME/friends
TARGET_CONNECTION_COUNT = 16
AUTOCONNECT = YES
FRIENDS_ONLY = NO
[nat]
DISABLEV6 = NO
ENABLE_UPNP = YES
BEHIND_NAT = YES
ENABLE_ICMP_SERVER = NO
ENABLE_ICMP_CLIENT = NO
INTERNAL_ADDRESS = 0.0.0.0
EXTERNAL_ADDRESS = example-app.klutch.sh
[gns]
START_ON_DEMAND = YES
[namestore]
DATABASE = sqlite
[rest]
BIND_TO = 0.0.0.0
PORT = 8080

Configuration Highlights:

  • Paths: Uses environment variables for flexible directory configuration
  • Transport: Configures TCP/UDP on port 2086, HTTP on port 8080
  • Storage: Uses SQLite for lightweight database needs (can be changed to PostgreSQL for production)
  • File Sharing: Enables caching and pushing with reasonable resource limits
  • NAT: Configured for containerized environments with UPnP enabled
  • Peer Discovery: Connects to GNUnet hostlist servers for bootstrapping

Step 5: Create Startup Script

Create start.sh to initialize and start GNUnet services:

#!/bin/bash
set -e
echo "Starting GNUnet services..."
# Initialize GNUnet if not already initialized
if [ ! -f "$GNUNET_DATA_HOME/.gnunet-initialized" ]; then
echo "Initializing GNUnet for first time..."
# Generate identity
gnunet-identity -C default
# Mark as initialized
touch "$GNUNET_DATA_HOME/.gnunet-initialized"
echo "GNUnet initialization complete"
fi
# Update external address if set via environment
if [ -n "$GNUNET_EXTERNAL_ADDRESS" ]; then
echo "Setting external address to: $GNUNET_EXTERNAL_ADDRESS"
sed -i "s/example-app.klutch.sh/$GNUNET_EXTERNAL_ADDRESS/g" ~/.config/gnunet/gnunet.conf
fi
# Start GNUnet ARM (Automatic Restart Manager)
echo "Starting GNUnet ARM..."
gnunet-arm -s
# Wait for services to start
sleep 5
# Verify services are running
echo "Verifying GNUnet services..."
gnunet-arm -I
echo "GNUnet is running!"
echo "Transport endpoints:"
gnunet-transport -i
# Keep container running by following logs
tail -f ~/.local/share/gnunet/*.log

Startup Script Features:

  • First-Run Initialization: Generates peer identity on first startup
  • Configuration Updates: Applies external address from environment variables
  • Service Management: Uses GNUnet ARM to start and monitor services
  • Health Verification: Checks that all services started successfully
  • Log Streaming: Keeps container alive while providing log output

Step 6: Create .dockerignore

Create .dockerignore to exclude unnecessary files:

.git
.gitignore
README.md
*.log
node_modules
.env
*.db
*.db-shm
*.db-wal

Step 7: Create Documentation

Create README.md with deployment information:

# GNUnet on Klutch.sh
Privacy-focused peer-to-peer networking framework deployed on Klutch.sh.
## Features
- Secure peer-to-peer communication
- Anonymous file sharing
- Decentralized DHT storage
- GNU Name System (GNS) support
- Censorship-resistant messaging
- Privacy by design architecture
## Architecture
GNUnet runs as a containerized application with:
- TCP/UDP transport on port 2086 for peer connections
- HTTP REST API on port 8080 (optional)
- SQLite database for local storage
- Persistent volumes for peer data and shared files
## Configuration
Key configuration options in gnunet.conf:
- **Transport**: TCP/UDP/HTTP protocols for peer communication
- **Storage**: SQLite for datastore, DHT cache, and namestore
- **File Sharing**: Enabled with caching and pushing
- **Peer Discovery**: Automatic connection to hostlist servers
- **NAT**: Configured for containerized deployment with UPnP
## Deployment
Deploy to Klutch.sh with the provided Dockerfile. See deployment guide for full instructions.
## Environment Variables
- `GNUNET_EXTERNAL_ADDRESS`: External hostname/IP for peer connections
- `GNUNET_HOME`: Home directory for GNUnet (default: /var/lib/gnunet)
- `GNUNET_DATA_HOME`: Data directory for persistent storage (default: /data/gnunet)
## Persistent Storage
Mount persistent volumes for:
- `/data/gnunet` - Peer database, shared files, and configuration
## Ports
- **2086/tcp** - TCP transport for peer connections
- **2086/udp** - UDP transport for peer connections
- **8080/tcp** - HTTP REST API (optional)
## Usage
After deployment, use GNUnet CLI tools to interact with the network:
```bash
# Check running services
gnunet-arm -I
# View connected peers
gnunet-core
# Share a file
gnunet-publish /path/to/file
# Search for files
gnunet-search keyword
# Download a file
gnunet-download gnunet://fs/chk/HASH...

Resources

### Step 8: Initialize Git Repository
Initialize a Git repository and push to GitHub:
```bash
# Initialize repository
git init
# Add files
git add Dockerfile gnunet.conf start.sh .dockerignore README.md
# Commit
git commit -m "Initial GNUnet deployment setup"
# Add remote (replace with your repository URL)
git remote add origin https://github.com/yourusername/gnunet-deploy.git
# Push to GitHub
git push -u origin main

Deploying on Klutch.sh

With your repository prepared, deploy GNUnet on Klutch.sh:

import { Steps } from ‘@astrojs/starlight/components’;

  1. **Log in to Klutch.sh Dashboard**

    Navigate to klutch.sh/app and log in to your account.

  2. **Create New Application**

    Click “New”“Application” to start a new deployment.

  3. **Connect GitHub Repository**
    • Select GitHub as your git source
    • Choose your gnunet-deploy repository
    • Select the main branch for deployment
  4. **Configure Network Settings**

    GNUnet requires TCP access for peer connections:

    • Traffic Type: Select TCP
    • External Port: Klutch.sh routes to port 8000 externally
    • Internal Port: Set to 2086 (GNUnet’s TCP transport port)

    Important: Your GNUnet peers will connect to your deployment at example-app.klutch.sh:8000, which routes to internal port 2086.

  5. **Add Environment Variables**

    Configure the following environment variables in the Klutch.sh dashboard:

    Required:

    • GNUNET_EXTERNAL_ADDRESS: Your Klutch.sh domain (e.g., example-app.klutch.sh)

    Optional:

    • GNUNET_HOME: /var/lib/gnunet (default, usually not needed)
    • GNUNET_DATA_HOME: /data/gnunet (default, usually not needed)
  6. **Attach Persistent Volumes**

    GNUnet requires persistent storage for peer databases and shared files:

    Volume Configuration:

    • Mount Path: /data/gnunet
    • Size: Start with 10 GB (increase based on file sharing needs)

    This volume stores:

    • Peer identity and configuration
    • DHT and datastore databases
    • Shared files and metadata
    • Friend list and peer topology
  7. **Configure Compute Resources**

    Set appropriate resources based on your usage:

    Recommended Resources:

    • CPU: 1 core (sufficient for moderate peer activity)
    • Memory: 1 GB RAM (minimum 512 MB, more for heavy file sharing)
    • Instances: 1 (GNUnet peer identity is bound to instance)

    For Heavy File Sharing:

    • CPU: 2 cores
    • Memory: 2 GB RAM
    • Storage: 50+ GB depending on content
  8. **Deploy Your Application**
    • Review your configuration settings
    • Click “Create” to start the deployment
    • Monitor build logs for any issues
    • Wait for deployment to complete (typically 2-3 minutes)
  9. **Verify Deployment**

    Once deployed, verify GNUnet is running:

    • Check the deployment logs for “GNUnet is running!” message
    • View transport endpoints in the logs
    • Access the application URL to confirm connectivity

Your GNUnet peer is now live and ready to connect to the GNUnet network!


Verification and Testing

After deployment, verify your GNUnet installation is working correctly:

Check Service Status

Access your container logs to verify services are running:

GNUnet ARM...
Starting GNUnet services...
transport (gnunet-service-transport)
core (gnunet-service-core)
datastore (gnunet-service-datastore)
fs (gnunet-service-fs)
dht (gnunet-service-dht)
...
GNUnet is running!

Verify Peer Connectivity

Check your peer’s external addresses:

Transport endpoints:
tcp://example-app.klutch.sh:8000
udp://example-app.klutch.sh:8000
http://example-app.klutch.sh:8080

Test File Sharing

To test file sharing functionality, you’ll need to access the container shell. Use the GNUnet CLI tools:

Terminal window
# Create a test file
echo "Hello GNUnet!" > test.txt
# Publish the file
gnunet-publish test.txt
# Output will show:
# Publishing `/data/test.txt' done.
# URI is gnunet://fs/chk/HASH...

Verify DHT Participation

Check that your peer is participating in the DHT:

Terminal window
# View DHT routing table
gnunet-dht-get -t txt "test-key"
# Should show DHT is operational

Monitor Peer Connections

Watch active peer connections:

Terminal window
# List connected peers
gnunet-core
# Should show:
# Peer `PEER_ID' is connected (direct)
# ...

Configuration Options

Transport Configuration

GNUnet supports multiple transport protocols. Configure in gnunet.conf:

TCP Transport (Primary):

[transport-tcp]
PORT = 2086
ADVERTISED_PORT = 2086
BINDTO = 0.0.0.0

UDP Transport (Fast, NAT-friendly):

[transport-udp]
PORT = 2086
ADVERTISED_PORT = 2086
BINDTO = 0.0.0.0

HTTP Transport (Firewall-friendly):

[transport-http_server]
PORT = 8080
EXTERNAL_HOSTNAME = your-domain.klutch.sh

Storage Configuration

SQLite (Default, Lightweight):

[datastore]
DATABASE = sqlite
QUOTA = 1 GB
[dhtcache]
DATABASE = sqlite
QUOTA = 100 MB

PostgreSQL (Production, Scalable):

If you have a PostgreSQL database deployed (see our PostgreSQL guide):

[datastore]
DATABASE = postgres
CONFIG = postgresql://user:password@postgres-host:8000/gnunet
QUOTA = 10 GB

File Sharing Configuration

Control file sharing behavior:

[fs]
START_ON_DEMAND = YES
CONTENT_CACHING = YES # Cache files for faster retrieval
CONTENT_PUSHING = YES # Push content to other peers
MAX_PENDING_REQUESTS = 65536
DELAY = 1000 ms # Artificial delay for anonymity
ANONYMITY_LEVEL = 1 # 0-3, higher = more anonymous

Anonymity Levels:

  • 0: No anonymity (direct transfers)
  • 1: Single-hop routing
  • 2: Multi-hop routing (balanced)
  • 3: Maximum anonymity (slower)

Peer Discovery Configuration

Configure how your peer discovers others:

[topology]
TARGET_CONNECTION_COUNT = 16 # Desired peer connections
AUTOCONNECT = YES # Automatic peer discovery
FRIENDS_ONLY = NO # Connect only to trusted friends
[hostlist]
SERVERS = https://gnunet.org/hostlist
OPTIONS = -b -e # Bootstrap from hostlist

NAT Configuration

For deployments behind NAT (Klutch.sh environments):

[nat]
BEHIND_NAT = YES
ENABLE_UPNP = YES # Attempt UPnP port mapping
EXTERNAL_ADDRESS = your-domain.klutch.sh
INTERNAL_ADDRESS = 0.0.0.0

Using GNUnet

File Sharing

Publishing Files:

To publish files to the GNUnet network, you’ll need shell access to your container:

Terminal window
# Publish a file with indexing (efficient)
gnunet-publish -i filename.txt
# Publish with insertion (full copy to network)
gnunet-publish filename.txt
# Publish with keywords
gnunet-publish -k "keyword1" -k "keyword2" filename.txt
# Publish with metadata
gnunet-publish -m "title:My Document" -m "author:Your Name" file.pdf

Searching for Files:

Terminal window
# Search by keyword
gnunet-search "keyword"
# Search with specific timeout
gnunet-search -t 30s "keyword"
# Output shows:
# gnunet://fs/chk/HASH... (filename.txt)

Downloading Files:

Terminal window
# Download by URI
gnunet-download gnunet://fs/chk/HASH...
# Download to specific location
gnunet-download -o /path/to/output.txt gnunet://fs/chk/HASH...
# Download with anonymity level
gnunet-download -a 2 gnunet://fs/chk/HASH...

GNU Name System (GNS)

GNS provides decentralized, privacy-preserving name resolution:

Create a Zone (Namespace):

Terminal window
# Create a new identity/zone
gnunet-identity -C myzone

Add Records:

Terminal window
# Add an A record (IPv4)
gnunet-namestore -z myzone -a -e 1d -t A -n www -V 192.168.1.1
# Add a GNS record (point to another GNS name)
gnunet-namestore -z myzone -a -e 1d -t PKEY -n subdomain -V PKEY_VALUE
# Add a file sharing record
gnunet-namestore -z myzone -a -e never -t FS -n myfile -V "gnunet://fs/chk/HASH..."

Resolve Names:

Terminal window
# Resolve a GNS name
gnunet-gns -u www.myzone.gnu
# Resolve with type specification
gnunet-gns -t A -u www.myzone.gnu

Peer Management

View Connected Peers:

Terminal window
# List all connected peers
gnunet-core
# Output:
# Peer `PEER_ID` is connected
# ...

Manage Friend List:

Create a friends file for trusted peer connections:

Terminal window
# Add friend (create /data/gnunet/friends file)
echo "PEER_ID" >> /data/gnunet/friends
# Configure to use friends only
# In gnunet.conf:
# [topology]
# FRIENDS_ONLY = YES

Service Management

View Running Services:

Terminal window
# List all GNUnet services
gnunet-arm -I
# Output:
# transport (gnunet-service-transport) - running
# core (gnunet-service-core) - running
# ...

Restart Specific Services:

Terminal window
# Restart file sharing service
gnunet-arm -r fs
# Start a stopped service
gnunet-arm -i dht
# Stop a service
gnunet-arm -k fs

Production Best Practices

Security Hardening

1. Use Strong Peer Identity

Your peer identity is automatically generated, but ensure it’s backed up:

Terminal window
# Backup peer identity (from container)
cp ~/.local/share/gnunet/private_key.ecc /data/gnunet/backup/

2. Implement Friend-Only Mode (Optional)

For private networks, enable friends-only mode:

[topology]
FRIENDS_ONLY = YES
FRIENDS = /data/gnunet/friends

3. Configure Firewall Rules

On Klutch.sh, ensure only necessary ports are exposed:

  • Port 2086: Peer connections (TCP/UDP)
  • Port 8080: REST API (only if needed, consider restricting access)

4. Regular Updates

Keep GNUnet updated by rebuilding your Docker image with latest packages:

# In Dockerfile, periodically update base image
FROM debian:bookworm-slim
RUN apt-get update && apt-get upgrade -y gnunet

Performance Optimization

1. Database Configuration

For production deployments with heavy file sharing, use PostgreSQL instead of SQLite:

[datastore]
DATABASE = postgres
CONFIG = postgresql://user:password@postgres-host:8000/gnunet
QUOTA = 100 GB
[dhtcache]
DATABASE = postgres
CONFIG = postgresql://user:password@postgres-host:8000/gnunet_dht
QUOTA = 10 GB

Deploy PostgreSQL following our PostgreSQL deployment guide.

2. Bandwidth Management

Control bandwidth usage in gnunet.conf:

[core]
TOTAL_QUOTA_IN = 100 MB # Incoming bandwidth limit
TOTAL_QUOTA_OUT = 100 MB # Outgoing bandwidth limit

Adjust based on your Klutch.sh instance capacity and network requirements.

3. Connection Limits

Optimize peer connections for your resources:

[topology]
TARGET_CONNECTION_COUNT = 32 # More connections = better routing
AUTOCONNECT = YES

Higher connection counts improve routing but consume more resources.

4. Storage Quotas

Set appropriate storage limits:

[datastore]
QUOTA = 50 GB # Adjust based on volume size
[dhtcache]
QUOTA = 5 GB # DHT cache size

Ensure quotas are lower than your persistent volume size.

Monitoring and Maintenance

1. Health Monitoring

The Dockerfile includes a health check, but you can also manually monitor:

Terminal window
# Check service status
gnunet-arm -I
# View statistics
gnunet-statistics
# Monitor transport connections
gnunet-transport -i

2. Log Analysis

GNUnet logs are stored in ~/.local/share/gnunet/*.log:

Terminal window
# View core service logs
tail -f ~/.local/share/gnunet/gnunet-service-core.log
# View transport logs
tail -f ~/.local/share/gnunet/gnunet-service-transport.log
# View file sharing logs
tail -f ~/.local/share/gnunet/gnunet-service-fs.log

3. Resource Monitoring

Monitor container resources through Klutch.sh dashboard:

  • CPU usage (should be < 80% average)
  • Memory usage (watch for leaks)
  • Storage usage (ensure sufficient space for growth)
  • Network I/O (bandwidth consumption)

4. Backup Strategy

Implement regular backups of critical data:

Terminal window
# Backup peer identity
/data/gnunet/private_key.ecc
# Backup configuration
/data/gnunet/gnunet.conf
# Backup friend list
/data/gnunet/friends
# Backup shared files metadata
/data/gnunet/datastore/

Use Klutch.sh volume snapshots or export data regularly.

Scaling Considerations

1. Vertical Scaling

Increase resources for a single peer:

  • CPU: Scale to 2-4 cores for heavy file sharing
  • Memory: 2-4 GB for large datastore
  • Storage: Expand volume as needed (10-100+ GB)

2. Bandwidth Requirements

Estimate bandwidth needs:

  • Light Use: 1-5 Mbps (minimal file sharing)
  • Moderate Use: 5-20 Mbps (active peer, some sharing)
  • Heavy Use: 20-100+ Mbps (major file sharing node)

3. Storage Growth

Plan for storage growth:

  • Datastore: Grows with published/cached files
  • DHT Cache: Relatively stable (quota-limited)
  • Logs: Rotate logs to prevent unbounded growth

Troubleshooting

Common Issues and Solutions

Issue: Peer Not Connecting to Network

Symptoms: No peer connections, gnunet-core shows no peers

Solutions:

  1. Verify transport configuration in gnunet.conf

  2. Check external address is correctly set

  3. Ensure port 2086 is accessible

  4. Verify hostlist servers are reachable:

    Terminal window
    curl https://gnunet.org/hostlist
  5. Check logs for connection errors:

    Terminal window
    tail -f ~/.local/share/gnunet/gnunet-service-transport.log

Issue: File Sharing Not Working

Symptoms: Cannot publish or download files

Solutions:

  1. Verify FS service is running:

    Terminal window
    gnunet-arm -I | grep fs
  2. Check datastore quota not exceeded:

    Terminal window
    gnunet-statistics -s datastore
  3. Restart file sharing service:

    Terminal window
    gnunet-arm -r fs
  4. Verify sufficient disk space on persistent volume

Issue: High Memory Usage

Symptoms: Container using excessive RAM, potential OOM kills

Solutions:

  1. Reduce connection count in gnunet.conf:

    [topology]
    TARGET_CONNECTION_COUNT = 8
  2. Lower datastore quota:

    [datastore]
    QUOTA = 1 GB
  3. Disable content caching:

    [fs]
    CONTENT_CACHING = NO
  4. Scale up memory in Klutch.sh dashboard

Issue: Slow File Downloads

Symptoms: Downloads taking unusually long time

Solutions:

  1. Reduce anonymity level (less hops):

    Terminal window
    gnunet-download -a 1 URI
  2. Increase bandwidth quotas:

    [core]
    TOTAL_QUOTA_IN = 200 MB
    TOTAL_QUOTA_OUT = 200 MB
  3. Connect to more peers (better routing):

    [topology]
    TARGET_CONNECTION_COUNT = 32
  4. Check network latency to other peers

Issue: Database Corruption

Symptoms: Services failing to start, database errors in logs

Solutions:

  1. Stop GNUnet services:

    Terminal window
    gnunet-arm -e
  2. Backup current database:

    Terminal window
    cp -r /data/gnunet /data/gnunet-backup
  3. Remove corrupted database:

    Terminal window
    rm -rf ~/.local/share/gnunet/*.db
  4. Restart services (will recreate database):

    Terminal window
    gnunet-arm -s

Issue: GNS Resolution Not Working

Symptoms: Cannot resolve .gnu names

Solutions:

  1. Verify GNS service is running:

    Terminal window
    gnunet-arm -I | grep gns
  2. Check namestore service:

    Terminal window
    gnunet-arm -I | grep namestore
  3. Test with known GNS name:

    Terminal window
    gnunet-gns -u www.gnu
  4. Verify DNS configuration (if using system-wide GNS)

Debugging Tips

Enable Verbose Logging:

Modify gnunet.conf to increase log verbosity:

[arm]
OPTIONS = -L DEBUG
[transport]
OPTIONS = -L DEBUG
[fs]
OPTIONS = -L DEBUG

Redeploy to see detailed logs.

Check Configuration:

Verify configuration is loaded correctly:

Terminal window
# Dump current configuration
gnunet-config -s
# Check specific option
gnunet-config -s transport-tcp -o PORT

Network Diagnostics:

Test connectivity from inside container:

Terminal window
# Test external connectivity
curl -v https://gnunet.org/
# Test UDP connectivity
nc -u -v -z example-app.klutch.sh 2086
# Check listening ports
netstat -tuln | grep 2086

Advanced Configuration

Using PostgreSQL for Production

For production deployments with high file sharing activity, PostgreSQL provides better performance than SQLite.

1. Deploy PostgreSQL

Follow our PostgreSQL deployment guide to set up a database instance.

2. Create GNUnet Databases

Connect to PostgreSQL and create databases:

CREATE DATABASE gnunet_datastore;
CREATE DATABASE gnunet_dhtcache;
CREATE DATABASE gnunet_namestore;
-- Create user
CREATE USER gnunet WITH PASSWORD 'secure_password';
-- Grant permissions
GRANT ALL PRIVILEGES ON DATABASE gnunet_datastore TO gnunet;
GRANT ALL PRIVILEGES ON DATABASE gnunet_dhtcache TO gnunet;
GRANT ALL PRIVILEGES ON DATABASE gnunet_namestore TO gnunet;

3. Update GNUnet Configuration

Modify gnunet.conf:

[datastore]
DATABASE = postgres
CONFIG = postgresql://gnunet:secure_password@postgres-host.klutch.sh:8000/gnunet_datastore
QUOTA = 100 GB
[dhtcache]
DATABASE = postgres
CONFIG = postgresql://gnunet:secure_password@postgres-host.klutch.sh:8000/gnunet_dhtcache
QUOTA = 10 GB
[namestore]
DATABASE = postgres
CONFIG = postgresql://gnunet:secure_password@postgres-host.klutch.sh:8000/gnunet_namestore

4. Update Dockerfile

Add PostgreSQL client libraries:

RUN apt-get update && apt-get install -y \
gnunet \
gnunet-fuse \
postgresql-client \
libpq-dev \
curl \
&& rm -rf /var/lib/apt/lists/*

5. Redeploy

Commit changes and push to trigger redeployment on Klutch.sh.

Running Multiple GNUnet Services

You can deploy multiple specialized GNUnet instances:

1. File Sharing Node

Optimized for file storage and sharing:

[fs]
CONTENT_CACHING = YES
CONTENT_PUSHING = YES
[datastore]
QUOTA = 500 GB
[topology]
TARGET_CONNECTION_COUNT = 64

2. DHT Bootstrap Node

Optimized for peer discovery:

[dht]
START_ON_DEMAND = YES
[dhtcache]
QUOTA = 50 GB
[topology]
TARGET_CONNECTION_COUNT = 128

3. GNS Resolver

Dedicated name resolution service:

[gns]
START_ON_DEMAND = YES
[namestore]
DATABASE = postgres
QUOTA = 10 GB

Deploy each as separate Klutch.sh applications for specialized roles.

Custom Transport Plugins

GNUnet supports custom transport plugins. To add Bluetooth or WLAN support:

1. Install Dependencies

Add to Dockerfile:

RUN apt-get install -y \
bluetooth \
bluez \
libbluetooth-dev

2. Configure Transport

Add to gnunet.conf:

[transport-bluetooth]
DEVICE = hci0

3. Rebuild and Redeploy

Note: Bluetooth transport requires host device access, which may not be available in containerized environments.


Additional Resources

Klutch.sh Resources:


Conclusion

You now have a fully functional GNUnet peer running on Klutch.sh! Your privacy-focused peer-to-peer node is ready to participate in the GNUnet network for secure file sharing, decentralized name resolution, and censorship-resistant communication.

GNUnet’s architecture provides strong privacy guarantees through end-to-end encryption, traffic obfuscation, and multi-hop routing. With persistent storage on Klutch.sh, your peer can maintain its identity and contribute to the decentralized network long-term.

Remember to:

  • Keep your peer identity backed up (it’s your unique identifier on the network)
  • Monitor storage usage as your datastore grows
  • Scale resources based on your file sharing activity
  • Consider PostgreSQL for production deployments
  • Participate in the GNUnet community for support and contributions

For additional support or questions about deploying GNUnet on Klutch.sh, refer to the official documentation and community resources linked above.

Next Steps:

  1. Share your peer ID with friends for direct connections
  2. Publish files to the network and test anonymous downloading
  3. Experiment with GNS for decentralized name resolution
  4. Join the GNUnet community to learn about advanced features
  5. Consider running specialized services (DHT bootstrap, file sharing node, etc.)

Happy peer-to-peer networking! 🔐🌐