ワンクリックで
fabric-vpn
Set up Tailscale mesh VPN and SSH tunnels for secure access to FABRIC nodes
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Set up Tailscale mesh VPN and SSH tunnels for secure access to FABRIC nodes
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Run iPerf3 network performance benchmarks with optional CPU pinning and SmartNIC optimization
Generate FABRIC testbed environment setup, configuration validation, and SSH key management code
Deploy Docker containers and Kubernetes clusters on FABRIC nodes
Connect FABRIC to external testbeds via facility ports and set up port mirroring
Provision and flash Xilinx U280 FPGAs on FABRIC nodes
Provision GPU nodes on FABRIC with driver installation and CUDA setup
| name | fabric-vpn |
| description | Set up Tailscale mesh VPN and SSH tunnels for secure access to FABRIC nodes |
| allowed-tools | ["Read","Grep","Glob","Write","Edit","Bash"] |
When invoked, generate code for VPN and tunneling on FABRIC. Two main capabilities:
Help the user choose the right approach and generate complete setup code.
from fabrictestbed_extensions.fablib.fablib import FablibManager
fablib = FablibManager()
slice = fablib.new_slice(name="tailscale-experiment")
node1 = slice.add_node(name="node1", site="TACC", cores=4, ram=16, disk=50)
node1.add_fabnet()
node2 = slice.add_node(name="node2", site="UCSD", cores=4, ram=16, disk=50)
node2.add_fabnet()
slice.submit()
# Tailscale auth key from https://login.tailscale.com/admin/settings/keys
ts_key = "tskey-auth-XXXXXXXX"
# Install and start Tailscale on all nodes
for node in slice.get_nodes():
node.execute(
f"curl -fsSL https://tailscale.com/install.sh | sh && "
f"sudo tailscale up --authkey {ts_key}"
)
# Verify Tailscale status
for node in slice.get_nodes():
stdout, _ = node.execute("tailscale status")
print(f"{node.get_name()}:\n{stdout}")
# Access services directly from your laptop via Tailscale hostname
# Example: Start a file browser on node1
node1 = slice.get_node(name="node1")
node1.execute(
"docker run -d --name filebrowser -p 8989:8989 "
f"-v /home/{node1.get_username()}:/data "
"-e FB_ROOT=/data -e FB_PORT=8989 -e FB_NOAUTH=noauth "
"filebrowser/filebrowser"
)
# From your laptop (connected to same Tailscale network):
# http://node1:8989
# IMPORTANT: Logout before deleting slice
for node in slice.get_nodes():
node.execute("sudo tailscale logout")
slice.delete()
slice = fablib.new_slice(name="tunnel-experiment")
node = slice.add_node(
name="service-node",
site=fablib.get_random_site(),
cores=4,
ram=16,
disk=100,
image="docker_rocky_8",
)
# Enable Docker
node.add_post_boot_upload_directory('node_tools', '.')
node.add_post_boot_execute('node_tools/enable_docker.sh {{ _self_.image }}')
slice.submit()
# Start a service bound to localhost
node = slice.get_node(name="service-node")
node.execute(
"docker run -d --name filebrowser -p 127.0.0.1:5555:5555 "
f"-v /home/{node.get_username()}/data:/data "
"-e FB_BASEURL=/filebrowser -e FB_ROOT=/data "
"-e FB_PORT=5555 -e FB_NOAUTH=noauth "
"filebrowser/filebrowser"
)
# Generate SSH tunnel config
fablib.create_ssh_tunnel_config(overwrite=True)
# Print tunnel command
import os
local_port = "5555"
target_host = f"{node.get_username()}@{node.get_management_ip()}"
key_file = os.path.basename(fablib.get_default_slice_public_key_file())[:-4]
print(
f"ssh -L 127.0.0.1:{local_port}:127.0.0.1:{local_port} "
f"-i {key_file} -F ssh_config {target_host}"
)
print(f"\nThen browse: http://127.0.0.1:{local_port}/filebrowser")
# For any web service running on a FABRIC node:
node = slice.get_node(name="monitor-node")
# Get management IP for tunnel
mgmt_ip = node.get_management_ip()
username = node.get_username()
# Generic tunnel pattern
service_port = "3000" # e.g., Grafana
print(f"Run on your laptop:")
print(
f"ssh -L 127.0.0.1:{service_port}:127.0.0.1:{service_port} "
f"-i <slice_key> -F ssh_config {username}@{mgmt_ip}"
)
print(f"Then browse: http://127.0.0.1:{service_port}")
# Forward multiple ports in a single SSH command
ports = {"Grafana": 3000, "Prometheus": 9090, "App": 8080}
tunnel_flags = " ".join(
f"-L 127.0.0.1:{port}:127.0.0.1:{port}" for port in ports.values()
)
print(f"ssh {tunnel_flags} -i <key> -F ssh_config {username}@{mgmt_ip}")
for name, port in ports.items():
print(f" {name}: http://127.0.0.1:{port}")
tailscale logout before deleting slices to clean up devicesfablib.create_ssh_tunnel_config() for bastion-aware SSH config127.0.0.1 for security, not 0.0.0.0