Update docs v1.2

This commit is contained in:
2026-03-13 11:09:37 +01:00
parent 3831e69ed0
commit 978306677b
16 changed files with 872 additions and 1044 deletions
+95 -207
View File
@@ -1,263 +1,151 @@
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![GNU GPL v3 License][license-shield]][license-url]
[![Release][release-shield]][release-url]
[![Latest Release][release-shield]][release-url]
<br />
<!--
<p align="center">
<a href="https://github.com/swissmakers/infra-manager">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/WhNYRgX.png">
<img alt="Infram Banner" src="https://i.imgur.com/TBMT7dt.png">
</picture>
</a>
</p>-->
<div align="center">
## What is infra-manager?
# Infram
Infram (infra-manager) is a privacy-first and security focused platform for remote infrastructure operations.
It combines remote access, identity-aware administration, inventory synchronization, and auditability in one system.
**Open-source platform for secure remote infrastructure operations**
Core capabilities:
[Quick Start](#quick-start-container) •
[Documentation](#documentation) •
[API Reference](docs/api-reference.md) •
[Security Notes](#security-notes)
- Remote access to Servers / Clients / IoT, via SSH, RDP, VNC (or Telnet)
- Integrated file management over same SSH-session that used by terminal
- Team isolation through seperate tenant Organizations and access-rules
- LDAP / 2FA / FIDO2 capability for identity and access control. (OIDC as addition)
- Script and snippet automation for repeatable operations (e.g. give a long command "a name", and execute it directly from the WebUI console)
- NetBox (and Proxmox -> we may remove that) integration for infrastructure sync and manager automation.
- Audit logs and session lifecycle controls for operational traceability
- Optional session recording (video) for productive systems
</div>
## Upstream Attribution
Infram (infra-manager) provides a central control plane for day-to-day infrastructure access and operations across distributed Linux and mixed-protocol environments. It combines remote access, identity-aware authentication, automation, and auditability in one operational surface.
This project is a fork/rebrand maintained by Swissmakers GmbH.
It is based on the original Nexterm project by Mathias Wagner.
Infram follows an independent roadmap centered on production reliability, security hardening, and privacy-by-default operation.
## What Infram Provides
Original copyright and third-party notices are preserved in `LICENSE` and `NOTICE`.
- Remote access over SSH, RDP, VNC, and Telnet
- Integrated remote file operations over SSH sessions
- Multi-tenant isolation with organizations, folders, and scoped identities
- Authentication options: local users, LDAP, OIDC/SSO, TOTP, and passkeys
- Scripts and snippets for repeatable operations and runbooks
- Session lifecycle visibility, audit events, and status-checking features
## Fork Changes vs Upstream (Nexterm)
## Quick Start (Container)
Infram is intentionally maintained as an operationally independent software because our product goals prioritize stricter security and privacy controls.
Image: [`swissmakers/infram`](https://hub.docker.com/r/swissmakers/infram)
### Security and Privacy Hardening
1) Create persistent storage:
- Removed AI runtime integrations and related backend/frontend feature surfaces.
- Hardened default behavior with strict outbound TLS validation (`STRICT_TLS=true`).
- Disabled external source synchronization by default (`ENABLE_SOURCE_SYNC=false`).
- Added UI/runtime control for external link handling (`VITE_ENABLE_EXTERNAL_LINKS=false` by default).
- Restricted sensitive audit capabilities to admin-level access.
- Build/runtime cleanup with reduced non-essential runtime dependencies.
- Added container-first dependency and vulnerability workflow with optional SBOM generation:
- `make security-update`, `make security-audit`, `make security-all`, `make security-sbom`
- `yarn security:update`, `yarn security:audit`, `yarn security:all`, `yarn security:sbom`
```sh
mkdir -p /opt/podman-infra-manager
```
### Platform and Feature Architecture
2) Generate a 64-character hex encryption key:
- Replaced the old broad monitoring module with a focused status-checker architecture (that only checks if a server is online or not).
- Added NetBox integration and synchronization services:
- inventory import for devices/VMs
- auto-create/update of managed entries
- role/tag filtering and protocol mapping
- delete-on-remote-delete synchronization behavior
- Extended LDAP integration:
- additional directory attributes
- automatic organization assignment on login
- improved org-admin mapping support
- Evolved File Manager implementation:
- SSH-session-based operation model
- improved multi-file download/upload behavior and failure handling for e.g. permission-denied paths
- Improved lockfile/dependency hygiene across root/client/landing/connector.
```sh
openssl rand -hex 32
```
### Upstream Sync Policy
3) Start Infram:
Once again, the upstream is treated as a historical source, not as the product roadmap baseline.
Relevant upstream fixes can be selectively backported after compatibility review.
```sh
podman run -d \
--name infram \
--network host \
--restart always \
-e ENCRYPTION_KEY="<replace-with-generated-key>" \
-e TRUST_PROXY=1 \
-v /opt/podman-infra-manager:/app/data:Z \
swissmakers/infram:latest
```
## Screenshots
4) Open `http://<host>:6989`.
<table>
<tr>
<td><img src="docs/public/assets/showoff/servers.png" alt="Servers" /></td>
<td><img src="docs/public/assets/showoff/connections.png" alt="Connections" /></td>
<td><img src="docs/public/assets/showoff/sftp.png" alt="SFTP" /></td>
</tr>
<tr>
<td><img src="docs/public/assets/showoff/snippets.png" alt="Snippets" /></td>
<td><img src="docs/public/assets/showoff/monitoring.png" alt="Monitoring" /></td>
<td><img src="docs/public/assets/showoff/recordings.png" alt="Recordings" /></td>
</tr>
</table>
> [!TIP]
> `ENCRYPTION_KEY` can also be supplied as a runtime secret file (`/run/secrets/encryption_key`), which is auto-loaded as `ENCRYPTION_KEY`.
## Install
## Documentation
You can install Infram by clicking [here](https://github.com/swissmakers/infra-manager).
- [Installation](docs/installation.md)
- [Reverse Proxy](docs/reverse-proxy.md)
- [SSL/HTTPS](docs/ssl.md)
- [LDAP](docs/ldap.md)
- [OIDC / SSO](docs/oidc.md)
- [Custom Sources](docs/customsource.md)
- [Scripts & Snippets](docs/scripts&snippets.md)
- [Scripting Variables & Directives](docs/ScriptingVariables.md)
- [API Reference](docs/api-reference.md)
- [Screenshots](docs/screenshots.md)
- [Licensing](docs/licensing.md)
- [Contributing](docs/contributing.md)
## Configuration Baseline
Core runtime variables:
- `ENCRYPTION_KEY` (required): 64-char hex key used for credential encryption
- `SERVER_PORT` (default `6989`): HTTP listener
- `HTTPS_PORT` (default `5878`): optional HTTPS listener when cert files exist
- `TRUST_PROXY` (default `false`): Express proxy trust policy (`true`, `false`, count, CIDR/IP list)
- `STRICT_TLS` (default `true`): strict certificate validation for outbound TLS integrations
- `ENABLE_SOURCE_SYNC` (default `false`): enables/disables custom source sync worker
- `ENABLE_VERSION_CHECK` (default `true`): enables/disables release check endpoint
- `VITE_ENABLE_EXTERNAL_LINKS` (default `false`): client-side external URL opening policy
## Development
### Prerequisites
Prerequisites:
- Node.js 18+
- Yarn
- Docker (optional)
### Local Setup
#### Clone the repository
- Node.js 18+
- Yarn
- Podman or Docker (optional, for local container testing)
```sh
git clone https://github.com/swissmakers/infra-manager.git
cd infra-manager
```
#### Install dependencies
```sh
yarn install
cd client && yarn install
cd ..
```
#### Start development mode
```sh
cd client && yarn install && cd ..
yarn dev
```
## Configuration
The server listens on port 6989 by default. You can modify this behavior using environment variables:
- `SERVER_PORT`: Server listening port (default: 6989)
- `NODE_ENV`: Runtime environment (development/production)
- `ENCRYPTION_KEY`: Encryption key for passwords, SSH keys and passphrases. Supports Docker secrets via /run/secrets/encryption_key`
- `TRUST_PROXY`: Express proxy trust setting for client IP extraction (`false` by default).
- `LOG_LEVEL`: Logging level for application and guacd (system/info/verbose/debug/warn/error, default: system)
- `STRICT_TLS`: Enforce TLS certificate validation for outbound integrations like Proxmox and LDAP (default: true)
- `ENABLE_SOURCE_SYNC`: Enable source synchronization requests and default official source creation (default: false)
- `ENABLE_VERSION_CHECK`: Allow GitHub version check endpoint (`/api/service/version/check`) (default: true)
- `VITE_ENABLE_EXTERNAL_LINKS`: Allow opening external links from the web UI (default: false)
### Proxy and Client IP Configuration (`TRUST_PROXY`)
Infram uses Express `trust proxy` behavior to determine the real client IP (`req.ip`) for:
- audit log actor IPs
- authentication/session IP tracking
- WebSocket session metadata
`TRUST_PROXY` accepts the same formats as Express:
- `false` (default): do not trust forwarding headers (`X-Forwarded-For`, etc.)
- `true`: trust all proxies (not recommended in most production environments)
- integer (for example `1`): trust that many proxy hops
- CSV/list/network names (for example `loopback,uniquelocal`) to trust specific proxy source ranges
Recommended values:
- Containerized backend behind exactly one Apache reverse proxy: `TRUST_PROXY=1`
- Multiple chained, controlled reverse proxies: set explicit trusted hops or ranges
- Direct/no reverse proxy deployments: keep `TRUST_PROXY=false`
Important:
- Never use broad trust settings unless your network boundary is controlled.
- Incorrect `TRUST_PROXY` values can cause wrong actor IP attribution in audit logs.
### Offline Runtime Defaults
- AI assistant features are removed from the productive app runtime.
- External source synchronization is disabled by default (`ENABLE_SOURCE_SYNC=false`).
- External link opening in the web client is disabled by default (`VITE_ENABLE_EXTERNAL_LINKS=false`).
- GitHub version check remains available through `/api/service/version/check` and can be disabled with `ENABLE_VERSION_CHECK=false`.
### NetBox Inventory Sync
- Add a NetBox integration in the Servers import menu (folder or organization scope).
- Initial sync imports all matching devices/VMs and auto-creates missing entries.
- Ongoing sync applies configurable filters (roles/tags) and protocol mapping rules.
- Default protocol is SSH; rules can switch matching entries to RDP/VNC.
- Entries removed from NetBox (or filtered out later) are deleted from managed entries during sync.
## Security
- Two-factor authentication
- Session management
- Password encryption
- Docker container isolation
- Oauth 2.0 OpenID Connect SSO
### Container-Only Security Pipeline
You can run dependency updates and vulnerability audits without installing Node.js, Yarn, pnpm, Flutter or Cargo on your host.
Only Docker or Podman is required.
Useful docs commands:
```sh
yarn docs:dev
yarn docs:build
```
## Security Notes
- Keep Infram behind a reverse proxy, VPN, or private network boundary
- Set `TRUST_PROXY` correctly to preserve accurate client IP attribution
- Keep `STRICT_TLS=true` for production unless explicitly troubleshooting
- Store and rotate `ENCRYPTION_KEY` using your secrets management standard
- Back up `/app/data` before upgrades
Security pipeline helpers:
```sh
# Update dependency locks (root/client/landing/connector) in containers
make security-update
# Run vulnerability audits with fail-on threshold (default: high)
make security-audit
# Update + audit in one run
make security-all
# Audit + SBOM generation
make security-sbom
```
Equivalent npm scripts are available:
```sh
yarn security:update
yarn security:audit
yarn security:all
yarn security:sbom
```
Useful environment variables:
- `SECURITY_FAIL_ON` (`none|critical|high|moderate|low|info`, default: `high`)
- `SECURITY_GENERATE_SBOM` (`1` to enable SBOM output under `artifacts/security/`)
- `SECURITY_NODE_IMAGE` (override Node image, default: `node:22-bookworm-slim`)
- `SECURITY_SYFT_IMAGE` (override Syft image, default: `anchore/syft:latest`)
- `SECURITY_DRY_RUN` (`1` to print container commands without executing)
## Contributing
Contributions are welcome! Please feel free to:
1. Fork the project
2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## Useful Links
- [Documentation](https://github.com/swissmakers/infra-manager)
- [License & Third-Party Notices](docs/licensing.md)
- [Report a bug](https://github.com/swissmakers/infra-manager/issues)
- [Request a feature](https://github.com/swissmakers/infra-manager/issues)
Contribution workflow, coding conventions, and validation steps are documented in [docs/contributing.md](docs/contributing.md).
## License
Distributed under the GNU General Public License v3.0. See `LICENSE` for more information.
This repository is distributed under **GNU GPL v3.0**. See `LICENSE` and `NOTICE` for terms and third-party attribution.
## Upstream Attribution
Infram is maintained by Swissmakers GmbH and based on the original Nexterm project by Mathias Wagner. Upstream and third-party attribution is preserved in `LICENSE` and `NOTICE`.
[contributors-shield]: https://img.shields.io/github/contributors/swissmakers/infra-manager.svg?style=for-the-badge
[contributors-url]: https://github.com/swissmakers/infra-manager/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/swissmakers/infra-manager.svg?style=for-the-badge
[forks-url]: https://github.com/swissmakers/infra-manager/network/members
[stars-shield]: https://img.shields.io/github/stars/swissmakers/infra-manager.svg?style=for-the-badge
[stars-url]: https://github.com/swissmakers/infra-manager/stargazers
[issues-shield]: https://img.shields.io/github/issues/swissmakers/infra-manager.svg?style=for-the-badge
[issues-url]: https://github.com/swissmakers/infra-manager/issues
[license-shield]: https://img.shields.io/github/license/swissmakers/infra-manager.svg?style=for-the-badge
[license-url]: https://github.com/swissmakers/infra-manager/blob/master/LICENSE
[license-url]: https://github.com/swissmakers/infra-manager/blob/main/LICENSE
[release-shield]: https://img.shields.io/github/v/release/swissmakers/infra-manager.svg?style=for-the-badge
[release-url]: https://github.com/swissmakers/infra-manager/releases/latest
+37 -28
View File
@@ -11,7 +11,7 @@ const sidebar = useSidebar({ spec, linkPrefix: "/operations/" });
export default defineConfig({
title: "Infram",
description: "The open source server management software for SSH, VNC & RDP",
description: "Open-source platform for secure remote infrastructure operations",
lastUpdated: true,
cleanUrls: true,
metaChunk: true,
@@ -53,7 +53,7 @@ export default defineConfig({
footer: {
message: "Distributed under the GNU GPL v3 License",
copyright: 2024 Mathias Wagner",
copyright: Swissmakers GmbH and contributors",
},
search: {
provider: "local",
@@ -61,38 +61,47 @@ export default defineConfig({
sidebar: [
{
text: "Documentation",
text: "Getting Started",
items: [
{ text: "Home", link: "/" },
{ text: "Screenshots", link: "/screenshots" },
{ text: "Install", link: "/installation" },
],
},
{
text: "Operations",
items: [
{ text: "SSL/HTTPS", link: "/ssl" },
{ text: "Reverse Proxy", link: "/reverse-proxy" },
{ text: "Licensing", link: "/licensing" },
{
text: "Authentication",
collapsed: true,
items: [
{ text: "OIDC / SSO", link: "/oidc" },
{ text: "LDAP", link: "/ldap" },
],
},
{
text: "Custom Sources",
collapsed: true,
link: "/customsource",
items: [
{ text: "Scripts & Snippets", link: "/scripts&snippets" },
{ text: "Scripting Variables & Directives", link: "/ScriptingVariables" },
],
},
{ text: "Screenshots", link: "/screenshots" },
],
},
{
text: "Authentication",
items: [
{ text: "LDAP", link: "/ldap" },
{ text: "OIDC / SSO", link: "/oidc" },
],
},
{
text: "Integrations & Automation",
items: [
{ text: "Custom Sources", link: "/customsource" },
{ text: "Scripts & Snippets", link: "/scripts&snippets" },
{ text: "Scripting Variables & Directives", link: "/ScriptingVariables" },
],
},
{
text: "API",
items: [
{ text: "API Reference", link: "/api-reference" },
...sidebar.generateSidebarGroups(),
],
},
{
text: "Project",
items: [
{ text: "Contributing", link: "/contributing" },
{
text: "API Reference",
collapsed: true,
link: "/api-reference",
items: [...sidebar.generateSidebarGroups()],
},
{ text: "Licensing", link: "/licensing" },
],
},
],
+39 -336
View File
@@ -1,351 +1,54 @@
# 📋 Scripting Variables & Directives
# Scripting Variables & Directives
Infram provides a set of special directives that allow you to create interactive, user-friendly scripts with structured input, feedback, and progress tracking. These directives enhance the script execution experience by providing clear communication and data collection from users.
Use `@INFRAM:*` directives to make scripts interactive, safer, and easier to operate.
## Overview
## Directive Syntax Reference
Scripting directives are special annotations prefixed with `@INFRAM:` that you can embed in your scripts to control the user interface and workflow. They enable you to:
| Directive | Purpose | Example |
|---|---|---|
| `@INFRAM:STEP "text"` | Mark logical execution step | `@INFRAM:STEP "Validate prerequisites"` |
| `@INFRAM:INPUT <var> "prompt" "default"` | Prompt for free-text input | `@INFRAM:INPUT HOST "Target host" "localhost"` |
| `@INFRAM:SELECT <var> "prompt" "A" "B"` | Prompt for fixed options | `@INFRAM:SELECT MODE "Deploy mode" "Rolling" "BlueGreen"` |
| `@INFRAM:CONFIRM "text"` | Require explicit user confirmation | `@INFRAM:CONFIRM "Continue with restart?"` |
| `@INFRAM:INFO "text"` | Emit informational message | `@INFRAM:INFO "Applying configuration"` |
| `@INFRAM:WARN "text"` | Emit warning message | `@INFRAM:WARN "Low disk space"` |
| `@INFRAM:SUCCESS "text"` | Mark successful milestone | `@INFRAM:SUCCESS "Backup completed"` |
| `@INFRAM:PROGRESS <0-100\|$var>` | Update progress indicator | `@INFRAM:PROGRESS 75` |
| `@INFRAM:SUMMARY "title" "k1" "v1" ...` | Show structured key/value summary | `@INFRAM:SUMMARY "Result" "Changed" "14"` |
| `@INFRAM:TABLE "title" "h1" "h2" "r1c1" ...` | Render tabular output | `@INFRAM:TABLE "Users" "Name" "Role" "alice" "admin"` |
| `@INFRAM:MSGBOX "title" "message"` | Display message dialog | `@INFRAM:MSGBOX "Completed" "Operation finished"` |
- Guide users through step-by-step processes
- Collect user input with validation
- Provide real-time feedback and status updates
- Track progress visually
- Display structured information
## End-to-End Example
## Available Directives
### `@INFRAM:STEP`
Marks a logical step in your script workflow and displays it in the UI.
**Purpose:** Breaks down complex scripts into clear, numbered steps that help users understand the script's flow and their progress.
**Usage:**
```sh
@INFRAM:STEP "Step description"
```
**Example:**
```sh
@INFRAM:STEP "Installing dependencies"
npm install
@INFRAM:STEP "Building the application"
npm run build
@INFRAM:STEP "Running tests"
npm test
```
**Design Pattern:** Used to create a visual roadmap of the script execution, making it clear what's happening at each stage.
---
### `@INFRAM:INPUT`
Prompts the user to enter a value with an optional default value.
**Purpose:** Collect user-provided data with a default fallback to streamline user interactions.
**Usage:**
```sh
@INFRAM:INPUT "Enter value" "default"
```
**Parameters:**
- `"Enter value"` - The prompt message displayed to the user
- `"default"` - (Optional) The default value if the user doesn't provide input
**Example:**
```sh
@INFRAM:INPUT "Enter the database host" "localhost"
@INFRAM:INPUT "Enter the database port" "5432"
@INFRAM:INPUT "Enter the API key" ""
```
**Design Pattern:** Enables dynamic script execution by allowing users to customize behavior without editing the script. Defaults reduce required input for common scenarios.
---
### `@INFRAM:SELECT`
Presents the user with multiple choice options and captures their selection.
**Purpose:** Restrict user input to predefined options, reducing errors and clarifying available choices.
**Usage:**
```sh
@INFRAM:SELECT "Select option" "Option 1" "Option 2" "Option 3"
```
**Parameters:**
- First parameter: The prompt message
- Remaining parameters: The available options to choose from
**Example:**
```sh
@INFRAM:SELECT "Select deployment environment" "Development" "Staging" "Production"
@INFRAM:SELECT "Choose backup type" "Full" "Incremental" "Differential"
@INFRAM:SELECT "Select database version" "PostgreSQL 12" "PostgreSQL 13" "PostgreSQL 14"
```
**Design Pattern:** Enforces validation at the input level by limiting choices to safe, predefined options. Improves user experience by clearly showing available alternatives.
---
### `@INFRAM:CONFIRM`
Requires the user to confirm an action before proceeding, typically for critical operations.
**Purpose:** Prevent accidental execution of destructive or important operations by requiring explicit user confirmation.
**Usage:**
```sh
@INFRAM:CONFIRM "Are you sure you want to continue?"
```
**Example:**
```sh
@INFRAM:STEP "Preparing to delete database"
@INFRAM:CONFIRM "Are you sure you want to delete the entire database? This cannot be undone."
rm -rf /var/lib/postgresql/data
```
**Design Pattern:** Acts as a safety guard for critical operations (deletions, deployments to production, etc.). Blocks execution until user explicitly acknowledges the action.
---
### `@INFRAM:INFO`
Displays an informational message to the user without blocking execution.
**Purpose:** Communicate important information, instructions, or context to the user during script execution.
**Usage:**
```sh
@INFRAM:INFO "Information message"
```
**Example:**
```sh
@INFRAM:INFO "Docker is not installed. Installing Docker now..."
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
@INFRAM:INFO "Configuration will be applied after the service restarts."
systemctl restart myservice
```
**Design Pattern:** Keeps users informed about what's happening without requiring interaction. Improves transparency and helps users understand the script's workflow.
---
### `@INFRAM:SUCCESS`
Displays a success message indicating successful completion of a task or milestone.
**Purpose:** Provide positive feedback and confirmation that an operation completed successfully.
**Usage:**
```sh
@INFRAM:SUCCESS "Operation completed successfully!"
```
**Example:**
```sh
@INFRAM:STEP "Deploying application"
docker pull myapp:latest
docker run -d myapp:latest
@INFRAM:SUCCESS "Application deployed successfully!"
@INFRAM:STEP "Running health checks"
curl http://localhost:8080/health
@INFRAM:SUCCESS "All health checks passed!"
```
**Design Pattern:** Provides clear feedback that a task succeeded, improving user confidence and allowing them to understand which operations completed successfully.
---
### `@INFRAM:WARN`
Displays a warning message alerting the user to potential issues or important considerations.
**Purpose:** Alert users about non-critical issues that may affect operation but allow execution to continue.
**Usage:**
```sh
@INFRAM:WARN "Warning: proceeding with caution"
```
**Example:**
```sh
@INFRAM:STEP "Updating production configuration"
@INFRAM:WARN "Warning: You are modifying production configuration. Ensure you have a backup."
cp config.prod.yml config.prod.yml.backup
sed -i 's/old_value/new_value/g' config.prod.yml
@INFRAM:WARN "Warning: This operation requires manual verification in the admin panel."
```
**Design Pattern:** Brings attention to situations that may need user awareness or intervention, without blocking execution. Helps users understand potential consequences of their actions.
---
### `@INFRAM:ERROR`
Displays an error message indicating that something has gone wrong.
**Purpose:** Communicate failures, misconfigurations, or other error conditions to the user.
**Usage:**
```sh
@INFRAM:ERROR "Error occurred"
```
**Example:**
```sh
@INFRAM:STEP "Verifying prerequisites"
if ! command -v docker &> /dev/null; then
@INFRAM:ERROR "Docker is not installed. Please install Docker before proceeding."
exit 1
fi
@INFRAM:SUCCESS "All prerequisites verified"
@INFRAM:STEP "Connecting to database"
if ! psql -h localhost -U user -d mydb -c "SELECT 1" &> /dev/null; then
@INFRAM:ERROR "Failed to connect to database. Check your connection parameters."
exit 1
fi
```
**Design Pattern:** Clearly marks failure points, helping users quickly identify what went wrong and where they need to take action.
---
### `@INFRAM:PROGRESS`
Updates a progress indicator showing the completion percentage of an operation.
**Purpose:** Provide visual feedback during long-running operations, showing the user progress without blocking.
**Usage:**
```sh
@INFRAM:PROGRESS 50
```
**Parameters:**
- A number from `0` to `100` representing the percentage completed
**Example:**
```sh
@INFRAM:STEP "Processing large file"
total_lines=$(wc -l < input.txt)
@INFRAM:PROGRESS 0
processed=0
while IFS= read -r line; do
# Process each line
process_line "$line"
((processed++))
percentage=$((processed * 100 / total_lines))
@INFRAM:PROGRESS "$percentage"
done < input.txt
@INFRAM:STEP "Collect input"
@INFRAM:INPUT HOST "Target host" "localhost"
@INFRAM:SELECT MODE "Deployment mode" "Rolling" "BlueGreen"
@INFRAM:CONFIRM "Continue with deployment?"
@INFRAM:STEP "Deploy"
@INFRAM:INFO "Starting deployment"
@INFRAM:PROGRESS 20
# deployment commands...
@INFRAM:PROGRESS 100
@INFRAM:SUCCESS "File processed successfully"
@INFRAM:SUCCESS "Deployment finished"
@INFRAM:SUMMARY "Deployment Summary" "Host" "$HOST" "Mode" "$MODE" "Status" "Success"
```
**Design Pattern:** Keeps users informed during lengthy operations, preventing the perception of a frozen interface and allowing users to estimate remaining time.
## Implementation Notes
---
### `@INFRAM:SUMMARY`
Displays a structured summary of results with key-value pairs.
**Purpose:** Present comprehensive results or information in an organized, readable format at the end of a script execution.
**Usage:**
```sh
@INFRAM:SUMMARY "Summary Title" "Key 1" "Value 1" "Key 2" "Value 2"
```
**Parameters:**
- First parameter: The summary title/heading
- Alternating key-value pairs: Information to display
**Example:**
```sh
@INFRAM:STEP "Gathering server statistics"
uptime_value=$(uptime)
memory_value=$(free -h | grep Mem | awk '{print $2}')
disk_value=$(df -h / | awk 'NR==2 {print $2}')
cpu_value=$(nproc)
@INFRAM:SUMMARY "Server Information" \
"Uptime" "$uptime_value" \
"Total Memory" "$memory_value" \
"Total Disk" "$disk_value" \
"CPU Cores" "$cpu_value"
@INFRAM:STEP "Backup completed"
@INFRAM:SUMMARY "Backup Results" \
"Backup Size" "2.5GB" \
"Files Backed Up" "15,847" \
"Backup Location" "/backups/2024-01-20" \
"Duration" "45 minutes"
```
**Design Pattern:** Presents information in a clean, structured format making it easy for users to digest and reference results. Ideal for displaying final statistics, configuration details, or operation summaries.
---
## Design Principles
### 1. **Clarity and Guidance**
Directives provide clear navigation through script execution with `@INFRAM:STEP` helping users understand where they are in the process.
### 2. **User Engagement**
Interactive directives like `@INFRAM:INPUT`, `@INFRAM:SELECT`, and `@INFRAM:CONFIRM` keep users involved and allow customization.
### 3. **Feedback and Status**
Real-time feedback through `@INFRAM:INFO`, `@INFRAM:SUCCESS`, `@INFRAM:WARN`, and `@INFRAM:ERROR` keeps users informed about script progress and status.
### 4. **Safety**
The `@INFRAM:CONFIRM` directive prevents accidental execution of critical operations.
### 5. **Progress Visibility**
The `@INFRAM:PROGRESS` directive provides visual feedback during long operations, improving perceived performance.
### 6. **Structured Results**
The `@INFRAM:SUMMARY` directive presents comprehensive results in an organized, easy-to-read format.
---
- Directives are transformed server-side before execution.
- `sudo` commands are automatically adjusted to support password prompts.
- Escape literal colons in directive payloads when needed.
## Best Practices
1. **Use Steps Logically** - Break scripts into meaningful steps that represent distinct phases of work.
- Use `STEP` markers in long-running scripts.
- Use `CONFIRM` before destructive operations.
- Prefer `SELECT` over free-text where possible.
- End critical workflows with `SUMMARY` for auditable output.
2. **Provide Defaults** - Always offer sensible defaults in `@INFRAM:INPUT` to reduce required user interaction.
## Related
3. **Confirm Critical Operations** - Use `@INFRAM:CONFIRM` for operations that modify, delete, or deploy to production.
4. **Inform Users** - Use `@INFRAM:INFO` to explain what's happening, especially during long operations.
5. **Validate Input** - Use `@INFRAM:SELECT` instead of free-text input when possible to prevent errors.
6. **Progressive Feedback** - Update `@INFRAM:PROGRESS` frequently to show activity during long operations.
7. **Clear Error Messages** - Use `@INFRAM:ERROR` with actionable information about what went wrong and how to fix it.
8. **Summarize Results** - Always end important scripts with `@INFRAM:SUMMARY` showing key results and completion details.
---
## Related Documentation
- [Scripts & Snippets](./scripts&snippets.md) - Learn how to create and organize scripts and snippets in Infram.
- [Scripts & Snippets](/scripts&snippets)
+46 -2
View File
@@ -1,4 +1,48 @@
# API Reference
Welcome to the API Reference section. Here you can find detailed information about the API endpoints, their parameters,
and responses.
Infram exposes a REST API under `/api`. The sidebar operation pages are generated from the live OpenAPI specification.
## Base URL
- Local install: `http://<host>:6989/api`
- Reverse proxy: `https://<your-domain>/api`
## Authentication Model
Most endpoints require a bearer token:
`Authorization: Bearer <session-token>`
Session tokens are returned by login endpoints and also set in the `Authorization` response header on successful authentication.
## Public vs Protected Endpoints
- **Typically public**: selected service and authentication bootstrap endpoints (for example login/startup checks)
- **Protected**: operational resources such as entries, sessions, scripts, identities, organizations, and audit data
## How To Use This Section
1. Open an operation in the API sidebar.
2. Review request schema, auth requirements, and response schema.
3. Execute requests against your environment base URL.
## Regenerating OpenAPI Documentation
If operation docs are stale or missing:
```sh
yarn docs:openapi
yarn docs:dev
```
For static docs build:
```sh
yarn docs:build
```
## Troubleshooting
- **401/invalid token**: obtain a new session token and resend bearer header.
- **400 schema error**: compare payload with endpoint validation schema in API docs.
- **Missing endpoints in docs**: regenerate OpenAPI and rebuild docs.
+51 -48
View File
@@ -1,69 +1,72 @@
# Contributing to Infram
You plan on contributing to Infram? That's great! This document will guide you through the process of contributing to
the project.
This guide defines the expected workflow for code and documentation contributions.
## 📦 Prerequisites
## Prerequisites
- [Node.js](https://nodejs.org/en/download/) (v18 or higher)
- [Node.js](https://nodejs.org/en/download/) 18+
- [Yarn](https://yarnpkg.com/getting-started/install)
- [Git](https://git-scm.com/downloads)
## 🛠️ Installation
## Local Setup
1. Clone the repository:
```sh
git clone https://github.com/swissmakers/infra-manager.git
```
2. Install the dependencies for the server:
```sh
yarn install
```
3. Install the dependencies for the client:
```sh
cd client
yarn install
```
```sh
git clone https://github.com/swissmakers/infra-manager.git
cd infra-manager
yarn install
cd client && yarn install && cd ..
```
## 🏃 Running the development server
Starting the development server is as simple as running the following command:
## Development Commands
```sh
yarn dev
```
This will start the server and the client in development mode. You can access the development server
at [http://127.0.0.1:5173](http://127.0.0.1:5173).
Documentation development:
## 🤝 Contributing
```sh
yarn docs:dev
```
1. **Fork the repository**: Click the "Fork" button at the top right of
the [repository page](https://github.com/swissmakers/infra-manager).
2. **Create a new branch**:
```sh
git checkout -b feature/my-new-feature
```
3. **Make your changes**: Implement your feature, fix, or improvement.
4. **Commit your changes**:
```sh
git commit -m "Add feature: my new feature"
```
5. **Push to your fork**:
```sh
git push origin feature/my-new-feature
```
6. **Open a pull request**: Go to the original repository and create a PR with a clear description.
## Contribution Workflow
## 📝 Guidelines
1. Fork repository and create a focused branch:
```sh
git checkout -b feature/<short-description>
```
2. Implement your changes with clear scope.
3. Validate locally:
- application behavior
- docs rendering (if docs changed)
4. Commit with descriptive messages.
5. Open a pull request that includes:
- change purpose
- validation performed
- compatibility or migration impact (if applicable)
- Follow the existing code style.
- Keep PRs focused and minimal.
- Include meaningful commit messages.
- Link related issues when applicable.
## Quality Guidelines
## 🌍 Translations
- Keep pull requests small and reviewable.
- Preserve existing behavior unless change is intentional.
- Update related documentation alongside functional changes.
- Avoid introducing unnecessary dependencies.
Infram uses [Crowdin](https://crowdin.com/project/nexterm) for managing translations. If you'd like to help translate Infram into your language or improve existing translations, please visit our [Crowdin project page](https://crowdin.com/project/nexterm).
## Documentation Contributions
To suggest a new language, please open an issue in the repository using the language request template. Translation pull requests will not be accepted as all translations are managed through Crowdin.
When updating docs:
- prefer production-safe defaults
- include verification and troubleshooting steps
- use explicit configuration paths/values instead of placeholders where feasible
## Security-Related Contributions
Run the security helper targets when relevant:
```sh
make security-update
make security-audit
make security-all
make security-sbom
```
+35 -18
View File
@@ -1,34 +1,51 @@
# 🔗 Custom Sources
# Custom Sources
Add your own scripts and snippets to Infram by connecting a Git repository. You can use public repositories from GitHub, GitLab, or any other Git hosting platform.
Custom Sources allow Infram to synchronize scripts and snippets from external Git repositories.
## Adding a Source
## Typical Use Cases
1. Open **Settings** and go to **Sources**
- Shared operational command libraries across teams
- Environment-specific runbooks (prod/stage/dev)
- Centralized script governance with pull-request workflows
![Navigate to Sources](/assets/image-1.png)
## Enable Source Sync
2. Click **Add** and enter a name and the repository URL
Source synchronization is controlled by:
![Create Custom Source](/assets/image-3.png)
- `ENABLE_SOURCE_SYNC=true` to enable periodic sync worker
- `ENABLE_SOURCE_SYNC=false` to disable sync worker (default)
The name is just for display purposes, so choose something descriptive.
## Add a Source
## Using Your Scripts & Snippets
1. Open **Settings -> Sources**.
2. Select **Add Source**.
3. Provide:
- display name
- repository URL
4. Save and trigger initial sync.
Once added, your scripts and snippets are available in the Snippets panel. Select your repository from the dropdown to see its contents.
## Operational Best Practices
![Add Snippet Dropdown](/assets/image-4.png)
- Use read-only deploy keys or tokens where possible.
- Keep script repositories private when containing internal logic.
- Separate production and non-production sources.
- Require code review on script/snippet changes.
- Keep scripts idempotent and rollback-aware.
Switch to the **Scripts** tab to access your scripts.
## Validation Checklist
![Scripts Tab View](/assets/image-6.png)
- Source status shows healthy in UI.
- Expected scripts appear in the **Scripts** tab.
- Expected snippets appear in terminal/snippet picker.
- Metadata tags render correctly (`@name`, `@description`, `@os`).
## Syncing
## Troubleshooting
Your repository syncs automatically when Infram starts. Push updates to your repository and restart Infram to see the changes.
- **No sync activity**: verify `ENABLE_SOURCE_SYNC=true`.
- **Auth failures**: check repository credentials/keys.
- **Unexpected content**: review default branch and source URL.
You can add multiple sources if you want to organize scripts by project or team.
## Related
> [!TIP]
> See [Scripts & Snippets](/scripts&snippets) for how to format your files.
- [Scripts & Snippets](/scripts&snippets)
- [Scripting Variables & Directives](/ScriptingVariables)
+26 -28
View File
@@ -3,50 +3,48 @@ layout: home
hero:
name: Infram
text: Server management
tagline: The open source server management software for SSH, VNC & RDP
text: Secure Infrastructure Access and Operations
tagline: Open-source operations platform for SSH, RDP, VNC, identity-aware access, and auditable remote administration.
actions:
- theme: brand
text: Install
text: Install Infram
link: /installation
- theme: alt
text: Screenshots
link: /screenshots
text: Reverse Proxy Guide
link: /reverse-proxy
- theme: alt
text: GitHub
link: https://github.com/swissmakers/infra-manager
image:
src: /logo.png
alt: MySpeed
alt: Infram logo
features:
- icon: 🔐
title: Secure Access
details: Access infrastructure over SSH, RDP, VNC, and Telnet with centralized identity controls.
- icon: 🧩
title: Identity Integration
details: Integrate LDAP and OIDC/SSO with support for passkeys and two-factor authentication.
- icon: 📂
title: File and Session Operations
details: Manage terminal and file workflows in one interface with reduced context switching.
- icon: ⚙️
title: Automation
details: Execute scripts and snippets with metadata, guided prompts, and operator-friendly directives.
- icon: 📝
title: Auditability
details: Capture action and session lifecycle events for compliance and troubleshooting.
- icon: ✅
title: Status Checker
details: Focused host/service availability checks for clear operational health visibility.
- icon: 🔒
title: Secure
details: Two-factor authentication, session management and encryption built-in.
- icon: 📁
title: Structured
details: Infram is structured into folders and tabs for easy navigation.
- icon: 🏢
title: Organizations
details: Seamlessly share server access with your team members.
- icon: ✂️
title: Snippets
details: Create and manage snippets for quick access to commands.
- icon: 📜
title: Scripts
details: Automate repetitive tasks with customizable scripts.
link: /scripts&snippets
linkText: Learn more
title: Operational Visibility
details: Track host/service availability with built-in status checking and centralized views.
---
<style>
:root {
--vp-home-hero-name-color: #314BD3;
--vp-home-hero-image-background-image: linear-gradient(rgba(49,75,211,0.25), rgba(49,75,211,0.25));
--vp-home-hero-name-color: #314bd3;
--vp-home-hero-image-background-image: linear-gradient(rgba(49, 75, 211, 0.25), rgba(49, 75, 211, 0.25));
--vp-home-hero-image-filter: blur(100px);
}
</style>
</style>
+104 -56
View File
@@ -1,102 +1,160 @@
# 🚀 Installation
# Installation
> [!WARNING]
> Infram is still in beta. Please back up your data regularly and report any issues on [GitHub](https://github.com/swissmakers/infra-manager/issues).
This guide provides a production-oriented baseline for running Infram with Podman or Docker.
## 🔐 Generate Encryption Key
## Prerequisites
Infram requires an encryption key to securely store your data. You can generate a strong key using the following command:
- Linux host with Podman or Docker
- `openssl` for encryption key generation
- Persistent storage for `/app/data`
- Reverse proxy plan for production exposure (recommended)
## Required Runtime Secret
Infram requires `ENCRYPTION_KEY` at startup. The value must be a 64-character hex string.
Generate one securely:
```sh
openssl rand -hex 32
```
## 🐳 Docker
You can provide it either as:
- environment variable `ENCRYPTION_KEY`
- runtime secret file `/run/secrets/encryption_key` (auto-loaded as `ENCRYPTION_KEY`)
## Podman Quick Start
```sh
mkdir -p /opt/podman-infra-manager
podman run -d \
--name infram \
--network host \
--restart always \
-e ENCRYPTION_KEY="<replace-with-generated-key>" \
-e TRUST_PROXY=1 \
-v /opt/podman-infra-manager:/app/data:Z \
swissmakers/infram:latest
```
## Docker Run
::: code-group
```shell [Host Network (Recommended)]
```sh [Host Network]
docker run -d \
-e ENCRYPTION_KEY=aba3aa8e29b9904d5d8d705230b664c053415c54be20ad13be99af0057dfa23a \
--network host \
--name infram \
--network host \
--restart always \
-v infram:/app/data \
germannewsmaker/infram:latest
-e ENCRYPTION_KEY="<replace-with-generated-key>" \
-e TRUST_PROXY=1 \
-v /opt/podman-infra-manager:/app/data \
swissmakers/infram:latest
```
```shell [Bridge Network]
```sh [Bridge Network]
docker run -d \
-e ENCRYPTION_KEY=aba3aa8e29b9904d5d8d705230b664c053415c54be20ad13be99af0057dfa23a \
-p 6989:6989 \
--name infram \
--restart always \
-v infram:/app/data \
germannewsmaker/nexterm:latest
-p 6989:6989 \
-e ENCRYPTION_KEY="<replace-with-generated-key>" \
-e TRUST_PROXY=1 \
-v /opt/podman-infra-manager:/app/data \
swissmakers/infram:latest
```
:::
> [!NOTE]
> **Host Network** is strongly recommended. It allows Infram to access your host's network stack directly, which is required for features like Wake-on-LAN and connecting to servers via `localhost`. Only use **Bridge Network** if you specifically need network isolation.
> Use host networking if you need host-local network behavior for operations and integrations.
## 📦 Docker Compose
## Docker Compose
::: code-group
```yaml [Host Network (Recommended)]
```yaml [Environment Variable]
services:
infram:
environment:
ENCRYPTION_KEY: "aba3aa8e29b9904d5d8d705230b664c053415c54be20ad13be99af0057dfa23a" # Replace with your generated key
network_mode: host
image: swissmakers/infram:latest
container_name: infram
restart: always
network_mode: host
environment:
ENCRYPTION_KEY: "<replace-with-generated-key>"
TRUST_PROXY: "1"
volumes:
- infram:/app/data
image: germannewsmaker/nexterm:latest
- infram-data:/app/data
volumes:
infram:
infram-data:
```
```yaml [Bridge Network]
```yaml [Runtime Secret File]
services:
infram:
environment:
ENCRYPTION_KEY: "aba3aa8e29b9904d5d8d705230b664c053415c54be20ad13be99af0057dfa23a" # Replace with your generated key
ports:
- "6989:6989"
image: swissmakers/infram:latest
container_name: infram
restart: always
network_mode: host
environment:
TRUST_PROXY: "1"
volumes:
- infram:/app/data
image: germannewsmaker/nexterm:latest
- infram-data:/app/data
- ./secrets/encryption_key:/run/secrets/encryption_key:ro
volumes:
infram:
infram-data:
```
:::
Start:
```sh
docker-compose up -d
docker compose up -d
```
### 🌐 IPv6 Support
## Post-Install Verification
To connect to IPv6 servers from within the container using bridge networking, add the following to your existing `docker-compose.yml` (not needed for host network):
1. Open `http://<host>:6989` (or your reverse-proxy URL).
2. Complete first-time setup and create an admin account.
3. Confirm data persistence under `/opt/podman-infra-manager` (or your named volume).
4. If reverse proxied, verify audit records show real client IP addresses.
5. Check container logs for startup confirmation and migration success.
```diff
services:
infram:
+ networks:
+ - infram-net
## Upgrade Procedure
+networks:
+ infram-net:
+ enable_ipv6: true
```sh
docker pull swissmakers/infram:latest
docker compose down
docker compose up -d
```
## Security Maintenance (Container-Only)
Podman equivalent:
For dependency updates and vulnerability scans, you can run the built-in container pipeline:
```sh
podman pull swissmakers/infram:latest
podman stop infram && podman rm infram
# start again with the same run command
```
## Backup and Restore
- **Backup**: archive `/opt/podman-infra-manager` (or export named volume)
- **Restore**: stop container, restore data, start container
- **Before upgrades**: always create and verify a backup
## Runtime Hardening Recommendations
- Keep `STRICT_TLS=true` in production
- Set `TRUST_PROXY` to the exact proxy topology
- Keep `ENABLE_SOURCE_SYNC=false` unless source sync is required
- Set `ENABLE_VERSION_CHECK=false` in restricted networks
- Keep container runtime and host OS patched
## Security Maintenance Helpers (DEVS only)
```sh
make security-update
@@ -104,13 +162,3 @@ make security-audit
make security-all
make security-sbom
```
This only requires Docker or Podman on the host. The required Node/Yarn/pnpm tooling is executed inside ephemeral containers.
## Offline Runtime Controls
For production environments without internet access:
- Keep `ENABLE_SOURCE_SYNC=false` (default) to prevent outbound source synchronization.
- Keep `VITE_ENABLE_EXTERNAL_LINKS=false` in the client build (default) to block opening external links from the UI.
- Version checks are controlled by `ENABLE_VERSION_CHECK` (default: `true`) and can be disabled with `ENABLE_VERSION_CHECK=false`.
+59 -72
View File
@@ -1,96 +1,83 @@
# 📁 LDAP Authentication
# LDAP Authentication
Authenticate users against your LDAP or Active Directory server.
Use LDAP or Active Directory integration for centralized login and role mapping.
## How It Works
## Authentication Flow
When a user logs in:
1. Infram binds using the configured service account (`bindDN`).
2. Infram searches for the user with `userSearchFilter`.
3. User credentials are validated against the discovered entry.
4. Local account fields are synchronized from LDAP attributes.
5. Admin privileges are resolved via configured group mapping.
1. Infram searches for the user in your directory
2. Tries to bind with their credentials
3. Creates/updates their local account with LDAP attributes
4. Issues a session token
## Required Provider Settings
## Setup
Configure under **Settings -> Authentication -> LDAP Provider**:
Go to **Settings****Authentication****Add LDAP**.
- `name`
- `host`
- `port` (`389` LDAP, `636` LDAPS)
- `bindDN`
- `bindPassword`
- `baseDN`
- `userSearchFilter` (must include `{{username}}`)
- `usernameAttribute`
![LDAP Provider](/assets/add-ldap-provider.png)
Useful defaults:
| Field | Description |
|--------------------|-------------------------------|
| Host | LDAP server hostname |
| Port | 389 (LDAP) or 636 (LDAPS) |
| Bind DN | Service account for searching |
| Bind Password | Service account password |
| Base DN | Where to search for users |
| User Search Filter | How to find users |
| Use TLS | Enable for LDAPS |
- `userSearchFilter`: `(uid={{username}})`
- `usernameAttribute`: `uid`
- `firstNameAttribute`: `givenName`
- `lastNameAttribute`: `sn`
- `emailAttribute`: `mail`
## Examples
## Search Filter Examples
### Active Directory
| Directory | User Search Filter |
|---|---|
| Active Directory | `(sAMAccountName={{username}})` |
| OpenLDAP | `(uid={{username}})` |
| Email login pattern | `(mail={{username}})` |
::: v-pre
## Admin Group Mapping
```text
Host: dc01.corp.example.com
Port: 636
Bind DN: CN=svc_infram,CN=Users,DC=corp,DC=example,DC=com
Base DN: CN=Users,DC=corp,DC=example,DC=com
User Search Filter: (sAMAccountName={{username}})
Use TLS: enabled
```
Use these fields for elevated role mapping:
:::
- `adminGroupDNs`: explicit allow-list of admin groups
- `groupSearchBaseDN`: group search root
- `groupSearchFilter`: default `(member={{dn}})`
- `groupNameAttribute`: default `cn`
- `groupMemberAttribute`: default `member`
### OpenLDAP
## TLS and Certificate Validation
::: v-pre
- Set `useTLS=true` for LDAPS deployments.
- Keep `STRICT_TLS=true` in production so LDAP server certificates are verified.
- Only disable strict TLS in isolated troubleshooting scenarios.
```text
Host: ldap.example.com
Port: 389
Bind DN: cn=readonly,dc=example,dc=com
Base DN: ou=users,dc=example,dc=com
User Search Filter: (uid={{username}})
```
## Timeout Tuning
:::
Provider timeout fields:
## Search Filters
- `connectionTimeoutMs` (default `10000`)
- `searchTimeoutMs` (default `10000`)
The <code v-pre>{{username}}</code> placeholder gets replaced with the login input.
Increase values for high-latency links or large directory trees.
| Directory | Filter |
|------------------|--------------------------------------------------|
| Active Directory | <code v-pre>(sAMAccountName={{username}})</code> |
| OpenLDAP | <code v-pre>(uid={{username}})</code> |
| Email login | <code v-pre>(mail={{username}})</code> |
## Validation Workflow
## Attribute Mapping
Defaults work for most setups. Change in **Advanced Settings** if needed.
| Field | Default |
|------------|-------------|
| Username | `uid` |
| First Name | `givenName` |
| Last Name | `sn` |
For AD, change Username to `sAMAccountName`.
## Testing
Click **Test Connection** after saving to verify the bind credentials work.
![Test LDAP Connection](/assets/test-ldap-connection.png)
1. Save provider settings.
2. Run **Test Connection**.
3. Run **Test Users** and verify:
- expected users are discovered
- usernames are unique and deduplicated
- admin candidate mapping behaves as expected
4. Perform an end-to-end login test with a non-admin and admin user.
## Troubleshooting
**ECONNREFUSED** - Server not reachable. Check host/port and firewall.
**INVALID_CREDENTIALS** - Wrong bind DN or password.
**Users can't log in** - Check Base DN and search filter. Try <code v-pre>(&(objectClass=person)(
uid={{username}}))</code>.
- **`ECONNREFUSED`**: LDAP host/port unreachable.
- **`INVALID_CREDENTIALS`**: incorrect bind credentials.
- **No users found**: verify `baseDN` and `userSearchFilter`.
- **Admin role missing**: verify `adminGroupDNs` and group search fields.
- **TLS handshake failure**: verify LDAP certificate chain and `STRICT_TLS` policy.
+55 -10
View File
@@ -2,19 +2,63 @@
## Project License
Infram (infra-manager) is distributed under the **GNU General Public License v3.0 (GPL-3.0)**.
The full license text is provided in the repository root at `LICENSE`.
Infram (infra-manager) is distributed under **GNU GPL v3.0**.
- Full license text: `LICENSE`
- Third-party attribution and notices: `NOTICE`
## Scope of GPL-3.0 in This Repository
- The original project code maintained in this repository is licensed under GPL-3.0.
- Modifications made in this fork are released under GPL-3.0.
- Distribution of modified binaries/images must follow GPL-3.0 obligations, including source availability requirements.
- Project code in this repository is released under GPL-3.0.
- Modifications and redistributed derivatives must satisfy GPL obligations.
- Distribution of binaries/images must preserve source-availability obligations.
## Third-Party Components
Third-party components retain their original licenses and are not relicensed by repository GPL terms.
Notable examples:
- Apache Guacamole sources in `vendor/guacamole-server/` and `vendor/guacamole-client/` (Apache-2.0)
- Guacamole-derived connection files:
- `server/lib/ClientConnection.js`
- `server/lib/GuacdClient.js`
- Bundled fonts/assets that include their own license files
## Maintainer and Contributor Guidance
When adding third-party code or assets:
- preserve upstream copyright headers
- preserve original license files
- add required attribution to `NOTICE` when redistribution obligations apply
- avoid copying third-party code without clear license provenance
## Distribution Checklist
If you distribute Infram internally or externally, include:
- `LICENSE`
- `NOTICE`
- third-party license files bundled with vendored code/assets
# Licensing and Third-Party Notices
## Project License
Infram (infra-manager) is distributed under **GNU GPL v3.0**.
- Full license text: `LICENSE`
- Third-party attribution: `NOTICE`
## Scope of GPL-3.0 in This Repository
- Project code in this repository is GPL-3.0.
- Fork modifications are GPL-3.0.
- Redistributed modified binaries/images must satisfy GPL source-availability obligations.
## Third-Party Components and Their Licenses
This repository includes third-party components that keep their original licenses.
These licenses remain valid for those specific components and do not get replaced by the project root GPL file.
Third-party components retain their original licenses and are not relicensed by project GPL terms.
Notable examples:
@@ -26,8 +70,7 @@ Notable examples:
## NOTICE File
The repository-level `NOTICE` file documents key third-party attribution and licensing obligations for included components.
When adding, replacing, or updating third-party code, keep `NOTICE` and related attributions up to date.
The repository-level `NOTICE` file tracks key third-party attribution and redistribution obligations.
## Compliance Guidance
@@ -38,7 +81,9 @@ When contributing:
- Add attribution and license metadata for newly introduced third-party code/assets.
- Prefer adding explicit references in `NOTICE` when redistribution obligations apply.
If you are packaging Infram for internal or external distribution, review:
## Operator Distribution Checklist
If you package or distribute Infram internally or externally, review and ship:
- `LICENSE` (GPL-3.0 terms),
- `NOTICE` (third-party attributions),
+53 -59
View File
@@ -1,85 +1,79 @@
# 🔐 OIDC Authentication
# OIDC / SSO Authentication
SSO via OpenID Connect. Users log in with their existing identity provider.
Use OpenID Connect (OIDC) to authenticate users with a centralized identity provider.
## Setup
## Prerequisites
Go to **Settings****Authentication****Add Provider**.
- OIDC-compatible IdP (for example Keycloak, Entra ID, Authentik, Google)
- Public URL for Infram
- Registered OIDC client/application in your IdP
- Redirect URI configured in IdP and Infram
![Add OIDC Provider](/assets/add-oidc-provider.png)
## Required Provider Fields
| Field | Description |
|---------------|--------------------------|
| Display Name | Shown on login button |
| Issuer URL | IdP's discovery URL |
| Client ID | From your IdP |
| Client Secret | From your IdP |
| Redirect URI | Copy this to your IdP |
| Scope | Usually `openid profile` |
Configure in **Settings -> Authentication -> Add OIDC Provider**:
## Provider Setup
- `name`
- `issuer` (must match IdP metadata exactly)
- `clientId`
- `clientSecret` (if confidential client)
- `redirectUri`
- `scope` (default: `openid profile`)
### Microsoft Entra ID (Azure AD)
Recommended baseline scope:
1. [Azure Portal](https://portal.azure.com) → **Microsoft Entra ID****App registrations****New registration**
2. Add redirect URI: `https://infram.yourdomain.com/api/auth/oidc/callback`
3. Copy **Application (client) ID** → Client ID
4. **Certificates & secrets****New client secret** → copy value → Client Secret
5. Issuer URL: `https://login.microsoftonline.com/{tenant-id}/v2.0`
`openid profile email`
### Google
## Redirect URI
1. [Google Cloud Console](https://console.cloud.google.com) → **APIs & Services****Credentials**
2. **Create Credentials****OAuth client ID****Web application**
3. Add redirect URI: `https://infram.yourdomain.com/api/auth/oidc/callback`
4. Issuer URL: `https://accounts.google.com`
Use the callback endpoint exposed by Infram:
`https://<infram-host>/api/auth/oidc/callback`
> [!WARNING]
> Google requires app verification for production. Add test users in OAuth consent screen during dev.
> Redirect URI mismatch is the most common cause of failed OIDC sign-in.
### Keycloak
## Claim Mapping
1. **Clients****Create client**
2. Enable **Client authentication**
3. Add redirect URI, copy Client Secret from **Credentials** tab
4. Issuer URL: `https://keycloak.yourdomain.com/realms/{realm-name}`
Default mappings:
### Authentik
| Infram Field | OIDC Claim |
|---|---|
| Username | `preferred_username` |
| First Name | `given_name` |
| Last Name | `family_name` |
1. **Applications****Providers****Create****OAuth2/OpenID Provider**
2. Set redirect URI, copy Client ID/Secret
3. Issuer URL: `https://authentik.yourdomain.com/application/o/{application-slug}/`
Adjust `usernameAttribute`, `firstNameAttribute`, and `lastNameAttribute` if your IdP uses non-standard claim names.
> [!TIP]
> The trailing slash matters. Check `/.well-known/openid-configuration` to see the exact issuer value.
## Provider Examples
### Authelia
- **Entra ID** issuer: `https://login.microsoftonline.com/<tenant-id>/v2.0`
- **Google** issuer: `https://accounts.google.com`
- **Keycloak** issuer: `https://<host>/realms/<realm>`
- **Authentik** issuer: `https://<host>/application/o/<slug>/`
```yaml
identity_providers:
oidc:
clients:
- client_id: infram
client_secret: '$pbkdf2-sha512$your-hashed-secret'
redirect_uris:
- https://infram.yourdomain.com/api/auth/oidc/callback
scopes: [ openid, profile, email ]
```
Always verify the issuer and endpoints through:
Issuer URL: `https://auth.yourdomain.com`
`<issuer>/.well-known/openid-configuration`
## Attribute Mapping
## Validation Workflow
Defaults in **Advanced Settings**:
1. Save provider configuration.
2. Enable provider.
3. Confirm login page displays provider button.
4. Complete login flow and return to Infram.
5. Verify mapped user profile fields after first login.
| Field | Claim |
|------------|----------------------|
| Username | `preferred_username` |
| First Name | `given_name` |
| Last Name | `family_name` |
## Security Guidance
- Keep Infram behind HTTPS when using OIDC.
- Use confidential clients where supported.
- Restrict client redirect URIs to exact production URLs.
- Rotate client secrets according to security policy.
## Troubleshooting
**Redirect URI mismatch** - Must match exactly. Check trailing slashes, http vs https.
**User attributes wrong** - Check claim names in your IdP's token and adjust mapping.
- **Issuer mismatch**: use exact `issuer` from metadata.
- **Callback error**: check redirect URI and proxy forwarding.
- **Missing username/name fields**: adjust scope and claim mapping.
- **Login loop**: verify system clock synchronization on both IdP and Infram hosts.
+100 -52
View File
@@ -1,50 +1,108 @@
# Reverse Proxy & Cloudflare Tunnel
# Reverse Proxy
This guide helps you with setting up Infram behind a reverse proxy or Cloudflare Tunnel. Make sure WebSocket support is
enabled for it to work.
This guide describes production-safe reverse proxy patterns for Infram, including complete TLS configuration and WebSocket forwarding requirements.
## Nginx
## Prerequisites
- Infram reachable on `http://127.0.0.1:6989`
- Reverse proxy with WebSocket support
- Correct `TRUST_PROXY` setting in Infram runtime
- Certificate and private key available on the proxy host
## Critical Requirements
Your proxy configuration must:
- forward `Host`, `X-Forwarded-For`, and `X-Forwarded-Proto`
- support `Upgrade` and `Connection` headers for WebSockets
- allow long-lived connections for terminal/session streams
- terminate TLS with a valid certificate chain
## `TRUST_PROXY` Guidance
Set `TRUST_PROXY` according to your topology:
- `TRUST_PROXY=1` for one trusted proxy hop
- `TRUST_PROXY=<n>` for multiple trusted hops
- `TRUST_PROXY=<cidr-or-ip-list>` for explicit trust boundaries
- `TRUST_PROXY=false` when no reverse proxy is used
> [!WARNING]
> Incorrect `TRUST_PROXY` values can produce wrong client IP attribution in audit and session records.
## NGINX (TLS Termination)
```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name infram.yourdomain.com;
listen [::]:80;
server_name infram.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name infram.example.com;
ssl_certificate /etc/letsencrypt/live/infram.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/infram.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://127.0.0.1:6989;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}
```
With SSL, add a redirect block and use `listen 443 ssl http2` with your cert paths.
## Apache HTTPD (TLS Termination)
## Apache
Enable modules first:
Enable modules:
```sh
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite
sudo a2enmod ssl proxy proxy_http proxy_wstunnel headers rewrite
```
Virtual host:
```apache
<VirtualHost *:80>
ServerName infram.yourdomain.com
ServerName infram.example.com
Redirect permanent / https://infram.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName infram.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/infram.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/infram.example.com/privkey.pem
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
# WebSocket
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
@@ -58,58 +116,48 @@ sudo a2enmod proxy proxy_http proxy_wstunnel rewrite
## Caddy
Caddy automatically provisions certificates when DNS and inbound access are correct:
```caddy
infram.yourdomain.com {
infram.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:6989
}
```
Caddy handles WebSockets and SSL automatically.
## Traefik (Docker)
## Traefik (Container Deployments)
```yaml
services:
infram:
image: swissmakers/infram:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.infram.rule=Host(`infram.yourdomain.com`)"
- "traefik.http.routers.infram.rule=Host(`infram.example.com`)"
- "traefik.http.routers.infram.entrypoints=websecure"
- "traefik.http.routers.infram.tls=true"
- "traefik.http.routers.infram.tls.certresolver=letsencrypt"
- "traefik.http.services.infram.loadbalancer.server.port=6989"
```
## Cloudflare Tunnel
## Certificate Operations
Cloudflare Tunnel lets you expose Infram to the internet without opening inbound ports. Traffic flows through
Cloudflare's network, giving you DDoS protection and optional Zero Trust authentication.
- Use full certificate chain (`fullchain.pem`) for `ssl_certificate`/`SSLCertificateFile`
- Restrict private key permissions (`chmod 600`)
- Automate renewal (for example `certbot renew`)
- Reload proxy service after renewal
### Prerequisites
## Validation Checklist
- A Cloudflare account with an active domain
- `cloudflared` installed on your
server ([download](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/))
1. Open `https://infram.example.com` and inspect certificate validity.
2. Login and open an interactive terminal session.
3. Confirm session remains stable for long-running commands.
4. Validate audit events include the real client IP.
5. Confirm HTTP requests are redirected to HTTPS.
### 1. Create a Tunnel
## Troubleshooting
Log in to [Cloudflare Zero Trust](https://one.dash.cloudflare.com/) and go to **Networks****Connectors**.
1. Click **Create a tunnel**
2. Choose **Cloudflared** as the connector type
3. Give your tunnel a name (e.g., `infram`)
4. Copy the installation command and run it on your server
### 2. Configure the Public Hostname
After creating the tunnel, add a public hostname:
| Field | Value |
|-----------|--------------------------------|
| Subdomain | `infram` (or your preference) |
| Domain | Select your domain |
| Type | `HTTP` |
| URL | `localhost:6989` |
![Create Tunnel in Cloudflare Dashboard](/assets/cloudflare-tunnel-create.png)
Click **Save tunnel**. Your Infram instance should now be accessible at `https://infram.yourdomain.com`.
- **WebSocket disconnects**: verify upgrade headers and long timeout settings.
- **Wrong source IP in audit logs**: re-check `TRUST_PROXY` value.
- **TLS errors**: verify cert/key paths and file permissions on the proxy host.
- **Redirect loops**: ensure backend protocol is HTTP when TLS terminates at proxy.
+21 -13
View File
@@ -1,45 +1,53 @@
# Screenshots
Take a look at what Infram has to offer.
This gallery highlights key interfaces in Infram.
## Servers
## Server Inventory
Organize your servers into folders for easy navigation.
Organize infrastructure entries by folders and organizations.
![Servers](/assets/showoff/servers.png)
## Connections
## Connection Workspace
Manage multiple SSH, VNC and RDP connections with a tabbed interface.
Operate SSH, VNC, and RDP sessions in a tabbed workspace.
![Connections](/assets/showoff/connections.png)
## SFTP
## SFTP Operations
Browse and manage files on remote servers with the built-in file manager.
Browse and manage remote files directly from the interface.
![SFTP](/assets/showoff/sftp.png)
## Snippets
Create and manage snippets for quick access to frequently used commands.
Store and execute reusable command snippets.
![Snippets](/assets/showoff/snippets.png)
## Monitoring
## Status Checker
Monitor server performance and resource usage in real-time.
Track host and service availability.
![Monitoring](/assets/showoff/monitoring.png)
## Recordings
## Session Recordings
Record and replay terminal sessions for documentation or debugging.
Record and replay terminal sessions for audit or troubleshooting.
![Recordings](/assets/showoff/recordings.png)
## Settings
Customize Infram to fit your workflow.
Configure authentication, integrations, and operational behavior.
![Settings](/assets/showoff/settings.png)
## Related Documentation
- [Installation](/installation)
- [Reverse Proxy](/reverse-proxy)
- [LDAP](/ldap)
- [OIDC / SSO](/oidc)
- [Custom Sources](/customsource)
+47 -53
View File
@@ -1,75 +1,69 @@
# Scripts & Snippets
Infram uses file extensions to distinguish scripts from snippets, not folder structure. This means you can organize your repository however you like.
Infram classifies automation files by extension, not folder structure. This supports flexible repository layouts while preserving predictable behavior.
## Scripts vs Snippets
**Scripts** are full executable files that run on the server. Use them to automate tasks like system maintenance, deployments, or batch operations.
- **Scripts**: executable automation files intended for full task execution.
- **Snippets**: quick command fragments for interactive terminal use.
**Snippets** are quick commands you can paste into your terminal session. They're useful for frequently used commands you don't want to type out every time.
## Metadata Header
## File Format
Use comment tags at the top of each file:
Both scripts and snippets use comments at the top to define metadata:
::: code-group
```sh [Script (.sh)]
```sh
# @name: Largest files
# @description: Find the 10 largest files on the system.
# @os: Ubuntu, Debian, Fedora
find / -type f -exec ls -lh {} + | sort -k5 -h | tail -10
# @description: Show the ten largest files on the target system.
# @os: Ubuntu, Debian, Rocky Linux
```
```txt [Snippet (.snippet)]
# @name: Update packages
# @description: Update and upgrade all packages
# @os: Ubuntu, Debian
## Supported File Extensions
sudo apt update && sudo apt upgrade -y
```
- **Snippets**: `.snippet`, `.txt`, `.cmd`
- **Scripts**: `.sh`, `.bash`, `.zsh`, `.fish`, `.ps1`
```txt [Proxmox Snippet]
# @name: Backup all VMs
# @description: Create a backup of all running VMs
# @os: Proxmox VE
## Supported Metadata Tags
vzdump --all --mode snapshot --compress zstd
```
| Tag | Purpose |
|---|---|
| `@name` | Display name in UI |
| `@description` | Functional description |
| `@os` | Comma-separated OS filter |
:::
## Supported `@os` Values
## Supported Extensions
**Snippets:** `.snippet`, `.txt`, `.cmd`
**Scripts:** `.sh`, `.bash`, `.zsh`, `.fish`, `.ps1`
## Available Tags
| Tag | Description |
|-----|-------------|
| `@name` | Display name in the Infram UI |
| `@description` | Additional context about what the command does |
| `@os` | Comma-separated list of compatible operating systems |
## Supported OS Values
Use these exact values for the `@os` tag:
Use these exact values:
`Ubuntu`, `Debian`, `Alpine Linux`, `Fedora`, `CentOS`, `Red Hat`, `Rocky Linux`, `AlmaLinux`, `openSUSE`, `Arch Linux`, `Manjaro`, `Gentoo`, `NixOS`, `Proxmox VE`
> [!TIP]
> Snippets without an `@os` tag are shown on all systems. Use `Proxmox VE` for commands specific to PVE shell or LXC consoles.
If `@os` is omitted, the entry is shown for all systems.
> [!TIP]
> Check out the [NexStore repository](https://github.com/gnmyt/NexStore/tree/main/nexterm) for more examples.
## Repository Layout Example
### Scripting Variables & Directives
```text
automation-repo/
├─ snippets/
│ ├─ update-packages.snippet
│ └─ check-disk.txt
└─ scripts/
├─ rotate-logs.sh
└─ backup-db.sh
```
For advanced script functionality, including step tracking, user input collection, and real-time feedback, see the [📋 Scripting Variables & Directives](./ScriptingVariables.md) guide.
## Quality Guidelines
- Keep commands idempotent where possible.
- Include explicit error handling in scripts.
- Avoid interactive prompts unless required.
- Document destructive actions clearly in `@description`.
## Validation Checklist
- Header includes `@name` and `@description`.
- Extension matches intended behavior (script vs snippet).
- `@os` values are valid and spelled exactly.
- Script executes successfully in a non-production environment first.
## Advanced Interactivity
For guided prompts, confirmations, progress markers, and result summaries, see [Scripting Variables & Directives](/ScriptingVariables).
+53 -35
View File
@@ -1,62 +1,80 @@
# 🔐 Enabling SSL/HTTPS
# SSL/HTTPS
## 📁 Certificate Setup
Use this guide if you want Infram itself to expose HTTPS. If TLS is terminated at a reverse proxy, keep Infram on HTTP and follow [Reverse Proxy](/reverse-proxy).
Place your SSL certificate files in the `data/certs` folder:
## How Infram Enables HTTPS
- `cert.pem` - Your SSL certificate
- `key.pem` - Your private key
Infram starts an HTTPS listener automatically when these files exist:
Infram will automatically detect them and start an HTTPS server.
- `/app/data/certs/cert.pem` (certificate chain)
- `/app/data/certs/key.pem` (private key)
## 🔌 Ports
When present, HTTP (`SERVER_PORT`, default `6989`) and HTTPS (`HTTPS_PORT`, default `5878`) can run in parallel.
- HTTP runs on port `6989` (default)
- HTTPS runs on port `5878` by default
## Container Example
You can change the HTTPS port by setting the `HTTPS_PORT` environment variable.
## 🐳 Docker Setup
Add the following to your existing `docker-compose.yml`:
```diff
```yaml
services:
infram:
image: swissmakers/infram:latest
container_name: infram
restart: always
environment:
+ HTTPS_PORT: 5878 # optional, this is the default
ENCRYPTION_KEY: "<replace-with-generated-key>"
HTTPS_PORT: "5878"
ports:
+ - "5878:5878"
- "6989:6989"
- "5878:5878"
volumes:
+ - ./certs:/app/data/certs
- ./data:/app/data
- ./certs/cert.pem:/app/data/certs/cert.pem:ro
- ./certs/key.pem:/app/data/certs/key.pem:ro
```
## 🔧 Generating Self-Signed Certs
## Certificate Sources
For testing purposes, you can generate a self-signed certificate:
### Let's Encrypt (Recommended)
```sh
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
sudo certbot certonly --standalone -d infram.example.com
install -m 644 /etc/letsencrypt/live/infram.example.com/fullchain.pem ./certs/cert.pem
install -m 600 /etc/letsencrypt/live/infram.example.com/privkey.pem ./certs/key.pem
```
Then move `cert.pem` and `key.pem` into your `data/certs` folder.
### Self-Signed (Testing Only)
```sh
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 \
-nodes \
-keyout key.pem \
-out cert.pem \
-subj "/CN=infram.local"
```
> [!WARNING]
> Self-signed certificates will show a browser warning. For production, use certificates from Let's Encrypt or your CA.
> Self-signed certificates are suitable only for development and isolated test environments.
## 🚀 Let's Encrypt with Certbot
## File Permissions
To obtain certificates from Let's Encrypt:
- `key.pem`: readable only by the runtime account (recommended mode `600`)
- `cert.pem`: world-readable is acceptable (`644`)
- Store cert material outside source control and managed backups where possible
```sh
sudo certbot certonly --standalone -d yourdomain.com
```
## Renewal and Rotation
Then copy the generated files:
1. Renew certificate from your PKI provider.
2. Replace `cert.pem` and `key.pem`.
3. Restart or recreate container to reload TLS material.
4. Validate expiration date and chain from a client endpoint.
```sh
cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem ./data/certs/cert.pem
cp /etc/letsencrypt/live/yourdomain.com/privkey.pem ./data/certs/key.pem
```
## Verification
Restart Infram to apply the changes.
- Open `https://<host>:5878` (or configured `HTTPS_PORT`).
- Verify browser trust chain and certificate subject/SAN.
- Confirm login and interactive sessions operate correctly over TLS.
## Common Issues
- **HTTPS not starting**: verify both `cert.pem` and `key.pem` exist in `/app/data/certs`.
- **Invalid certificate in browser**: ensure SAN/CN matches requested hostname.
- **Permission denied**: check private key ownership and mode on mounted file.
+51 -27
View File
@@ -1,9 +1,11 @@
import "./styles.sass";
import {faDocker} from "@fortawesome/free-brands-svg-icons";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faCheck, faCopy, faChevronRight, faChevronLeft, faRefresh, faLayerGroup, faTerminal, faHardDrive, faFolderOpen} from "@fortawesome/free-solid-svg-icons";
import {useState, useEffect} from "react";
import {DOCUMENTATION_BASE} from "@/main.jsx";
import { faDocker } from "@fortawesome/free-brands-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck, faCopy, faChevronRight, faChevronLeft, faRefresh, faLayerGroup, faTerminal, faHardDrive, faFolderOpen } from "@fortawesome/free-solid-svg-icons";
import { useState, useEffect } from "react";
import { DOCUMENTATION_BASE } from "@/main.jsx";
const IMAGE = "swissmakers/infram:latest";
const generateEncryptionKey = () => {
const array = new Uint8Array(32);
@@ -14,10 +16,11 @@ const generateEncryptionKey = () => {
export const Install = () => {
const [step, setStep] = useState(1);
const [encryptionKey, setEncryptionKey] = useState('');
const [deployMethod, setDeployMethod] = useState('docker');
const [deployMethod, setDeployMethod] = useState('run');
const [runtime, setRuntime] = useState("podman");
const [volumeType, setVolumeType] = useState('named');
const [volumeName, setVolumeName] = useState('infram');
const [bindPath, setBindPath] = useState('./infram-data');
const [bindPath, setBindPath] = useState('/opt/podman-infra-manager/data');
const [copied, setCopied] = useState(false);
useEffect(() => {
@@ -34,21 +37,22 @@ export const Install = () => {
setTimeout(() => setCopied(false), 2000);
};
const getDockerCommand = () => {
const getRunCommand = () => {
const volumeArg = volumeType === 'named'
? `-v ${volumeName}:/app/data`
: `-v ${bindPath}:/app/data`;
: `-v ${bindPath}:/app/data${runtime === "podman" ? ":Z" : ""}`;
return `docker run -d \\
-e ENCRYPTION_KEY=${encryptionKey} \\
return `${runtime} run -d \\
--name infram-local \\
--network host \\
--name infram \\
--restart always \\
-e ENCRYPTION_KEY=${encryptionKey} \\
-e TRUST_PROXY=1 \\
${volumeArg} \\
germannewsmaker/nexterm:latest`;
${IMAGE}`;
};
const getDockerComposeContent = () => {
const getComposeContent = () => {
const volumeConfig = volumeType === 'named'
? ` - ${volumeName}:/app/data`
: ` - ${bindPath}:/app/data`;
@@ -59,12 +63,13 @@ export const Install = () => {
return `services:
infram:
image: germannewsmaker/nexterm:latest
container_name: infram
image: ${IMAGE}
container_name: infram-local
network_mode: host
restart: always
environment:
- ENCRYPTION_KEY=${encryptionKey}
- TRUST_PROXY=1
volumes:
${volumeConfig}${volumesSection}`;
};
@@ -100,15 +105,15 @@ ${volumeConfig}${volumesSection}`;
{step === 1 && (
<div className="wizard-step">
<h2>Deployment Method</h2>
<p>Choose how you want to deploy Infram.</p>
<p>Choose deployment format and runtime.</p>
<div className="option-cards">
<button
className={`option-card ${deployMethod === 'docker' ? 'selected' : ''}`}
onClick={() => setDeployMethod('docker')}
className={`option-card ${deployMethod === 'run' ? 'selected' : ''}`}
onClick={() => setDeployMethod('run')}
>
<FontAwesomeIcon icon={faTerminal}/>
<span className="option-title">Docker CLI</span>
<span className="option-title">Run Command</span>
<span className="option-desc">Single command deployment</span>
</button>
<button
@@ -120,6 +125,25 @@ ${volumeConfig}${volumesSection}`;
<span className="option-desc">YAML configuration file</span>
</button>
</div>
<div className="option-cards">
<button
className={`option-card ${runtime === 'podman' ? 'selected' : ''}`}
onClick={() => setRuntime('podman')}
>
<FontAwesomeIcon icon={faDocker}/>
<span className="option-title">Podman</span>
<span className="option-desc">Recommended runtime</span>
</button>
<button
className={`option-card ${runtime === 'docker' ? 'selected' : ''}`}
onClick={() => setRuntime('docker')}
>
<FontAwesomeIcon icon={faDocker}/>
<span className="option-title">Docker</span>
<span className="option-desc">Compatible runtime</span>
</button>
</div>
</div>
)}
@@ -166,21 +190,21 @@ ${volumeConfig}${volumesSection}`;
<div className="wizard-step">
<h2>Deploy Infram</h2>
<p>
{deployMethod === 'docker'
? 'Run this command in your terminal:'
{deployMethod === 'run'
? `Run this command with ${runtime}:`
: 'Save this as docker-compose.yml and run docker compose up -d:'}
</p>
<div className="command-block" onClick={() => copyToClipboard(deployMethod === 'docker' ? getDockerCommand() : getDockerComposeContent())}>
<div className="command-block" onClick={() => copyToClipboard(deployMethod === 'run' ? getRunCommand() : getComposeContent())}>
<div className="command-header">
<FontAwesomeIcon icon={faDocker}/>
<span>{deployMethod === 'docker' ? 'Terminal' : 'docker-compose.yml'}</span>
<span>{deployMethod === 'run' ? 'Terminal' : 'docker-compose.yml'}</span>
<button className={`copy-btn ${copied ? 'copied' : ''}`}>
<FontAwesomeIcon icon={copied ? faCheck : faCopy}/>
{copied ? 'Copied!' : 'Copy'}
</button>
</div>
<pre><code>{deployMethod === 'docker' ? getDockerCommand() : getDockerComposeContent()}</code></pre>
<pre><code>{deployMethod === 'run' ? getRunCommand() : getComposeContent()}</code></pre>
</div>
<div className="key-section">
@@ -222,12 +246,12 @@ ${volumeConfig}${volumesSection}`;
<div className="help-section">
<p>Need more options?</p>
<div className="help-links">
<a onClick={() => openDocs("/installation")}>Installation Guide</a>
<a onClick={() => openDocs("/reverse-proxy")}>Reverse Proxy</a>
<a onClick={() => openDocs("/ssl")}>SSL Setup</a>
<a onClick={() => openDocs("/")}>Full Documentation</a>
</div>
</div>
</div>
</div>
);
}
};