mirror of
https://github.com/swissmakers/infram.git
synced 2026-05-08 22:49:00 +02:00
Update docs v1.2
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||

|
||||
## Enable Source Sync
|
||||
|
||||
2. Click **Add** and enter a name and the repository URL
|
||||
Source synchronization is controlled by:
|
||||
|
||||

|
||||
- `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
|
||||
|
||||

|
||||
- 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
|
||||
|
||||

|
||||
- 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
@@ -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
@@ -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
@@ -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`
|
||||
|
||||

|
||||
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.
|
||||
|
||||

|
||||
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
@@ -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
@@ -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
|
||||
|
||||

|
||||
## 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
@@ -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` |
|
||||
|
||||

|
||||
|
||||
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
@@ -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.
|
||||
|
||||

|
||||
|
||||
## Connections
|
||||
## Connection Workspace
|
||||
|
||||
Manage multiple SSH, VNC and RDP connections with a tabbed interface.
|
||||
Operate SSH, VNC, and RDP sessions in a tabbed workspace.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
## Snippets
|
||||
|
||||
Create and manage snippets for quick access to frequently used commands.
|
||||
Store and execute reusable command snippets.
|
||||
|
||||

|
||||
|
||||
## Monitoring
|
||||
## Status Checker
|
||||
|
||||
Monitor server performance and resource usage in real-time.
|
||||
Track host and service availability.
|
||||
|
||||

|
||||
|
||||
## Recordings
|
||||
## Session Recordings
|
||||
|
||||
Record and replay terminal sessions for documentation or debugging.
|
||||
Record and replay terminal sessions for audit or troubleshooting.
|
||||
|
||||

|
||||
|
||||
## Settings
|
||||
|
||||
Customize Infram to fit your workflow.
|
||||
Configure authentication, integrations, and operational behavior.
|
||||
|
||||

|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Installation](/installation)
|
||||
- [Reverse Proxy](/reverse-proxy)
|
||||
- [LDAP](/ldap)
|
||||
- [OIDC / SSO](/oidc)
|
||||
- [Custom Sources](/customsource)
|
||||
|
||||
+47
-53
@@ -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
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user