Air-gapped Installation
This guide covers installing the PatchCTL agent in environments without direct internet access.
Air-gapped installations require a proxy or bastion host for the agent to communicate with the PatchCTL API. Fully offline operation is not supported.
Architecture Options
Option 1: HTTPS Proxy
Route agent traffic through an HTTPS proxy with internet access:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Air-gapped │ │ HTTPS Proxy │ │ PatchCTL API │
│ Server │────►│ (Squid, etc) │────►│ │
│ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └── ───────────────┘
Option 2: Bastion Host
Use a bastion host with internet access to relay traffic:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Air-gapped │ │ Bastion Host │ │ PatchCTL API │
│ Server │────►│ (SSH tunnel) │────►│ │
│ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Prerequisites
- A method to transfer files to the air-gapped network
- Either a proxy server or bastion host with internet access
- Firewall rules allowing the required connectivity
Step 1: Download Files Externally
On a machine with internet access, download the required files:
# Create a transfer directory
mkdir patchctl-transfer && cd patchctl-transfer
# Download the appropriate binary for your distro
# For Ubuntu/Debian:
curl -fsSLO https://downloads.patchctl.com/latest/patchctl-agent-linux-amd64
# For RHEL/Rocky:
curl -fsSLO https://downloads.patchctl.com/latest/patchctl-agent-linux-amd64-rhel
# For SUSE:
curl -fsSLO https://downloads.patchctl.com/latest/patchctl-agent-linux-amd64-suse
# Verify checksums (recommended)
sha256sum patchctl-agent-*
Step 2: Transfer to Air-gapped Network
Transfer the downloaded binary using your approved method:
- USB drive
- Secure file transfer
- Network share
- CD/DVD
Step 3: Install on Target Server
# Create directories
sudo mkdir -p /opt/patchctl/bin /etc/patchctl
# Copy binary
sudo cp patchctl-agent-linux-amd64 /opt/patchctl/bin/patchctl-agent
sudo chmod +x /opt/patchctl/bin/patchctl-agent
# Create configuration (see below for proxy settings)
sudo nano /etc/patchctl/config.json
Step 4: Configure Proxy
Environment Variables
Set proxy environment variables in the systemd service:
sudo tee /etc/systemd/system/patchctl.service > /dev/null << 'EOF'
[Unit]
Description=PatchCTL Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/patchctl/bin/patchctl-agent
Restart=always
RestartSec=10
User=root
WorkingDirectory=/opt/patchctl
# Proxy configuration
Environment="HTTPS_PROXY=http://proxy.internal:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.internal"
[Install]
WantedBy=multi-user.target
EOF
Configuration File
Create the agent configuration:
{
"license_key": "YOUR_LICENSE_KEY",
"api_endpoint": "https://api.patchctl.com",
"heartbeat_interval": 300,
"log_level": "info"
}
Step 5: Start the Service
sudo systemctl daemon-reload
sudo systemctl enable patchctl
sudo systemctl start patchctl
SSH Tunnel Method
If using an SSH tunnel through a bastion:
On the Air-gapped Server
Create a persistent SSH tunnel:
# Create tunnel (runs in background)
ssh -f -N -L 8443:api.patchctl.com:443 [email protected]
Configure the agent to use localhost:
{
"license_key": "YOUR_LICENSE_KEY",
"api_endpoint": "https://localhost:8443",
"heartbeat_interval": 300,
"log_level": "info"
}
Persistent Tunnel with autossh
For production, use autossh to maintain the tunnel:
# Install autossh
sudo apt install autossh # or dnf/zypper
# Create systemd service for tunnel
sudo tee /etc/systemd/system/patchctl-tunnel.service > /dev/null << 'EOF'
[Unit]
Description=PatchCTL API Tunnel
Before=patchctl.service
[Service]
ExecStart=/usr/bin/autossh -M 0 -N -L 8443:api.patchctl.com:443 [email protected]
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable patchctl-tunnel
sudo systemctl start patchctl-tunnel
Verification
# Check agent status
sudo systemctl status patchctl
# Test API connectivity through proxy/tunnel
curl -x http://proxy.internal:8080 -I https://api.patchctl.com/health
# or for tunnel:
curl -I https://localhost:8443/health
Troubleshooting
Proxy Authentication
If your proxy requires authentication:
Environment="HTTPS_PROXY=http://username:[email protected]:8080"
Certificate Issues
If using an SSL-inspecting proxy, add the proxy's CA certificate:
# Ubuntu/Debian
sudo cp proxy-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# RHEL/Rocky
sudo cp proxy-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
# SUSE
sudo cp proxy-ca.crt /etc/pki/trust/anchors/
sudo update-ca-certificates
Connection Timeouts
Increase timeout if network is slow:
{
"license_key": "YOUR_LICENSE_KEY",
"api_endpoint": "https://api.patchctl.com",
"heartbeat_interval": 300,
"connection_timeout": 60,
"log_level": "info"
}
Security Considerations
- Use authenticated proxies where possible
- Rotate SSH keys for tunnel access
- Monitor tunnel/proxy logs for anomalies
- Consider network segmentation between proxy and internal servers