PTG Product AMIs

Zero Trust VPN
on RHEL 9

A CIS Level 2 hardened RHEL 9 base pre-configured for Zero Trust VPN deployments using WireGuard. Includes the full PTG security stack — SELinux enforcing, auditd, firewalld, fail2ban — plus WireGuard pre-installed and the PTG validation script for ongoing security posture verification.

Versionv1.0
Base OSRHEL 9
VPNWireGuard
HardeningCIS Level 2
Lynis Score85+ / 100
Post-Launch Required

Two known issues affect this image after launch due to CIS hardening side effects. The PATH fix and Lynis profile fix must be applied before running any validation or security scans. See the Post-Launch Fixes section. The PTG validation script with --fix handles both automatically.

What is included

WG

WireGuard Pre-installed

WireGuard kernel module and tools installed. Kernel module enabled at boot. Ready for key generation and peer configuration.

ZT

Zero Trust Architecture

Default-deny firewall. No implicit trust. Every peer must be explicitly authorized. Key-pair only authentication throughout.

CIS

CIS Level 2 Base

Full ansible-lockdown RHEL9-CIS hardening. SELinux enforcing. Auditd immutable. All PTG kernel sysctl hardening applied.

VAL

PTG Validation Script

Included validation script checks VPN config, security posture, PATH integrity, and Lynis profile. Client-ready reporting.

Getting Started

Quick Start

Launch, fix the two known post-launch issues, configure WireGuard, and validate — in under 20 minutes.

1

Launch the instance

Instance type: t3.medium minimum. Assign a key pair. Allow inbound SSH port 22 and UDP port 51820 (WireGuard) in your security group.

2

Connect and fix PATH immediately

bash
ssh -i your-key.pem ec2-user@PUBLIC_IP

# Fix PATH before doing anything else
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3

Run the PTG auto-fix script

bash
sudo bash /opt/PTG/ptg_validate.sh --fix

This fixes PATH in all profile files and removes the invalid Lynis directive. Both post-launch issues resolved in one command.

4

Configure WireGuard

See the WireGuard Setup section for full key generation and peer configuration steps.

5

Run full validation

bash
# Security posture + VPN check
sudo bash /opt/PTG/ptg_validate.sh

# Include full Lynis scan (takes 3-5 min)
sudo bash /opt/PTG/ptg_validate.sh --full
Getting Started

Requirements

Minimum instance
t3.medium
2 vCPU, 4 GB RAM
Recommended
t3.large
For VPN gateway with multiple peers
Root volume
10 GB gp3
Do not reduce
Architecture
x86_64
ARM not supported in v1.0

Security group — required ports

PortProtocolDirectionPurpose
22TCPInboundSSH management — restrict to your IP
51820UDPInboundWireGuard VPN tunnel
Post-Launch Fix

PATH Fix Required

The CIS Level 2 hardening role aggressively restricts the system PATH. This causes grep, tr, ls, awk, uname, and other core utilities to appear missing when switching to root with sudo su.

Symptoms

When you run sudo su you see errors like: bash: tr: command not found, grep: command not found, /usr/libexec/grepconf.sh: line 5: grep: command not found. This is a PATH issue — the binaries exist but the shell cannot find them.

Option 1 — PTG auto-fix script (recommended)

bash
# Run as ec2-user immediately after login
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
sudo bash /opt/PTG/ptg_validate.sh --fix

This fixes PATH in all 6 profile locations and also removes the Lynis profile error in one shot.

Option 2 — Manual fix

bash
# Step 1: Fix current session immediately
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Step 2: Fix all profile files permanently
sudo bash -c 'echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /root/.bashrc'
sudo bash -c 'echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /root/.bash_profile'
sudo bash -c 'echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /etc/bashrc'
sudo bash -c 'echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /etc/profile'
echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> ~/.bashrc

# Step 3: Reload
source /etc/bashrc

# Step 4: Verify
which grep && which tr && which ls && echo "PATH OK"

Why this happens

The CIS role sets secure_path in sudoers and restricts PATH in several profile files to reduce attack surface. This is technically correct per CIS guidelines but breaks utilities during the shell initialization sequence when switching users. The fix restores the standard PATH without compromising the security configuration — all the actual CIS controls remain in place.

Future builds

This fix is baked into the updated rhel_hardened.yml playbook as tasks 4 through 4f. New AMIs built from that playbook will not have this issue at launch.

Post-Launch Fix

Lynis Profile Fix Required

Lynis aborts before scanning due to an invalid directive in /etc/lynis/default.prf. This must be removed before running any Lynis scan.

Symptom

When you run sudo lynis audit system you see: Error: found one or more errors in profile /etc/lynis/default.prf — Unknown option 'profile' found (with value: /etc/lynis/ptg.prf). Lynis exits immediately without scanning.

Fix — one command

bash
sudo sed -i '/^profile=/d' /etc/lynis/default.prf

# Verify it is removed
sudo grep "profile=" /etc/lynis/default.prf && echo "STILL PRESENT" || echo "CLEAN"

Verify Lynis runs correctly

bash
# Quick test — should begin scanning without errors
sudo lynis audit system --quick

After this fix Lynis will initialize and run normally. Expected score on this image is 85 or higher.

VPN Setup

WireGuard Setup

WireGuard is pre-installed. These steps configure it as either a server (accepting peer connections) or a client (connecting to a WireGuard server).

Step 1 — Generate server key pair

bash
# Generate private and public keys
sudo bash -c 'wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key'

# Lock down key permissions
sudo chmod 600 /etc/wireguard/server_private.key
sudo chmod 644 /etc/wireguard/server_public.key

# View your public key (share this with peers)
sudo cat /etc/wireguard/server_public.key

# View your private key (never share this)
sudo cat /etc/wireguard/server_private.key

Step 2 — Create WireGuard interface config

bash
# Get your private key
PRIVATE_KEY=$(sudo cat /etc/wireguard/server_private.key)

# Create wg0.conf
sudo bash -c "cat > /etc/wireguard/wg0.conf" << EOF
[Interface]
# This server's VPN IP address
Address = 10.0.0.1/24

# WireGuard listening port
ListenPort = 51820

# This server's private key
PrivateKey = $PRIVATE_KEY

# Save peers when they connect
SaveConfig = true

# NAT — enable if this is a gateway (clients route internet traffic through VPN)
# PostUp = firewall-cmd --permanent --add-masquerade
# PostDown = firewall-cmd --permanent --remove-masquerade

[Peer]
# Add peer blocks below — one per client
# PublicKey = CLIENT_PUBLIC_KEY_HERE
# AllowedIPs = 10.0.0.2/32
EOF

# Secure the config file
sudo chmod 600 /etc/wireguard/wg0.conf

Step 3 — Open WireGuard port in firewall

bash
# Allow WireGuard UDP port
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-ports

Step 4 — Start and enable WireGuard

bash
# Start WireGuard interface
sudo wg-quick up wg0

# Enable at boot
sudo systemctl enable wg-quick@wg0

# Check status
sudo wg show

Step 5 — Add a peer (client)

On each client machine, generate a key pair and share the public key with the server.

bash — run on the client machine
# Generate client keys
wg genkey | tee client_private.key | wg pubkey > client_public.key

# Client wg0.conf
cat > /etc/wireguard/wg0.conf << EOF
[Interface]
Address = 10.0.0.2/24
PrivateKey = $(cat client_private.key)
DNS = 8.8.8.8

