Raven Scott 12b25c1717
CI / Build & Test (push) Successful in 2m52s
Update Copyright Notice
2026-03-16 15:51:39 -04:00
2026-03-16 13:14:15 -04:00
2026-03-16 15:44:21 -04:00
2026-03-16 15:31:54 -04:00
2026-03-16 15:49:11 -04:00
2026-03-16 13:05:58 -04:00
2026-03-16 15:31:54 -04:00
2026-03-16 15:31:54 -04:00
2026-03-16 15:51:39 -04:00
2026-03-16 15:31:54 -04:00
2026-03-16 15:49:11 -04:00
2026-03-16 15:31:54 -04:00
2026-03-16 15:49:11 -04:00
2026-03-16 15:31:54 -04:00

Anisail

Ansible connection plugin that uses Holesail P2P tunnels to reach hosts behind NAT, firewalls, or CGNAT — with no port forwarding or static IPs.

  • On the target: Run holesail --live 22 (or your SSH port); copy the hs://... URL.
  • In inventory: Set ansible_connection and ansible_holesail_key.
  • Ansible starts a local tunnel, connects SSH through it, and runs your playbooks as usual.

Requires the anisail-tunnel binary (Bare-built, shipped in releases/ or built via npm run build:tunnel) and asyncssh on the control node.

Installation

To install anisail-tunnel, the Ansible collection, and asyncssh from the latest release:

macOS / Linux:

curl -fsSL https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.sh | bash

Windows (PowerShell):

irm https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.ps1 | iex

The script installs the tunnel binary (to ~/.anisail/bin or %LOCALAPPDATA%\anisail\bin on Windows), installs asyncssh if missing, and installs the anisail.anisail collection from the repo archive. See docs/INSTALLATION.md for details, custom install paths, and build-from-source.

1. Install the collection manually (if needed)

If the install script could not install the collection (e.g. Ansible not installed yet), from the repo root:

ansible-galaxy collection install ansible_collections/anisail/anisail/ --force

Or link for development:

export ANSIBLE_COLLECTIONS_PATHS="$PWD/ansible_collections"
# or symlink/copy ansible_collections/anisail into your collections path

2. Tunnel binary (if not using the install script)

If you did not run the install script above, either use a prebuilt binary from the releases (download the zip for your platform and extract anisail-tunnel) or build from source (requires Node.js and npm).

Option A — Build from source (Bare binary)

npm install
npm run build:tunnel

Output: releases/<platform>/anisail-tunnel (e.g. releases/darwin-arm64/anisail-tunnel). Either add that directory to PATH or set ansible_holesail_tunnel_path in inventory to the full path.

Option B — Use collection releases

If you ship the built binary inside the collection (e.g. under ansible_collections/anisail/anisail/releases/<platform>/anisail-tunnel), the plugin will find it automatically. Copy from repo releases/ after building:

cp -r releases/* ansible_collections/anisail/anisail/releases/

Option C — System PATH

Install the binary somewhere on PATH and name it anisail-tunnel. The plugin will use it if ansible_holesail_tunnel_path is not set and no collection-relative binary is found.

3. Install asyncssh (if not installed by the script)

pip install asyncssh

Inventory

Use the holesail connection and set the Holesail key (and optionally port/timeout):

# inventory.yml
all:
  hosts:
    my_device:
      ansible_connection: anisail.anisail.holesail   # or "holesail" if collection is default
      ansible_holesail_key: "hs://s000..."           # from "holesail --live 22" on the target
      ansible_user: admin                           # SSH user (optional)
      # ansible_port: 22                            # remote port to tunnel to (default 22)
      # ansible_holesail_tunnel_path: /path/to/anisail-tunnel
      # ansible_holesail_ready_timeout: 30           # seconds (default 30)

If your playbook sets collections: [anisail.anisail], you can use the short name:

ansible_connection: holesail
ansible_holesail_key: "hs://s000..."

Target setup

On each device you want to manage, run Holesail in server mode exposing the SSH port:

npm i holesail -g
holesail --live 22

Use the printed URL (e.g. hs://s000...) as ansible_holesail_key for that host.

Playbook example

---
- name: Run through Holesail tunnel
  hosts: my_device
  gather_facts: true
  tasks:
    - name: Ping
      ping:
    - name: Run a command
      command: uname -a
      register: out
    - name: Print result
      debug:
        var: out.stdout

Run as usual:

ansible-playbook -i inventory.yml playbook.yml

Connection variables

Variable Description Default
ansible_holesail_key Holesail URL from target (hs://...) (required)
ansible_port Remote port to tunnel to (e.g. SSH 22) 22
ansible_holesail_tunnel_path Path to anisail-tunnel binary auto (collection bin/releases or PATH)
ansible_holesail_ready_timeout Seconds to wait for tunnel ready 30
ansible_user SSH user play context default
ansible_private_key_file / ansible_ssh_private_key_file SSH key path (optional; if unset, system keys ~/.ssh/id_ed25519, id_rsa, etc. and SSH agent are used)
ansible_password / ansible_ssh_pass SSH password

Building the tunnel binary

From the repo root:

npm install
npm run build:tunnel          # current platform only
npm run build:tunnel:all      # all platforms (darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-x64)

Output is under releases/<platform>/anisail-tunnel (or anisail-tunnel.exe on Windows). The tunnel is a statically built Bare binary; no Node.js is required at runtime.

CI and releases

The repo includes a Gitea Actions workflow (.gitea/workflows/ci.yml) that:

  • Runs on push and pull requests to main
  • Installs dependencies, lint-checks the tunnel and connection plugin, and builds tunnel binaries for all platforms (node scripts/build-tunnel.js --all)
  • Packages each binary as anisail-tunnel-<platform>.zip and publishes a rolling release on push

Required secret: RELEASE_TOKEN — a token with permission to push the latest-main tag and create/update releases and upload assets. Configure it in your Gitea repo Settings → Secrets.

The workflow uses the same pattern as Holesail-Browser CI: force-push tag latest-main, create or update a prerelease, and upload all zip artifacts plus SHA256SUMS.txt.

Documentation

Detailed docs live in docs/. Quick links:

License

AGPL-3.0. See LICENSE or https://www.gnu.org/licenses/agpl-3.0.html.

References

S
Description
No description provided
Readme AGPL-3.0
305 KiB
Languages
Python 38.4%
JavaScript 33%
Shell 15.2%
PowerShell 13.4%