Initial commit: Certificate management tools
- cert-manager.py: Interactive certificate lifecycle management - generate-csr.sh: Generate CSR on remote host - sign-cert.sh: Sign certificate with UCS CA - README.md: Complete documentation - .gitignore: Ignore certificate and config files Features: - Interactive prompts with default values - Config persistence between runs - Remote CSR generation with proper server extensions - Automated CA signing - Optional certificate deployment
This commit is contained in:
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Certificate files
|
||||||
|
*.req
|
||||||
|
*.csr
|
||||||
|
*.pem
|
||||||
|
*.crt
|
||||||
|
*.key
|
||||||
|
|
||||||
|
# Python cache
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Config files
|
||||||
|
.cert-manager-config.json
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Editor files
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
84
README.md
Normal file
84
README.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# Certificate Management Tools
|
||||||
|
|
||||||
|
Automated certificate generation and signing tools for UCS CA.
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
### 1. cert-manager.py (Interactive Mode)
|
||||||
|
The main interactive tool that handles the entire certificate lifecycle.
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
./cert-manager.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Interactive prompts with default values
|
||||||
|
- Remembers last used values
|
||||||
|
- Generates CSR on remote host
|
||||||
|
- Signs certificate with UCS CA
|
||||||
|
- Optionally deploys certificate back to target host
|
||||||
|
|
||||||
|
### 2. generate-csr.sh (Standalone)
|
||||||
|
Generates a certificate signing request on a remote host.
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
./generate-csr.sh <hostname> <common-name> [country] [state] [locality] [org] [ou]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
./generate-csr.sh 192.168.1.100 server.example.com DE berlin berlin egonetix it
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. sign-cert.sh (Standalone)
|
||||||
|
Signs a certificate request with the UCS CA.
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
./sign-cert.sh <req-file> <hostname> [days]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
./sign-cert.sh server.req server 3650
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The interactive tool stores default values in `~/.cert-manager-config.json`.
|
||||||
|
|
||||||
|
Default values:
|
||||||
|
- Country: DE
|
||||||
|
- State: berlin
|
||||||
|
- Locality: berlin
|
||||||
|
- Organization: egonetix
|
||||||
|
- Organizational Unit: it
|
||||||
|
- CA Server: 10.0.0.21
|
||||||
|
- Validity: 3650 days (10 years)
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
1. Run `./cert-manager.py`
|
||||||
|
2. Enter target host (IP or hostname where certificate will be used)
|
||||||
|
3. Enter common name (FQDN for the certificate)
|
||||||
|
4. Review/modify certificate subject fields
|
||||||
|
5. Confirm and proceed
|
||||||
|
6. The tool will:
|
||||||
|
- Generate CSR on target host
|
||||||
|
- Sign it with UCS CA
|
||||||
|
- Optionally copy certificate back to target
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- SSH access to target host as root
|
||||||
|
- SSH access to UCS CA server (10.0.0.21) as root
|
||||||
|
- OpenSSL on target host
|
||||||
|
- Python 3.6+ for interactive tool
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Private keys are generated and remain on the target host
|
||||||
|
- Certificate requests (.req) and signed certificates (-cert.pem) are stored locally
|
||||||
|
- The interactive tool remembers your last target host and common name for convenience
|
||||||
225
cert-manager.py
Executable file
225
cert-manager.py
Executable file
@@ -0,0 +1,225 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Interactive Certificate Manager
|
||||||
|
Generates CSR on remote host and signs it with UCS CA
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CONFIG_FILE = Path.home() / '.cert-manager-config.json'
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
'country': 'DE',
|
||||||
|
'state': 'berlin',
|
||||||
|
'locality': 'berlin',
|
||||||
|
'organization': 'egonetix',
|
||||||
|
'organizational_unit': 'it',
|
||||||
|
'ca_server': '10.0.0.21',
|
||||||
|
'validity_days': '3650',
|
||||||
|
'last_target_host': '',
|
||||||
|
'last_common_name': ''
|
||||||
|
}
|
||||||
|
|
||||||
|
def load_config():
|
||||||
|
"""Load configuration from file or return defaults"""
|
||||||
|
if CONFIG_FILE.exists():
|
||||||
|
try:
|
||||||
|
with open(CONFIG_FILE, 'r') as f:
|
||||||
|
config = json.load(f)
|
||||||
|
# Merge with defaults to add any new fields
|
||||||
|
return {**DEFAULT_CONFIG, **config}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: Could not load config: {e}")
|
||||||
|
return DEFAULT_CONFIG.copy()
|
||||||
|
|
||||||
|
def save_config(config):
|
||||||
|
"""Save configuration to file"""
|
||||||
|
try:
|
||||||
|
with open(CONFIG_FILE, 'w') as f:
|
||||||
|
json.dump(config, f, indent=2)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: Could not save config: {e}")
|
||||||
|
|
||||||
|
def prompt_with_default(prompt, default):
|
||||||
|
"""Prompt user with a default value"""
|
||||||
|
if default:
|
||||||
|
user_input = input(f"{prompt} [{default}]: ").strip()
|
||||||
|
return user_input if user_input else default
|
||||||
|
else:
|
||||||
|
return input(f"{prompt}: ").strip()
|
||||||
|
|
||||||
|
def yes_no_prompt(prompt, default=True):
|
||||||
|
"""Ask a yes/no question"""
|
||||||
|
default_str = "Y/n" if default else "y/N"
|
||||||
|
while True:
|
||||||
|
response = input(f"{prompt} [{default_str}]: ").strip().lower()
|
||||||
|
if not response:
|
||||||
|
return default
|
||||||
|
if response in ['y', 'yes']:
|
||||||
|
return True
|
||||||
|
if response in ['n', 'no']:
|
||||||
|
return False
|
||||||
|
print("Please answer 'y' or 'n'")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print("Interactive Certificate Manager")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Load config
|
||||||
|
config = load_config()
|
||||||
|
|
||||||
|
# Ask if user wants to modify defaults
|
||||||
|
if CONFIG_FILE.exists():
|
||||||
|
if yes_no_prompt("Do you want to modify default values?", False):
|
||||||
|
print("\n--- Default Values Configuration ---")
|
||||||
|
config['country'] = prompt_with_default("Country (C)", config['country'])
|
||||||
|
config['state'] = prompt_with_default("State/Province (ST)", config['state'])
|
||||||
|
config['locality'] = prompt_with_default("Locality (L)", config['locality'])
|
||||||
|
config['organization'] = prompt_with_default("Organization (O)", config['organization'])
|
||||||
|
config['organizational_unit'] = prompt_with_default("Organizational Unit (OU)", config['organizational_unit'])
|
||||||
|
config['ca_server'] = prompt_with_default("CA Server", config['ca_server'])
|
||||||
|
config['validity_days'] = prompt_with_default("Validity (days)", config['validity_days'])
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Get certificate details
|
||||||
|
print("--- Certificate Details ---")
|
||||||
|
target_host = prompt_with_default("Target Host (IP or hostname)", config['last_target_host'])
|
||||||
|
|
||||||
|
if not target_host:
|
||||||
|
print("Error: Target host is required!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
common_name = prompt_with_default("Common Name (FQDN)", config['last_common_name'])
|
||||||
|
|
||||||
|
if not common_name:
|
||||||
|
print("Error: Common name is required!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Extract short name for filenames
|
||||||
|
short_name = common_name.split('.')[0]
|
||||||
|
|
||||||
|
# Ask for custom values for this certificate
|
||||||
|
print("\n--- Certificate Subject (press Enter to use defaults) ---")
|
||||||
|
country = prompt_with_default("Country (C)", config['country'])
|
||||||
|
state = prompt_with_default("State/Province (ST)", config['state'])
|
||||||
|
locality = prompt_with_default("Locality (L)", config['locality'])
|
||||||
|
organization = prompt_with_default("Organization (O)", config['organization'])
|
||||||
|
org_unit = prompt_with_default("Organizational Unit (OU)", config['organizational_unit'])
|
||||||
|
validity_days = prompt_with_default("Validity (days)", config['validity_days'])
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Summary:")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"Target Host: {target_host}")
|
||||||
|
print(f"Common Name: {common_name}")
|
||||||
|
print(f"Country: {country}")
|
||||||
|
print(f"State: {state}")
|
||||||
|
print(f"Locality: {locality}")
|
||||||
|
print(f"Organization: {organization}")
|
||||||
|
print(f"Org Unit: {org_unit}")
|
||||||
|
print(f"Validity: {validity_days} days")
|
||||||
|
print(f"CA Server: {config['ca_server']}")
|
||||||
|
print(f"Output files: {short_name}.req, {short_name}-cert.pem")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
if not yes_no_prompt("Proceed with certificate generation?", True):
|
||||||
|
print("Cancelled.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Save config for next run
|
||||||
|
config['last_target_host'] = target_host
|
||||||
|
config['last_common_name'] = common_name
|
||||||
|
save_config(config)
|
||||||
|
|
||||||
|
# Get script directory
|
||||||
|
script_dir = Path(__file__).parent.absolute()
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Step 1: Generating CSR on target host")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Run generate-csr.sh
|
||||||
|
generate_cmd = [
|
||||||
|
str(script_dir / 'generate-csr.sh'),
|
||||||
|
target_host,
|
||||||
|
common_name,
|
||||||
|
country,
|
||||||
|
state,
|
||||||
|
locality,
|
||||||
|
organization,
|
||||||
|
org_unit
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(generate_cmd, check=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\nError: CSR generation failed with exit code {e.returncode}")
|
||||||
|
sys.exit(1)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"\nError: generate-csr.sh not found in {script_dir}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Step 2: Signing certificate with CA")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Run sign-cert.sh
|
||||||
|
req_file = f"{short_name}.req"
|
||||||
|
sign_cmd = [
|
||||||
|
str(script_dir / 'sign-cert.sh'),
|
||||||
|
req_file,
|
||||||
|
short_name,
|
||||||
|
validity_days
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(sign_cmd, check=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\nError: Certificate signing failed with exit code {e.returncode}")
|
||||||
|
sys.exit(1)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"\nError: sign-cert.sh not found in {script_dir}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Step 3: Deploying certificate to target host")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
cert_file = f"{short_name}-cert.pem"
|
||||||
|
|
||||||
|
if yes_no_prompt("Do you want to copy the certificate back to the target host?", True):
|
||||||
|
try:
|
||||||
|
# Copy certificate to target
|
||||||
|
subprocess.run(['scp', cert_file, f'root@{target_host}:/tmp/{short_name}.crt'], check=True)
|
||||||
|
print(f"\n✓ Certificate copied to target host at /tmp/{short_name}.crt")
|
||||||
|
print(f" Private key is at /tmp/{short_name}.key")
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print("\nWarning: Failed to copy certificate to target host")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("✓ Certificate Management Complete!")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"\nFiles created:")
|
||||||
|
print(f" - {req_file} (Certificate Request)")
|
||||||
|
print(f" - {cert_file} (Signed Certificate)")
|
||||||
|
print(f"\nOn target host ({target_host}):")
|
||||||
|
print(f" - /tmp/{short_name}.key (Private Key)")
|
||||||
|
print(f" - /tmp/{short_name}.crt (Certificate)")
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\nCancelled by user.")
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\nError: {e}")
|
||||||
|
sys.exit(1)
|
||||||
113
generate-csr.sh
Executable file
113
generate-csr.sh
Executable file
@@ -0,0 +1,113 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script to generate a certificate request on a remote host
|
||||||
|
# Usage: ./generate-csr.sh <hostname> <common-name> [country] [state] [locality] [org] [ou]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check arguments
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo "Usage: $0 <hostname> <common-name> [country] [state] [locality] [org] [ou]"
|
||||||
|
echo ""
|
||||||
|
echo "Example: $0 192.168.1.100 myserver.domain.com DE berlin berlin egonetix it"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_HOST="$1"
|
||||||
|
COMMON_NAME="$2"
|
||||||
|
COUNTRY="${3:-DE}"
|
||||||
|
STATE="${4:-berlin}"
|
||||||
|
LOCALITY="${5:-berlin}"
|
||||||
|
ORG="${6:-egonetix}"
|
||||||
|
OU="${7:-it}"
|
||||||
|
|
||||||
|
# Extract short hostname from common name
|
||||||
|
SHORT_NAME=$(echo "$COMMON_NAME" | cut -d'.' -f1)
|
||||||
|
OUTPUT_FILE="${SHORT_NAME}.req"
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Certificate Request Generation"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Target host: $TARGET_HOST"
|
||||||
|
echo "Common Name: $COMMON_NAME"
|
||||||
|
echo "Country: $COUNTRY"
|
||||||
|
echo "State: $STATE"
|
||||||
|
echo "Locality: $LOCALITY"
|
||||||
|
echo "Organization: $ORG"
|
||||||
|
echo "Org Unit: $OU"
|
||||||
|
echo "Output file: $OUTPUT_FILE"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Create OpenSSL config
|
||||||
|
CONFIG_CONTENT="[req]
|
||||||
|
default_bits = 4096
|
||||||
|
prompt = no
|
||||||
|
default_md = sha256
|
||||||
|
distinguished_name = dn
|
||||||
|
req_extensions = v3_req
|
||||||
|
|
||||||
|
[dn]
|
||||||
|
C=$COUNTRY
|
||||||
|
ST=$STATE
|
||||||
|
L=$LOCALITY
|
||||||
|
O=$ORG
|
||||||
|
OU=$OU
|
||||||
|
CN=$COMMON_NAME
|
||||||
|
|
||||||
|
[v3_req]
|
||||||
|
keyUsage = digitalSignature, keyEncipherment
|
||||||
|
extendedKeyUsage = serverAuth
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = $COMMON_NAME
|
||||||
|
DNS.2 = $SHORT_NAME"
|
||||||
|
|
||||||
|
# Add alternative names if common name contains domain
|
||||||
|
if [[ "$COMMON_NAME" == *.* ]]; then
|
||||||
|
CONFIG_CONTENT="$CONFIG_CONTENT
|
||||||
|
DNS.3 = ${SHORT_NAME}.${COMMON_NAME#*.}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[1/4] Creating OpenSSL configuration..."
|
||||||
|
echo "$CONFIG_CONTENT" > /tmp/csr_config.conf
|
||||||
|
|
||||||
|
echo "[2/4] Copying config to target host..."
|
||||||
|
scp /tmp/csr_config.conf root@${TARGET_HOST}:/tmp/csr_config.conf
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to copy config to target host"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[3/4] Generating CSR on target host..."
|
||||||
|
ssh root@${TARGET_HOST} "openssl req -new -newkey rsa:4096 -nodes -keyout /tmp/${SHORT_NAME}.key -out /tmp/${SHORT_NAME}.csr -config /tmp/csr_config.conf"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to generate CSR on target host"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[4/4] Downloading CSR..."
|
||||||
|
scp root@${TARGET_HOST}:/tmp/${SHORT_NAME}.csr "$OUTPUT_FILE"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to download CSR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up local temp file
|
||||||
|
rm -f /tmp/csr_config.conf
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "✓ CSR generated successfully!"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Certificate request saved to: $OUTPUT_FILE"
|
||||||
|
echo ""
|
||||||
|
echo "CSR details:"
|
||||||
|
openssl req -in "$OUTPUT_FILE" -noout -text | grep -A 10 "Subject:"
|
||||||
|
echo ""
|
||||||
|
echo "IMPORTANT: Private key is stored on target host at:"
|
||||||
|
echo " /tmp/${SHORT_NAME}.key"
|
||||||
|
echo ""
|
||||||
|
echo "Next step: Sign this CSR with:"
|
||||||
|
echo " ./sign-cert.sh $OUTPUT_FILE $SHORT_NAME"
|
||||||
|
echo "=========================================="
|
||||||
87
sign-cert.sh
Executable file
87
sign-cert.sh
Executable file
@@ -0,0 +1,87 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script to sign a certificate request with UCS CA
|
||||||
|
# Usage: ./sign-cert.sh <req-file> <hostname> [days]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
UCS_SERVER="10.0.0.21"
|
||||||
|
UCS_USER="root"
|
||||||
|
DEFAULT_DAYS=3650
|
||||||
|
|
||||||
|
# Check arguments
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo "Usage: $0 <req-file> <hostname> [days]"
|
||||||
|
echo ""
|
||||||
|
echo "Example: $0 webui.req myserver 3650"
|
||||||
|
echo ""
|
||||||
|
echo "The script will:"
|
||||||
|
echo " 1. Copy the CSR to UCS server"
|
||||||
|
echo " 2. Sign it with the UCS CA"
|
||||||
|
echo " 3. Download the signed certificate to current directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REQ_FILE="$1"
|
||||||
|
HOSTNAME="$2"
|
||||||
|
DAYS="${3:-$DEFAULT_DAYS}"
|
||||||
|
|
||||||
|
# Validate req file exists
|
||||||
|
if [ ! -f "$REQ_FILE" ]; then
|
||||||
|
echo "Error: Certificate request file '$REQ_FILE' not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get absolute path of req file
|
||||||
|
REQ_FILE=$(realpath "$REQ_FILE")
|
||||||
|
OUTPUT_FILE="${HOSTNAME}-cert.pem"
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "UCS Certificate Signing Script"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Request file: $REQ_FILE"
|
||||||
|
echo "Hostname: $HOSTNAME"
|
||||||
|
echo "Valid days: $DAYS"
|
||||||
|
echo "Output file: $OUTPUT_FILE"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Step 1: Copy CSR to UCS server
|
||||||
|
echo "[1/3] Copying CSR to UCS server..."
|
||||||
|
scp "$REQ_FILE" ${UCS_USER}@${UCS_SERVER}:/tmp/${HOSTNAME}.csr
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to copy CSR to UCS server"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 2: Sign the certificate
|
||||||
|
echo "[2/3] Signing certificate on UCS server..."
|
||||||
|
ssh ${UCS_USER}@${UCS_SERVER} "univention-certificate sign -request /tmp/${HOSTNAME}.csr -name ${HOSTNAME} -days ${DAYS}"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to sign certificate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 3: Download signed certificate
|
||||||
|
echo "[3/3] Downloading signed certificate..."
|
||||||
|
scp ${UCS_USER}@${UCS_SERVER}:/etc/univention/ssl/${HOSTNAME}/cert.pem "$OUTPUT_FILE"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to download signed certificate"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo "✓ Certificate signed successfully!"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Certificate saved to: $OUTPUT_FILE"
|
||||||
|
echo ""
|
||||||
|
echo "Certificate details:"
|
||||||
|
openssl x509 -in "$OUTPUT_FILE" -noout -subject -issuer -dates
|
||||||
|
echo ""
|
||||||
|
echo "Subject Alternative Names:"
|
||||||
|
openssl x509 -in "$OUTPUT_FILE" -noout -text | grep -A 1 "Subject Alternative Name" | tail -1
|
||||||
|
echo ""
|
||||||
|
echo "Extended Key Usage:"
|
||||||
|
openssl x509 -in "$OUTPUT_FILE" -noout -text | grep -A 1 "Extended Key Usage" | tail -1
|
||||||
|
echo "=========================================="
|
||||||
Reference in New Issue
Block a user