[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
EOF
bash — run on the server to add the peer
# Add peer dynamically (no restart needed)
sudo wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips 10.0.0.2/32

# Save config so it persists
sudo wg-quick save wg0
Verify tunnel

After the client connects, run sudo wg show on the server. You will see the peer listed with a recent handshake timestamp and transfer bytes if traffic is flowing.

VPN Setup

VPN Validation

Use the PTG validation script to verify your VPN configuration is correct and active.

VPN-only check

bash
sudo bash /opt/PTG/ptg_validate.sh --vpn

Manual VPN verification commands

bash
# Show all active WireGuard interfaces and peers
sudo wg show

# Show transfer statistics
sudo wg show wg0 transfer

# Show handshake times (confirm peers are connecting)
sudo wg show wg0 latest-handshakes

# Confirm interface is up
ip addr show wg0

# Confirm firewall port is open
sudo firewall-cmd --list-ports | grep 51820

# Test connectivity from a peer
ping 10.0.0.1
Security

PTG Validation Script

The PTG validation script is included at /opt/PTG/ptg_validate.sh. It checks VPN configuration, security posture, and produces a timestamped report suitable for client delivery.

Usage modes

CommandWhat it does
sudo bash ptg_validate.shFull security posture check — SSH, SELinux, firewall, auditd, fail2ban, kernel, permissions
sudo bash ptg_validate.sh --fullAll of the above plus a full Lynis scan (3–5 min)
sudo bash ptg_validate.sh --vpnVPN checks only — WireGuard status, peers, ports, firewall
sudo bash ptg_validate.sh --fixAuto-fix PATH and Lynis profile issues — run this first on any new instance

Output

Results are printed to the terminal with color-coded PASS/FAIL/WARN/INFO labels and written to a timestamped file at /opt/PTG/compliance/ptg_validation_YYYYMMDD_HHMMSS.txt. Share this file with clients as a security posture report.

Install or update the script

bash
# Make executable
sudo chmod +x /opt/PTG/ptg_validate.sh

# Run auto-fix first on any new instance
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
sudo bash /opt/PTG/ptg_validate.sh --fix

# Then run full validation
sudo bash /opt/PTG/ptg_validate.sh --full
Security

Security Posture

This AMI inherits the full PTG Hardened RHEL 9 CIS Level 2 security stack plus WireGuard-specific additions.

Controls applied

  • CIS Level 2 hardening — ansible-lockdown RHEL9-CIS role
  • SELinux enforcing mode (targeted policy)
  • auditd with full CIS ruleset and -e 2 immutable flag
  • firewalld — default zone drop, SSH and WireGuard port open
  • fail2ban with SSH jail (5 retries, 1-hour ban)
  • WireGuard config files chmod 600
  • IP forwarding configurable for gateway vs client mode
  • Kernel sysctl hardening — 12 values applied via 99-ptg-lynis.conf
  • SSH hardened — no root login, no password auth, MaxAuthTries 3
  • No baked-in SSH keys — regenerated on every customer launch
  • AIDE file integrity monitoring
  • rkhunter rootkit detection
  • dnf-automatic unattended security updates
  • Compliance manifest at /opt/PTG/compliance/manifest.txt
  • PTG validation script at /opt/PTG/ptg_validate.sh
Security

Lynis Scoring

Target score for this image is 85 or higher. Apply the post-launch fixes before running any scan.

85
/ 100 target
PTG Zero Trust VPN — v1.0
Tests: 248
Warnings: 0
Firewall: Active
Intrusion detection: Active

Lynis scan commands

bash
# Standard full scan
sudo lynis audit system

# Quick scan — faster, same score
sudo lynis audit system --quick

# Quiet — score and warnings only
sudo lynis audit system --quiet

# Get score from last scan
sudo grep "hardening_index" /var/log/lynis-report.dat | tail -1

# Get all warnings from last scan
sudo grep "^warning" /var/log/lynis-report.dat

# Investigate a specific test
sudo lynis show details TEST-ID
Reference

Changelog

v1.0 — April 2026 Initial Release

  • CIS Level 2 hardening via ansible-lockdown RHEL9-CIS role
  • WireGuard pre-installed and kernel module enabled
  • SELinux enforcing mode — targeted policy
  • auditd with CIS ruleset and immutable flag
  • firewalld — default drop, SSH and UDP 51820 open
  • fail2ban SSH jail active
  • PTG validation script included at /opt/PTG/ptg_validate.sh
  • --fix mode resolves PATH and Lynis profile post-launch issues
  • Lynis score: 85+ / 100
  • Known issues: PATH fix and Lynis profile fix required post-launch
Reference

Support

TypeContactResponse
Generalsupport@powelltechnologygroup.com48 hours Mon–Fri ET
UrgentSubject: PTG VPN RHEL9 - UrgentBest effort same day
Refund policy

Refunds within 7 days of initial subscription for any reason. Contact support with your AWS account ID and subscription date.