Finished BUD 1

This commit is contained in:
Your Name
2025-08-18 21:51:54 -04:00
parent e641c813eb
commit 95ccb3a9c4
24 changed files with 1728 additions and 31 deletions

233
config/deploy.sh Executable file
View File

@@ -0,0 +1,233 @@
#!/bin/bash
set -euo pipefail
# Ginxsom Deployment Script
# This script sets up the ginxsom blossom server configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_root() {
if [[ $EUID -eq 0 ]]; then
log_error "This script should not be run as root. Please run as a regular user with sudo access."
exit 1
fi
}
check_dependencies() {
log_info "Checking dependencies..."
if ! command -v nginx &> /dev/null; then
log_error "nginx is not installed. Please install nginx first."
exit 1
fi
if ! command -v systemctl &> /dev/null; then
log_error "systemctl is not available. This script requires systemd."
exit 1
fi
log_info "Dependencies check passed."
}
create_directories() {
log_info "Creating required directories..."
# Create data directories
sudo mkdir -p /var/lib/ginxsom/files
sudo mkdir -p /var/lib/ginxsom/db
sudo mkdir -p /run/ginxsom
sudo mkdir -p /var/log/ginxsom
sudo mkdir -p /etc/ginxsom
log_info "Directories created."
}
create_user() {
log_info "Creating ginxsom user..."
if ! id "ginxsom" &>/dev/null; then
sudo useradd --system --no-create-home --shell /bin/false ginxsom
log_info "User 'ginxsom' created."
else
log_info "User 'ginxsom' already exists."
fi
}
set_permissions() {
log_info "Setting file permissions..."
# Set ownership of data directories
sudo chown -R ginxsom:ginxsom /var/lib/ginxsom
sudo chown -R ginxsom:ginxsom /run/ginxsom
sudo chown -R ginxsom:ginxsom /var/log/ginxsom
sudo chown -R ginxsom:ginxsom /etc/ginxsom
# Set proper permissions
sudo chmod 755 /var/lib/ginxsom
sudo chmod 755 /var/lib/ginxsom/files
sudo chmod 755 /var/lib/ginxsom/db
sudo chmod 755 /run/ginxsom
sudo chmod 755 /var/log/ginxsom
sudo chmod 755 /etc/ginxsom
log_info "Permissions set."
}
deploy_nginx_config() {
log_info "Deploying nginx configuration..."
# Copy nginx configuration
sudo cp "$SCRIPT_DIR/nginx/ginxsom.conf" /etc/nginx/sites-available/ginxsom
# Enable the site
if [[ ! -L /etc/nginx/sites-enabled/ginxsom ]]; then
sudo ln -sf /etc/nginx/sites-available/ginxsom /etc/nginx/sites-enabled/ginxsom
log_info "Nginx site enabled."
else
log_info "Nginx site already enabled."
fi
# Test nginx configuration
if sudo nginx -t; then
log_info "Nginx configuration test passed."
else
log_error "Nginx configuration test failed. Please check the configuration."
exit 1
fi
}
deploy_systemd_service() {
log_info "Deploying systemd service..."
# Copy systemd service file
sudo cp "$SCRIPT_DIR/systemd/ginxsom.service" /etc/systemd/system/ginxsom.service
# Reload systemd
sudo systemctl daemon-reload
log_info "Systemd service installed."
}
create_sample_config() {
log_info "Creating sample configuration..."
if [[ ! -f /etc/ginxsom/config.toml ]]; then
sudo tee /etc/ginxsom/config.toml > /dev/null << 'EOF'
# Ginxsom Blossom Server Configuration
[server]
# FastCGI socket path
socket = "/run/ginxsom/ginxsom.sock"
# Data directory for files
data_dir = "/var/lib/ginxsom"
# Maximum file size in bytes (100MB)
max_file_size = 104857600
[logging]
level = "info"
file = "/var/log/ginxsom/ginxsom.log"
[storage]
# File storage directory
files_dir = "/var/lib/ginxsom/files"
# Database file for metadata
database = "/var/lib/ginxsom/db/ginxsom.db"
[auth]
# Enable authentication for uploads
require_auth = true
# Enable list endpoint
enable_list = false
# Enable mirror endpoint
enable_mirror = false
EOF
sudo chown ginxsom:ginxsom /etc/ginxsom/config.toml
sudo chmod 640 /etc/ginxsom/config.toml
log_info "Sample configuration created at /etc/ginxsom/config.toml"
else
log_info "Configuration file already exists at /etc/ginxsom/config.toml"
fi
}
show_status() {
log_info "Deployment complete! Next steps:"
echo ""
echo "1. Build and install the ginxsom binary:"
echo " cd $PROJECT_ROOT"
echo " make build"
echo " sudo make install"
echo ""
echo "2. Start the services:"
echo " sudo systemctl enable ginxsom"
echo " sudo systemctl start ginxsom"
echo " sudo systemctl reload nginx"
echo ""
echo "3. Check status:"
echo " sudo systemctl status ginxsom"
echo " sudo systemctl status nginx"
echo ""
echo "4. Test the server:"
echo " curl http://localhost/health"
echo ""
echo "Configuration files:"
echo " - Nginx: /etc/nginx/sites-available/ginxsom"
echo " - SystemD: /etc/systemd/system/ginxsom.service"
echo " - Config: /etc/ginxsom/config.toml"
echo ""
}
main() {
log_info "Starting ginxsom deployment..."
check_root
check_dependencies
create_user
create_directories
set_permissions
deploy_nginx_config
deploy_systemd_service
create_sample_config
show_status
log_info "Deployment script completed successfully!"
}
# Parse command line arguments
case "${1:-}" in
--help|-h)
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " --help, -h Show this help message"
echo ""
echo "This script deploys the ginxsom blossom server configuration."
exit 0
;;
*)
main "$@"
;;
esac

