Menu
About Services Journey Work With Me
Terminal window with SSH connection on a dark monitor
Security Mar 13, 2026 • 16 min read

SSH Like You Mean It: The Windows-to-Kali Pipeline That Just Works

Build a bulletproof SSH workflow from Windows to Kali Linux using Git Bash, MobaXterm, and 1Password. Set up key-based auth, lock down your server, and never type a password again.

Share:
Lee Foropoulos

Lee Foropoulos

16 min read

There's a moment in every tech journey where you realize you've been doing something the hard way. For a lot of people running Windows and managing Linux boxes, that moment comes with SSH. You're juggling PuTTY sessions, copying key files around like it's 2004, typing passwords into three different terminals, and wondering why none of it feels smooth.

This is the guide that fixes all of that. In one afternoon.

We're going to build a pipeline where you type ssh kali from your terminal and you're in. No password prompts. No raw key files sitting on your hard drive. Your private keys live inside 1Password's vault, your sessions are organized in MobaXterm's tabbed interface, and Git Bash gives you a proper Unix shell right on Windows. And on the other end, your Kali box is locked down so tight that only your specific machine can connect to it.

"The best security setup is the one you actually use every day. If SSH feels like friction, you'll avoid it. If it feels like a superpower, you'll build everything around it."

Sound good? Let's build it.


The Stack: Why These Three Tools

Before we touch a config file, let's talk about why this particular stack works so well together. Each tool solves a specific problem, and together they eliminate every common SSH headache.

Git Bash: Your Unix Shell on Windows

Git Bash (packaged with Git for Windows) gives you a full MINGW64 environment. That means grep, awk, sed, cat, and all the Unix tools you'd expect, running natively on your Windows filesystem. You get access to C:\Users\YourName as /c/Users/YourName. You can run shell scripts. You can pipe commands. It's the bridge between Windows and the Linux world.

Install it from git-scm.com if you haven't already.

MobaXterm: The Session Manager You Didn't Know You Needed

MobaXterm is a tabbed terminal for Windows that supports SSH, SFTP, RDP, VNC, and a dozen other protocols in one window. But the killer feature? You can embed Git Bash as your default shell and then open SSH sessions in new tabs. One window. Everything accessible. Dragging files between your local machine and remote servers with a built-in SFTP browser.

Grab the free Home Edition from mobaxterm.mobatek.net. The paid version is worth it if you manage more than a handful of hosts, but the free edition handles everything in this guide.

1Password: SSH Keys Without the Key Files

Here's where things get interesting. 1Password isn't just a password manager. It has a built-in SSH agent that stores your private keys inside its encrypted vault and presents them to your SSH client on demand. Your private key never touches your filesystem as a raw file. When you connect to a server, 1Password pops up an approval prompt, you confirm, and the key is used for that session.

This is a massive security upgrade over the traditional approach of having id_rsa sitting in ~/.ssh/ where any malware or careless chmod can expose it.

Why This Stack Wins

Git Bash gives you Unix commands on Windows. MobaXterm gives you organized, tabbed sessions with SFTP built in. 1Password eliminates raw key files from your disk entirely. Together, they create an SSH workflow that's both more secure and more convenient than any single tool alone.

Multiple terminal tabs open showing SSH sessions to different servers
MobaXterm's tabbed interface lets you manage multiple SSH sessions, SFTP transfers, and local shells in a single window. No more alt-tabbing between six different PuTTY windows.

Part 1: Setting Up SSH on Your Kali Box

Before you can connect to Kali, Kali needs to be listening for connections. The SSH server isn't running by default on most Kali installations, and that's by design. Kali is a penetration testing distro. It doesn't want services running that it doesn't need.

Let's change that.

Installing and Starting the SSH Service

