Skip to content

feat: Implement binary integrity verification and anti-tampering meas… #6

feat: Implement binary integrity verification and anti-tampering meas…

feat: Implement binary integrity verification and anti-tampering meas… #6

Workflow file for this run

name: Beta Build
on:
push:
branches:
- main
paths-ignore:
- '**.md'
- 'LICENSE'
- '.gitignore'
env:
GO_VERSION: '1.24'
NODE_VERSION: '20'
jobs:
build-frontend:
name: Build Frontend
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
working-directory: frontend
run: npm ci
- name: Build frontend
working-directory: frontend
run: npm run build
- name: Upload frontend artifact
uses: actions/upload-artifact@v4
with:
name: frontend-dist
path: frontend/dist
retention-days: 1
build-binaries:
name: Build ${{ matrix.name }}
runs-on: ubuntu-latest
needs: build-frontend
strategy:
matrix:
include:
- name: Linux x64
goos: linux
goarch: amd64
artifact: nettool-linux-amd64
- name: Linux x32
goos: linux
goarch: '386'
artifact: nettool-linux-386
- name: Linux Pi Zero (ARMv6)
goos: linux
goarch: arm
goarm: '6'
artifact: nettool-linux-arm6
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: Download frontend artifact
uses: actions/download-artifact@v4
with:
name: frontend-dist
path: frontend/dist
- name: Get version info
id: version
run: |
SHORT_SHA=$(git rev-parse --short HEAD)
VERSION="beta-${SHORT_SHA}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "commit=$SHORT_SHA" >> $GITHUB_OUTPUT
echo "build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT
- name: Build binary (hardened)
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm }}
CGO_ENABLED: '0'
run: |
# Hardened build flags for security and size optimization
# -w: Omit DWARF symbol table
# -s: Omit symbol table and debug information
# -buildid=: Remove build ID (reduces uniqueness for analysis)
# -trimpath: Remove file system paths from binary
LDFLAGS="-w -s -buildid="
LDFLAGS="$LDFLAGS -X main.Version=${{ steps.version.outputs.version }}"
LDFLAGS="$LDFLAGS -X main.BuildTime=${{ steps.version.outputs.build_time }}"
LDFLAGS="$LDFLAGS -X main.GitCommit=${{ steps.version.outputs.commit }}"
LDFLAGS="$LDFLAGS -X github.com/gin-gonic/gin.Mode=release"
LDFLAGS="$LDFLAGS -X github.com/NetScout-Go/NetTool/app/core.IntegrityEnabled=true"
# Build tags for static compilation
BUILD_TAGS="netgo,osusergo"
echo "Building NetTool for ${{ matrix.name }} (hardened beta)..."
go build -a -trimpath -installsuffix cgo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS" -o nettool ./main.go
echo "Building CLI tool..."
go build -a -trimpath -installsuffix cgo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS" -o nettool-iterate ./app/cmd/iterate/main.go
- name: Strip binaries (additional size reduction)
run: |
# Strip for x86 targets
if [ "${{ matrix.goarch }}" = "amd64" ] || [ "${{ matrix.goarch }}" = "386" ]; then
strip --strip-all nettool 2>/dev/null || true
strip --strip-all nettool-iterate 2>/dev/null || true
fi
- name: Generate checksums
id: checksums
run: |
# Generate SHA256 checksums for binaries
MAIN_HASH=$(sha256sum nettool | cut -d' ' -f1)
CLI_HASH=$(sha256sum nettool-iterate | cut -d' ' -f1)
echo "main_hash=$MAIN_HASH" >> $GITHUB_OUTPUT
echo "cli_hash=$CLI_HASH" >> $GITHUB_OUTPUT
# Create checksums file
echo "$MAIN_HASH nettool" > SHA256SUMS
echo "$CLI_HASH nettool-iterate" >> SHA256SUMS
echo "Generated checksums:"
cat SHA256SUMS
- name: Prepare package
run: |
mkdir -p package/frontend/dist
mkdir -p package/app/plugins/plugins
cp nettool package/
cp nettool-iterate package/
cp SHA256SUMS package/
cp -r frontend/dist/* package/frontend/dist/
cp app/plugins/config.json.example package/app/plugins/
[ -f app/plugins/config.json ] && cp app/plugins/config.json package/app/plugins/ || true
[ -d app/plugins/plugins/demo_plugin ] && cp -r app/plugins/plugins/demo_plugin package/app/plugins/plugins/ || true
cp README.md package/ || true
cp LICENSE package/ || true
# Create install script with integrity verification
cat > package/install.sh << 'INSTALL_EOF'
#!/bin/bash
set -e
INSTALL_DIR="/opt/nettool"
SERVICE_FILE="/etc/systemd/system/nettool.service"
USER="nettool"
GROUP="nettool"
echo "πŸš€ Installing NetTool (Beta)..."
if [ "$EUID" -ne 0 ]; then
echo "❌ Please run as root (use sudo)"
exit 1
fi
# Verify checksums before installation
echo "πŸ” Verifying binary integrity..."
if [ -f SHA256SUMS ]; then
if sha256sum -c SHA256SUMS --status 2>/dev/null; then
echo "βœ… Checksums verified"
else
echo "⚠️ Checksum verification failed! Binaries may have been modified."
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
else
echo "⚠️ No checksums file found, skipping verification"
fi
if ! getent group $GROUP >/dev/null; then
groupadd --system $GROUP
fi
if ! getent passwd $USER >/dev/null; then
useradd --system --gid $GROUP --shell /bin/false --home-dir $INSTALL_DIR $USER
fi
mkdir -p $INSTALL_DIR
cp -r . $INSTALL_DIR/
chown -R $USER:$GROUP $INSTALL_DIR
chmod +x $INSTALL_DIR/nettool $INSTALL_DIR/nettool-iterate
ln -sf $INSTALL_DIR/nettool /usr/local/bin/nettool
ln -sf $INSTALL_DIR/nettool-iterate /usr/local/bin/nettool-iterate
cat > $SERVICE_FILE << 'SERVICE_EOF'
[Unit]
Description=NetTool Network Analysis Server
After=network.target
[Service]
Type=simple
User=nettool
Group=nettool
WorkingDirectory=/opt/nettool
ExecStart=/opt/nettool/nettool --port=8080
Restart=always
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/nettool
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
[Install]
WantedBy=multi-user.target
SERVICE_EOF
systemctl daemon-reload
systemctl enable nettool
echo "βœ… Installation complete!"
echo " Start: sudo systemctl start nettool"
echo " Logs: sudo journalctl -u nettool -f"
echo " Web: http://localhost:8080"
echo ""
echo "πŸ” Verify integrity anytime: nettool --integrity"
INSTALL_EOF
chmod +x package/install.sh
- name: Create archive
run: |
cd package
tar -czvf ../${{ matrix.artifact }}-beta.tar.gz .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}-beta.tar.gz
retention-days: 7
- name: Upload checksums artifact
uses: actions/upload-artifact@v4
with:
name: checksums-${{ matrix.artifact }}
path: SHA256SUMS
retention-days: 7
update-beta-release:
name: Update Beta Release
runs-on: ubuntu-latest
needs: build-binaries
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get commit info
id: info
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "sha_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "date=$(date -u +%Y-%m-%d)" >> $GITHUB_OUTPUT
echo "time=$(date -u +%H:%M:%S)" >> $GITHUB_OUTPUT
echo "commit_msg=$(git log -1 --pretty=%s)" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Move artifacts
run: |
mkdir -p release-files
find artifacts -name "*.tar.gz" -exec mv {} release-files/ \;
ls -la release-files/
- name: Generate combined checksums
run: |
cd release-files
# Create checksums.json manifest
echo '{' > checksums.json
echo ' "version": "beta-${{ steps.info.outputs.sha_short }}",' >> checksums.json
echo ' "build_time": "${{ steps.info.outputs.date }}T${{ steps.info.outputs.time }}Z",' >> checksums.json
echo ' "hashes": {' >> checksums.json
FIRST=true
for file in *.tar.gz; do
HASH=$(sha256sum "$file" | cut -d' ' -f1)
if [ "$FIRST" = true ]; then
FIRST=false
else
echo ',' >> checksums.json
fi
echo -n " \"$file\": \"$HASH\"" >> checksums.json
done
echo '' >> checksums.json
echo ' }' >> checksums.json
echo '}' >> checksums.json
# Also create traditional SHA256SUMS file
sha256sum *.tar.gz > SHA256SUMS
echo "Generated checksums:"
cat checksums.json
cd ..
- name: Delete existing beta tag and release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Delete the release if it exists
gh release delete beta --yes || true
# Delete the tag if it exists
git push origin :refs/tags/beta || true
- name: Create Beta Release
uses: softprops/action-gh-release@v2
with:
tag_name: beta
name: "πŸ§ͺ Beta Build (${{ steps.info.outputs.date }})"
body: |
## ⚠️ Beta Build - Use at Your Own Risk
This is an automatically generated build from the latest `main` branch commit.
**Build Info:**
- πŸ“… Date: ${{ steps.info.outputs.date }} ${{ steps.info.outputs.time }} UTC
- πŸ”– Commit: [`${{ steps.info.outputs.sha_short }}`](https://github.com/${{ github.repository }}/commit/${{ steps.info.outputs.sha_full }})
- πŸ’¬ Message: ${{ steps.info.outputs.commit_msg }}
**πŸ” Security Features:**
- Debug symbols stripped for smaller size
- Build paths removed for privacy
- Integrity verification enabled (`nettool --integrity`)
- SHA256 checksums included
**Downloads:**
| Platform | File |
|----------|------|
| Linux x64 | `nettool-linux-amd64-beta.tar.gz` |
| Linux x32 | `nettool-linux-386-beta.tar.gz` |
| Pi Zero (ARMv6) | `nettool-linux-arm6-beta.tar.gz` |
**Verify your download:**
```bash
# Download and verify checksums
curl -sL https://github.com/${{ github.repository }}/releases/download/beta/SHA256SUMS | sha256sum -c
# Or verify after installation
nettool --integrity
```
---
> πŸ’‘ For stable releases, check the [Releases](https://github.com/${{ github.repository }}/releases) page.
files: |
release-files/*.tar.gz
release-files/checksums.json
release-files/SHA256SUMS
prerelease: true
draft: false
make_latest: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}