109
config/local-nginx.conf Normal file
View File

@@ -0,0 +1,109 @@
# Local Ginxsom Development Server Configuration
# This configuration serves files directly from the local repo directory
# Main context - specify error log here to override system default
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
# HTTP context
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging (relative to prefix directory)
access_log logs/access.log;
# FastCGI upstream configuration
upstream fastcgi_backend {
server unix:/tmp/ginxsom-fcgi.sock;
}
# Local development server
server {
listen 9001;
server_name localhost;
# Root directory for blossom files (local blobs directory)
root blobs;
# Maximum upload size (adjust as needed)
client_max_body_size 100M;
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
# Handle GET and HEAD requests for blob files - Blossom compliant
location ~ "^/([a-f0-9]{64}).*$" {
limit_except HEAD GET {
deny all;
}
# Route HEAD requests to FastCGI via rewrite
if ($request_method = HEAD) {
rewrite ^/(.*)$ /fcgi-head/$1 last;
}
# GET requests served directly with hash-only lookup
try_files /$1* =404;
# Set appropriate headers for blobs
add_header Cache-Control "public, max-age=31536000, immutable";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
}
# FastCGI handler for HEAD requests
location ~ "^/fcgi-head/([a-f0-9]{64}).*$" {
internal;
fastcgi_pass fastcgi_backend;
fastcgi_param REQUEST_METHOD HEAD;
fastcgi_param REQUEST_URI /$1;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
}
# Health check endpoint
location /health {
access_log off;
return 200 "OK\n";
add_header Content-Type text/plain;
}
# List files endpoint for debugging
location /debug/list {
autoindex on;
autoindex_format json;
}
# Root redirect
location = / {
return 200 "Ginxsom Local Development Server\nTry: GET /<sha256>\nHealth: GET /health\n";
add_header Content-Type text/plain;
}
}
}

131
config/nginx/ginxsom.conf Normal file
View File

@@ -0,0 +1,131 @@
# Ginxsom Blossom Server Configuration
# This configuration serves files directly via nginx for maximum performance
# while handling authenticated operations through FastCGI
server {
listen 80;
server_name localhost; # Change this to your domain
# Root directory for blossom files (organized by SHA-256 hash)
root /var/lib/ginxsom/files;
# Maximum upload size (adjust as needed)
client_max_body_size 100M;
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
# Logging
access_log /var/log/nginx/ginxsom_access.log;
error_log /var/log/nginx/ginxsom_error.log;
# Static file serving - nginx handles this directly for maximum performance
# Files are stored as: /var/lib/ginxsom/files/{first2chars}/{remaining_hash}
location ~ ^/([a-f0-9]{64})$ {
set $hash $1;
set $prefix $1; # First 2 characters
set $suffix $1; # Remaining characters
# Extract first 2 chars and remaining
if ($hash ~ ^([a-f0-9]{2})([a-f0-9]{62})$) {
set $prefix $1;
set $suffix $2;
}
try_files /$prefix/$suffix =404;
# Set proper content type based on file extension in metadata
# This will be enhanced when we add metadata lookup
add_header Content-Type application/octet-stream;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# HEAD requests for file existence checking
# This endpoint checks if a file exists and returns metadata
location ~ ^/head/([a-f0-9]{64})$ {
# Pass to FastCGI application for metadata lookup
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_param REQUEST_METHOD HEAD;
fastcgi_param BLOSSOM_HASH $1;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
}
# Upload endpoint - requires authentication
location /upload {
# Pass to FastCGI application for processing
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
# Only allow PUT method for uploads
if ($request_method !~ ^(PUT)$ ) {
return 405;
}
}
# List endpoint - returns list of files (if enabled)
location /list {
# Pass to FastCGI application
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
# Only allow GET method
if ($request_method !~ ^(GET)$ ) {
return 405;
}
}
# Mirror endpoint - for mirroring files from other servers
location /mirror {
# Pass to FastCGI application
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
# Only allow PUT method
if ($request_method !~ ^(PUT)$ ) {
return 405;
}
}
# Delete endpoint - requires authentication
location ~ ^/([a-f0-9]{64})$ {
# Handle DELETE requests through FastCGI
if ($request_method = DELETE) {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_param BLOSSOM_HASH $1;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
}
# For GET/HEAD, fall through to static file serving above
}
# Health check endpoint
location /health {
# Pass to FastCGI application
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
access_log off;
}
# Deny access to hidden files and directories
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny access to backup and temporary files
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
}

View File

@@ -0,0 +1,47 @@
[Unit]
Description=Ginxsom Blossom Server FastCGI Application
After=network.target
Wants=network-online.target
After=network-online.target
[Service]
Type=notify
User=ginxsom
Group=ginxsom
WorkingDirectory=/var/lib/ginxsom
ExecStart=/usr/local/bin/ginxsom --fastcgi --socket /run/ginxsom/ginxsom.sock
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=5s
# Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/ginxsom /run/ginxsom /var/log/ginxsom
PrivateTmp=true
PrivateDevices=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
# Environment
Environment=GINXSOM_CONFIG=/etc/ginxsom/config.toml
Environment=GINXSOM_DATA_DIR=/var/lib/ginxsom
Environment=GINXSOM_LOG_LEVEL=info
[Install]
WantedBy=multi-user.target