Boot into your Kali machine (physical, VM, whatever you're running) and open a terminal:

bash
1# Install OpenSSH server if not already present
2sudo apt update
3sudo apt install openssh-server
4
5# Start the SSH service
6sudo systemctl start ssh
7
8# Enable it to start on every boot
9sudo systemctl enable ssh
10
11# Verify it's running
12sudo systemctl status ssh

You should see output with active (running) in green. If you see anything else, the service failed to start and you'll want to check the logs with journalctl -u ssh.

Finding Your Kali's IP Address

You need to know where to point your SSH client:

bash
ip a | grep inet

Look for the address on your main interface (usually eth0 or wlan0). Something like 192.168.1.50. That's your target.

Private keys and public keys are two halves of a mathematical lock. The public key is the lock you put on the door. The private key is the only key that opens it. You share the lock freely. You guard the key with your life.

Part 2: Public and Private Key Infrastructure

This is the concept that makes everything else in this guide work, so let's make sure it clicks.

How Key-Based Authentication Works

Traditional SSH uses passwords. You type your username and password, and if they match what's on the server, you're in. The problem? Passwords can be guessed, brute-forced, intercepted, or reused across systems. Key-based authentication eliminates all of that.

Here's the flow:

  1. You generate a key pair: a private key and a public key
  2. The public key gets installed on every server you want to access (in ~/.ssh/authorized_keys)
  3. The private key stays with you, protected by your 1Password vault
  4. When you connect, the server sends a challenge that only your private key can answer
  5. Your SSH client (through 1Password's agent) answers the challenge without ever transmitting the private key
  6. The server verifies the response against your public key. Match? You're in.

The private key never leaves your machine. It never crosses the network. Even if someone is watching every packet between you and the server, they can't extract the key. That's the beauty of asymmetric cryptography.

Generating Your Key Pair

You have two options here, and both work with this stack.

Option A: Generate inside 1Password (recommended)

Open 1Password, create a new item, and select SSH Key. 1Password will generate an Ed25519 key pair for you. The private key lives exclusively inside the vault. You can copy the public key to install on your servers.

Option B: Generate with ssh-keygen, then import

If you prefer the command line:

bash
ssh-keygen -t ed25519 -C "yourname@yourmachine"

This creates two files:

  • ~/.ssh/id_ed25519 (private key)
  • ~/.ssh/id_ed25519.pub (public key)

Import the private key into 1Password, then delete the file from disk. The whole point is keeping it off your filesystem.

Why Ed25519?

Ed25519 keys are shorter, faster, and more secure than traditional RSA keys. A 256-bit Ed25519 key provides equivalent security to a 3072-bit RSA key. Unless you're connecting to ancient systems that only support RSA, always choose Ed25519.

Installing Your Public Key on Kali

Copy your public key from 1Password (or from ~/.ssh/id_ed25519.pub) and add it to your Kali server:

bash
1# On your Kali box, as the user you'll be connecting as:
2mkdir -p ~/.ssh
3chmod 700 ~/.ssh
4
5# Paste your public key into authorized_keys:
6echo "ssh-ed25519 AAAAC3Nz... yourname@yourmachine" >> ~/.ssh/authorized_keys
7
8chmod 600 ~/.ssh/authorized_keys

Or if you still have the key file on your Windows machine temporarily, use ssh-copy-id:

bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

The permissions matter. SSH is paranoid about file permissions (and rightfully so). If authorized_keys is world-readable, SSH will refuse to use it.


Part 3: Locking Down Your SSH Server

A running SSH server with default settings is an open invitation. Let's fix that.

The SSH Server Configuration

Edit the main config file on your Kali box:

bash
sudo nano /etc/ssh/sshd_config

Here are the changes that matter:

bash
1# Disable password authentication entirely
2# (forces key-based auth only)
3PasswordAuthentication no
4
5# Disable root login over SSH
6PermitRootLogin no
7
8# Only allow specific users
9AllowUsers youruser
10
11# Disable empty passwords
12PermitEmptyPasswords no
13
14# Use only the modern protocol
15Protocol 2
16
17# Set a reasonable timeout
18ClientAliveInterval 300
19ClientAliveCountMax 2
20
21# Limit authentication attempts
22MaxAuthTries 3

After saving, restart the SSH service:

bash
sudo systemctl restart ssh

Restricting Access to a Single Client

This is the "nuclear option" for security, and it's perfect for a home lab. You can tell SSH to only accept connections from a specific IP address or hostname.

Method 1: Using AllowUsers with IP restriction

In /etc/ssh/sshd_config:

bash
AllowUsers [email protected]

This means the user youruser can only connect from 192.168.1.10. Every other IP gets rejected before authentication even starts.

Method 2: Using TCP Wrappers

Edit /etc/hosts.allow:

bash
sshd: 192.168.1.10

Edit /etc/hosts.deny:

bash
sshd: ALL

This tells the system: allow SSH from this one IP, deny everyone else. Simple and brutal.

Method 3: Firewall rules with UFW

bash
1sudo ufw allow from 192.168.1.10 to any port 22
2sudo ufw deny 22
3sudo ufw enable

"Defense in depth isn't about picking one security layer. It's about stacking so many layers that an attacker runs out of patience before they run out of obstacles."

Pick one method or stack them. For a home lab, AllowUsers with an IP restriction is usually enough. For a production server facing the internet, use all three.

Server rack with blue network cables and blinking lights
Your SSH server doesn't need to welcome everyone. Lock it down to the one client that should be connecting, and everything else bounces off.

Part 4: Windows SSH Client Setup

Now for the part that trips up almost everyone: making Windows, Git Bash, MobaXterm, and 1Password all play nicely together.

The core problem is simple: Git Bash ships with its own SSH binaries, and those binaries can't talk to 1Password's agent. You need to force Git Bash to use Windows OpenSSH instead.

Step 1: Verify Windows OpenSSH Is Installed

Open PowerShell and run:

powershell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Client*'

You want to see State : Installed. If it says NotPresent:

powershell
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Step 2: Enable 1Password's SSH Agent

Open 1Password Desktop, go to Settings, then Developer, and enable:

  • Use SSH Agent

This tells 1Password to expose your stored SSH keys through the Windows OpenSSH authentication pipe.

Step 3: Configure the 1Password Agent Policy

1Password won't expose keys unless you tell it which vaults to use. The config file lives at:

%LOCALAPPDATA%\1Password\config\ssh\agent.toml

Add your vault:

toml
[[ssh-keys]]
vault = "Private"

This tells the agent to make all SSH keys in your "Private" vault available. Restart 1Password after editing this file.

Step 4: Verify the Agent Works

In PowerShell:

powershell
ssh-add.exe -l

You should see your key listed:

256 SHA256:xxxxx... ED25519 (1Password SSH Key)

If you see this, Windows OpenSSH is talking to 1Password successfully. If you get "Could not open a connection to your authentication agent," 1Password's SSH agent isn't running. Check that the Developer settings are enabled and restart the app.

0
private key files on disk when using 1Password SSH agent. That's the whole point.

Part 5: Making Git Bash Use Windows SSH

This is the step that took the most debugging. Here's why it matters and how to fix it permanently.

Git Bash has its own OpenSSH at /usr/bin/ssh. When you type ssh kali in Git Bash, it uses that binary, which communicates over Unix sockets. But 1Password's agent speaks through a Windows named pipe. These two can't talk to each other. The result? Git Bash ignores your 1Password keys entirely and asks for a password.

The fix: override Git Bash's SSH commands with the Windows versions.

Edit Your .bashrc

Open ~/.bashrc in your favorite editor (this file lives in your Git Bash home directory, usually /c/Users/YourName/.bashrc):

bash
1# Force Windows OpenSSH instead of Git Bash's built-in SSH
2export PATH="/c/Windows/System32/OpenSSH:$PATH"
3
4# Create function wrappers to ensure the .exe versions are called
5ssh() { command ssh.exe "$@"; }
6ssh-add() { command ssh-add.exe "$@"; }
7scp() { command scp.exe "$@"; }
8sftp() { command sftp.exe "$@"; }

Reload it:

bash
source ~/.bashrc
hash -r

Verify the Override

bash
type -a ssh
type -a ssh-add

You should see paths pointing to C:/Windows/System32/OpenSSH/ssh instead of /usr/bin/ssh. If you still see the Git Bash paths, the PATH override isn't taking priority. Make sure the export line is at the top of your .bashrc, before any other PATH modifications.

Now test the agent:

bash
ssh-add -l

Same output as PowerShell? Your key is listed? You're golden.


Part 6: SSH Config for One-Command Connections

Nobody wants to type ssh [email protected] every time. Let's fix that.

Create Your SSH Config

Create or edit ~/.ssh/config:

bash
1# Kali Lab Machine
2Host kali
3    HostName 192.168.1.50
4    User youruser
5
6# Home Router
7Host router
8    HostName 192.168.1.1
9    User admin
10
11# Raspberry Pi
12Host pi
13    HostName 192.168.1.200
14    User pi
15
16# Defaults for all connections
17Host *
18    IdentityAgent ~/.1password/agent.sock
19    ServerAliveInterval 60
20    ServerAliveCountMax 3

Set the permissions:

bash
chmod 600 ~/.ssh/config

Now you just type:

bash
1ssh kali
2ssh router
3ssh pi

And you're connected. 1Password pops up its approval dialog, you click approve (or use biometrics), and you're in a shell on the remote machine. No passwords. No hunting for IP addresses. No raw key files anywhere on your disk.

The best part of this whole setup? You type two words and you're inside your Kali box. All the security happens invisibly behind those two words.

Part 7: The Full Picture

Let's step back and look at what you just built:

1┌─────────────────────────────────┐
2│       MobaXterm Window          │
3│  ┌───────┬───────┬───────┐     │
4│  │ Kali  │Router │  Pi   │     │
5│  │ Tab   │ Tab   │ Tab   │     │
6│  └───┬───┴───────┴───────┘     │
7│      │                          │
8│  Git Bash (MINGW64)             │
9│      │                          │
10│  Windows OpenSSH (ssh.exe)      │
11│      │                          │
12│  1Password SSH Agent            │
13│      │                          │
14│  Private Key (in vault)         │
15│      │                          │
16│  ── Network ──                  │
17│      │                          │
18│  Kali SSH Server (locked down)  │
19│  • Key auth only                │
20│  • Single user allowed          │
21│  • Single IP allowed            │
22│  • Root login disabled          │
23└─────────────────────────────────┘

Every layer is doing its job:

  • MobaXterm organizes your sessions and gives you visual file browsing
  • Git Bash provides Unix commands on Windows for scripting and file manipulation
  • Windows OpenSSH handles the protocol and talks to 1Password's agent
  • 1Password stores the private key in an encrypted vault, never on disk
  • The Kali SSH server only accepts key-based auth from your specific user at your specific IP

No weak links. No shortcuts. No passwords floating around in plaintext.


Troubleshooting: When Things Go Sideways

Even with perfect instructions, SSH finds ways to frustrate you. Here are the most common issues and their fixes.

"Permission denied (publickey)"

This means the server rejected your key. Check:

bash
1# Is your key loaded in the agent?
2ssh-add -l
3
4# Are permissions correct on the server?
5# (SSH on Kali, check these)
6ls -la ~/.ssh/
7# authorized_keys should be 600
8# .ssh directory should be 700
9
10# Is the right public key in authorized_keys?
11cat ~/.ssh/authorized_keys

"Could not open a connection to your authentication agent"

Git Bash is using its own SSH, not Windows OpenSSH. Go back to Part 5 and verify your .bashrc overrides are working.

1Password Doesn't Show the Approval Prompt

The agent might not be running or the vault config is wrong:

  1. Check 1Password Developer settings: SSH agent must be enabled
  2. Verify agent.toml points to the correct vault name
  3. Restart 1Password completely (quit from system tray, relaunch)

Connection Refused

The SSH service on Kali isn't running or a firewall is blocking it:

bash
1# On Kali:
2sudo systemctl status ssh
3sudo ufw status

Connection Times Out

Network issue. Can you reach the machine at all?

bash
ping 192.168.1.50

If ping works but SSH doesn't, the port is blocked or the service is listening on a different port.


Bonus: Quick SSH Tricks

Once you have this pipeline running, here are some things you can do with it:

bash
1# Execute a command on Kali without opening a session
2ssh kali "sudo apt update && sudo apt upgrade -y"
3
4# Copy a file from Kali to your local machine
5scp kali:/root/scan_results.txt ./
6
7# Copy a directory recursively
8scp -r kali:/opt/project/ ./local_copy/
9
10# Forward a port (access Kali's port 8080 on your localhost)
11ssh -L 8080:localhost:8080 kali
12
13# SOCKS proxy through Kali (browse the web through your Kali box)
14ssh -D 9050 kali
15# Then set your browser's SOCKS proxy to localhost:9050
16
17# Mount Kali's filesystem locally (needs sshfs)
18sshfs kali:/root/ /mnt/kali/
19
20# Run a script on Kali from your local machine
21ssh kali "bash -s" < local_script.sh

Pro Tip: MobaXterm's SFTP Sidebar

When you SSH into a host through MobaXterm, it automatically opens an SFTP file browser in the left sidebar. You can drag and drop files between your Windows machine and the remote server. No separate SFTP client needed. It's one of those features that seems small until you realize you're using it twenty times a day.

Hands typing on a mechanical keyboard with colorful backlighting in a dark room
Once this pipeline is running, SSH stops being a chore and becomes second nature. Two keystrokes and you're on any machine in your lab.

What You Just Built

You spent one afternoon, and now you have:

  • A Kali SSH server that only accepts key-based auth from one user at one IP address
  • An encrypted key vault where your private keys live, protected by 1Password's security model
  • A terminal environment where ssh kali connects you instantly with biometric approval
  • A tabbed session manager that keeps every host organized with built-in file transfer
  • Unix tools on Windows for scripting, piping, and automation

No passwords to remember. No key files to protect. No clunky GUI tools to wrestle with. Just a clean, secure, professional SSH workflow that handles everything from your Kali lab to your home router to your Raspberry Pi projects.

This is the kind of setup that separates people who use computers from people who control them.

Your SSH Setup Checklist 0/11

Now go SSH into something. You've earned it.

How was this article?

Share

Link copied to clipboard!

You Might Also Like

Lee Foropoulos

Lee Foropoulos

Business Development Lead at Lookatmedia, fractional executive, and founder of gotHABITS.

🔔

Never Miss a Post

Get notified when new articles are published. No email required.

You will see a banner on the site when a new post is published, plus a browser notification if you allow it.

Browser notifications only. No spam, no email.