Self-Hosting Hylas Toolkit on NAS — External Access Guide
v1.0 // Hylas Security

NAS HOSTING

Self-hosting the Hylas Security toolkit on local NAS with safe external access

This guide covers hosting your standalone HTML toolkit (HASHID, SHELLFORGE, ENCODR, etc.) on a NAS-based web server, accessible externally without exposing home IP or opening firewall ports. The approach uses Cloudflare Tunnel — free, no port-forwarding, automatic TLS, with optional access control.

01 // Overview

The toolkit consists entirely of standalone HTML files — no server-side code, no database, no build step. This makes hosting trivial: any web server that can serve static files works. The complexity is solely in external access — reaching your NAS from field locations without exposing your home network.

The recommended stack: Nginx on NAS serving static files, with a Cloudflare Tunnel (cloudflared daemon) providing encrypted external access via Cloudflare's edge, and Cloudflare Access as a zero-config auth layer. No open ports. No DynDNS. No SSL certificate management.

02 // Architecture

Internet / Field
→
Cloudflare Edge
TLS termination, Access auth
→ tunnel →
NAS (cloudflared)
outbound only
→
Nginx
localhost:8080
→
HTML Files
/hylas/tools/
No inbound ports open. cloudflared makes outbound connections only. Your home IP is never exposed.

The key insight: cloudflared opens an outbound HTTPS connection to Cloudflare's network. Traffic from the internet enters via Cloudflare's edge and is forwarded through the persistent tunnel to your NAS. Your router requires no configuration.

03 // Delivery Options

Nginx Reverse Proxy + Port Forward Alternative

No third-party dependency Full control Exposes home IP Requires router port 443 open DDNS needed for dynamic IP Won't work behind CGNAT (Virgin Media etc.)

Tailscale VPN Best for single-user

Zero-trust mesh VPN No public exposure at all Free tier covers this use case Requires Tailscale client on every device Not practical for sharing with others

Synology QuickConnect Synology only

Zero config Built into DSM Synology-routed, limited control Web Station needed for static files Performance unpredictable

04 // Nginx on NAS

Most NAS devices can run Docker, which is the cleanest way to run Nginx without interfering with NAS firmware. On Synology: Container Manager. On QNAP: Container Station.

Docker Compose — Nginx Static Server

# docker-compose.yml
version: '3.8'
services:
  hylas-web:
    image: nginx:alpine
    container_name: hylas-web
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"  # bind localhost only — not exposed externally
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache/nginx
      - /var/run

Nginx Config — Security Headers Included

# nginx.conf
server {
    listen 80;
    server_name _;

    root /usr/share/nginx/html;
    index index.html;

    # Security headers
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' fonts.googleapis.com fonts.gstatic.com; img-src 'self' data:;" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

    # Prevent directory listing
    autoindex off;

    # HTML files — no caching (tools update frequently)
    location ~* \.html$ {
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        expires -1;
    }

    # Fonts/static assets — cache aggressively
    location ~* \.(woff2|woff|ttf|css|js|png|ico)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }

    # Deny dotfiles
    location ~ /\. {
        deny all;
        return 404;
    }

    error_page 404 /404.html;
}

05 // Cloudflare Tunnel

You need a domain on Cloudflare (free plan works). A cheap .co.uk from Namecheap (~£5/yr) pointed at Cloudflare nameservers is sufficient.

Step 1 — Create the Tunnel

# On NAS (SSH or Terminal)
# Install cloudflared — Docker is cleanest on NAS

# Or install binary directly:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 \
  -o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflared

# Login (opens browser, authenticate with CF account)
cloudflared tunnel login

# Create tunnel (name it)
cloudflared tunnel create hylas-toolkit

# Note the UUID printed — you'll need it

Step 2 — Cloudflared as Docker Service

# Add to docker-compose.yml
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --config /etc/cloudflared/config.yml run
    volumes:
      - ./cloudflared:/etc/cloudflared:ro
    depends_on:
      - hylas-web
    network_mode: "host"  # or use shared docker network

Tunnel Config File

# cloudflared/config.yml
tunnel: YOUR-TUNNEL-UUID-HERE
credentials-file: /etc/cloudflared/YOUR-TUNNEL-UUID.json

ingress:
  - hostname: tools.yourdomain.com
    service: http://127.0.0.1:8080
    originRequest:
      noTLSVerify: false
  - service: http_status:404  # catch-all

Step 3 — DNS Record

# Create CNAME pointing to tunnel (CLI)
cloudflared tunnel route dns hylas-toolkit tools.yourdomain.com

# Or in Cloudflare dashboard:
# DNS → Add Record → CNAME → tools → YOUR-TUNNEL-UUID.cfargotunnel.com
# Proxy status: Proxied (orange cloud)

06 // Authentication

The toolkit contains pentest tooling — it should not be publicly accessible. Cloudflare Access provides a free, zero-config auth layer in front of your tunnel.

Cloudflare Access — One-Time Email OTP

STEP 01
Cloudflare Zero Trust dashboard → Access → Applications → Add Application
Choose Self-hosted. Set domain to tools.yourdomain.com. Name it "Hylas Toolkit".
STEP 02
Create Policy — Email OTP
Action: Allow. Rule: Emails → your@email.com. This sends a one-time code to your email on first access per session. No passwords. No accounts for visitors.
STEP 03
Session duration
Set session lifetime to 24 hours for field use. Once authenticated, the browser cookie persists and you won't be challenged again until expiry.
For single-user use: set a Service Auth token instead of email OTP — paste the token in a header when accessing, no interactive login required. Useful for scripted access.

Nginx Basic Auth (Fallback / No Cloudflare)

# Generate password file
htpasswd -c /path/to/.htpasswd hylas

