save progress
This commit is contained in:
199
devops/tools/sbom-validators/AIRGAP_INSTALL.md
Normal file
199
devops/tools/sbom-validators/AIRGAP_INSTALL.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# SBOM Validator Air-Gap Deployment
|
||||
|
||||
This guide explains how to deploy SBOM validators in air-gapped environments.
|
||||
|
||||
## Overview
|
||||
|
||||
StellaOps Scanner uses two external validators for SBOM validation:
|
||||
|
||||
| Validator | Purpose | Runtime |
|
||||
|-----------|---------|---------|
|
||||
| sbom-utility | CycloneDX JSON/XML validation | Native binary |
|
||||
| spdx-tools | SPDX JSON/RDF/Tag-Value validation | Java (JRE 11+) |
|
||||
|
||||
## Creating the Bundle
|
||||
|
||||
### On a Connected System
|
||||
|
||||
1. Navigate to the tools directory:
|
||||
```bash
|
||||
cd devops/tools/sbom-validators
|
||||
```
|
||||
|
||||
2. Run the bundle script:
|
||||
```bash
|
||||
# Bundle for current platform
|
||||
./bundle.sh
|
||||
|
||||
# Bundle for specific platform
|
||||
./bundle.sh --platform linux-amd64
|
||||
|
||||
# Bundle for all platforms
|
||||
./bundle.sh --all-platforms
|
||||
```
|
||||
|
||||
3. The bundle will be created in `./bundle/<platform>/`
|
||||
|
||||
### Bundle Contents
|
||||
|
||||
```
|
||||
bundle/
|
||||
├── linux-amd64/
|
||||
│ ├── sbom-utility/
|
||||
│ │ └── 0.17.0/
|
||||
│ │ └── sbom-utility
|
||||
│ ├── spdx-tools/
|
||||
│ │ └── 1.1.9/
|
||||
│ │ └── tools-java-1.1.9-jar-with-dependencies.jar
|
||||
│ ├── SHA256SUMS
|
||||
│ ├── manifest.json
|
||||
│ └── README.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Installation on Air-Gapped System
|
||||
|
||||
### 1. Transfer Bundle
|
||||
|
||||
Transfer the appropriate platform bundle to your air-gapped system.
|
||||
|
||||
### 2. Verify Integrity
|
||||
|
||||
```bash
|
||||
cd /path/to/bundle
|
||||
sha256sum -c SHA256SUMS
|
||||
```
|
||||
|
||||
All files should report `OK`.
|
||||
|
||||
### 3. Configure StellaOps
|
||||
|
||||
**Option A: Environment Variable**
|
||||
```bash
|
||||
export STELLAOPS_VALIDATOR_DIR=/path/to/bundle
|
||||
```
|
||||
|
||||
**Option B: Configuration File** (`appsettings.yaml`)
|
||||
```yaml
|
||||
Scanner:
|
||||
Validation:
|
||||
BinaryDirectory: /path/to/bundle
|
||||
OfflineMode: true
|
||||
DownloadTimeout: 00:05:00 # Ignored in offline mode
|
||||
```
|
||||
|
||||
**Option C: Docker Volume**
|
||||
```yaml
|
||||
services:
|
||||
scanner:
|
||||
volumes:
|
||||
- ./validator-bundle:/opt/stellaops/validators:ro
|
||||
environment:
|
||||
STELLAOPS_VALIDATOR_DIR: /opt/stellaops/validators
|
||||
```
|
||||
|
||||
### 4. Verify Installation
|
||||
|
||||
```bash
|
||||
# Check sbom-utility
|
||||
/path/to/bundle/sbom-utility/0.17.0/sbom-utility --version
|
||||
|
||||
# Check spdx-tools (requires Java)
|
||||
java -jar /path/to/bundle/spdx-tools/1.1.9/tools-java-1.1.9-jar-with-dependencies.jar --version
|
||||
```
|
||||
|
||||
## Java Runtime Requirement
|
||||
|
||||
spdx-tools requires Java Runtime Environment (JRE) 11 or later.
|
||||
|
||||
### Installing Java in Air-Gap
|
||||
|
||||
**Red Hat / CentOS / Rocky:**
|
||||
```bash
|
||||
# Download on connected system
|
||||
yum download --downloadonly --downloaddir=/tmp/java java-11-openjdk-headless
|
||||
|
||||
# Transfer and install
|
||||
sudo rpm -ivh /tmp/java/*.rpm
|
||||
```
|
||||
|
||||
**Debian / Ubuntu:**
|
||||
```bash
|
||||
# Download on connected system
|
||||
apt download openjdk-11-jre-headless
|
||||
|
||||
# Transfer and install
|
||||
sudo dpkg -i openjdk-11-jre-headless*.deb
|
||||
```
|
||||
|
||||
**Alpine:**
|
||||
```bash
|
||||
# Download on connected system
|
||||
apk fetch openjdk11-jre-headless
|
||||
|
||||
# Transfer and install
|
||||
apk add --allow-untrusted openjdk11-jre-headless-*.apk
|
||||
```
|
||||
|
||||
## Updating Validators
|
||||
|
||||
1. On a connected system, update version numbers in `bundle.sh`
|
||||
2. Run the bundle script to download new versions
|
||||
3. Verify the bundle integrity
|
||||
4. Transfer to air-gapped system
|
||||
5. Update configuration if paths changed
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Validator Not Found
|
||||
|
||||
```
|
||||
ValidatorBinaryException: Validator 'sbom-utility' not found and offline mode is enabled
|
||||
```
|
||||
|
||||
**Solution:** Verify `STELLAOPS_VALIDATOR_DIR` points to the bundle directory.
|
||||
|
||||
### Hash Mismatch
|
||||
|
||||
```
|
||||
ValidatorBinaryException: Downloaded file hash mismatch
|
||||
```
|
||||
|
||||
**Solution:** Re-download the bundle or verify file integrity with `sha256sum -c SHA256SUMS`.
|
||||
|
||||
### Java Not Found
|
||||
|
||||
```
|
||||
SpdxValidator: Java runtime not found
|
||||
```
|
||||
|
||||
**Solution:** Install JRE 11+ and ensure `java` is in PATH.
|
||||
|
||||
### Permission Denied
|
||||
|
||||
```
|
||||
Permission denied: /path/to/sbom-utility
|
||||
```
|
||||
|
||||
**Solution:** Set executable permission:
|
||||
```bash
|
||||
chmod +x /path/to/bundle/sbom-utility/*/sbom-utility
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Verify bundle source** - Only use bundles from trusted sources
|
||||
2. **Check signatures** - Verify SHA256SUMS against known good values
|
||||
3. **Principle of least privilege** - Run validators with minimal permissions
|
||||
4. **Audit trail** - Log all validation operations
|
||||
|
||||
## Version Pinning
|
||||
|
||||
The bundle uses pinned versions for reproducibility:
|
||||
|
||||
| Validator | Version | SHA-256 |
|
||||
|-----------|---------|---------|
|
||||
| sbom-utility | 0.17.0 | See SHA256SUMS |
|
||||
| spdx-tools | 1.1.9 | See SHA256SUMS |
|
||||
|
||||
To use different versions, modify `bundle.sh` and regenerate the bundle.
|
||||
342
devops/tools/sbom-validators/bundle.sh
Normal file
342
devops/tools/sbom-validators/bundle.sh
Normal file
@@ -0,0 +1,342 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# Copyright (c) StellaOps
|
||||
#
|
||||
# bundle.sh - Bundle SBOM validators for air-gap deployment
|
||||
# Sprint: SPRINT_20260107_005_003 Task VG-008
|
||||
#
|
||||
# Usage:
|
||||
# ./bundle.sh [--output-dir DIR] [--platform PLATFORM]
|
||||
#
|
||||
# Options:
|
||||
# --output-dir DIR Output directory for bundle (default: ./bundle)
|
||||
# --platform PLATFORM Target platform (linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, windows-amd64)
|
||||
# If not specified, bundles for current platform
|
||||
# --all-platforms Bundle for all supported platforms
|
||||
# --help Show this help message
|
||||
#
|
||||
# Examples:
|
||||
# ./bundle.sh # Bundle for current platform
|
||||
# ./bundle.sh --platform linux-amd64 # Bundle for specific platform
|
||||
# ./bundle.sh --all-platforms # Bundle for all platforms
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Validator versions - pin for reproducibility
|
||||
SBOM_UTILITY_VERSION="0.17.0"
|
||||
SPDX_TOOLS_VERSION="1.1.9"
|
||||
|
||||
# Download URLs
|
||||
SBOM_UTILITY_BASE="https://github.com/CycloneDX/sbom-utility/releases/download/v${SBOM_UTILITY_VERSION}"
|
||||
SPDX_TOOLS_BASE="https://github.com/spdx/tools-java/releases/download/v${SPDX_TOOLS_VERSION}"
|
||||
|
||||
# Script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Defaults
|
||||
OUTPUT_DIR="${SCRIPT_DIR}/bundle"
|
||||
TARGET_PLATFORM=""
|
||||
ALL_PLATFORMS=false
|
||||
|
||||
# Supported platforms
|
||||
PLATFORMS=("linux-amd64" "linux-arm64" "darwin-amd64" "darwin-arm64" "windows-amd64")
|
||||
|
||||
# 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" >&2
|
||||
}
|
||||
|
||||
detect_platform() {
|
||||
local os arch
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux*) os="linux" ;;
|
||||
Darwin*) os="darwin" ;;
|
||||
MINGW*|MSYS*|CYGWIN*) os="windows" ;;
|
||||
*) log_error "Unsupported OS: $(uname -s)"; exit 1 ;;
|
||||
esac
|
||||
|
||||
case "$(uname -m)" in
|
||||
x86_64|amd64) arch="amd64" ;;
|
||||
arm64|aarch64) arch="arm64" ;;
|
||||
*) log_error "Unsupported architecture: $(uname -m)"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "${os}-${arch}"
|
||||
}
|
||||
|
||||
show_help() {
|
||||
head -n 24 "$0" | tail -n +2 | sed 's/^# //' | sed 's/^#//'
|
||||
exit 0
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--output-dir)
|
||||
OUTPUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--platform)
|
||||
TARGET_PLATFORM="$2"
|
||||
shift 2
|
||||
;;
|
||||
--all-platforms)
|
||||
ALL_PLATFORMS=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$TARGET_PLATFORM" && "$ALL_PLATFORMS" == "false" ]]; then
|
||||
TARGET_PLATFORM=$(detect_platform)
|
||||
fi
|
||||
}
|
||||
|
||||
download_file() {
|
||||
local url="$1"
|
||||
local output="$2"
|
||||
|
||||
log_info "Downloading: ${url}"
|
||||
|
||||
if command -v curl &> /dev/null; then
|
||||
curl -fsSL -o "$output" "$url"
|
||||
elif command -v wget &> /dev/null; then
|
||||
wget -q -O "$output" "$url"
|
||||
else
|
||||
log_error "Neither curl nor wget found"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_checksum() {
|
||||
local file="$1"
|
||||
local expected="$2"
|
||||
|
||||
local actual
|
||||
actual=$(sha256sum "$file" | cut -d' ' -f1)
|
||||
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
log_error "Checksum mismatch for ${file}"
|
||||
log_error "Expected: ${expected}"
|
||||
log_error "Actual: ${actual}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Checksum verified: ${file}"
|
||||
return 0
|
||||
}
|
||||
|
||||
bundle_sbom_utility() {
|
||||
local platform="$1"
|
||||
local bundle_dir="$2"
|
||||
|
||||
local os arch ext
|
||||
os="${platform%-*}"
|
||||
arch="${platform#*-}"
|
||||
ext=""
|
||||
|
||||
[[ "$os" == "windows" ]] && ext=".exe"
|
||||
|
||||
local filename="sbom-utility-v${SBOM_UTILITY_VERSION}-${os}-${arch}.tar.gz"
|
||||
local url="${SBOM_UTILITY_BASE}/${filename}"
|
||||
local temp_dir
|
||||
temp_dir=$(mktemp -d)
|
||||
|
||||
log_info "Bundling sbom-utility for ${platform}..."
|
||||
|
||||
download_file "$url" "${temp_dir}/${filename}"
|
||||
|
||||
# Extract
|
||||
tar -xzf "${temp_dir}/${filename}" -C "${temp_dir}"
|
||||
|
||||
# Copy binary
|
||||
local binary_name="sbom-utility${ext}"
|
||||
local src_binary="${temp_dir}/${binary_name}"
|
||||
local dest_binary="${bundle_dir}/sbom-utility/${SBOM_UTILITY_VERSION}/${binary_name}"
|
||||
|
||||
mkdir -p "$(dirname "$dest_binary")"
|
||||
cp "$src_binary" "$dest_binary"
|
||||
chmod +x "$dest_binary" 2>/dev/null || true
|
||||
|
||||
# Compute and record hash
|
||||
local hash
|
||||
hash=$(sha256sum "$dest_binary" | cut -d' ' -f1)
|
||||
echo "sbom-utility/${SBOM_UTILITY_VERSION}/${binary_name}:${hash}" >> "${bundle_dir}/SHA256SUMS"
|
||||
|
||||
# Cleanup
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
log_info "sbom-utility ${SBOM_UTILITY_VERSION} bundled for ${platform}"
|
||||
}
|
||||
|
||||
bundle_spdx_tools() {
|
||||
local bundle_dir="$1"
|
||||
|
||||
local filename="tools-java-${SPDX_TOOLS_VERSION}-jar-with-dependencies.jar"
|
||||
local url="${SPDX_TOOLS_BASE}/${filename}"
|
||||
local temp_dir
|
||||
temp_dir=$(mktemp -d)
|
||||
|
||||
log_info "Bundling spdx-tools (platform-independent JAR)..."
|
||||
|
||||
download_file "$url" "${temp_dir}/${filename}"
|
||||
|
||||
# Copy JAR
|
||||
local dest_jar="${bundle_dir}/spdx-tools/${SPDX_TOOLS_VERSION}/${filename}"
|
||||
mkdir -p "$(dirname "$dest_jar")"
|
||||
cp "${temp_dir}/${filename}" "$dest_jar"
|
||||
|
||||
# Compute and record hash
|
||||
local hash
|
||||
hash=$(sha256sum "$dest_jar" | cut -d' ' -f1)
|
||||
echo "spdx-tools/${SPDX_TOOLS_VERSION}/${filename}:${hash}" >> "${bundle_dir}/SHA256SUMS"
|
||||
|
||||
# Cleanup
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
log_info "spdx-tools ${SPDX_TOOLS_VERSION} bundled"
|
||||
}
|
||||
|
||||
create_manifest() {
|
||||
local bundle_dir="$1"
|
||||
|
||||
cat > "${bundle_dir}/manifest.json" << EOF
|
||||
{
|
||||
"schema": "stellaops.validator-bundle@1",
|
||||
"generatedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"validators": {
|
||||
"sbom-utility": {
|
||||
"version": "${SBOM_UTILITY_VERSION}",
|
||||
"source": "https://github.com/CycloneDX/sbom-utility",
|
||||
"formats": ["cyclonedx-json", "cyclonedx-xml"]
|
||||
},
|
||||
"spdx-tools": {
|
||||
"version": "${SPDX_TOOLS_VERSION}",
|
||||
"source": "https://github.com/spdx/tools-java",
|
||||
"formats": ["spdx-json", "spdx-rdf", "spdx-tag-value"],
|
||||
"requires": "java >= 11"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Created manifest.json"
|
||||
}
|
||||
|
||||
create_readme() {
|
||||
local bundle_dir="$1"
|
||||
|
||||
cat > "${bundle_dir}/README.md" << 'EOF'
|
||||
# SBOM Validator Bundle
|
||||
|
||||
This bundle contains pre-downloaded SBOM validators for air-gap deployments.
|
||||
|
||||
## Contents
|
||||
|
||||
- **sbom-utility**: CycloneDX validator (Go binary)
|
||||
- **spdx-tools**: SPDX validator (Java JAR, requires JRE 11+)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Copy this bundle to your air-gapped environment
|
||||
2. Set `STELLAOPS_VALIDATOR_DIR` environment variable to point to this directory
|
||||
3. Or configure in `appsettings.yaml`:
|
||||
|
||||
```yaml
|
||||
Scanner:
|
||||
Validation:
|
||||
BinaryDirectory: /path/to/validator-bundle
|
||||
OfflineMode: true
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Verify file integrity using the SHA256SUMS file:
|
||||
|
||||
```bash
|
||||
cd /path/to/validator-bundle
|
||||
sha256sum -c SHA256SUMS
|
||||
```
|
||||
|
||||
## Version Information
|
||||
|
||||
See `manifest.json` for exact versions and source URLs.
|
||||
|
||||
## License
|
||||
|
||||
- sbom-utility: Apache-2.0
|
||||
- spdx-tools: Apache-2.0
|
||||
EOF
|
||||
|
||||
log_info "Created README.md"
|
||||
}
|
||||
|
||||
bundle_platform() {
|
||||
local platform="$1"
|
||||
local bundle_dir="${OUTPUT_DIR}/${platform}"
|
||||
|
||||
log_info "Creating bundle for platform: ${platform}"
|
||||
|
||||
mkdir -p "$bundle_dir"
|
||||
|
||||
# Initialize checksum file
|
||||
: > "${bundle_dir}/SHA256SUMS"
|
||||
|
||||
# Bundle validators
|
||||
bundle_sbom_utility "$platform" "$bundle_dir"
|
||||
bundle_spdx_tools "$bundle_dir"
|
||||
|
||||
# Create metadata files
|
||||
create_manifest "$bundle_dir"
|
||||
create_readme "$bundle_dir"
|
||||
|
||||
# Sort checksums for determinism
|
||||
sort -o "${bundle_dir}/SHA256SUMS" "${bundle_dir}/SHA256SUMS"
|
||||
|
||||
log_info "Bundle created: ${bundle_dir}"
|
||||
}
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
log_info "SBOM Validator Bundle Generator"
|
||||
log_info "sbom-utility version: ${SBOM_UTILITY_VERSION}"
|
||||
log_info "spdx-tools version: ${SPDX_TOOLS_VERSION}"
|
||||
log_info "Output directory: ${OUTPUT_DIR}"
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
if [[ "$ALL_PLATFORMS" == "true" ]]; then
|
||||
for platform in "${PLATFORMS[@]}"; do
|
||||
bundle_platform "$platform"
|
||||
done
|
||||
else
|
||||
bundle_platform "$TARGET_PLATFORM"
|
||||
fi
|
||||
|
||||
log_info "Bundle generation complete!"
|
||||
log_info "To install, copy the bundle to your target system and set STELLAOPS_VALIDATOR_DIR"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user