Tool DevOps untuk melakukan remote deployment dan eksekusi command pada server private melalui protokol HTTP. Cocok untuk server yang hanya bisa diakses via port 80/443 tanpa VPN.
Click to expand screenshots
Modern glassmorphism login page with animated gradient background.
Overview of deployment statistics and recent activity.
Manage applications with deployment tokens for CI/CD integration.
Configure deployment commands with shell scripts.
Track all command executions with status and output.
Interactive WebSocket-based terminal with full PTY support.
Browse and manage server files securely.
Track all user actions for security compliance.
Configure account settings and enable Two-Factor Authentication.
Enable 2FA with QR code for authenticator apps.
- Modern React SPA UI - Built with React 18, TypeScript, and Tailwind CSS
- 2FA/TOTP Support - Two-factor authentication with encrypted secret storage (AES-256-GCM)
- Backup Codes - Recovery codes for 2FA with encryption
- Remote Terminal - Interactive WebSocket-based shell access with PTY support
- Web UI & REST API - Dashboard web dan API untuk otomatisasi
- App Management - Kelola multiple aplikasi/project
- Command Templates - Simpan command deployment untuk reuse
- Real-time Output - Streaming output via SSE (Server-Sent Events)
- Session Auth - Login dengan username/password untuk Web UI
- Token Auth - Deploy via API menggunakan token (untuk CI/CD)
- UUID Identifiers - Semua resource menggunakan UUID
- SQLite Database - Portable, tidak perlu database server
- Single Binary - Semua assets (HTML, CSS, JS) embedded dalam satu executable
- Audit Logging - Track all user actions and executions
- Rate Limiting - Protection against brute force attacks
- Go 1.21+
- GCC (untuk kompilasi SQLite)
- Node.js 18+ and npm (for building frontend)
Binary sudah include semua assets (HTML, CSS, JS) - tidak perlu folder web/ terpisah.
# Clone repository
git clone https://github.com/pandeptwidyaop/http-remote.git
cd http-remote
# Build frontend (React SPA)
cd web
npm install
npm run build
cd ..
# Build single binary (includes embedded frontend assets)
go build -o http-remote ./cmd/server
# Run dari mana saja (tidak perlu folder web/)
./http-remote
# Atau dengan config custom
./http-remote -config /path/to/config.yaml# Build untuk Linux AMD64
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc \
go build -ldflags="-s -w" -o http-remote-linux-amd64 ./cmd/server
# Build untuk Linux ARM64
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=aarch64-linux-musl-gcc \
go build -ldflags="-s -w" -o http-remote-linux-arm64 ./cmd/serverNote: Cross-compile membutuhkan musl-cross toolchain karena CGO (SQLite). Install via:
brew install FiloSottile/musl-cross/musl-cross
Buat file config.yaml:
server:
host: "0.0.0.0"
port: 8080
path_prefix: "/devops"
secure_cookie: false # Set true for production (requires HTTPS)
database:
path: "./data/deploy.db"
auth:
session_duration: "24h"
bcrypt_cost: 12
execution:
default_timeout: 300 # seconds
max_timeout: 3600 # seconds
max_output_size: 10485760 # 10MB
admin:
username: "admin"
password: "your-secure-password" # REQUIRED: Must NOT be "changeme"
terminal:
shell: "/bin/bash" # Shell to use (default: /bin/bash)
args: ["-l"] # Shell arguments (default: ["-l"] for login shell)
env: # Additional environment variables
- "SUDO_ASKPASS=/usr/bin/ssh-askpass"
# enabled: true # Set to false to disable terminal feature
# Security settings (REQUIRED)
security:
# 32-byte encryption key for TOTP secrets (64 hex characters)
# Generate with: openssl rand -hex 32
encryption_key: "your-64-char-hex-key-here"
# Account lockout settings (brute force protection)
max_login_attempts: 5 # Lock after 5 failed attempts (default: 5)
lockout_duration: "15m" # Lock for 15 minutes (default: 15m)
# File browser security settings (optional)
files:
# Whitelist: Only allow access to these paths (if set, all other paths are blocked)
allowed_paths:
- "/home/devops"
- "/opt/apps"
# Blacklist: Block access to these paths (in addition to system paths)
blocked_paths:
- "/home/devops/.ssh"
- "/home/devops/.gnupg"admin.password: Must be changed from "changeme" to a secure passwordsecurity.encryption_key: Must be set to a 64-character hex string (32 bytes)
Generate an encryption key with:
openssl rand -hex 32The application will refuse to start if these requirements are not met.
Jika menggunakan Nginx sebagai reverse proxy untuk HTTP Remote:
# /etc/nginx/sites-available/devops.conf
upstream http_remote {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80;
server_name devops.example.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name devops.example.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/devops.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/devops.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy settings for /devops path
location /devops {
proxy_pass http://http_remote;
proxy_http_version 1.1;
# Headers
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;
# WebSocket support (for terminal)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 3600s; # Long timeout for terminal sessions
# Buffering (disable for SSE streaming)
proxy_buffering off;
proxy_cache off;
}
# Health check endpoint (optional)
location /devops/api/version {
proxy_pass http://http_remote;
proxy_http_version 1.1;
proxy_set_header Host $host;
access_log off;
}
}Catatan penting:
proxy_read_timeout 3600sdiperlukan untuk terminal WebSocket yang bisa berjalan lamaproxy_buffering offpenting untuk SSE streaming outputUpgradedanConnectionheaders diperlukan untuk WebSocket terminal- Gunakan
secure_cookie: truedi config.yaml saat menggunakan HTTPS
Before running, create your config.yaml with required settings:
# Generate encryption key
ENCRYPTION_KEY=$(openssl rand -hex 32)
echo "Your encryption key: $ENCRYPTION_KEY"Buka browser ke http://localhost:8080/devops/
Login dengan:
- Username:
admin - Password: (password yang Anda set di config.yaml)
Klik "New App" dan isi:
- Name: Nama aplikasi (e.g.,
my-webapp) - Working Directory: Path ke aplikasi (e.g.,
/opt/apps/my-webapp)
Pada halaman app, klik "New Command" dan isi:
- Name: Nama command (e.g.,
deploy) - Command: Shell command yang akan dieksekusi
- Timeout: Batas waktu eksekusi (seconds)
Contoh command:
git pull origin main && docker-compose up -d --buildKlik "Execute" pada command untuk menjalankannya. Output akan ditampilkan secara real-time.
- Navigate to Settings page
- Click "Enable 2FA"
- Scan QR code with authenticator app (Google Authenticator, Authy, etc.)
- Enter 6-digit code to verify
- Save backup codes securely for account recovery
- Navigate to Terminal page in the navigation menu
- Interactive shell session will open automatically
- Execute commands directly on the server with real-time output
- Security Warning: Terminal provides full shell access - use with caution
Setiap app memiliki token unik yang bisa digunakan untuk trigger deployment tanpa login. Token bisa dilihat di halaman detail app.
# Deploy menggunakan command default (command pertama)
curl -X POST http://localhost:8080/devops/deploy/{app_uuid} \
-H "X-Deploy-Token: {token}"
# Deploy dengan command spesifik
curl -X POST http://localhost:8080/devops/deploy/{app_uuid} \
-H "X-Deploy-Token: {token}" \
-H "Content-Type: application/json" \
-d '{"command_id": "command-uuid"}'Response:
{
"message": "deployment started",
"execution_id": "exec-uuid",
"app_id": "app-uuid",
"app_name": "my-webapp",
"stream_url": "/devops/api/executions/exec-uuid/stream",
"status_url": "/devops/api/executions/exec-uuid"
}curl http://localhost:8080/devops/deploy/{app_uuid}/status/{execution_uuid} \
-H "X-Deploy-Token: {token}"Response:
{
"id": "exec-uuid",
"command_id": "cmd-uuid",
"status": "success",
"output": "Already up to date.\nContainer started.\n",
"exit_code": 0,
"started_at": "2024-01-15T10:30:00Z",
"finished_at": "2024-01-15T10:30:05Z"
}Jika token bocor, regenerate via Web UI atau API:
curl -X POST http://localhost:8080/devops/api/apps/{app_uuid}/regenerate-token \
-b "session_id=YOUR_SESSION_ID"# Login
curl -X POST http://localhost:8080/devops/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"changeme"}'
# Logout
curl -X POST http://localhost:8080/devops/api/auth/logout \
-b "session_id=YOUR_SESSION_ID"
# Get current user
curl http://localhost:8080/devops/api/auth/me \
-b "session_id=YOUR_SESSION_ID"# List apps
curl http://localhost:8080/devops/api/apps \
-b "session_id=YOUR_SESSION_ID"
# Create app
curl -X POST http://localhost:8080/devops/api/apps \
-H "Content-Type: application/json" \
-b "session_id=YOUR_SESSION_ID" \
-d '{
"name": "my-app",
"description": "My Application",
"working_dir": "/opt/apps/my-app"
}'
# Get app detail
curl http://localhost:8080/devops/api/apps/{app_uuid} \
-b "session_id=YOUR_SESSION_ID"
# Update app
curl -X PUT http://localhost:8080/devops/api/apps/{app_uuid} \
-H "Content-Type: application/json" \
-b "session_id=YOUR_SESSION_ID" \
-d '{"description": "Updated description"}'
# Delete app
curl -X DELETE http://localhost:8080/devops/api/apps/{app_uuid} \
-b "session_id=YOUR_SESSION_ID"
# Regenerate token
curl -X POST http://localhost:8080/devops/api/apps/{app_uuid}/regenerate-token \
-b "session_id=YOUR_SESSION_ID"# List commands for app
curl http://localhost:8080/devops/api/apps/{app_uuid}/commands \
-b "session_id=YOUR_SESSION_ID"
# Create command
curl -X POST http://localhost:8080/devops/api/apps/{app_uuid}/commands \
-H "Content-Type: application/json" \
-b "session_id=YOUR_SESSION_ID" \
-d '{
"name": "deploy",
"description": "Pull and restart containers",
"command": "git pull && docker-compose up -d --build",
"timeout_seconds": 600
}'
# Get command detail
curl http://localhost:8080/devops/api/commands/{command_uuid} \
-b "session_id=YOUR_SESSION_ID"
# Update command
curl -X PUT http://localhost:8080/devops/api/commands/{command_uuid} \
-H "Content-Type: application/json" \
-b "session_id=YOUR_SESSION_ID" \
-d '{"timeout_seconds": 900}'
# Delete command
curl -X DELETE http://localhost:8080/devops/api/commands/{command_uuid} \
-b "session_id=YOUR_SESSION_ID"
# Execute command
curl -X POST http://localhost:8080/devops/api/commands/{command_uuid}/execute \
-b "session_id=YOUR_SESSION_ID"# List executions
curl http://localhost:8080/devops/api/executions \
-b "session_id=YOUR_SESSION_ID"
# Get execution detail
curl http://localhost:8080/devops/api/executions/{execution_uuid} \
-b "session_id=YOUR_SESSION_ID"
# Stream execution output (SSE)
curl http://localhost:8080/devops/api/executions/{execution_uuid}/stream \
-b "session_id=YOUR_SESSION_ID"name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Trigger deployment
run: |
curl -X POST ${{ secrets.DEPLOY_URL }}/devops/deploy/${{ secrets.APP_ID }} \
-H "X-Deploy-Token: ${{ secrets.DEPLOY_TOKEN }}"deploy:
stage: deploy
script:
- |
curl -X POST ${DEPLOY_URL}/devops/deploy/${APP_ID} \
-H "X-Deploy-Token: ${DEPLOY_TOKEN}"
only:
- mainpipeline {
agent any
stages {
stage('Deploy') {
steps {
sh '''
curl -X POST ${DEPLOY_URL}/devops/deploy/${APP_ID} \
-H "X-Deploy-Token: ${DEPLOY_TOKEN}"
'''
}
}
}
}Jika keduanya berjalan di Docker:
http:
routers:
devops:
rule: "Host(`app.example.com`) && PathPrefix(`/devops`)"
service: devops-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
devops-service:
loadBalancer:
servers:
- url: "http://http-remote:8080"Untuk skenario dimana Traefik berjalan di Docker dan HTTP Remote berjalan langsung di host (systemd service):
Internet → Traefik (Docker, port 80/443) → Host (port 8080) → http-remote
1. Docker Compose untuk Traefik:
# docker-compose.yml
version: '3.8'
services:
traefik:
image: traefik:v3.0
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./dynamic:/etc/traefik/dynamic:ro
- ./letsencrypt:/letsencrypt
extra_hosts:
- "host.docker.internal:host-gateway" # Penting untuk akses host dari Docker
restart: unless-stopped2. Traefik Static Config:
# traefik.yml
api:
dashboard: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: your-email@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
providers:
file:
directory: /etc/traefik/dynamic
watch: true3. Dynamic Config untuk HTTP Remote:
# dynamic/http-remote.yml
http:
routers:
http-remote:
rule: "Host(`deploy.example.com`) && PathPrefix(`/devops`)"
service: http-remote
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
http-remote:
loadBalancer:
servers:
- url: "http://host.docker.internal:8080"4. Pastikan HTTP Remote Listen di Semua Interface:
# /etc/http-remote/config.yaml
server:
host: "0.0.0.0" # Listen semua interface
port: 8080
path_prefix: "/devops"Alternatif: Menggunakan IP Docker Bridge
Jika host.docker.internal tidak tersedia:
# Dapatkan IP docker bridge
ip addr show docker0
# Output: inet 172.17.0.1/16# dynamic/http-remote.yml
http:
services:
http-remote:
loadBalancer:
servers:
- url: "http://172.17.0.1:8080"Verifikasi:
# Test dari dalam container Traefik
docker exec -it traefik wget -qO- http://host.docker.internal:8080/devops/login
# Test dari luar via HTTPS
curl https://deploy.example.com/devops/FROM golang:1.21-alpine AS builder
RUN apk add --no-cache gcc musl-dev
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 go build -o http-remote ./cmd/server
FROM alpine:latest
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/http-remote .
COPY --from=builder /app/config.yaml .
RUN mkdir -p /app/data
EXPOSE 8080
CMD ["./http-remote"]version: '3.8'
services:
http-remote:
build: .
ports:
- "8080:8080"
volumes:
- ./data:/app/data
- ./config.yaml:/app/config.yaml
restart: unless-stoppedUntuk menjalankan HTTP Remote sebagai service di Linux:
# Build (single binary dengan embedded assets)
go build -ldflags="-s -w" -o http-remote ./cmd/server
# Copy binary ke /usr/local/bin
sudo cp http-remote /usr/local/bin/
sudo chmod +x /usr/local/bin/http-remote
# Buat direktori untuk config dan data
sudo mkdir -p /etc/http-remote
sudo mkdir -p /var/lib/http-remote
# Copy config
sudo cp config.yaml /etc/http-remote/
# Set permission
sudo chown -R root:root /etc/http-remote
sudo chown -R root:root /var/lib/http-remoteNote: Tidak perlu copy folder
web/karena sudah embedded dalam binary.
Edit /etc/http-remote/config.yaml:
server:
host: "0.0.0.0"
port: 8080
path_prefix: "/devops"
database:
path: "/var/lib/http-remote/deploy.db"
auth:
session_duration: "24h"
bcrypt_cost: 12
execution:
default_timeout: 300
max_timeout: 3600
max_output_size: 10485760
admin:
username: "admin"
password: "your-secure-password"Buat file /etc/systemd/system/http-remote.service:
[Unit]
Description=HTTP Remote - DevOps Deployment Tool
Documentation=https://github.com/pandeptwidyaop/http-remote
After=network.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/etc/http-remote
ExecStart=/usr/local/bin/http-remote -config /etc/http-remote/config.yaml
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
# Environment
Environment=GIN_MODE=release
# Security hardening (optional)
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/http-remote
[Install]
WantedBy=multi-user.target# Reload systemd
sudo systemctl daemon-reload
# Enable service (auto-start on boot)
sudo systemctl enable http-remote
# Start service
sudo systemctl start http-remote
# Check status
sudo systemctl status http-remote
# View logs
sudo journalctl -u http-remote -f# Stop service
sudo systemctl stop http-remote
# Restart service
sudo systemctl restart http-remote
# Disable auto-start
sudo systemctl disable http-remote
# View recent logs
sudo journalctl -u http-remote -n 100
# View logs since today
sudo journalctl -u http-remote --since todayUntuk keamanan lebih baik, jalankan service dengan user khusus:
# Buat user dan group
sudo useradd -r -s /bin/false http-remote
# Set ownership
sudo chown -R http-remote:http-remote /var/lib/http-remote
sudo chown -R http-remote:http-remote /etc/http-remote
# Update service file
sudo sed -i 's/User=root/User=http-remote/' /etc/systemd/system/http-remote.service
sudo sed -i 's/Group=root/Group=http-remote/' /etc/systemd/system/http-remote.service
# Reload dan restart
sudo systemctl daemon-reload
sudo systemctl restart http-remoteNote: Jika menggunakan user non-root, pastikan user tersebut memiliki akses ke working directory aplikasi yang akan di-deploy.
Jika ingin rotasi log manual, buat /etc/logrotate.d/http-remote:
/var/log/http-remote/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 http-remote http-remote
postrotate
systemctl reload http-remote > /dev/null 2>&1 || true
endscript
}
- Ganti password default setelah instalasi
- Gunakan HTTPS di production (via Traefik/Nginx)
- Simpan token dengan aman - jangan commit ke repository
- Regenerate token jika ada kebocoran
- Batasi akses ke path
/devopsvia firewall/reverse proxy - Review command sebelum menyimpan - hindari command berbahaya
.
├── cmd/server/main.go # Entry point
├── internal/
│ ├── config/config.go # Configuration loader
│ ├── database/
│ │ ├── database.go # SQLite connection
│ │ └── migrations.go # DB schema
│ ├── handlers/
│ │ ├── auth.go # Login/logout
│ │ ├── apps.go # App CRUD
│ │ ├── commands.go # Command CRUD & execute
│ │ ├── deploy.go # Token-based deploy API
│ │ ├── stream.go # SSE streaming
│ │ └── web.go # Web UI handlers
│ ├── middleware/
│ │ ├── auth.go # Session auth middleware
│ │ └── logging.go # Request logging
│ ├── models/ # Data models
│ ├── router/router.go # Route definitions
│ └── services/
│ ├── auth.go # Auth & session service
│ ├── apps.go # App & command service
│ └── executor.go # Command executor
├── web/
│ ├── static/css/style.css # Styles
│ ├── static/js/app.js # Frontend JS
│ └── templates/ # HTML templates
├── config.yaml # Configuration
├── Dockerfile
├── go.mod
└── README.md
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /devops/deploy/:app_id |
Token | Trigger deployment |
| GET | /devops/deploy/:app_id/status/:exec_id |
Token | Get deployment status |
| POST | /devops/api/auth/login |
- | Login |
| POST | /devops/api/auth/logout |
Session | Logout |
| GET | /devops/api/auth/me |
Session | Get current user |
| GET | /devops/api/apps |
Session | List apps |
| POST | /devops/api/apps |
Session | Create app |
| GET | /devops/api/apps/:id |
Session | Get app |
| PUT | /devops/api/apps/:id |
Session | Update app |
| DELETE | /devops/api/apps/:id |
Session | Delete app |
| POST | /devops/api/apps/:id/regenerate-token |
Session | Regenerate token |
| GET | /devops/api/apps/:id/commands |
Session | List commands |
| POST | /devops/api/apps/:id/commands |
Session | Create command |
| GET | /devops/api/commands/:id |
Session | Get command |
| PUT | /devops/api/commands/:id |
Session | Update command |
| DELETE | /devops/api/commands/:id |
Session | Delete command |
| POST | /devops/api/commands/:id/execute |
Session | Execute command |
| GET | /devops/api/executions |
Session | List executions |
| GET | /devops/api/executions/:id |
Session | Get execution |
| GET | /devops/api/executions/:id/stream |
Session | Stream output (SSE) |
| GET | /devops/api/2fa/status |
Session | Get 2FA status |
| POST | /devops/api/2fa/generate-secret |
Session | Generate TOTP secret |
| GET | /devops/api/2fa/qrcode |
Session | Get QR code for TOTP setup |
| POST | /devops/api/2fa/enable |
Session | Enable 2FA with verification |
| POST | /devops/api/2fa/disable |
Session | Disable 2FA |
| GET | /devops/api/terminal/ws |
Session | WebSocket terminal connection |
| GET | /devops/api/audit-logs |
Session | List audit logs |
HTTP Remote implements multiple security layers to protect your deployment infrastructure:
- Bcrypt Password Hashing: Cost factor 12 (configurable)
- Secure Session Cookies: HttpOnly flag enabled, Secure flag configurable
- Session Regeneration: Automatic session invalidation on login to prevent session fixation
- Required Secure Password: Application refuses to start with default password "changeme"
- Timing-Safe Login: Constant-time credential verification prevents username enumeration
- Two-Factor Authentication (2FA/TOTP): Optional TOTP-based 2FA using authenticator apps (Google Authenticator, Authy, etc.)
- Encrypted TOTP Secrets: TOTP secrets encrypted at rest using AES-256-GCM (required encryption key)
- Backup Codes: Encrypted recovery codes for 2FA account recovery
Built-in rate limiting to prevent brute-force attacks:
- Login Endpoint: 5 requests/minute
- API Endpoints: 60 requests/minute
- Deploy Endpoint: 30 requests/minute
- 2FA Endpoints: 10 requests/minute (generate, enable, disable)
Rate limit headers included in responses:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remainingX-RateLimit-Reset: Unix timestamp when limit resetsRetry-After: Seconds to wait before retry
- Constant-time Comparison: Prevents timing attacks on token validation
- UUID v4 Tokens: Cryptographically random, non-predictable tokens
- Path Traversal Protection: All file paths validated using
filepath.EvalSymlinks()to prevent symlink attacks - System Path Protection: Critical system directories (
/bin,/etc,/usr, etc.) are protected from modification - Configurable Path Access:
files.allowed_paths: Whitelist of allowed paths (if set, only these paths are accessible)files.blocked_paths: Blacklist of blocked paths (in addition to system paths)
- Filename Sanitization: Uploaded file names are sanitized to remove dangerous characters and patterns
- Command Output Limits: Execution output is truncated at configurable limit (default 10MB) to prevent memory exhaustion
All sensitive operations are logged to audit_logs table:
- User login/logout events
- Command create/update/delete operations
- Command execution with user and IP tracking
-
Configure Required Security Settings:
admin: password: "your-secure-password" # REQUIRED: Cannot be "changeme" security: encryption_key: "your-64-char-hex-key" # REQUIRED: Generate with openssl rand -hex 32
-
Enable Secure Cookies:
server: secure_cookie: true # Requires HTTPS
-
Use HTTPS: Deploy behind reverse proxy (Traefik, Nginx, Caddy) with TLS
-
Firewall Rules: Limit access to trusted IPs if possible
-
Regular Updates: Use
http-remote upgradeto keep up-to-date
Code coverage dijalankan otomatis pada setiap push ke branch main dan develop, serta pada setiap pull request.
# Menjalankan test dengan coverage
make test-ci
# Atau dengan output HTML untuk detail coverage
make test-coverageHasil coverage akan disimpan di:
coverage.out- Format Go coverage (untuk CI/Codecov)coverage.html- Format HTML untuk dilihat di browser
Setelah menjalankan make test-coverage, buka file coverage.html di browser:
# macOS
open coverage.html
# Linux
xdg-open coverage.htmlMIT









