Connecto
AirDrop-like SSH key pairing for your terminal.
Connecto eliminates the hassle of manual SSH key setup. Instead of copying IP addresses and managing keys by hand, simply run connecto listen on one machine and connecto pair on another. Done.
Features
- mDNS Discovery - Automatically discover devices on your local network
- VPN Support - Save subnets for cross-network discovery
- Zero-config Pairing - Exchange SSH keys with a single command
- Auto SSH Config -
ssh hostnamejust works after pairing - Modern Cryptography - Uses Ed25519 by default (RSA-4096 also supported)
- Cross-platform - Works on Linux, macOS, and Windows
How it works
┌─────────────────┐ ┌─────────────────┐
│ Target Machine │ │ Client Machine │
│ │ │ │
│ connecto listen│◄───── mDNS ───────►│ connecto scan │
│ │ │ │
│ │◄── TCP/8099 ──────►│ connecto pair 0│
│ │ │ │
│ authorized_keys│ │ ~/.ssh/config │
│ updated │ │ updated │
└─────────────────┘ └─────────────────┘
│
▼
ssh mydesktop ✓
- Target runs
connecto listen- advertises via mDNS - Client runs
connecto scan- discovers available devices - Client runs
connecto pair 0- exchanges SSH keys - Done -
ssh hostnamejust works
Quick example
On the target machine (where you want to SSH into):
connecto listen
On the client machine (where you want to SSH from):
connecto scan
connecto pair 0
ssh mydesktop # It just works!
Next steps
- Installation - Install Connecto on your system
- Quick Start - Get up and running in minutes
- VPN Setup - Configure for VPN/cross-subnet use
Installation
Connecto can be installed on macOS, Linux, and Windows.
macOS
Homebrew (Recommended)
brew install andreisuslov/connecto/connecto
Binary download
Download the latest release from GitHub Releases:
# Apple Silicon (M1/M2/M3)
curl -LO https://github.com/andreisuslov/connecto/releases/latest/download/connecto-aarch64-apple-darwin.tar.gz
tar xzf connecto-aarch64-apple-darwin.tar.gz
sudo mv connecto /usr/local/bin/
# Intel Mac
curl -LO https://github.com/andreisuslov/connecto/releases/latest/download/connecto-x86_64-apple-darwin.tar.gz
tar xzf connecto-x86_64-apple-darwin.tar.gz
sudo mv connecto /usr/local/bin/
Windows
PowerShell (Recommended)
Run in PowerShell as Administrator:
irm https://raw.githubusercontent.com/andreisuslov/connecto/main/install.ps1 | iex
This will:
- Download the latest release
- Install to
C:\Program Files\Connecto - Add to PATH
- Configure firewall rules for mDNS and the Connecto port
Chocolatey
choco install connecto
Manual installation
- Download
connecto-x86_64-pc-windows-msvc.zipfrom GitHub Releases - Extract to
C:\Program Files\Connecto - Add to PATH
Linux
Binary download
# x86_64
curl -LO https://github.com/andreisuslov/connecto/releases/latest/download/connecto-x86_64-unknown-linux-gnu.tar.gz
tar xzf connecto-x86_64-unknown-linux-gnu.tar.gz
sudo mv connecto /usr/local/bin/
From source
Requires Rust 1.70+:
git clone https://github.com/andreisuslov/connecto
cd connecto
cargo install --path connecto_cli
Verify installation
connecto --version
Shell completions
Enable tab completion for your shell:
# Bash
connecto completions bash >> ~/.bashrc
# Zsh
connecto completions zsh >> ~/.zshrc
# Fish
connecto completions fish > ~/.config/fish/completions/connecto.fish
# PowerShell
connecto completions powershell >> $PROFILE
Restart your shell or source the config file.
Firewall configuration
Connecto uses:
- UDP 5353 for mDNS discovery
- TCP 8099 for the pairing protocol
Linux (iptables)
sudo iptables -A INPUT -p udp --dport 5353 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8099 -j ACCEPT
Linux (firewalld)
sudo firewall-cmd --add-port=5353/udp --permanent
sudo firewall-cmd --add-port=8099/tcp --permanent
sudo firewall-cmd --reload
macOS
macOS typically allows these connections by default. If needed, add rules in System Preferences > Security & Privacy > Firewall.
Windows
The PowerShell installer automatically configures firewall rules. For manual setup:
New-NetFirewallRule -DisplayName "Connecto mDNS" -Direction Inbound -Protocol UDP -LocalPort 5353 -Action Allow
New-NetFirewallRule -DisplayName "Connecto TCP" -Direction Inbound -Protocol TCP -LocalPort 8099 -Action Allow
Quick start
Get SSH access between two machines in under a minute.
Prerequisites
- Connecto installed on both machines (Installation)
- Both machines on the same network (or VPN setup)
Step 1: Start the Listener
On the target machine (the one you want to SSH into):
connecto listen
You’ll see:
CONNECTO LISTENER
→ Device name: mydesktop
→ Port: 8099
Local IP addresses:
• 192.168.1.55
✓ mDNS service registered - device is now discoverable
Listening for pairing requests on port 8099...
Step 2: Scan for Devices
On the client machine (the one you want to SSH from):
connecto scan
You’ll see:
CONNECTO SCANNER
→ Scanning for devices...
✓ Found 1 device(s):
[0] mydesktop (192.168.1.55:8099)
To pair with a device, run: connecto pair <number>
Step 3: Pair
Still on the client machine:
connecto pair 0
You’ll see:
CONNECTO PAIRING
→ Connecting to 192.168.1.55:8099...
→ Using Ed25519 key (modern, secure, fast)
✓ Pairing successful!
Key saved:
• Private: /home/user/.ssh/connecto_mydesktop
• Public: /home/user/.ssh/connecto_mydesktop.pub
✓ Added to ~/.ssh/config as 'mydesktop'
You can now connect with:
ssh mydesktop
Step 4: Connect!
ssh mydesktop
That’s it! The listener exits automatically after successful pairing.
What just happened?
- Listener advertised itself via mDNS on your local network
- Scanner discovered the listener and displayed it
- Pair command:
- Generated a new Ed25519 SSH key pair
- Sent the public key to the listener
- Listener added it to
~/.ssh/authorized_keys - Client saved the private key and updated
~/.ssh/config
Alternative: Bidirectional sync
If you want both devices to be able to SSH to each other, use sync instead:
# Run on BOTH devices at the same time
connecto sync
This exchanges keys bidirectionally - after sync completes, both devices can SSH to each other. See sync command for details.
Next steps
- List paired hosts:
connecto hosts - Test connection:
connecto test mydesktop - Update IP:
connecto update-ip mydesktop 10.0.0.5 - Remove pairing:
connecto unpair mydesktop - Bidirectional sync:
connecto sync
VPN Setup
When devices are on different subnets (common with VPNs), mDNS discovery won’t work across subnets. Connecto provides a simple solution: save the remote subnet once, and scans will include it automatically.
The problem
┌─────────────────────────────────────────────────────────────┐
│ VPN Network │
├─────────────────────────┬───────────────────────────────────┤
│ Subnet A: 10.0.1.0/24 │ Subnet B: 10.0.2.0/24 │
│ │ │
│ ┌─────────────┐ │ ┌─────────────┐ │
│ │ Your Mac │ │ │ Windows │ │
│ │ 10.0.1.50 │ ✗ mDNS ✗ │ 10.0.2.100 │ │
│ └─────────────┘ │ └─────────────┘ │
│ │ │
└─────────────────────────┴───────────────────────────────────┘
mDNS broadcasts don’t cross subnet boundaries, so connecto scan won’t find devices on other subnets.
The solution
Step 1: Find the remote subnet
Ask your colleague or check your VPN documentation for the subnet. Common formats:
10.0.2.0/24(256 addresses)192.168.100.0/24172.16.5.0/24
Step 2: Save the Subnet
connecto config add-subnet 10.0.2.0/24
You can add multiple subnets:
connecto config add-subnet 10.0.3.0/24
connecto config add-subnet 192.168.100.0/24
Step 3: Scan and Pair
Now connecto scan will automatically include saved subnets:
connecto scan
CONNECTO SCANNER
→ Scanning for devices...
✓ Found 1 device(s):
[0] windows-workstation (10.0.2.100:8099)
Pair as usual:
connecto pair 0
Managing subnets
List saved subnets
connecto config list
Configured subnets:
• 10.0.2.0/24
• 10.0.3.0/24
Remove a subnet
connecto config remove-subnet 10.0.3.0/24
Config file location
connecto config path
The config file is stored at:
- macOS/Linux:
~/.config/connecto/config.json - Windows:
%APPDATA%\connecto\config.json
One-time subnet scan
If you don’t want to save a subnet permanently, use the --subnet flag:
connecto scan --subnet 10.0.2.0/24
You can specify multiple subnets:
connecto scan -s 10.0.2.0/24 -s 10.0.3.0/24
Listener VPN hint
When someone pairs from a different subnet, the listener shows a helpful message:
✓ Successfully paired with mac-laptop!
→ They can now SSH to this machine.
VPN/Cross-subnet connection detected!
→ Tell mac-laptop to save your subnet for future scans:
connecto config add-subnet 10.0.1.0/24
Direct pairing
If you know the exact IP, skip scanning entirely:
connecto pair 10.0.2.100:8099
Troubleshooting
Scan takes too long
Scanning large subnets can take time. Connecto scans up to 100 IPs concurrently with 500ms timeout per IP.
For faster scans, use a smaller subnet if possible:
/24= 254 IPs (~2-3 seconds)/22= 1022 IPs (~5-10 seconds)/16= 65534 IPs (not recommended)
Connection refused
Ensure:
- The target is running
connecto listen - Firewall allows TCP 8099
- VPN is connected and routing works
Test connectivity:
# Check if port is open
nc -zv 10.0.2.100 8099
listen
Start a listener to accept pairing requests.
Usage
connecto listen [OPTIONS]
Description
The listen command starts a pairing listener on the current machine. It:
- Advertises the device via mDNS on the local network
- Waits for incoming pairing requests on TCP port 8099
- Accepts public keys and adds them to
~/.ssh/authorized_keys - Exits after successful pairing (unless
--continuousis used)
Options
| Option | Description |
|---|---|
-p, --port <PORT> | Port to listen on (default: 8099) |
-n, --name <NAME> | Device name to advertise (default: hostname) |
-c, --continuous | Keep listening after successful pairing |
--verify | Require verification code for pairing |
Examples
Basic usage
connecto listen
Output:
CONNECTO LISTENER
→ Device name: mydesktop
→ Port: 8099
Local IP addresses:
• 192.168.1.55
✓ mDNS service registered - device is now discoverable
Listening for pairing requests on port 8099...
Custom name and port
connecto listen --name workstation --port 9000
Continuous mode
Keep listening for multiple pairings:
connecto listen --continuous
What happens during pairing
- Client connects and sends their public key
- Listener adds the key to
~/.ssh/authorized_keys - Listener sends back its hostname and username
- Both sides confirm success
- Listener exits (or continues if
--continuous)
VPN/Cross-Subnet Detection
When a pairing comes from a different subnet, the listener displays a helpful message:
✓ Successfully paired with mac-laptop!
→ They can now SSH to this machine.
VPN/Cross-subnet connection detected!
→ Tell mac-laptop to save your subnet for future scans:
connecto config add-subnet 10.0.1.0/24
Security notes
- Only run
listenwhen you intend to pair - The listener only accepts SSH public keys (not arbitrary data)
- Keys are added to
authorized_keyswith a comment identifying Connecto - Stop the listener when done to prevent unwanted pairings
scan
Discover devices running connecto listen.
Usage
connecto scan [OPTIONS]
Description
The scan command discovers devices on your network that are running connecto listen. It uses:
- mDNS discovery - Finds devices advertising the
_connecto._tcpservice - Subnet scanning - Scans saved subnets and optionally specified subnets
Options
| Option | Description |
|---|---|
-s, --subnet <CIDR> | Additional subnet to scan (can be repeated) |
-t, --timeout <SECONDS> | Scan timeout in seconds (default: 5) |
Examples
Basic scan
connecto scan
Output:
CONNECTO SCANNER
→ Scanning for devices...
✓ Found 2 device(s):
[0] mydesktop (192.168.1.55:8099)
[1] workstation (192.168.1.100:8099)
To pair with a device, run: connecto pair <number>
Scan additional subnet
connecto scan --subnet 10.0.2.0/24
Scan multiple subnets
connecto scan -s 10.0.2.0/24 -s 10.0.3.0/24
Discovery methods
mDNS Discovery
mDNS (multicast DNS) automatically finds devices on the same subnet. No configuration needed.
Limitations:
- Only works within the same subnet
- May be blocked by some network configurations
Subnet scanning
For VPN or cross-subnet scenarios, Connecto scans IP ranges directly.
Saved subnets are automatically included:
connecto config add-subnet 10.0.2.0/24
connecto scan # Now includes 10.0.2.0/24
One-time subnets can be specified with --subnet:
connecto scan --subnet 10.0.2.0/24
Scan performance
| Subnet Size | IPs | Approximate Time |
|---|---|---|
| /24 | 254 | 2-3 seconds |
| /22 | 1,022 | 5-10 seconds |
| /16 | 65,534 | Not recommended |
Connecto scans up to 100 IPs concurrently with a 500ms timeout per IP.
No devices found?
If no devices are found:
- Ensure the target is running
connecto listen - Check firewall allows TCP 8099 and UDP 5353
- For VPN, add the remote subnet:
connecto config add-subnet <CIDR> - Try direct pairing:
connecto pair <ip>:8099
See Troubleshooting for more help.
pair
Pair with a discovered device or direct IP.
Usage
connecto pair <TARGET>
Arguments
| Argument | Description |
|---|---|
TARGET | Device number from scan, or direct IP:port |
Options
| Option | Description |
|---|---|
-k, --key <PATH> | Use existing SSH key instead of generating new |
-c, --comment <TEXT> | Custom key comment |
--rsa | Generate RSA-4096 instead of Ed25519 |
Description
The pair command establishes SSH key-based authentication with a remote device:
- Generates a new Ed25519 SSH key pair
- Sends the public key to the target device
- Saves the private key to
~/.ssh/connecto_<hostname> - Updates
~/.ssh/configfor easyssh hostnameaccess
Examples
Pair by Device Number
After running connecto scan:
connecto pair 0
Output:
CONNECTO PAIRING
→ Connecting to 192.168.1.55:8099...
→ Using Ed25519 key (modern, secure, fast)
✓ Pairing successful!
Key saved:
• Private: /home/user/.ssh/connecto_mydesktop
• Public: /home/user/.ssh/connecto_mydesktop.pub
✓ Added to ~/.ssh/config as 'mydesktop'
You can now connect with:
ssh mydesktop
Pair by IP Address
Skip scanning and pair directly:
connecto pair 192.168.1.55:8099
Or with just the IP (uses default port 8099):
connecto pair 192.168.1.55
What gets created
SSH key pair
- Private key:
~/.ssh/connecto_<hostname> - Public key:
~/.ssh/connecto_<hostname>.pub
Keys use Ed25519 by default (modern, secure, fast).
SSH config entry
An entry is added to ~/.ssh/config:
# Added by Connecto
Host mydesktop
HostName 192.168.1.55
User john
IdentityFile ~/.ssh/connecto_mydesktop
IdentitiesOnly yes
This allows simple ssh mydesktop without specifying user, IP, or key.
Re-pairing
If you pair with a device that already has an entry:
- The old key files are overwritten
- The SSH config entry is updated
- A new key exchange occurs
This is useful when:
- The remote machine was reinstalled
- You want to refresh the keys
- The IP address changed
Using existing keys
Instead of generating a new key for each pairing, you can use an existing SSH key.
One-time usage
connecto pair 0 --key ~/.ssh/id_ed25519
Set default key
Set a default key for all future pairings:
connecto config set-default-key ~/.ssh/id_ed25519
Now all connecto pair commands will use this key automatically.
Clear default key
Return to generating new keys:
connecto config clear-default-key
Priority order
When pairing, Connecto looks for keys in this order:
--keyflag (if specified)- Config default key (if set)
- Generate new key (default behavior)
After pairing
Connect immediately:
ssh mydesktop
Or verify the pairing:
connecto test mydesktop
sync
Bidirectional SSH key pairing between two devices.
Usage
connecto sync [OPTIONS]
Description
The sync command enables two devices to simultaneously exchange SSH keys so both can SSH to each other. Unlike the listen + pair workflow which is one-directional (client can SSH to target), sync establishes bidirectional access.
Both devices run connecto sync at the same time, and they:
- Advertise via mDNS (
_connecto-sync._tcp.local.) - Scan for sync peers on the network
- When found, exchange SSH public keys
- Both add each other’s key to
~/.ssh/authorized_keys - Both can now SSH to each other
Options
| Option | Description |
|---|---|
-p, --port <PORT> | Port to use for sync (default: 8099) |
-n, --name <NAME> | Custom device name (default: hostname) |
-t, --timeout <SECS> | Peer search timeout in seconds (default: 60) |
--rsa | Use RSA-4096 key instead of Ed25519 |
-k, --key <PATH> | Use existing SSH key instead of generating new one |
Examples
Basic usage
Run on both devices simultaneously:
# On Device A
connecto sync
# On Device B (at the same time)
connecto sync
Output on Device A:
CONNECTO SYNC
→ Device name: device-a
→ Port: 8099
→ Timeout: 60s
Local IP addresses:
• 192.168.1.100
→ Generating Ed25519 key for sync...
→ Key saved: /Users/alice/.ssh/connecto_sync_device-a
Waiting for sync peer...
Run 'connecto sync' on another device on the same network
Press Ctrl+C to cancel
→ Found peer: Device B (192.168.1.101:8099)
→ Connected to Device B
→ Received key from Device B: bob@device-b
→ Our key was accepted by peer
✓ Sync completed with Device B!
→ Bidirectional SSH access established.
→ You can SSH to them, and they can SSH to you.
Sync Summary:
• Peer: Device B
• User: bob
• Address: 192.168.1.101:8099
Next steps:
→ SSH to peer: ssh device-b
✓ Sync successful!
With custom timeout
For slower networks:
connecto sync --timeout 120
Using an existing key
connecto sync --key ~/.ssh/my_existing_key
Using RSA instead of Ed25519
connecto sync --rsa
How it works
- Both devices advertise: Each device registers a sync service via mDNS
- Both devices search: Each device also searches for other sync services
- Priority determines initiator: Each device generates a random priority; the one that connects first becomes the initiator
- Key exchange: Initiator sends
SyncHellowith its public key, responder replies withSyncHelloAckcontaining its key - Mutual installation: Both devices add the received key to their
authorized_keys - Confirmation: Both send
SyncCompleteto confirm success
Comparison with listen + pair
| Aspect | listen + pair | sync |
|---|---|---|
| Direction | One-way | Bidirectional |
| Workflow | Run listen on target, pair on client | Run sync on both |
| Result | Client can SSH to target | Both can SSH to each other |
| Use case | Setting up access to a server | Two peers that need mutual access |
Protocol messages
The sync protocol uses these message types:
- SyncHello: Contains version, device name, priority, public key, and SSH user
- SyncHelloAck: Response with the peer’s public key and acceptance status
- SyncComplete: Final confirmation of success or failure
Troubleshooting
Timeout waiting for sync peer
- Ensure both devices are on the same network
- Check that mDNS/Bonjour is not blocked by firewall
- Try increasing the timeout:
connecto sync --timeout 120
Connection refused
- Make sure both devices start sync around the same time
- Check that port 8099 is not in use by another service
- Try a different port:
connecto sync --port 9000
Keys not being added
- Check write permissions on
~/.ssh/authorized_keys - Ensure
~/.sshdirectory exists with proper permissions (700)
Security notes
- Sync only with trusted devices on your local network
- The sync protocol requires both parties to actively participate
- Keys are generated fresh for each sync (unless
--keyis specified) - Only run sync when you intend to exchange keys with another device
hosts
List all paired hosts.
Usage
connecto hosts
Description
The hosts command displays all devices you’ve paired with using Connecto. It reads from ~/.ssh/config and shows hosts that have Connecto-generated keys.
Example
connecto hosts
Output:
PAIRED HOSTS
[0] mydesktop
→ Host: 192.168.1.55
→ User: john
→ Key: ~/.ssh/connecto_mydesktop
[1] workstation
→ Host: 10.0.2.100
→ User: admin
→ Key: ~/.ssh/connecto_workstation
[2] laptop
→ Host: 192.168.1.42
→ User: alice
→ Key: ~/.ssh/connecto_laptop
Output fields
| Field | Description |
|---|---|
| Host | IP address or hostname of the remote machine |
| User | Username for SSH connection |
| Key | Path to the private key file |
Related commands
| Command | Description |
|---|---|
connecto test <host> | Test SSH connection |
connecto update-ip <host> <ip> | Update host’s IP address |
connecto unpair <host> | Remove pairing |
connecto export | Backup all pairings |
unpair
Remove a paired host and delete its keys.
Usage
connecto unpair <HOST>
Arguments
| Argument | Description |
|---|---|
HOST | Name of the paired host to remove |
Description
The unpair command removes a pairing established by Connecto:
- Removes the host entry from
~/.ssh/config - Deletes the private key (
~/.ssh/connecto_<host>) - Deletes the public key (
~/.ssh/connecto_<host>.pub)
Example
connecto unpair mydesktop
Output:
CONNECTO UNPAIR
→ Removing host: mydesktop
✓ Removed from ~/.ssh/config
✓ Deleted key: ~/.ssh/connecto_mydesktop
✓ Deleted key: ~/.ssh/connecto_mydesktop.pub
Host 'mydesktop' has been unpaired.
Notes
- This only removes the local configuration
- The public key remains in the remote machine’s
~/.ssh/authorized_keys - To fully revoke access, also remove the key from the remote machine
Re-pairing
After unpairing, you can pair again:
connecto scan
connecto pair 0
A new key pair will be generated and exchanged.
Related commands
| Command | Description |
|---|---|
connecto hosts | List all paired hosts |
connecto export | Backup pairings before removing |
test
Test SSH connection to a paired host.
Usage
connecto test <HOST>
Arguments
| Argument | Description |
|---|---|
HOST | Name of the paired host to test |
Description
The test command verifies that SSH connectivity works to a paired host. It:
- Looks up the host in
~/.ssh/config - Attempts an SSH connection
- Runs a simple command (
echo "Connecto test successful") - Reports success or failure
Example
Successful test
connecto test mydesktop
Output:
CONNECTO TEST
→ Testing connection to: mydesktop
✓ Connection successful!
→ SSH to mydesktop is working.
Failed test
connecto test mydesktop
Output:
CONNECTO TEST
→ Testing connection to: mydesktop
✗ Connection failed!
→ Error: Connection refused
Troubleshooting:
• Check if the host is online
• Verify the IP address: connecto hosts
• Update IP if changed: connecto update-ip mydesktop <new-ip>
Common issues
| Error | Cause | Solution |
|---|---|---|
| Connection refused | Host offline or SSH not running | Start the remote machine |
| Connection timed out | Wrong IP or network issue | Update IP with connecto update-ip |
| Permission denied | Key not in authorized_keys | Re-pair with connecto pair |
| Host key verification failed | Remote host changed | Remove from ~/.ssh/known_hosts |
Related commands
| Command | Description |
|---|---|
connecto hosts | List all paired hosts |
connecto update-ip | Update host’s IP address |
connecto pair | Re-establish pairing |
update-ip
Update the IP address for a paired host.
Usage
connecto update-ip <HOST> <IP>
Arguments
| Argument | Description |
|---|---|
HOST | Name of the paired host |
IP | New IP address |
Description
The update-ip command changes the IP address for a paired host in ~/.ssh/config. This is useful when:
- A device gets a new DHCP lease
- You’re switching between networks (home/office)
- The VPN assigns a different IP
The SSH keys remain valid - only the IP changes.
Example
connecto update-ip mydesktop 10.0.2.50
Output:
CONNECTO UPDATE-IP
→ Updating IP for: mydesktop
→ Old IP: 192.168.1.55
→ New IP: 10.0.2.50
✓ Updated successfully!
You can now connect with:
ssh mydesktop
Finding the New IP
On the Remote Machine
# Linux/macOS
ip addr show | grep inet
# Windows
ipconfig
Using Connecto scan
If the remote is running connecto listen:
connecto scan
The scan results show the current IP.
Notes
- The SSH keys are not affected
- You don’t need to re-pair after updating the IP
- Consider using static IPs or hostnames for frequently-changing devices
Related commands
| Command | Description |
|---|---|
connecto hosts | View current IP addresses |
connecto test | Verify connection after update |
export / import
Backup and restore paired hosts configuration.
Export
Usage
connecto export [OUTPUT]
Arguments
| Argument | Description |
|---|---|
OUTPUT | Output file path (optional, prints to stdout if omitted) |
Description
Exports all paired hosts to a JSON file for backup or transfer to another machine.
Examples
Export to file:
connecto export ~/connecto-backup.json
Export to stdout:
connecto export
Pipe to clipboard (macOS):
connecto export | pbcopy
Export format
{
"version": 1,
"hosts": [
{
"host": "mydesktop",
"hostname": "192.168.1.55",
"user": "john",
"identity_file": "~/.ssh/connecto_mydesktop"
}
],
"subnets": ["10.0.2.0/24", "10.0.3.0/24"]
}
Note: The export contains SSH config entries only, not the actual key files. To fully backup/restore, you should also copy the key files from ~/.ssh/.
Import
Usage
connecto import <FILE>
Arguments
| Argument | Description |
|---|---|
FILE | Path to the export JSON file |
Description
Imports paired hosts from a previously exported JSON file. This:
- Restores SSH key files
- Adds entries to
~/.ssh/config - Restores saved subnets to config
Example
connecto import ~/connecto-backup.json
Output:
CONNECTO IMPORT
→ Importing from: ~/connecto-backup.json
✓ Imported host: mydesktop
✓ Imported host: workstation
✓ Imported 2 subnets
Successfully imported 2 hosts.
Handling conflicts
If a host already exists:
- Existing keys are preserved
- The import skips that host
- A warning is displayed
To replace an existing host, first unpair it:
connecto unpair mydesktop
connecto import backup.json
Use cases
Backup before reinstall
connecto export > ~/Dropbox/connecto-backup.json
# Reinstall OS
connecto import ~/Dropbox/connecto-backup.json
Transfer to new machine
# On old machine
connecto export > /tmp/connecto.json
scp /tmp/connecto.json newmachine:/tmp/
# On new machine
connecto import /tmp/connecto.json
Sync across machines
While not a true sync, you can share exports via cloud storage:
# Machine A
connecto export > ~/Dropbox/connecto.json
# Machine B
connecto import ~/Dropbox/connecto.json
Security notes
- The export contains references to private keys (file paths), not the keys themselves
- The actual key files in
~/.ssh/should be backed up separately - For a complete backup, also copy the key files:
# Full backup
connecto export > connecto-backup.json
cp ~/.ssh/connecto_* ~/backup/
Related commands
| Command | Description |
|---|---|
connecto hosts | List current pairings |
connecto config list | List saved subnets |
config
Manage Connecto configuration.
Usage
connecto config <SUBCOMMAND>
Subcommands
| Subcommand | Description |
|---|---|
add-subnet <CIDR> | Add a subnet to scan automatically |
remove-subnet <CIDR> | Remove a saved subnet |
set-default-key <PATH> | Set default SSH key for pairing |
clear-default-key | Clear the default SSH key |
list | List all configuration |
path | Show config file location |
add-subnet
Add a subnet that will be scanned automatically.
connecto config add-subnet 10.0.2.0/24
Output:
✓ Added subnet: 10.0.2.0/24
Useful for VPN networks where mDNS doesn’t work across subnets.
remove-subnet
Remove a previously saved subnet.
connecto config remove-subnet 10.0.2.0/24
Output:
✓ Removed subnet: 10.0.2.0/24
set-default-key
Set a default SSH key to use for all pairings.
connecto config set-default-key ~/.ssh/id_ed25519
Output:
✓ Default key set: /Users/john/.ssh/id_ed25519
→ All future pairings will use this key.
This is useful when you want to:
- Reuse your existing SSH key across all devices
- Use a single key for easier management
- Avoid generating multiple Connecto-specific keys
clear-default-key
Remove the default SSH key setting.
connecto config clear-default-key
Output:
✓ Default key cleared.
→ Pairings will generate new keys again.
list
Show all configured subnets.
connecto config list
Output:
Configured subnets:
• 10.0.2.0/24
• 10.0.3.0/24
• 192.168.100.0/24
path
Show where the config file is stored.
connecto config path
Output:
Config file: /Users/john/.config/connecto/config.json
Config file locations
| Platform | Path |
|---|---|
| macOS | ~/.config/connecto/config.json |
| Linux | ~/.config/connecto/config.json |
| Windows | %APPDATA%\connecto\config.json |
Config file format
The config file is JSON:
{
"subnets": [
"10.0.2.0/24",
"10.0.3.0/24"
],
"default_key": "/Users/john/.ssh/id_ed25519"
}
You can edit it manually, but using the connecto config commands is recommended.
Use cases
VPN Setup
When connecting to machines on a VPN:
# Save the VPN subnet once
connecto config add-subnet 10.0.2.0/24
# Now scans include that subnet automatically
connecto scan
Multiple office networks
connecto config add-subnet 10.0.1.0/24 # Office A
connecto config add-subnet 10.0.2.0/24 # Office B
connecto config add-subnet 192.168.0.0/24 # Home
Scans will check all saved subnets regardless of which network you’re on.
Related commands
| Command | Description |
|---|---|
connecto scan | Scan for devices |
connecto scan --subnet | One-time subnet scan |
keys
Manage SSH keys.
GUI key management
The Connecto GUI provides a full-featured key management interface in the Keys tab:
Authorized keys
View and manage SSH keys that are authorized to connect to this machine. You can:
- View key algorithm, fingerprint, and comment
- Remove keys to revoke access
Local keys
View and manage SSH key pairs stored in ~/.ssh/:
- List keys: See all local key pairs with algorithm, comment, and fingerprint
- Copy path: Copy the public key path to clipboard
- Rename: Rename key files (both private and public)
- Delete: Remove key pairs permanently
Generate new key
Create new SSH key pairs:
- Choose between Ed25519 (default) and RSA-4096
- Set custom key name and comment
- Keys are saved to
~/.ssh/
CLI key management
The CLI key management commands are planned for a future release.
Planned features
List keys
connecto keys list
Show all Connecto-generated SSH keys.
Rotate keys
connecto keys rotate <HOST>
Generate a new key pair for a host and update the remote authorized_keys.
Key info
connecto keys info <HOST>
Display key details (type, fingerprint, creation date).
Current CLI workarounds
List Connecto keys
ls -la ~/.ssh/connecto_*
View key fingerprint
ssh-keygen -lf ~/.ssh/connecto_mydesktop.pub
Manual key rotation
- Unpair the host:
connecto unpair mydesktop - Re-pair:
connecto scan && connecto pair 0
Related commands
| Command | Description |
|---|---|
connecto hosts | List paired hosts |
connecto unpair | Remove pairing |
connecto pair | Establish new pairing |
completions
Generate shell completion scripts.
Usage
connecto completions <SHELL>
Arguments
| Argument | Description |
|---|---|
SHELL | Target shell: bash, zsh, fish, or powershell |
Description
Generates tab-completion scripts for your shell. After installation, pressing Tab will complete Connecto commands and options.
Installation
Bash
# Add to ~/.bashrc
connecto completions bash >> ~/.bashrc
# Or install system-wide
sudo connecto completions bash > /etc/bash_completion.d/connecto
Restart your shell or run:
source ~/.bashrc
Zsh
# Add to ~/.zshrc
connecto completions zsh >> ~/.zshrc
Or for Oh My Zsh:
connecto completions zsh > ~/.oh-my-zsh/completions/_connecto
Restart your shell or run:
source ~/.zshrc
Fish
connecto completions fish > ~/.config/fish/completions/connecto.fish
Completions are available immediately in new shells.
PowerShell
# Add to your profile
connecto completions powershell >> $PROFILE
# Reload profile
. $PROFILE
To find your profile path:
echo $PROFILE
Example usage
After installation:
connecto <Tab>
# Shows: config export hosts import listen pair scan test unpair update-ip
connecto config <Tab>
# Shows: add-subnet list path remove-subnet
connecto scan --<Tab>
# Shows: --subnet --timeout
Troubleshooting
Bash completions not working
Ensure bash-completion is installed:
# macOS
brew install bash-completion
# Ubuntu/Debian
apt install bash-completion
Zsh completions not working
Ensure completion system is initialized. Add to ~/.zshrc:
autoload -Uz compinit && compinit
Fish completions not working
Check that the completions directory exists:
mkdir -p ~/.config/fish/completions
Configuration
Connecto stores configuration in platform-specific locations.
Config file location
| Platform | Path |
|---|---|
| macOS | ~/.config/connecto/config.json |
| Linux | ~/.config/connecto/config.json |
| Windows | %APPDATA%\connecto\config.json |
Find your config path:
connecto config path
Config file format
{
"subnets": [
"10.0.2.0/24",
"192.168.100.0/24"
],
"default_key": "/Users/john/.ssh/id_ed25519"
}
Fields
| Field | Type | Description |
|---|---|---|
subnets | string[] | CIDR ranges to scan automatically |
default_key | string? | Path to default SSH key for pairing (optional) |
SSH Configuration
Connecto modifies ~/.ssh/config when pairing. Each paired host gets an entry:
# Added by Connecto
Host mydesktop
HostName 192.168.1.55
User john
IdentityFile ~/.ssh/connecto_mydesktop
IdentitiesOnly yes
Entry fields
| Field | Description |
|---|---|
Host | Alias used with ssh command |
HostName | IP address or hostname |
User | Remote username |
IdentityFile | Path to private key |
IdentitiesOnly | Use only the specified key |
SSH Keys
Keys are stored in the SSH directory:
| Platform | Directory |
|---|---|
| macOS/Linux | ~/.ssh/ |
| Windows | %USERPROFILE%\.ssh\ |
Key files
For each paired host:
~/.ssh/connecto_<hostname>- Private key~/.ssh/connecto_<hostname>.pub- Public key
Key type
Connecto generates Ed25519 keys by default:
- Modern elliptic curve cryptography
- 256-bit security level
- Small key size (compact
authorized_keys) - Fast generation and authentication
Environment variables
| Variable | Description |
|---|---|
HOME | Home directory (Unix) - used to find ~/.ssh |
USERPROFILE | Home directory (Windows) - used to find .ssh |
Ports
| Port | Protocol | Purpose |
|---|---|---|
| 5353 | UDP | mDNS discovery |
| 8099 | TCP | Pairing protocol |
authorized_keys Format
When accepting a pairing, Connecto adds to ~/.ssh/authorized_keys:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG... connecto_laptop_2024-01-15
The comment includes:
connecto_prefix for identification- Source hostname
- Date of pairing
Protocol
Technical details of the Connecto pairing protocol.
Overview
Connecto uses a simple TCP-based protocol for key exchange:
┌────────────┐ ┌────────────┐
│ Client │ │ Listener │
│ (pair) │ │ (listen) │
└─────┬──────┘ └──────┬─────┘
│ │
│──── TCP Connect (port 8099) ─────>│
│ │
│──── HELLO <version> ─────────────>│
│ │
│<──── HELLO <version> ─────────────│
│ │
│──── PUBKEY <ssh-public-key> ─────>│
│ │
│<──── OK <hostname> <user> ────────│
│ │
│──── BYE ─────────────────────────>│
│ │
×─────── Connection Closed ─────────×
Message format
All messages are newline-terminated strings:
COMMAND [ARGUMENTS...]\n
Messages
HELLO
Version handshake.
HELLO 1
| Field | Description |
|---|---|
| Version | Protocol version (currently 1) |
PUBKEY
Client sends their SSH public key.
PUBKEY ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG... user@hostname
| Field | Description |
|---|---|
| Key | Full SSH public key in OpenSSH format |
OK
Listener confirms successful pairing.
OK mydesktop john
| Field | Description |
|---|---|
| Hostname | Listener’s hostname |
| User | Username for SSH connection |
ERR
Error response.
ERR Invalid public key format
| Field | Description |
|---|---|
| Message | Human-readable error description |
BYE
Connection closing.
BYE
Discovery
mDNS
Connecto advertises via mDNS:
| Field | Value |
|---|---|
| Service Type | _connecto._tcp |
| Port | 8099 |
| TXT Records | version=1 |
Devices respond to mDNS queries on UDP port 5353.
Subnet scanning
For cross-subnet discovery, Connecto scans IP ranges:
- Generate list of IPs from CIDR (e.g.,
10.0.2.0/24→ 254 IPs) - Attempt TCP connection to port 8099 on each IP
- 100 concurrent connections, 500ms timeout each
- Valid listeners respond to HELLO
Security considerations
What’s protected
- Authentication: SSH keys provide cryptographic authentication
- Integrity: SSH protocol ensures connection integrity
- Authorization: Keys only added with physical/network access
What’s not protected
- Initial Exchange: The pairing protocol itself is unencrypted
- Network Eavesdropping: Public keys are sent in plaintext (this is safe - they’re public)
- Man-in-the-Middle: No certificate verification during pairing
Recommendations
- Only run
listenon trusted networks - Verify the IP address before pairing
- Use SSH host key verification after pairing
- Review
authorized_keysperiodically
Wire format example
Complete pairing session:
CLIENT: HELLO 1
SERVER: HELLO 1
CLIENT: PUBKEY ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKx... user@laptop
SERVER: OK desktop john
CLIENT: BYE
[connection closed]
Future considerations
Potential protocol enhancements:
- TLS encryption for the pairing channel
- Challenge-response verification
- QR code / out-of-band verification
- Key rotation protocol
Security
Security model and best practices for Connecto.
Threat model
Protected against
| Threat | Protection |
|---|---|
| Password guessing | SSH key authentication only |
| Credential theft | Private keys never leave the device |
| Replay attacks | SSH protocol cryptographic protection |
| Network sniffing | SSH encrypts all traffic after pairing |
Not protected against
| Threat | Mitigation |
|---|---|
| Malicious network access | Only pair on trusted networks |
| Physical device access | Use full-disk encryption |
| Compromised endpoints | Keep systems updated |
Key security
Key generation
- Algorithm: Ed25519 (elliptic curve)
- Security level: 128-bit equivalent
- Key size: 256-bit private, 256-bit public
Ed25519 advantages:
- No known practical attacks
- Resistant to timing attacks
- Small, fast signatures
- Widely supported (OpenSSH 6.5+)
When to prefer RSA-4096
While Ed25519 is the default and recommended for most users, RSA-4096 may be preferred in certain scenarios:
| Reason | Details |
|---|---|
| Legacy compatibility | Systems running OpenSSH < 6.5 (pre-2014) or older embedded devices may not support Ed25519 |
| Hardware security modules | Some older HSMs, smart cards, and hardware tokens only support RSA keys |
| Compliance requirements | Certain regulatory frameworks (e.g., older FIPS 140-2 configurations, some government standards) may mandate RSA |
| Conservative cryptographic choice | RSA has 40+ years of cryptanalysis; some organizations prefer battle-tested algorithms |
| Cross-platform interoperability | Better support across legacy SSH implementations, older libraries, and enterprise software |
RSA-4096 trade-offs:
- Slower: key generation, signing, and verification are significantly slower than Ed25519
- Larger keys: 4096-bit keys vs 256-bit (affects storage and transmission)
- More complex implementation: higher risk of implementation flaws (padding oracles, timing attacks)
To use RSA-4096 with Connecto, specify the key type during pairing:
connecto pair --key-type rsa <target>
Key storage
| Component | Location | Permissions |
|---|---|---|
| Private key | ~/.ssh/connecto_* | 600 (owner read/write) |
| Public key | ~/.ssh/connecto_*.pub | 644 (world readable) |
| Authorized keys | ~/.ssh/authorized_keys | 600 |
Key lifecycle
- Generation: Created fresh for each pairing
- Distribution: Public key sent to listener
- Storage: Private key saved locally, public key in
authorized_keys - Revocation:
connecto unpairremoves local keys; manual removal fromauthorized_keys
Network security
Pairing protocol
The pairing protocol is unencrypted but designed to be safe:
- Only public keys are transmitted (safe to expose)
- Connection requires network access (implicit trust boundary)
- Short-lived listener (exits after pairing)
Ports used
| Port | Protocol | Purpose | Exposure |
|---|---|---|---|
| 5353 | UDP | mDNS | Local network |
| 8099 | TCP | Pairing | Local network |
| 22 | TCP | SSH | Configurable |
Recommendations
- Firewall: Only allow 8099 during pairing
- VPN: Use VPN for cross-internet pairing
- Monitoring: Log
authorized_keyschanges
Best practices
Before pairing
-Verify you’re on a trusted network -Confirm the target IP is correct -Ensure the listener is running on the intended machine
After pairing
- Test the connection:
connecto test <host> - Verify SSH host key fingerprint on first connect
- Stop the listener if still running
Ongoing
- Periodically review
~/.ssh/authorized_keys - Remove unused pairings:
connecto unpair <host> - Keep Connecto and SSH updated
Auditing
List Connecto keys
connecto hosts
View authorized_keys
grep connecto ~/.ssh/authorized_keys
Check key fingerprints
for key in ~/.ssh/connecto_*.pub; do
echo "=== $key ==="
ssh-keygen -lf "$key"
done
SSH connection logs
# macOS
log show --predicate 'process == "sshd"' --last 1h
# Linux
journalctl -u sshd --since "1 hour ago"
# Windows
Get-EventLog -LogName Security -InstanceId 4624 |
Where-Object { $_.Message -like "*ssh*" }
Incident response
Suspected compromise
-
Immediately: Remove unauthorized keys
# Edit authorized_keys nano ~/.ssh/authorized_keys -
Audit: Check all Connecto pairings
connecto hosts -
Revoke: Remove suspicious pairings
connecto unpair <suspicious-host> -
Investigate: Check SSH logs for unauthorized access
Key rotation
To rotate keys for a host:
connecto unpair mydesktop
# Have target run: connecto listen
connecto scan
connecto pair 0
Comparison
vs password authentication
| Aspect | Password | Connecto (SSH keys) |
|---|---|---|
| Brute force | Vulnerable | Immune |
| Credential reuse | Common | Impossible |
| Phishing | Possible | Difficult |
| Setup complexity | Low | Low (with Connecto) |
vs manual SSH keys
| Aspect | Manual | Connecto |
|---|---|---|
| Key generation | Manual | Automatic |
| Key distribution | Copy/paste | Protocol |
| Config setup | Manual | Automatic |
| Discovery | Manual | mDNS |
Troubleshooting
Common issues and solutions.
Discovery issues
“No devices found” during scan
Causes:
- Listener not running
- Firewall blocking mDNS or TCP
- Different subnets (VPN scenario)
Solutions:
-
Verify listener is running:
# On target machine connecto listen -
Check firewall:
# Test mDNS (macOS/Linux) dns-sd -B _connecto._tcp # Test TCP port nc -zv <target-ip> 8099 -
For VPN/cross-subnet:
connecto config add-subnet 10.0.2.0/24 connecto scan
Scan finds device but can’t connect
Causes:
- Firewall allows mDNS but blocks TCP
- Listener crashed after advertising
Solutions:
- Restart listener:
connecto listen - Check TCP connectivity:
nc -zv <ip> 8099 - Review firewall rules for TCP 8099
Pairing issues
“Connection refused”
Causes:
- Listener not running
- Wrong port
- Firewall blocking TCP
Solutions:
# Verify listener is running
ps aux | grep connecto
# Check if port is listening
lsof -i :8099 # macOS/Linux
netstat -an | findstr 8099 # Windows
# Test connection
nc -zv <ip> 8099
“Connection timed out”
Causes:
- Wrong IP address
- Network routing issue
- Firewall dropping packets
Solutions:
# Verify IP is reachable
ping <ip>
# Check route
traceroute <ip> # macOS/Linux
tracert <ip> # Windows
“Permission denied” after pairing
Causes:
- Key not added to authorized_keys
- Wrong username
- SSH config issue
Solutions:
# On target machine, verify key was added
grep connecto ~/.ssh/authorized_keys
# Check permissions
ls -la ~/.ssh/
# Should be: authorized_keys 600, .ssh dir 700
# Test with verbose SSH
ssh -v <host>
SSH Issues
“Host key verification failed”
The remote host’s SSH server key changed.
Solutions:
# Remove old key
ssh-keygen -R <ip>
# Connect again (will prompt to accept new key)
ssh <host>
“Too many authentication failures”
SSH agent offering too many keys.
Solutions:
# Connect with specific key only
ssh -o IdentitiesOnly=yes -i ~/.ssh/connecto_<host> <host>
# Or update ~/.ssh/config (Connecto does this automatically):
# IdentitiesOnly yes
Can’t connect after IP change
Solutions:
# Update the IP
connecto update-ip <host> <new-ip>
# Verify
connecto test <host>
Platform-specific issues
macOS
mDNS not working:
# Check mDNS daemon
sudo launchctl list | grep mDNS
# Restart mDNS
sudo killall -HUP mDNSResponder
Firewall prompts:
- Allow “connecto” in System Preferences → Security & Privacy → Firewall
Windows
Firewall blocking Connecto:
# Add firewall rules
New-NetFirewallRule -DisplayName "Connecto mDNS" -Direction Inbound -Protocol UDP -LocalPort 5353 -Action Allow
New-NetFirewallRule -DisplayName "Connecto TCP" -Direction Inbound -Protocol TCP -LocalPort 8099 -Action Allow
OpenSSH not installed:
# Check if OpenSSH is available
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
# Install OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
SSH service not running:
# Start SSH agent
Start-Service ssh-agent
Set-Service ssh-agent -StartupType Automatic
Linux
mDNS/Avahi issues:
# Check Avahi daemon
systemctl status avahi-daemon
# Restart Avahi
sudo systemctl restart avahi-daemon
# Install if missing
sudo apt install avahi-daemon # Debian/Ubuntu
sudo dnf install avahi # Fedora
SELinux blocking SSH:
# Check SELinux status
getenforce
# Temporarily disable (for testing)
sudo setenforce 0
# Check audit log
sudo ausearch -m avc -ts recent
Config issues
Config file corrupted
Symptoms: Commands fail with JSON parse errors
Solution:
# Find config location
connecto config path
# Reset config (backup first)
mv ~/.config/connecto/config.json ~/.config/connecto/config.json.bak
SSH config conflicts
Symptoms: SSH uses wrong key or settings
Solution:
# Check for duplicate entries
grep -n "Host <hostname>" ~/.ssh/config
# Remove duplicates, keep Connecto entry
# Or manually merge settings
Getting help
Verbose output
Most commands support verbose mode (planned feature):
connecto scan -v
connecto pair -v 0
Debug information
Collect for bug reports:
# Version
connecto --version
# Config
connecto config list
connecto config path
# SSH config (remove sensitive info)
grep -A5 "# Added by Connecto" ~/.ssh/config
# System info
uname -a # macOS/Linux
systeminfo | findstr /B /C:"OS" # Windows
Reporting bugs
Report issues at: github.com/andreisuslov/connecto/issues
Include:
- Connecto version
- Operating system
- Steps to reproduce
- Error messages
- Relevant config (sanitized)