Self-Hosted Setup
Looking for the quickest way to get started? Try NAT Cloud — sign up at app.nat-testing.io (opens in a new tab) for instant access with no infrastructure setup. Come back here when you need to run NAT entirely on your own infrastructure.
NAT can be deployed entirely on your own infrastructure. No data leaves your network — scans run locally, reports are stored locally, and the dashboard is served from your own server.
Self-hosting is available on all NAT plans. The self-hosted engine is installed via pip install nat-engine and includes the full scanning engine, REST API, and web dashboard.
Overview
A self-hosted NAT deployment consists of:
- NAT Engine — the core scanning process (installed via pip or Docker)
- NAT Server — a local web server that exposes the REST API and dashboard
- (Optional) Reverse proxy — nginx or Caddy for TLS termination and external access
Prerequisites
| Requirement | Value |
|---|---|
| Python | 3.10 or later |
| RAM | 2 GB minimum, 4 GB recommended |
| Disk | 5 GB for engine + scan data storage |
| OS | Linux (Ubuntu 20.04+, Debian 11+), macOS 12+ |
| Network | Outbound access to APIs under test |
Installation
Install Python 3.10+
# Ubuntu/Debian
sudo apt update && sudo apt install python3 python3-pip python3-venv
# macOS
brew install python@3.11Verify:
python3 --version # Python 3.11.xCreate a virtual environment (recommended)
python3 -m venv /opt/nat-engine
source /opt/nat-engine/bin/activateInstall nat-engine
pip install nat-engineVerify:
nat --version
# nat-engine 1.x.xGenerate a secret key
python3 -c "import secrets; print(secrets.token_hex(32))"Save this as your NAT_SECRET_KEY — it signs session tokens for the dashboard.
Create the configuration file
mkdir -p /etc/nat
cat > /etc/nat/config.yaml << 'EOF'
server:
host: 127.0.0.1 # Change to 0.0.0.0 for external access
port: 8080
data_dir: /var/lib/nat/data
log:
level: info
file: /var/log/nat/nat.log
EOFStart the server
NAT_SECRET_KEY="your-secret-key" nat server start \
--config /etc/nat/config.yamlThe dashboard is now available at http://localhost:8080.
After installation, run nat setup for an interactive wizard that configures your mode, database, authentication, and exporters in one step. Then run nat doctor to validate that everything is set up correctly before your first scan.
Running as a systemd service (Linux)
For production Linux deployments, run NAT as a systemd service:
Create a system user
sudo useradd --system --no-create-home --shell /bin/false nat
sudo mkdir -p /var/lib/nat/data /var/log/nat
sudo chown nat:nat /var/lib/nat /var/log/natInstall into a system-wide virtualenv
sudo python3 -m venv /opt/nat-engine
sudo /opt/nat-engine/bin/pip install nat-engineCreate the systemd unit file
sudo cat > /etc/systemd/system/nat.service << 'EOF'
[Unit]
Description=NAT API Security Engine
After=network.target
[Service]
Type=simple
User=nat
Group=nat
WorkingDirectory=/var/lib/nat
ExecStart=/opt/nat-engine/bin/nat server start --config /etc/nat/config.yaml
Restart=always
RestartSec=5
EnvironmentFile=/etc/nat/environment
[Install]
WantedBy=multi-user.target
EOFCreate the environment file
sudo cat > /etc/nat/environment << 'EOF'
NAT_SECRET_KEY=your-secret-key-here
NAT_LOG_LEVEL=info
EOF
sudo chmod 600 /etc/nat/environmentEnable and start the service
sudo systemctl daemon-reload
sudo systemctl enable nat
sudo systemctl start nat
sudo systemctl status natTLS with a reverse proxy
For production use, put NAT behind nginx or Caddy for TLS termination.
# /etc/nginx/sites-available/nat
server {
listen 443 ssl http2;
server_name docs-api.example.com;
ssl_certificate /etc/ssl/certs/nat.crt;
ssl_certificate_key /etc/ssl/private/nat.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
server {
listen 80;
server_name docs-api.example.com;
return 301 https://$host$request_uri;
}Upgrading nat-engine
# In your virtualenv
source /opt/nat-engine/bin/activate
pip install --upgrade nat-engine
# Restart the service
sudo systemctl restart natIf the upgrade includes database schema changes, run nat upgrade --migrate (or alembic upgrade head manually) before restarting the service. nat doctor will warn you if pending migrations are detected.
Configuration reference
# /etc/nat/config.yaml — all options with defaults
server:
host: 127.0.0.1
port: 8080
data_dir: /var/lib/nat/data
max_concurrent_scans: 3
scan:
concurrency: 5
timeout: 30
depth: 3
log:
level: info # debug | info | warn | error
file: "" # empty = stdout only
max_size_mb: 100
max_backups: 5Environment variables
All settings can be overridden via environment variables:
| Variable | Description |
|---|---|
NAT_SECRET_KEY | Required — secret key for session signing |
NAT_SERVER_HOST | Bind address |
NAT_SERVER_PORT | Listen port |
NAT_DATA_DIR | Data storage directory |
NAT_LOG_LEVEL | Log verbosity |
Network security recommendations
For a production self-hosted deployment:
- Bind to
127.0.0.1and use a reverse proxy for external access - Enable TLS with a certificate from Let's Encrypt or your internal CA
- Restrict dashboard access to your VPN or internal network
- Use a firewall to block direct access to port 8080 from external networks
- Rotate
NAT_SECRET_KEYperiodically (invalidates all active sessions)
Troubleshooting
See Common Issues and Connection Errors for self-hosted troubleshooting guidance.
Next steps
- Docker Deployment — run self-hosted NAT via Docker
- Deploy with Docker (how-to) — Docker production setup
- Dashboard — using the dashboard after setup