Last active
October 5, 2025 00:21
-
-
Save austinsonger/a1593979312c695b4007edc53e95cea1 to your computer and use it in GitHub Desktop.
phase
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Modified: 2025-10-05 | |
# Phase Console Installation Script for Rocky Linux and CentOS | |
# Installs and configures Phase Console server with Tor hidden service | |
set -euo pipefail | |
# Configuration variables | |
PHASE_CONSOLE_DIR="/opt/phase-console" | |
PHASE_USER="phaseuser" | |
PHASE_GROUP="phaseuser" | |
TOR_DATA_DIR="/var/lib/tor" | |
SSH_PORT="2222" | |
PHASE_CONSOLE_PORT="3000" | |
# Colors for output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
NC='\033[0m' # No Color | |
# Logging function | |
log() { | |
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | |
} | |
warn() { | |
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" | |
} | |
error() { | |
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | |
exit 1 | |
} | |
# Check if running as root | |
check_root() { | |
if [[ $EUID -ne 0 ]]; then | |
error "This script must be run as root" | |
fi | |
} | |
# Check OS version (Rocky Linux or CentOS) | |
check_os_version() { | |
if ! grep -qE "(Rocky Linux|CentOS)" /etc/os-release; then | |
error "This script is designed for Rocky Linux or CentOS" | |
fi | |
local os_name=$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2) | |
local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2) | |
log "Detected OS: $os_name (version: $version)" | |
} | |
# Update system packages | |
update_system() { | |
log "Updating system packages..." | |
dnf update -y | |
dnf install -y epel-release | |
dnf update -y | |
} | |
# Install required packages | |
install_packages() { | |
log "Installing required packages..." | |
# Core packages | |
dnf install -y \ | |
curl \ | |
wget \ | |
git \ | |
jq \ | |
openssl \ | |
firewalld \ | |
policycoreutils-python-utils \ | |
selinux-policy-devel | |
# Install Docker | |
log "Installing Docker..." | |
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | |
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | |
# Install Tor | |
log "Installing Tor..." | |
dnf install -y tor | |
# Install OpenSSH server | |
log "Installing OpenSSH server..." | |
dnf install -y openssh-server | |
} | |
# Ensure Tor user and group exist | |
ensure_tor_user() { | |
log "Ensuring Tor user and group exist..." | |
# Check if tor group exists, create if not | |
if ! getent group tor >/dev/null 2>&1; then | |
log "Creating tor group..." | |
groupadd -r tor | |
else | |
log "Tor group already exists" | |
fi | |
# Check if tor user exists, create if not | |
if ! getent passwd tor >/dev/null 2>&1; then | |
log "Creating tor user..." | |
useradd -r -g tor -d /var/lib/tor -s /bin/false -c "Tor daemon user" tor | |
else | |
log "Tor user already exists" | |
fi | |
# Ensure tor user home directory exists with correct ownership | |
if [[ ! -d /var/lib/tor ]]; then | |
mkdir -p /var/lib/tor | |
fi | |
chown tor:tor /var/lib/tor | |
chmod 700 /var/lib/tor | |
log "Tor user and group setup completed" | |
} | |
# Configure system services | |
configure_services() { | |
log "Configuring system services..." | |
# Enable and start Docker | |
systemctl enable docker | |
systemctl start docker | |
# Enable and start SSH | |
systemctl enable sshd | |
systemctl start sshd | |
# Configure Tor (will start later after configuration) | |
systemctl enable tor | |
} | |
# Create Phase Console user | |
create_phase_user() { | |
log "Creating Phase Console user..." | |
if ! id "$PHASE_USER" &>/dev/null; then | |
useradd -r -m -s /bin/bash -d "/home/$PHASE_USER" "$PHASE_USER" | |
usermod -aG docker "$PHASE_USER" | |
else | |
log "User $PHASE_USER already exists" | |
fi | |
} | |
# Create directory structure | |
create_directories() { | |
log "Creating directory structure..." | |
mkdir -p "$PHASE_CONSOLE_DIR"/{data,config,logs,ssh-keys,secrets} | |
mkdir -p "$TOR_DATA_DIR/phase-console" | |
mkdir -p "/home/$PHASE_USER/.ssh" | |
# Set ownership | |
chown -R "$PHASE_USER:$PHASE_GROUP" "$PHASE_CONSOLE_DIR" | |
chown -R "$PHASE_USER:$PHASE_GROUP" "/home/$PHASE_USER" | |
# Verify tor user exists before setting ownership | |
if getent passwd tor >/dev/null 2>&1; then | |
chown -R tor:tor "$TOR_DATA_DIR" | |
log "Set Tor data directory ownership to tor:tor" | |
else | |
error "Tor user does not exist. This should have been created by ensure_tor_user function." | |
fi | |
# Set permissions | |
chmod 700 "/home/$PHASE_USER/.ssh" | |
chmod 700 "$PHASE_CONSOLE_DIR/secrets" | |
chmod 755 "$PHASE_CONSOLE_DIR"/{data,config,logs,ssh-keys} | |
} | |
# Generate secrets | |
generate_secrets() { | |
log "Generating secrets..." | |
local secrets_dir="$PHASE_CONSOLE_DIR/secrets" | |
# Phase Console infrastructure secrets | |
log " Generating Phase Console infrastructure secrets..." | |
openssl rand -base64 32 > "$secrets_dir/postgres_password" | |
openssl rand -base64 32 > "$secrets_dir/redis_password" | |
openssl rand -base64 64 > "$secrets_dir/jwt_secret" | |
openssl rand -base64 32 > "$secrets_dir/encryption_key" | |
# ShadowBin Marketplace application secrets | |
log " Generating ShadowBin Marketplace application secrets..." | |
echo "base64:$(openssl rand -base64 32)" > "$secrets_dir/app_key" | |
openssl rand -base64 32 > "$secrets_dir/session_encryption_key" | |
openssl rand -hex 32 > "$secrets_dir/sanctum_secret_key" | |
openssl rand -base64 64 > "$secrets_dir/jwt_secret_app" | |
openssl rand -base64 32 > "$secrets_dir/encryption_master_key" | |
# Database secrets for ShadowBin | |
log " Generating database secrets..." | |
openssl rand -base64 24 > "$secrets_dir/db_password" | |
openssl rand -base64 32 > "$secrets_dir/db_root_password" | |
openssl rand -base64 24 > "$secrets_dir/redis_app_password" | |
# External API key placeholders (to be updated with real keys) | |
log " Creating external API key placeholders..." | |
echo "your_coinmarketcap_api_key_here" > "$secrets_dir/coinmarketcap_api_key" | |
echo "your_coingecko_api_key_here" > "$secrets_dir/coingecko_api_key" | |
echo "your_kraken_api_key_here" > "$secrets_dir/kraken_api_key" | |
echo "your_kraken_api_secret_here" > "$secrets_dir/kraken_api_secret" | |
# Monitoring secrets | |
log " Generating monitoring secrets..." | |
openssl rand -hex 32 > "$secrets_dir/telescope_secret" | |
openssl rand -hex 16 > "$secrets_dir/health_check_secret" | |
openssl rand -hex 24 > "$secrets_dir/metrics_api_token" | |
openssl rand -base64 32 > "$secrets_dir/log_encryption_key" | |
# Backup and recovery secrets | |
log " Generating backup secrets..." | |
openssl rand -base64 32 > "$secrets_dir/backup_encryption_key" | |
echo "your_s3_access_key_here" > "$secrets_dir/s3_access_key_id" | |
echo "your_s3_secret_key_here" > "$secrets_dir/s3_secret_access_key" | |
openssl rand -base64 32 > "$secrets_dir/disaster_recovery_key" | |
# Tor and network security | |
log " Generating network security secrets..." | |
openssl rand -base64 24 > "$secrets_dir/tor_control_password" | |
openssl rand -base64 32 > "$secrets_dir/proxy_auth_token" | |
# Set secure permissions | |
chmod 600 "$secrets_dir"/* | |
chown "$PHASE_USER:$PHASE_GROUP" "$secrets_dir"/* | |
log " Generated $(ls -1 "$secrets_dir" | wc -l) secrets for ShadowBin Marketplace" | |
} | |
# Configure Tor | |
configure_tor() { | |
log "Configuring Tor hidden service..." | |
# Backup original torrc | |
cp /etc/tor/torrc /etc/tor/torrc.backup | |
# Create Tor configuration | |
cat > /etc/tor/torrc << 'EOF' | |
# Phase Console Tor Configuration | |
# Created: 2025-09-14 | |
# Basic configuration | |
User tor | |
DataDirectory /var/lib/tor | |
PidFile /var/run/tor/tor.pid | |
# Logging | |
Log notice file /var/log/tor/tor.log | |
Log warn file /var/log/tor/warn.log | |
# Hidden Service for Phase Console | |
HiddenServiceDir /var/lib/tor/phase-console/ | |
HiddenServicePort 80 127.0.0.1:3000 | |
HiddenServicePort 22 127.0.0.1:2222 | |
# Security hardening | |
HiddenServiceVersion 3 | |
HiddenServiceNumIntroductionPoints 10 | |
HiddenServiceMaxStreams 65536 | |
HiddenServiceMaxStreamsCloseCircuit 1 | |
# Disable client functionality | |
SocksPort 0 | |
ControlPort 0 | |
CookieAuthentication 0 | |
# Additional security | |
AvoidDiskWrites 1 | |
DisableDebuggerAttachment 1 | |
SafeLogging 1 | |
WarnUnsafeSocks 1 | |
# Circuit security | |
CircuitBuildTimeout 30 | |
LearnCircuitBuildTimeout 0 | |
MaxCircuitDirtiness 300 | |
NewCircuitPeriod 15 | |
MaxClientCircuitsPending 32 | |
EOF | |
# Create log directory | |
mkdir -p /var/log/tor | |
chown tor:tor /var/log/tor | |
chmod 755 /var/log/tor | |
# Set SELinux context if enabled | |
if command -v setsebool &> /dev/null; then | |
setsebool -P tor_can_network_relay 1 | |
setsebool -P tor_bind_all_unreserved_ports 1 | |
fi | |
} | |
# Configure SSH | |
configure_ssh() { | |
log "Configuring SSH server..." | |
# Backup original sshd_config | |
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup | |
# Create SSH configuration for Phase Console | |
cat >> /etc/ssh/sshd_config << EOF | |
# Phase Console SSH Configuration | |
# Added: 2025-09-14 | |
Port $SSH_PORT | |
Protocol 2 | |
PermitRootLogin no | |
PasswordAuthentication no | |
PubkeyAuthentication yes | |
# Security hardening | |
MaxAuthTries 3 | |
MaxSessions 2 | |
ClientAliveInterval 300 | |
ClientAliveCountMax 2 | |
TCPKeepAlive no | |
Compression no | |
# Restrict user access | |
AllowUsers $PHASE_USER | |
DenyUsers root | |
# Logging | |
LogLevel VERBOSE | |
SyslogFacility AUTH | |
# Disable unnecessary features | |
AllowAgentForwarding no | |
AllowTcpForwarding no | |
X11Forwarding no | |
PermitTunnel no | |
GatewayPorts no | |
EOF | |
# Generate SSH host keys for custom port if needed | |
if [[ ! -f "/etc/ssh/ssh_host_rsa_key" ]]; then | |
ssh-keygen -A | |
fi | |
} | |
# Configure firewall | |
configure_firewall() { | |
log "Configuring firewall..." | |
# Start and enable firewalld | |
systemctl enable firewalld | |
systemctl start firewalld | |
# Allow SSH on custom port | |
firewall-cmd --permanent --add-port="$SSH_PORT/tcp" | |
# Allow Phase Console port (only from localhost) | |
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='127.0.0.1' port protocol='tcp' port='$PHASE_CONSOLE_PORT' accept" | |
# Allow Tor | |
firewall-cmd --permanent --add-service=tor | |
# Reload firewall | |
firewall-cmd --reload | |
log "Firewall configured. Open ports: $SSH_PORT/tcp (SSH), $PHASE_CONSOLE_PORT/tcp (localhost only)" | |
} | |
# Create Docker Compose file | |
create_docker_compose() { | |
log "Creating Docker Compose configuration..." | |
cat > "$PHASE_CONSOLE_DIR/docker-compose.yml" << 'EOF' | |
# Phase Console Docker Compose | |
# Created: 2025-09-14 | |
version: '3.8' | |
name: phase-console-server | |
networks: | |
phase-internal: | |
driver: bridge | |
ipam: | |
config: | |
- subnet: 172.30.0.0/16 | |
volumes: | |
phase-postgres-data: | |
name: phase-postgres-data | |
phase-redis-data: | |
name: phase-redis-data | |
phase-app-data: | |
name: phase-app-data | |
services: | |
postgres: | |
image: postgres:15-alpine | |
container_name: phase-postgres | |
restart: unless-stopped | |
environment: | |
POSTGRES_DB: phase_console | |
POSTGRES_USER: phase_user | |
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password | |
secrets: | |
- postgres_password | |
volumes: | |
- phase-postgres-data:/var/lib/postgresql/data | |
networks: | |
- phase-internal | |
healthcheck: | |
test: ["CMD-SHELL", "pg_isready -U phase_user -d phase_console"] | |
interval: 30s | |
timeout: 10s | |
retries: 3 | |
redis: | |
image: redis:7-alpine | |
container_name: phase-redis | |
restart: unless-stopped | |
command: ["redis-server", "--requirepass", "$(cat /run/secrets/redis_password)"] | |
secrets: | |
- redis_password | |
volumes: | |
- phase-redis-data:/data | |
networks: | |
- phase-internal | |
healthcheck: | |
test: ["CMD", "redis-cli", "--no-auth-warning", "-a", "$(cat /run/secrets/redis_password)", "ping"] | |
interval: 30s | |
timeout: 10s | |
retries: 3 | |
phase-console: | |
image: phasehq/console:latest | |
container_name: phase-console-app | |
restart: unless-stopped | |
ports: | |
- "127.0.0.1:3000:3000" | |
environment: | |
- DATABASE_URL=postgresql://phase_user:$(cat /run/secrets/postgres_password)@postgres:5432/phase_console | |
- REDIS_URL=redis://:$(cat /run/secrets/redis_password)@redis:6379 | |
- JWT_SECRET_FILE=/run/secrets/jwt_secret | |
- ENCRYPTION_KEY_FILE=/run/secrets/encryption_key | |
- NODE_ENV=production | |
secrets: | |
- postgres_password | |
- redis_password | |
- jwt_secret | |
- encryption_key | |
volumes: | |
- phase-app-data:/app/data | |
networks: | |
- phase-internal | |
depends_on: | |
postgres: | |
condition: service_healthy | |
redis: | |
condition: service_healthy | |
healthcheck: | |
test: ["CMD", "curl", "-f", "http://localhost:3000/health"] | |
interval: 30s | |
timeout: 10s | |
retries: 3 | |
secrets: | |
postgres_password: | |
file: ./secrets/postgres_password | |
redis_password: | |
file: ./secrets/redis_password | |
jwt_secret: | |
file: ./secrets/jwt_secret | |
encryption_key: | |
file: ./secrets/encryption_key | |
EOF | |
chown "$PHASE_USER:$PHASE_GROUP" "$PHASE_CONSOLE_DIR/docker-compose.yml" | |
} | |
# Create systemd service for Phase Console | |
create_systemd_service() { | |
log "Creating systemd service for Phase Console..." | |
cat > /etc/systemd/system/phase-console.service << EOF | |
[Unit] | |
Description=Phase Console Server | |
Requires=docker.service tor.service | |
After=docker.service tor.service | |
StartLimitIntervalSec=0 | |
[Service] | |
Type=oneshot | |
RemainAfterExit=yes | |
User=$PHASE_USER | |
Group=$PHASE_GROUP | |
WorkingDirectory=$PHASE_CONSOLE_DIR | |
ExecStart=/usr/bin/docker compose up -d | |
ExecStop=/usr/bin/docker compose down | |
ExecReload=/usr/bin/docker compose restart | |
TimeoutStartSec=300 | |
TimeoutStopSec=120 | |
Restart=on-failure | |
RestartSec=30 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
systemctl daemon-reload | |
systemctl enable phase-console.service | |
} | |
# Create management scripts | |
create_management_scripts() { | |
log "Creating management scripts..." | |
# Phase Console control script | |
cat > "$PHASE_CONSOLE_DIR/phase-control.sh" << 'EOF' | |
#!/bin/bash | |
# Phase Console Control Script | |
# Created: 2025-09-14 | |
set -euo pipefail | |
PHASE_CONSOLE_DIR="/opt/phase-console" | |
cd "$PHASE_CONSOLE_DIR" | |
case "${1:-}" in | |
start) | |
echo "Starting Phase Console..." | |
docker compose up -d | |
;; | |
stop) | |
echo "Stopping Phase Console..." | |
docker compose down | |
;; | |
restart) | |
echo "Restarting Phase Console..." | |
docker compose restart | |
;; | |
status) | |
echo "Phase Console Status:" | |
docker compose ps | |
;; | |
logs) | |
docker compose logs -f "${2:-}" | |
;; | |
update) | |
echo "Updating Phase Console..." | |
docker compose pull | |
docker compose up -d | |
;; | |
backup) | |
echo "Creating backup..." | |
backup_dir="/opt/phase-console/backups/$(date +%Y%m%d_%H%M%S)" | |
mkdir -p "$backup_dir" | |
docker compose exec postgres pg_dump -U phase_user phase_console > "$backup_dir/database.sql" | |
cp -r ./secrets "$backup_dir/" | |
echo "Backup created at: $backup_dir" | |
;; | |
*) | |
echo "Usage: $0 {start|stop|restart|status|logs|update|backup}" | |
echo " logs [service] - Show logs for specific service or all" | |
exit 1 | |
;; | |
esac | |
EOF | |
chmod +x "$PHASE_CONSOLE_DIR/phase-control.sh" | |
chown "$PHASE_USER:$PHASE_GROUP" "$PHASE_CONSOLE_DIR/phase-control.sh" | |
# Create symlink for easy access | |
ln -sf "$PHASE_CONSOLE_DIR/phase-control.sh" /usr/local/bin/phase-console | |
# SSH key management script | |
cat > "$PHASE_CONSOLE_DIR/manage-ssh-keys.sh" << 'EOF' | |
#!/bin/bash | |
# SSH Key Management Script for Phase Console | |
# Created: 2025-09-14 | |
set -euo pipefail | |
PHASE_USER="phaseuser" | |
SSH_DIR="/home/$PHASE_USER/.ssh" | |
AUTHORIZED_KEYS="$SSH_DIR/authorized_keys" | |
case "${1:-}" in | |
add) | |
if [[ -z "${2:-}" ]]; then | |
echo "Usage: $0 add <public_key_file_or_string>" | |
exit 1 | |
fi | |
if [[ -f "$2" ]]; then | |
# It's a file | |
cat "$2" >> "$AUTHORIZED_KEYS" | |
echo "Added public key from file: $2" | |
else | |
# It's a key string | |
echo "$2" >> "$AUTHORIZED_KEYS" | |
echo "Added public key string" | |
fi | |
# Set proper permissions | |
chmod 600 "$AUTHORIZED_KEYS" | |
chown "$PHASE_USER:$PHASE_USER" "$AUTHORIZED_KEYS" | |
;; | |
list) | |
echo "Authorized SSH keys:" | |
if [[ -f "$AUTHORIZED_KEYS" ]]; then | |
cat -n "$AUTHORIZED_KEYS" | |
else | |
echo "No authorized keys found" | |
fi | |
;; | |
remove) | |
if [[ -z "${2:-}" ]]; then | |
echo "Usage: $0 remove <line_number>" | |
exit 1 | |
fi | |
if [[ -f "$AUTHORIZED_KEYS" ]]; then | |
sed -i "${2}d" "$AUTHORIZED_KEYS" | |
echo "Removed key at line $2" | |
else | |
echo "No authorized keys file found" | |
fi | |
;; | |
clear) | |
read -p "Are you sure you want to remove all SSH keys? (y/N): " -n 1 -r | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
> "$AUTHORIZED_KEYS" | |
echo "All SSH keys removed" | |
fi | |
;; | |
*) | |
echo "Usage: $0 {add|list|remove|clear}" | |
echo " add <key_file_or_string> - Add SSH public key" | |
echo " list - List all authorized keys" | |
echo " remove <line_number> - Remove key at specific line" | |
echo " clear - Remove all keys" | |
exit 1 | |
;; | |
esac | |
EOF | |
chmod +x "$PHASE_CONSOLE_DIR/manage-ssh-keys.sh" | |
chown "$PHASE_USER:$PHASE_GROUP" "$PHASE_CONSOLE_DIR/manage-ssh-keys.sh" | |
# Create symlink for easy access | |
ln -sf "$PHASE_CONSOLE_DIR/manage-ssh-keys.sh" /usr/local/bin/phase-ssh-keys | |
} | |
# Start services | |
start_services() { | |
log "Starting services..." | |
# Start Tor first | |
systemctl start tor | |
sleep 5 | |
# Start SSH | |
systemctl restart sshd | |
# Start Phase Console | |
systemctl start phase-console | |
# Wait for services to be ready | |
log "Waiting for services to start..." | |
sleep 30 | |
} | |
# Get Tor onion address | |
get_onion_address() { | |
log "Retrieving Tor onion address..." | |
local onion_file="$TOR_DATA_DIR/phase-console/hostname" | |
local max_attempts=30 | |
local attempt=1 | |
while [[ $attempt -le $max_attempts ]]; do | |
if [[ -f "$onion_file" ]]; then | |
local onion_address=$(cat "$onion_file") | |
log "Phase Console .onion address: $onion_address" | |
# Save to easily accessible location | |
echo "$onion_address" > "$PHASE_CONSOLE_DIR/onion-address.txt" | |
chown "$PHASE_USER:$PHASE_GROUP" "$PHASE_CONSOLE_DIR/onion-address.txt" | |
return 0 | |
fi | |
log "Waiting for Tor to generate onion address... (attempt $attempt/$max_attempts)" | |
sleep 2 | |
((attempt++)) | |
done | |
warn "Could not retrieve onion address. Check Tor logs: journalctl -u tor" | |
} | |
# Create installation summary | |
create_summary() { | |
log "Creating installation summary..." | |
local summary_file="$PHASE_CONSOLE_DIR/installation-summary.txt" | |
local onion_address="Unknown" | |
if [[ -f "$PHASE_CONSOLE_DIR/onion-address.txt" ]]; then | |
onion_address=$(cat "$PHASE_CONSOLE_DIR/onion-address.txt") | |
fi | |
cat > "$summary_file" << EOF | |
Phase Console Installation Summary | |
================================== | |
Installation Date: $(date) | |
Server: $(hostname) | |
OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2) | |
Services: | |
--------- | |
Phase Console: http://127.0.0.1:$PHASE_CONSOLE_PORT | |
Tor Hidden Service: http://$onion_address | |
SSH Port: $SSH_PORT | |
Directories: | |
------------ | |
Installation: $PHASE_CONSOLE_DIR | |
Secrets: $PHASE_CONSOLE_DIR/secrets | |
Logs: $PHASE_CONSOLE_DIR/logs | |
Tor Data: $TOR_DATA_DIR/phase-console | |
Management Commands: | |
------------------- | |
Control Phase Console: phase-console {start|stop|restart|status|logs|update|backup} | |
Manage SSH Keys: phase-ssh-keys {add|list|remove|clear} | |
Generated Secrets for ShadowBin Marketplace: | |
-------------------------------------------- | |
Application Secrets: | |
- app_key (Laravel encryption key) | |
- session_encryption_key (Session encryption) | |
- sanctum_secret_key (API authentication) | |
- jwt_secret_app (JWT signing) | |
- encryption_master_key (Master encryption) | |
Database Secrets: | |
- db_password (MySQL application user) | |
- db_root_password (MySQL root user) | |
- redis_app_password (Redis authentication) | |
Monitoring Secrets: | |
- telescope_secret (Laravel Telescope) | |
- health_check_secret (Health endpoints) | |
- metrics_api_token (Metrics collection) | |
- log_encryption_key (Log encryption) | |
Backup & Recovery: | |
- backup_encryption_key (Backup encryption) | |
- disaster_recovery_key (Emergency access) | |
External API Placeholders (UPDATE WITH REAL VALUES): | |
- coinmarketcap_api_key | |
- coingecko_api_key | |
- kraken_api_key | |
- kraken_api_secret | |
- s3_access_key_id | |
- s3_secret_access_key | |
Service Status: | |
--------------- | |
$(systemctl is-active docker) - Docker | |
$(systemctl is-active tor) - Tor | |
$(systemctl is-active sshd) - SSH | |
$(systemctl is-active phase-console) - Phase Console | |
Next Steps: | |
----------- | |
1. Add SSH public keys: phase-ssh-keys add <public_key_file> | |
2. UPDATE PLACEHOLDER API KEYS with real values in $PHASE_CONSOLE_DIR/secrets/ | |
3. Configure ShadowBin Marketplace to connect to: $onion_address | |
4. Test SSH connection: ssh -p $SSH_PORT phaseuser@$onion_address | |
5. Access Phase Console: http://127.0.0.1:$PHASE_CONSOLE_PORT (local only) | |
6. Run post-install validation: phase-console-post-install.sh | |
Security Notes: | |
--------------- | |
- Phase Console is only accessible via Tor hidden service | |
- SSH access requires public key authentication | |
- All secrets are stored in $PHASE_CONSOLE_DIR/secrets with restricted permissions | |
- Firewall is configured to allow only necessary ports | |
- Generated $(ls -1 $PHASE_CONSOLE_DIR/secrets | wc -l) secrets for ShadowBin Marketplace | |
EOF | |
chown "$PHASE_USER:$PHASE_GROUP" "$summary_file" | |
# Display summary | |
cat "$summary_file" | |
} | |
# Main installation function | |
main() { | |
log "Starting Phase Console installation on Rocky Linux/CentOS..." | |
check_root | |
check_os_version | |
update_system | |
install_packages | |
ensure_tor_user | |
configure_services | |
create_phase_user | |
create_directories | |
generate_secrets | |
configure_tor | |
configure_ssh | |
configure_firewall | |
create_docker_compose | |
create_systemd_service | |
create_management_scripts | |
start_services | |
get_onion_address | |
create_summary | |
log "Phase Console installation completed successfully!" | |
log "Summary saved to: $PHASE_CONSOLE_DIR/installation-summary.txt" | |
log "Onion address saved to: $PHASE_CONSOLE_DIR/onion-address.txt" | |
} | |
# Run main function if script is executed directly | |
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then | |
main "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment