A minimalist HTTP server for Linux, written in x86_64 assembly。
asmhttpd - The tiniest webserver ever written.
HOW TO BUILD:
Just run "make". You will need NASM on your system.
HOW TO RUN:
./asmhttpd /path/to/your/webroot
sudo ./asmhttpd /path/to/your/webroot
If run as root, it will listen on port 80. Otherwise, it will use port 8080.
HOW TINY IS IT?
The entire text and data fit on a single 4K page:
{0}[calvin ~] cat /proc/$(pgrep -n asmhttpd)/maps
00401000-00402000 r-xp 00001000 00:16 2483272 asmhttpd
Each client allocates an additional 4K page and a thread while connected.
The code is written in a monolithic "branching tree" style with no functions,
and uses registers for all local variables. RAM is only used for buffering the
HTTP request, and for building structures necessary for system calls.
Because there is no stack, and the targets of all branch instructions are
constants, traditional buffer overflow exploits are impossible.
from https://github.com/jcalvinowens/asmhttpd
-------
A web server written in bash。
bashttpd is a simple, configurable web server written in bash
Note that in the socat example above, the web
server will immediately exit once the first connection closes. If you
wish to serve to more than one client - like most servers do, then use
the variant:
This way, a new process is spawned for each incoming connection.
Getting started
Running bashttpd for the first time will generate a default configuration file, bashttpd.conf
Review bashttpd.conf and configure it as you want.
Run bashttpd using netcat or socat, as listed above.
Features
Serves text and HTML files
Shows directory listings
Allows for configuration based on the client-specified URI
Limitations
Does not support authentication
Doesn't strictly adhere to the HTTP spec.
Security
Only rudimentary input handling. We would not running this on a public machine.
HTTP protocol support
403: Returned when a directory is not listable, or a file is not readable
400: Returned when the first word of the first line is not GET
200: Returned with valid content
Content-type: Bashttpd uses /usr/bin/file to determine the MIME type to sent to the browser
1.0: The server doesn't support Host: headers or other HTTP/1.1 features - it barely supports HTTP/1.0!
As always, your patches/pull requests are welcome!
from https://github.com/tootallnate/bashttpd
-----
GNU Libmicrohttpd
GNU libmicrohttpd is a small C library that makes it
easy to run an HTTP server as part of another application.
GNU Libmicrohttpd is free software and part of the GNU project. Key features that distinguish
GNU Libmicrohttpd from other projects are:
C library: fast and small
API is simple, expressive and fully reentrant
Implementation is HTTP 1.1 compliant
HTTP server can listen on multiple ports
Various threading modes: run in application thread, internal thread, thread pool, and thread-per-connection
Three different sockets polling modes: select(), poll(), and epoll
Minimised number of sys-calls to avoid extra user/kernel mode switches
Supported platforms include GNU/Linux, FreeBSD, OpenBSD, NetBSD, Android, Darwin (macOS), W32, OpenIndiana/Solaris, and z/OS
Support for IPv6
Support for SHOUTcast
Support for incremental processing of POST data (optional)
Support for basic and digest authentication (optional)
Support for TLS (requires libgnutls, optional)
Binary is only about 32k (without TLS support and other optional features)
GNU libmicrohttpd was started because the author needed an easy way to add
a concurrent HTTP server to other projects. Existing alternatives
were either non-free, not reentrant, standalone, of terrible code
quality, or a combination thereof. Do not use GNU libmicrohttpd if you are
looking for a standalone HTTP server, there are many other projects
out there that provide that kind of functionality already. However,
if you want to be able to serve WWW pages from within your C or
C++ application, check it out.
There are currently two main versions of the library available.
GNU libmicrohttpd 1.x is the stable version, and GNU libmicrohttpd 2.x
is experimental and remains under heavy development.
GNU libmicrohttpd 2.x can currently only be obtained by cloning our
Git repository at
git://git.gnunet.org/libmicrohttpd2.git.
Source Code
Libmicrohttpd
is available from the main GNU FTP server via
HTTP(S) and
FTP. It can also be found
on the GNU mirrors;
please
use
a mirror if possible.
The GNU Libmicrohttpd tutorial is available as one document in
PDF and HTML
formats.
Security audit 2025
Ada Logics with support from the Sovereign Tech Agency performed
a security audit of the source code of the GNU
libmicrohttpd 2.x
codebase in August 2025. All discovered issues
were addressed. The full
report is available here.
Mailing lists
Libmicrohttpd uses the
libmicrohttpd
mailinglist to discuss all aspects of
Libmicrohttpd,
including support, development, and enhancement requests, as well as bug reports.
Announcements about
Libmicrohttpd
and most other GNU software are made on
info-gnu
(archive).
Security reports that should not be made immediately public can be
sent directly to the
maintainers. If there is no response to an urgent issue, you can
escalate to the general
security
mailing list for advice.
Getting involved
Development of
Libmicrohttpd,
and GNU in general, is a volunteer effort, and you can contribute. For
information, please read How to help GNU. If you'd
like to get involved, it's a good idea to join the discussion mailing
list (see above).
Development
Known bugs and open feature requests are tracked in
our bugtracker.
You need to sign up for a reporter account. Please make
sure you report bugs under libmicrohttpd and not
under any of the other projects.
Git access
You can access the current development version of libmicrohttpd using
GNU Libmicrohttpd can be used without any dependencies; however,
for TLS (HTTPS) support it require
libgnutls.
Furthermore, the testcases use libcurl. Some extended
testcases also use zzuf and socat (to simulate
clients that violate the HTTP protocols). You can compile and use
GNU Libmicrohttpd without installing libgnutls, libcurl, zzuf or
socat.
Threading modes
The example above uses the simplest threading mode,
MHD_USE_THREAD_PER_CONNECTION. In this mode, MHD starts one
thread to listen on the port for new connections and then spawns a new
thread to handle each connection. This mode is great if the HTTP
server has hardly any state that is shared between connections (no
synchronization issues!) and may need to perform blocking operations
(such as extensive IO or running of code) to handle an individual
connection.
The second threading mode, MHD_USE_SELECT_INTERNALLY, uses
only a single thread to handle listening on the port and processing of
requests. This mode is preferable if spawning a thread for each
connection would be costly. If the HTTP server is able to quickly
produce responses without much computational overhead for each
connection, this mode can be a great choice. Note that MHD will
still start a single thread for itself – this way, the main program
can continue with its operations after calling MHD_daemon_start.
Naturally, if the HTTP server needs to interact with
shared state in the main application, synchronization will be
required. If such synchronization in code providing a response
results in blocking, all HTTP server operations on all connections
will stall. This mode is a bad choice if response data (for responses
generated using the MHD_create_response_from_callback
function) cannot always be provided instantly. The reason is that the
code generating responses should not block (since that would block all
other connections) and on the other hand, if response data is not
available immediately, MHD will start to busy wait on it. Use the
first mode if you want to block on providing response data in the
callback, or the last mode if you want to use a more event-driven
mode with one big select loop.
The third mode combines a thread pool with
the MHD_USE_SELECT_INTERNALLY mode, which can benefit
implementations that require scalability. As said before, by default
this mode only uses a single thread. When combined with the thread pool option, it
is possible to handle multiple connections with multiple threads. The
number of threads is specified using the
MHD_OPTION_THREAD_POOL_SIZE; any value greater than one for
this option will activate the use of the thread pool. In contrast to
the MHD_USE_THREAD_PER_CONNECTION mode (where each thread
handles one and only one connection), threads in the pool can handle a
large number of concurrent connections. Using
MHD_USE_SELECT_INTERNALLY in combination with a thread pool
is typically the most scalable (but also hardest to debug) mode of
operation for MHD.
The fourth threading mode (used when no specific flag is given), uses
no threads. Instead, the main application must (periodically) request
file descriptor sets from MHD, perform a select call and then call
MHD_run. MHD_run will then process HTTP requests as
usual and return. MHD_run is guaranteed to not block;
however, access handlers and response processing callbacks that it
invokes may block. This mode is useful if a single-threaded
implementation is desired and in particular if the main application
already uses a select loop for its processing. If the application is
not ready to provide a response, it can just return zero for the
number of bytes read and use its file descriptors in the external
select loop to wake up and continue once the data is ready – MHD will
unlist the socket from the write set if the application failed to
provide response data (this only happens in this mode).
The testcases provided include examples for using each of the
threading modes.
Generating responses
MHD provides various functions to create struct MHD_Response
objects. A response consists of a set of HTTP headers and a (possibly
empty) body. The three main ways to create a response are either by
specifying a given (fixed-size) body
(MHD_create_response_from_data), by providing a function of
type MHD_ContentReaderCallback which provides portions of the
response as needed or by providing an open file descriptor
(MHD_create_response_from_fd). The first response
construction is great for small and in particular static webpages that
fit into memory. The second response type should be used for response
objects where the size is initially not known or where the response
maybe too large to fit into memory. Finally, using a file descriptor
can be used on Linux systems to use the highly efficient
sendfile call for the file transfer.
A response is used by calling MHD_queue_response which sends
the response back to the client on the specified connection. Once
created, a response object can be used any number of times.
Internally, each response uses a reference counter. The response is
freed once the reference counter reaches zero. The HTTP server should
call MHD_destroy_response when a response object is no longer
needed, that is, the server will not call MHD_queue_response
again using this response object. Note that this does not mean that
the response will be immediately destroyed – destruction may be
delayed until sending of the response is complete on all connections
that have the response in the queue.
Queueing responses
Clients should never create a "100 CONTINUE" response. MHD
handles "100 CONTINUE" internally and only allows clients to
queue a single response per connection. Furthermore, clients must not
queue a response before the request has been fully received (except
in the case of rejecting PUT or POST operations in HTTP 1.1). If a
client attempts to queue multiple responses or attempts to queue a
response early, MHD_queue_response will fail (and return
MHD_NO).
The callback function for the respective URL will be called at least
twice. The first call happens after the server has received the
headers. The client should use the last void** argument to
store internal context for the session. The first call to the
callback function is mostly for this type of initialization and for
internal access checks. At least, the callback function should
"remember" that the first call with just the headers has
happened. Queueing a response during the first call (for a given
connection) should only be used for errors – if the client queues a
response during this first call, a "100 CONTINUE" response will
be suppressed, the request body will not be read and the connection
will be closed after sending the response. After the first call, the
callback function will be called with upload data. Until
*upload_data_size is zero, the callback may not queue a
response, any such attempt will fail. The callback function should
update *upload_data_size to indicate how many bytes were
processed. Depending on available buffer space, incremental
processing of the upload maybe required. Once all of the upload data
has been processed, MHD will call the callback a second time with
*upload_data_size being zero. At this point, the callback
should queue a "normal" response. If queueing a response is
not possible, the callback may either block or simply not queue a
response depending on the threading mode that is used. If the
callback does not queue a response at this point, MHD will either
(eventually) timeout the connection or keep calling it.
Parsing of POST requests
MHD includes a set of three functions for parsing and processing data
received in POST requests. The functions allow incremental parsing
and processing of POST data. Only a tiny fraction of the overall POST
data needs to fit into memory. As a result, applications using MHD
can support POST requests of arbitrary size. POST data is processed
by providing MHD with a callback function that is called on portions
of the received values. The POST parser itself is invoked repeatedly
whenever more input bytes become available. MHD supports both uri-
and multipart/form-encoded POST data.
Memory Management
The application can determine the size of buffers that MHD should use
for handling of HTTP requests and parsing of POST data. This way, MHD
users can trade-off processing time and memory utilization.
Applications can limit the overall number of connections MHD will
accept, as well as the total amount of memory used per connection.
MHD will gracefully handle all out-of-memory situations (by closing
the connection and cleaning up any remaining state).
SSHM is a beautiful command-line tool that transforms how you manage and
connect to your SSH hosts. Built with Go and featuring an intuitive TUI
interface, it makes SSH connection management effortless and enjoyable.
A modern, interactive SSH Manager for your terminal 🔥
SSHM is a beautiful command-line tool that transforms how
you manage and connect to your SSH hosts. Built with Go and featuring an
intuitive TUI interface, it makes SSH connection management effortless
and enjoyable.
🖱️ Click on the image to view in full size
✨ Features
🚀 Core Capabilities
🎨 Beautiful TUI Interface - Navigate your SSH hosts with an elegant, interactive terminal UI
⚡ Quick Connect - Connect to any host instantly through the TUI or the CLI with sshm <host>
🔄 Port Forwarding - Easy setup for Local, Remote, and Dynamic (SOCKS) forwarding with history persistence
🏷️ Tag Support - Organize your hosts with custom tags for better categorization; use the special hidden tag to exclude hosts from the list while keeping them connectable
🔍 Smart Search - Find hosts quickly with built-in filtering and search
📝 Real-time Status - Live SSH connectivity indicators with asynchronous ping checks and color-coded status
🔔 Smart Updates - Automatic version checking with update notifications
📈 Connection History - Track your SSH connections with last login timestamps
🛠️ Technical Features
🔒 Secure - Works directly with your existing ~/.ssh/config file
📁 Custom Config Support - Use any SSH configuration file with the -c flag
📂 SSH Include Support - Full support for SSH Include directives to organize configurations across multiple files
⚙️ SSH Options Support - Add any SSH configuration option through intuitive forms
🔄 Automatic Conversion - Seamlessly converts between command-line and config formats
🔄 Automatic Backups - Backup configurations automatically before changes
✅ Validation - Prevent configuration errors with built-in validation
🔗 ProxyJump/ProxyCommand Support - Secure connection tunneling through bastion hosts
⌨️ Keyboard Shortcuts - Power user navigation with vim-like shortcuts
🌐 Cross-platform - Supports Linux, macOS (Intel & Apple Silicon), and Windows
⚡ Lightweight - Single binary with no dependencies, zero configuration required
# Download specific release
wget https://github.com/Gu1llaum-3/sshm/releases/latest/download/sshm-linux-amd64.tar.gz
# Extract and install
tar -xzf sshm-linux-amd64.tar.gz
sudo mv sshm-linux-amd64 /usr/local/bin/sshm
Windows:
# Download and extractInvoke-WebRequest-Uri "https://github.com/Gu1llaum-3/sshm/releases/latest/download/sshm-windows-amd64.zip"-OutFile "sshm-windows-amd64.zip"Expand-Archive sshm-windows-amd64.zip -DestinationPath C:\tools\
# Add C:\tools to your PATH environment variable
📖 Usage
Interactive Mode
Launch SSHM without arguments to enter the beautiful TUI interface:
sshm
Navigation:
↑/↓ or j/k - Navigate hosts
Enter - Connect to selected host
a - Add new host
e - Edit selected host
d - Delete selected host
m - Move host to another config file (requires SSH Include directives)
f - Port forwarding setup
H - Toggle hidden hosts visibility
q - Quit
/ - Search/filter hosts
Real-time Status Indicators:
🟢 Online - Host is reachable via SSH
🟡 Connecting - Currently checking host connectivity
🔴 Offline - Host is unreachable or SSH connection failed
⚫ Unknown - Connectivity status not yet determined
Sorting & Filtering:
s - Switch between sorting modes (name ↔ last login)
n - Sort by name (alphabetical)
r - Sort by recent (last login time)
Tab - Cycle between filtering modes
Filter by name (default) - Search through host names
Filter by last login - Sort and filter by most recently used connections
The interactive forms will guide you through configuration:
Hostname/IP - Server address
Username - SSH user
Port - SSH port (default: 22)
Identity File - Private key path
ProxyJump - Jump server for connection tunneling
ProxyCommand - Jump command for connection tunneling
SSH Options - Additional SSH options in -o format (e.g., -o Compression=yes -o ServerAliveInterval=60)
Tags - Comma-separated tags for organization
Port Forwarding
SSHM provides an intuitive interface for setting up SSH port forwarding. Press f while selecting a host to open the port forwarding setup:
Forward Types:
Local (-L) - Forward a local port to a remote host/port through the SSH connection
Example: Access a remote database on localhost:5432 via local port 15432
Use case: ssh -L 15432:localhost:5432 server → Database accessible on localhost:15432
Remote (-R) - Forward a remote port back to a local host/port
Example: Expose local web server on remote host's port 8080
Use case: ssh -R 8080:localhost:3000 server → Local app accessible from remote host's port 8080
⚠️ Requirements for external access:
SSH Server Config: Add GatewayPorts yes to /etc/ssh/sshd_config and restart SSH service
Firewall: Open the remote port in the server's firewall (ufw allow 8080 or equivalent)
Port Availability: Ensure the remote port is not already in use
Bind Address: Use 0.0.0.0 for external access, 127.0.0.1 for local-only
Dynamic (-D) - Create a SOCKS proxy for secure browsing
Example: Route web traffic through the SSH connection
Use case: ssh -D 1080 server → Configure browser to use localhost:1080 as SOCKS proxy
⚠️ Configuration requirements:
Browser Setup: Configure SOCKS v5 proxy in browser settings
DNS: Enable "Proxy DNS when using SOCKS v5" for full privacy
Applications: Only SOCKS-aware applications will use the proxy
Bind Address: Use 127.0.0.1 for security (local access only)
Port Forwarding Interface:
Choose forward type with ←/→ arrow keys
Configure ports and addresses with guided forms
Optional bind address configuration (defaults to 127.0.0.1)
Real-time validation of port numbers and addresses
Port forwarding history - Save frequently used configurations for quick reuse
Connect automatically with configured forwarding options
Troubleshooting Port Forwarding:
Remote Forwarding Issues:
# Error: "remote port forwarding failed for listen port X"# Solutions:
1. Check if port is already in use: ssh server "netstat -tln | grep :X"
2. Use a different port that's available3. Enable GatewayPorts in SSH config for external access
SSH Server Configuration for Remote Forwarding:
# Edit SSH daemon config on the server:
sudo nano /etc/ssh/sshd_config
# Add or uncomment:
GatewayPorts yes
# Restart SSH service:
sudo systemctl restart sshd # Ubuntu/Debian/CentOS 7+# OR
sudo service ssh restart # Older systems
Firewall Configuration:
# Ubuntu/Debian (UFW):
sudo ufw allow [port_number]
# CentOS/RHEL/Rocky (firewalld):
sudo firewall-cmd --add-port=[port_number]/tcp --permanent
sudo firewall-cmd --reload
# Check if port is accessible:
telnet [server_ip] [port_number]
Dynamic Forwarding (SOCKS) Browser Setup:
Firefox: about:preferences → Network Settings
- Manual proxy configuration
- SOCKS Host: localhost, Port: [your_port]
- SOCKS v5: ✓
- Proxy DNS when using SOCKS v5: ✓
Chrome: Launch with proxy
chrome --proxy-server="socks5://localhost:[your_port]"
CLI Usage
SSHM provides both command-line operations and an interactive TUI interface:
# Launch interactive TUI mode for browsing and connecting to hosts
sshm
# Connect directly to a specific host (with history tracking)
sshm my-server
# Execute a command on a remote host
sshm my-server uptime
# Execute command with arguments
sshm my-server ls -la /var/log
# Force TTY allocation for interactive commands
sshm -t my-server sudo systemctl restart nginx
# Launch TUI with custom SSH config file
sshm -c /path/to/custom/ssh_config
# Connect directly with custom SSH config file
sshm my-server -c /path/to/custom/ssh_config
# Add a new host using interactive form
sshm add
# Add a new host with pre-filled hostname
sshm add hostname
# Add a new host with custom SSH config file
sshm add hostname -c /path/to/custom/ssh_config
# Edit an existing host configuration
sshm edit my-server
# Edit host with custom SSH config file
sshm edit my-server -c /path/to/custom/ssh_config
# Move a host to another SSH config file (requires Include directives)
sshm move my-server
# Move host with custom SSH config file (requires Include directives)
sshm move my-server -c /path/to/custom/ssh_config
# Search for hosts (interactive filter)
sshm search
# Print machine-readable info (JSON) for scripting
sshm info prod-server
sshm info prod-server --pretty
# With a custom SSH config file
sshm -c /path/to/custom/ssh_config info prod-server
# Pipe to jq
sshm info prod-server | jq -r '.result.target.hostname'
sshm info prod-server | jq -r '.result.target.user'# Show version information
sshm --version
# Disable automatic update check (useful on air-gapped machines)
sshm --no-update-check
# Show help and available commands
sshm --help
Host Info (JSON)
sshm info <hostname> prints a single JSON object to stdout so you can script against it with jq.
# Extract fields
sshm info prod-server | jq -r '.result.target.hostname'
sshm info prod-server | jq -r '.result.target.port'# Check not-found (exit code 2)
sshm info does-not-exist | jq -r '.error.code'
Shell Completion
SSHM supports shell completion for host names, making it easy to connect to hosts without typing full names:
sshm <TAB># Lists all available hosts
sshm pro<TAB># Completes to hosts starting with "pro" (e.g., prod-server)
Setup Instructions:
Bash:
# Enable for current sessionsource<(sshm completion bash)# Enable permanently (add to ~/.bashrc)echo'source <(sshm completion bash)'>>~/.bashrc
Zsh:
# Enable for current sessionsource<(sshm completion zsh)# Enable permanently (add to ~/.zshrc)echo'source <(sshm completion zsh)'>>~/.zshrc
Fish:
# Enable for current session
sshm completion fish |source# Enable permanently
sshm completion fish >~/.config/fish/completions/sshm.fish
PowerShell:
# Enable for current session
sshm completion powershell |Out-String|Invoke-Expression# Enable permanently (add to your PowerShell profile)Add-Content$PROFILE'sshm completion powershell | Out-String | Invoke-Expression'
Direct Host Connection
SSHM supports direct connection to hosts via the command line, making it easy to integrate into your existing workflow:
# Connect directly to any configured host
sshm production-server
sshm db-staging
sshm web-01
# All direct connections are tracked in your history# Use the TUI to see your most recently connected hosts
Features of Direct Connection:
Instant connection - No TUI navigation required
History tracking - All connections are recorded with timestamps
Error handling - Clear messages if host doesn't exist or configuration issues
Config file support - Works with custom config files using -c flag
Remote Command Execution
Execute commands on remote hosts without opening an interactive shell:
# Execute a single command
sshm prod-server uptime
# Execute command with arguments
sshm prod-server ls -la /var/log
# Check disk usage
sshm prod-server df -h
# View logs (pipe to local commands)
sshm prod-server 'cat /var/log/nginx/access.log'| grep 404
# Force TTY allocation for interactive commands (sudo, vim, etc.)
sshm -t prod-server sudo systemctl restart nginx
Features:
Exit code propagation - Remote command exit codes are passed through
TTY support - Use -t flag for commands requiring terminal interaction
Pipe-friendly - Output can be piped to local commands for processing
History tracking - Command executions are recorded in connection history
Backup Configuration
SSHM automatically creates backups of your SSH
configuration files before making any changes to ensure your
configurations are safe.
Backup Location:
Unix/Linux/macOS: ~/.config/sshm/backups/ (or $XDG_CONFIG_HOME/sshm/backups/ if set)
Connection History: Stored in the same config directory for persistent tracking
Port Forwarding History: Saved configurations for quick reuse of common forwarding setups
Quick Recovery:
# Unix/Linux/macOS
cp ~/.config/sshm/backups/config.backup ~/.ssh/config
# Windows
copy "%APPDATA%\sshm\backups\config.backup""%USERPROFILE%\.ssh\config"
Configuration File Options
By default, SSHM uses the standard SSH configuration file at ~/.ssh/config. You can specify a different configuration file using the -c flag:
# Use custom config file in TUI mode
sshm -c /path/to/custom/ssh_config
# Use custom config file with commands
sshm add hostname -c /path/to/custom/ssh_config
sshm edit hostname -c /path/to/custom/ssh_config
sshm move hostname -c /path/to/custom/ssh_config
Advanced Features
Host Movement Between Config Files
SSHM provides a powerful move command to relocate SSH hosts between different configuration files. This feature requires SSH Include directives to be present in your SSH configuration.
# Move a host to another config file (requires Include directives)
sshm move my-server
# Move with custom config file (requires Include directives)
sshm move my-server -c /path/to/custom/ssh_config
⚠️ Important Requirements:
SSH Include directives must be present in your SSH config file (either ~/.ssh/config or the file specified with -c)
The config file must contain Include statements referencing other SSH configuration files
Without Include directives, the move command will display an error message
Features:
Interactive file selector - Choose destination config file from Include directives
Include support - Works seamlessly with SSH Include directives structure
Atomic operations - Safe host movement with automatic backups
Validation - Prevents conflicts and ensures configuration integrity
Error handling - Clear messages when Include files are needed but not found
Use Cases:
Reorganize hosts from main config to specialized include files
Move development hosts to separate environment-specific configs
Consolidate configurations for better organization
Example Setup Required:
Your main SSH config file must contain Include directives like:
# ~/.ssh/config
Include ~/.ssh/config.d/*
Include work-servers.conf
Include projects/*.conf
Host personal-server
HostName personal.example.com
User myuser
Real-time Connectivity Status
SSHM features asynchronous SSH connectivity checking that provides visual indicators of host availability:
SSHM works directly with your standard SSH configuration file (~/.ssh/config). It adds special comment tags for enhanced functionality while maintaining full compatibility with standard SSH tools.
SSH Include Support
SSHM fully supports SSH Include directives, allowing you
to organize your SSH configurations across multiple files. This is
particularly useful for managing large numbers of hosts or organizing
configurations by environment, project, or team.
Include Examples:
# Main ~/.ssh/config file
Host personal-server
HostName personal.example.com
User myuser
# Include work-related configurations
Include work-servers.conf
# Include all configurations from a directory
Include projects/*
# Include with relative paths
Include ~/.ssh/configs/production.conf
Organization Examples:
work-servers.conf:
# Tags: work, production
Host prod-web-01
HostName 10.0.1.10
User deploy
ProxyJump bastion.company.com
# Tags: work, staging
Host staging-api
HostName staging-api.company.com
User developer
projects/client-alpha.conf:
# Tags: client, development
Host client-alpha-dev
HostName dev.client-alpha.com
User admin
Port 2222
Example configuration:
Include ~/.ssh/conf.d/*
# Tags: production, web, frontend
Host web-prod-01
HostName 192.168.1.10
User deploy
Port 22
IdentityFile ~/.ssh/production_key
Compression yes
ServerAliveInterval 60
# Tags: development, database
Host db-dev
HostName dev-db.company.com
User admin
Port 2222
IdentityFile ~/.ssh/dev_key
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# Tags: production, backend
Host backend-prod
HostName 10.0.1.50
User app
Port 22
ProxyJump bastion.company.com
ProxyCommand ssh -W %h:%p Jumphost
IdentityFile ~/.ssh/production_key
Compression yes
ServerAliveInterval 300
BatchMode yes
Supported SSH Options
SSHM supports all standard SSH configuration options:
Built-in Fields:
HostName - Server hostname or IP address
User - Username for SSH connection
Port - SSH port number
IdentityFile - Path to private key file
ProxyJump - Jump server for connection tunneling (e.g., user@jumphost:port)
Tags - Custom tags (SSHM extension); the special tag hidden hides the host from the TUI and sshm search while keeping it connectable via sshm <host>
Additional SSH Options:
You can add any valid SSH option using the "SSH Options" field in the
interactive forms. Enter them in command-line format (e.g., -o Compression=yes -o ServerAliveInterval=60) and SSHM will automatically convert them to the proper SSH config format.
Common SSH Options:
Compression - Enable/disable compression (yes/no)
ServerAliveInterval - Interval in seconds for keepalive messages
ServerAliveCountMax - Maximum number of keepalive messages
check_for_updates: Boolean to enable or disable the automatic update check at startup. Default: true. Set to false on air-gapped or offline machines to avoid connection delays.
quit_keys: Array of keys that will quit the application. Default: ["q", "ctrl+c"]
disable_esc_quit: Boolean flag to disable ESC key from quitting the application. Default: false
For Vim Users:
If you frequently press ESC accidentally causing the application to quit, set disable_esc_quit to true. This will disable ESC as a quit key while preserving all other functionality.
For Air-gapped Machines:
If SSHM is slow to start due to DNS timeouts when reaching GitHub, set check_for_updates to false. You can also use the --no-update-check CLI flag for a one-time override without editing the config file.
Default Configuration:
If no configuration file exists, SSHM will automatically create one with default settings that maintain backward compatibility.
🛠️ Development
Prerequisites
Go 1.23+
Git
Build from Source
# Clone the repository
git clone https://github.com/Gu1llaum-3/sshm.git
cd sshm
# Build the binary
go build -o sshm .# Run
./sshm
Project Structure
sshm/
├── main.go # Application entry point
├── cmd/ # CLI commands (Cobra)
│ ├── root.go # Root command and interactive mode
│ ├── add.go # Add host command
│ ├── edit.go # Edit host command
│ ├── move.go # Move host command
│ └── search.go # Search command
├── internal/
│ ├── config/ # SSH configuration management
│ │ └── ssh.go # Config parsing and manipulation
│ ├── connectivity/ # SSH connectivity checking
│ │ └── ping.go # Asynchronous SSH ping functionality
│ ├── history/ # Connection history tracking
│ │ ├── history.go # History management and last login tracking
│ │ └── port_forward_test.go # Port forwarding history tests
│ ├── version/ # Version checking and updates
│ │ ├── version.go # GitHub release checking and version comparison
│ │ └── version_test.go # Version parsing and comparison tests
│ ├── ui/ # Terminal UI components (Bubble Tea)
│ │ ├── tui.go # Main TUI interface and program setup
│ │ ├── model.go # Core TUI model and state
│ │ ├── update.go # Message handling and state updates
│ │ ├── view.go # UI rendering and layout
│ │ ├── table.go # Host list table component with status indicators
│ │ ├── add_form.go # Add host form interface
│ │ ├── edit_form.go# Edit host form interface
│ │ ├── move_form.go# Move host form interface
│ │ ├── port_forward_form.go # Port forwarding setup with history
│ │ ├── styles.go # Lip Gloss styling definitions
│ │ ├── sort.go # Sorting and filtering logic
│ │ └── utils.go # UI utility functions
│ └── validation/ # Input validation
│ └── ssh.go # SSH config validation
├── images/ # Documentation assets
│ ├── logo.png # Project logo
│ └── sshm.gif # Demo animation
├── install/ # Installation scripts
│ ├── unix.sh # Unix/Linux/macOS installer
│ └── README.md # Installation guide
├── .github/ # GitHub configuration
│ ├── copilot-instructions.md # Development guidelines
│ └── workflows/ # CI/CD pipelines
│ └── build.yml # Multi-platform builds
├── go.mod # Go module definition
├── go.sum # Go module checksums
├── LICENSE # MIT license
└── README.md # Project documentation
Contributions are welcome! Please feel free to submit a
Pull Request. For major changes, please open an issue first to discuss
what you would like to change.
Development Workflow
Fork the repository
Create a feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
KejiLion's Shell script is an all-in-one toolbox designed for Linux monitoring, testing, and
server management. It brings together Docker management, LDNMP website deployment, optimization,
protection, backup, restoration, migration, and common server applications in one interactive tool.