# Add to nginx.conf location block
location / {
    auth_basic "Hylas Security";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

07 // File Structure

Organise tools in a flat structure inside the html/ folder. Nginx serves anything in this directory.

docker-compose.yml
nginx.conf
cloudflared/
config.yml
<tunnel-uuid>.json
html/
index.html ← Hylas landing page / tool index
HASHID.html
SHELLFORGE.html
ENCODR.html
HEADSEC.html
JWTDECK.html
OUILOOKUP.html
PMKIDFORM.html
HIDREF.html
PERMUTATE.html
DORKSMITH.html
CRCPAD.html
HEXVIEW.html
NETSCOPE.html
assets/ ← optional shared assets

Index Page

Create a simple index.html at the root that lists all tools. This can be a minimal version of the existing Hylas dark terminal style — a grid of cards each linking to a tool. This serves as the internal portal when you navigate to tools.yourdomain.com.

08 // TLS / HTTPS

With the Cloudflare Tunnel approach, TLS is handled entirely by Cloudflare. Traffic between client and Cloudflare edge is TLS 1.3. Traffic from cloudflared daemon to Nginx is localhost HTTP — inside the NAS, never on the network.

In Cloudflare dashboard → SSL/TLS → set mode to Full (not Flexible). For the tunnel, no certificate installation is needed on the NAS side.

Do not set SSL mode to "Flexible" — it accepts HTTPS from clients but sends HTTP to origin, creating a false sense of security. Use "Full" or "Full (Strict)".

If Using Port-Forward Method Instead

# Get free cert from Let's Encrypt via Certbot
# (run on NAS or Pi — requires port 80 open for verification)

certbot certonly --standalone -d tools.yourdomain.com

# Or use Certbot DNS challenge (no port 80 needed)
certbot certonly --manual --preferred-challenges dns -d tools.yourdomain.com

# Auto-renewal cron (add to /etc/crontab)
0 3 * * * certbot renew --quiet && docker restart hylas-web

09 // Server Hardening

Nginx Rate Limiting

# In nginx.conf http block (before server block)
limit_req_zone $binary_remote_addr zone=hylas:10m rate=20r/m;

# In server location block
location / {
    limit_req zone=hylas burst=10 nodelay;
    limit_req_status 429;
}

IP Allowlist (Optional — Lock to Known IPs)

# In nginx.conf — restrict by IP
# Useful if always accessing from known VPN exit IPs
location / {
    allow 203.0.113.10;   # your VPN exit
    allow 198.51.100.0/24; # office range
    deny all;
}

Cloudflare WAF Rules

In Cloudflare Zero Trust → Gateway, add rules to block known scanner user agents, block access from Tor exit nodes, and enforce country restrictions if only accessing from UK. All free tier features.

Disable Nginx Server Token

# In nginx.conf http block
server_tokens off;

# Also set in headers (already in config above):
add_header X-Content-Type-Options "nosniff" always;

10 // Synology DSM Specifics

Container Manager Setup

DSM → Container Manager → Project
Create project from docker-compose.yml
Container Manager supports Docker Compose directly. Upload the compose file, set the path to your /volume1/docker/hylas-web/ folder. Start the project — both containers launch together.

File Permissions on Synology

# On Synology, set correct permissions for the html folder
# nginx container runs as user 101 (nginx)
chown -R 101:101 /volume1/docker/hylas-web/html/
chmod -R 755 /volume1/docker/hylas-web/html/

Web Station Alternative

If you prefer not to run Docker, Synology Web Station (in Package Centre) can serve static files directly. Install Web Station + Apache or Nginx. Create a Virtual Host pointing to your html folder. Use Web Station's built-in SSL to install a Let's Encrypt cert. Then run cloudflared as a separate Docker container or install it as a service.

Synology DSM 7.x includes a built-in reverse proxy under Control Panel → Login Portal → Advanced → Reverse Proxy. This can forward a custom hostname to the Web Station port, consolidating all traffic through port 443.

11 // Pre-Live Checklist

Infrastructure

Cloudflare account created, domain added, nameservers updated
Tunnel created (cloudflared tunnel create), UUID noted
CNAME record pointing tools.yourdomain.com to tunnel
Docker services (nginx + cloudflared) running on NAS
Nginx port bound to 127.0.0.1 only — not 0.0.0.0

Authentication

Cloudflare Access application configured for tools.yourdomain.com
Access policy set — email OTP or service token
Test access from external network (mobile data, not home WiFi)
Verify unauthenticated access is blocked (incognito, different device)

Security

Cloudflare SSL mode set to Full (not Flexible)
Security headers present — test with HEADSEC tool
server_tokens off in nginx
autoindex off — no directory listing
NAS admin interface not on same subdomain / not Cloudflare-tunnelled
cloudflared credentials file not inside html/ directory
Rate limiting configured in nginx

Operational

Docker containers set to restart: unless-stopped
All HTML tool files copied into html/ folder
index.html links to all tools — no need to remember filenames
Bookmark tools.yourdomain.com on phone, tablet, laptop
Test that large file handling (HEXVIEW, CRCPAD) works over tunnel
Never tunnel the NAS admin interface (DSM / QNAP QTS) through Cloudflare or expose it externally. Use a separate management-only VPN (Tailscale or WireGuard) for NAS admin access.

Updating Tools

Since tools are standalone HTML files, updating is a simple file copy — no restart required. Nginx serves files directly from disk. Copy the updated .html file into html/ on the NAS and it's live immediately.

# Deploy updated tool from dev machine
scp HASHID.html nas-user@192.168.1.x:/volume1/docker/hylas-web/html/

# Or rsync all tools at once
rsync -avz --include="*.html" --exclude="*" \
  ./tools/ nas-user@192.168.1.x:/volume1/docker/hylas-web/html/