Top Related Projects
The easiest, and most secure way to access and protect all of your infrastructure.
Repository for BLESS, an SSH Certificate Authority that runs as a AWS Lambda function
Cloudflare Tunnel client (formerly Argo Tunnel)
Transparent proxy server that works as a poor man's VPN. Forwards over ssh. Doesn't require admin. Works with Linux and MacOS. Supports DNS tunneling.
Boundary enables identity-based access management for dynamic infrastructure.
Quick Overview
SSHPortal is a simple, lightweight SSH bastion server that provides secure access to multiple SSH servers through a single entry point. It offers user management, access control, and auditing capabilities, making it easier to manage and secure SSH access across multiple servers in an organization.
Pros
- Easy to set up and use, with a simple command-line interface
- Supports user management and access control features
- Provides auditing and logging capabilities for enhanced security
- Can be run as a standalone binary or in a Docker container
Cons
- Limited documentation and community support compared to more established solutions
- May lack some advanced features found in enterprise-grade SSH bastion solutions
- Requires manual configuration and management of user access rules
Getting Started
To get started with SSHPortal, follow these steps:
-
Download the latest release from the GitHub repository:
wget https://github.com/moul/sshportal/releases/latest/download/sshportal_linux_amd64 chmod +x sshportal_linux_amd64
-
Run SSHPortal:
./sshportal_linux_amd64
-
Connect to SSHPortal using an SSH client:
ssh localhost -p 2222
-
Follow the on-screen instructions to set up your admin account and start configuring hosts and users.
For more detailed instructions and configuration options, refer to the project's README and documentation on GitHub.
Competitor Comparisons
The easiest, and most secure way to access and protect all of your infrastructure.
Pros of Teleport
- More comprehensive access management solution, covering SSH, Kubernetes, databases, and web applications
- Offers advanced features like session recording, audit logs, and role-based access control
- Supports multi-factor authentication and single sign-on integration
Cons of Teleport
- More complex setup and configuration compared to SSHPortal
- Requires more resources to run and maintain
- May be overkill for simple SSH bastion use cases
Code Comparison
SSHPortal configuration example:
sshportal:
listen: 0.0.0.0:2222
db_path: /var/lib/sshportal/db.sqlite
Teleport configuration example:
teleport:
nodename: example-node
data_dir: /var/lib/teleport
auth_token: secret-token
auth_servers:
- 10.1.0.5:3025
Both projects aim to provide secure access to SSH servers, but Teleport offers a more comprehensive solution with additional features and broader scope. SSHPortal is simpler and more focused on SSH bastion functionality, making it easier to set up for basic use cases. Teleport's advanced features come at the cost of increased complexity and resource requirements, while SSHPortal maintains a lighter footprint and simpler configuration.
Repository for BLESS, an SSH Certificate Authority that runs as a AWS Lambda function
Pros of Bless
- Designed for large-scale AWS environments, offering seamless integration with AWS services
- Implements short-lived certificates, enhancing security by reducing the risk of compromised credentials
- Supports multi-factor authentication (MFA) for added security
Cons of Bless
- Primarily focused on AWS environments, limiting its use in other infrastructures
- Requires more complex setup and maintenance compared to simpler SSH management solutions
- Less suitable for small to medium-sized organizations with simpler SSH needs
Code Comparison
SSHPortal (Go):
func (s *Server) handleNewClient(c ssh.NewChannel) {
if c.ChannelType() != "session" {
c.Reject(ssh.UnknownChannelType, "unknown channel type")
return
}
// ...
}
Bless (Python):
def lambda_handler(event, context=None):
"""
This is the function that will be called when the lambda function is invoked.
"""
bless_config = bless_config.BlessConfig()
# ...
Summary
SSHPortal is a more versatile SSH management solution suitable for various environments, while Bless is specifically designed for AWS infrastructures. SSHPortal offers easier setup and maintenance, making it more appropriate for smaller organizations. Bless, on the other hand, provides enhanced security features like short-lived certificates and MFA, making it ideal for large-scale AWS deployments with stringent security requirements.
Cloudflare Tunnel client (formerly Argo Tunnel)
Pros of cloudflared
- Offers a broader range of features, including HTTP/HTTPS tunneling and DNS-over-HTTPS
- Integrates seamlessly with Cloudflare's ecosystem and services
- Provides built-in DDoS protection and traffic acceleration
Cons of cloudflared
- Requires a Cloudflare account and domain to use effectively
- May have a steeper learning curve for users unfamiliar with Cloudflare's infrastructure
- Less focused on SSH-specific functionality compared to sshportal
Code Comparison
sshportal:
func (s *sshportal) handleChannels(chans <-chan ssh.NewChannel) {
for newChannel := range chans {
go s.handleChannel(newChannel)
}
}
cloudflared:
func (t *Tunnel) serveTunnel(ctx context.Context, connIndex uint8, c net.Conn) {
defer c.Close()
err := t.connection.Serve(ctx, c, connIndex)
t.logger.Error().Err(err).Msg("Tunnel connection closed")
}
Both projects use Go and handle connections, but cloudflared's code is more focused on serving tunnels, while sshportal specifically handles SSH channels.
Transparent proxy server that works as a poor man's VPN. Forwards over ssh. Doesn't require admin. Works with Linux and MacOS. Supports DNS tunneling.
Pros of sshuttle
- Transparent proxy that works with any application
- Supports routing all traffic through the SSH connection
- Can create a VPN-like setup without root access
Cons of sshuttle
- Requires Python installation on both client and server
- May have performance overhead for large-scale deployments
- Limited access control features compared to sshportal
Code Comparison
sshuttle:
def main():
options, args = parse_args()
if options.daemon:
daemon()
if options.firewall:
firewall()
if options.hostwatch:
hostwatch()
sshportal:
func main() {
app := cli.NewApp()
app.Name = "sshportal"
app.Usage = "SSH bastion server"
app.Version = VERSION
app.Run(os.Args)
}
sshuttle focuses on creating a transparent proxy using Python, while sshportal is written in Go and designed as a bastion server with more emphasis on access control and management features. sshuttle is more flexible for general traffic routing, whereas sshportal provides a more structured approach to SSH access management.
Boundary enables identity-based access management for dynamic infrastructure.
Pros of Boundary
- More comprehensive access management solution, covering multiple protocols beyond just SSH
- Backed by HashiCorp, offering enterprise-grade support and integration with other HashiCorp products
- Provides dynamic credential injection and just-in-time access
Cons of Boundary
- More complex setup and configuration compared to SSHPortal
- Requires additional infrastructure components, potentially increasing operational overhead
- Steeper learning curve for users and administrators
Code Comparison
SSHPortal configuration example:
sshportal:
users:
- name: john
keys:
- "ssh-rsa AAAAB3NzaC1yc2E..."
hosts:
- name: webserver
addr: 192.168.1.100:22
Boundary configuration example:
resource "boundary_host_catalog_static" "example" {
name = "example_catalog"
description = "My first static host catalog"
scope_id = boundary_scope.project.id
}
resource "boundary_host_static" "example" {
name = "example_host"
description = "My first static host"
address = "10.0.0.1"
host_catalog_id = boundary_host_catalog_static.example.id
}
Both projects aim to improve SSH access management, but Boundary offers a more comprehensive solution with additional features and integrations, while SSHPortal provides a simpler, more focused approach to SSH management.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
sshportal
Jump host/Jump server without the jump, a.k.a Transparent SSH bastion

Features include: independence of users and hosts, convenient user invite system, connecting to servers that don't support SSH keys, various levels of access, and many more. Easy to install, run and configure.
Contents
- Installation and usage
- Use cases
- Features and limitations
- Docker
- Manual Install
- Backup / Restore
- built-in shell
- Demo data
- Shell commands
- Healthcheck
- portal alias (.ssh/config)
- Scaling
- Under the hood
- Testing
Installation and usage
Start the server
$ sshportal server
2017/11/13 10:58:35 Admin user created, use the user 'invite:BpLnfgDsc2WD8F2q' to associate a public key with this account
2017/11/13 10:58:35 SSH Server accepting connections on :2222
Link your SSH key with the admin account
$ ssh localhost -p 2222 -l invite:BpLnfgDsc2WD8F2q
Welcome admin!
Your key is now associated with the user "admin@sshportal".
Shared connection to localhost closed.
$
If the association fails and you are prompted for a password, verify that the host you're connecting from has a SSH key set up or generate one with ssh-keygen -t rsa
Drop an interactive administrator shell
ssh localhost -p 2222 -l admin
__________ _____ __ __
/ __/ __/ // / _ \___ ____/ /____ _/ /
_\ \_\ \/ _ / ___/ _ \/ __/ __/ _ '/ /
/___/___/_//_/_/ \___/_/ \__/\_,_/_/
config>
Create your first host
config> host create bart@foo.example.org
1
config>
List hosts
config> host ls
ID | NAME | URL | KEY | PASS | GROUPS | COMMENT
+----+------+-------------------------+---------+------+---------+---------+
1 | foo | bart@foo.example.org:22 | default | | default |
Total: 1 hosts.
config>
Add the key to the server
$ ssh bart@foo.example.org "$(ssh localhost -p 2222 -l admin key setup default)"
$
Profit
ssh localhost -p 2222 -l foo
bart@foo>
Invite friends
This command doesn't create a user on the remote server, it only creates an account in the sshportal database.
config> user invite bob@example.com
User 2 created.
To associate this account with a key, use the following SSH user: 'invite:NfHK5a84jjJkwzDk'.
config>
Demo gif:
Use cases
Used by educators to provide temporary access to students. Feedback from a teacher. The author is using it in one of his projects, pathwar, to dynamically configure hosts and users, so that he can give temporary accesses for educational purposes.
vptech, the vente-privee.com technical team (a group of over 6000 people) is using it internally to manage access to servers/routers, saving hours on configuration management and not having to share the configuration information.
There are companies who use a jump host to monitor connections at a single point.
A hosting company is using SSHportal for its âloggingâ feature, among others. As every session is logged and introspectable, they have a detailed history of who performed which action. This company made its own contribution to the project, allowing the support of more than 65.000 sessions in the database.
The project has also received multiple contributions from a security researcher that made a thesis on quantum cryptography. This person uses SSHportal in their security-hardened hosting company.
If you need to invite multiple people to an event (hackathon, course, etc), the day before the event you can create multiple accounts at once, print the invite, and distribute the paper.
Features and limitations
- Single autonomous binary (~10-20Mb) with no runtime dependencies (embeds ssh server and client)
- Portable / Cross-platform (regularly tested on linux and OSX/darwin)
- Store data in Sqlite3 or MySQL (probably easy to add postgres, mssql thanks to gorm)
- Stateless -> horizontally scalable when using MySQL as the backend
- Connect to remote host using key or password
- Admin commands can be run directly or in an interactive shell
- Host management
- User management (invite, group, stats)
- Host Key management (create, remove, update, import)
- Automatic remote host key learning
- User Key management (multiple keys per user)
- ACL management (acl+user-groups+host-groups)
- User roles (admin, trusted, standard, ...)
- User invitations (no more "give me your public ssh key please")
- Easy server installation (generate shell command to setup
authorized_keys
) - Sensitive data encryption
- Session management (see active connections, history, stats, stop)
- Audit log (logging every user action)
- Record TTY Session (with ttyrec format, use
ttyplay
for replay) - Tunnels logging
- Host Keys verifications shared across users
- Healthcheck user (replying OK to any user)
- SSH compatibility
- ipv4 and ipv6 support
scp
supportrsync
support- tunneling (local forward, remote forward, dynamic forward) support
sftp
supportssh-agent
supportX11 forwarding
support- Git support (can be used to easily use multiple user keys on GitHub, or access your own firewalled gitlab server)
- Do not require any SSH client modification or custom
.ssh/config
, works with every tested SSH programming libraries and every tested SSH clients
- SSH to non-SSH proxy
- Telnet support
(Known) limitations
- Does not work (yet?) with
mosh
- It is not possible for a user to access a host with the same name as the user. This is easily circumvented by changing the user name, especially since the most common use cases does not expose it.
- It is not possible to access a host named
healthcheck
as this is a built-in command.
Docker
Docker is the recommended way to run sshportal.
An automated build is setup on the Docker Hub.
# Start a server in background
# mount `pwd` to persist the sqlite database file
docker run -p 2222:2222 -d --name=sshportal -v "$(pwd):$(pwd)" -w "$(pwd)" moul/sshportal:v1.10.0
# check logs (mandatory on first run to get the administrator invite token)
docker logs -f sshportal
The easier way to upgrade sshportal is to do the following:
# we consider you were using an old version and you want to use the new version v1.10.0
# stop and rename the last working container + backup the database
docker stop sshportal
docker rename sshportal sshportal_old
cp sshportal.db sshportal.db.bkp
# run the new version
docker run -p 2222:2222 -d --name=sshportal -v "$(pwd):$(pwd)" -w "$(pwd)" moul/sshportal:v1.10.0
# check the logs for migration or cross-version incompatibility errors
docker logs -f sshportal
Now you can test ssh-ing to sshportal to check if everything looks OK.
In case of problem, you can rollback to the latest working version with the latest working backup, using:
docker stop sshportal
docker rm sshportal
cp sshportal.db.bkp sshportal.db
docker rename sshportal_old sshportal
docker start sshportal
docker logs -f sshportal
Manual Install
Get the latest version using GO.
GO111MODULE=on go get -u moul.io/sshportal
Backup / Restore
sshportal embeds built-in backup/restore methods which basically import/export JSON objects:
# Backup
ssh portal config backup > sshportal.bkp
# Restore
ssh portal config restore < sshportal.bkp
This method is particularly useful as it should be resistant against future DB schema changes (expected during development phase).
I suggest you to be careful during this development phase, and use an additional backup method, for example:
# sqlite dump
sqlite3 sshportal.db .dump > sshportal.sql.bkp
# or just the immortal cp
cp sshportal.db sshportal.db.bkp
built-in shell
sshportal
embeds a configuration CLI.
By default, the configuration user is admin
, (can be changed using --config-user=<value>
when starting the server. The shell is also accessible through ssh [username]@portal.example.org
.
Each command can be run directly by using this syntax: ssh admin@portal.example.org <command> [args]
:
ssh admin@portal.example.org host inspect toto
You can enter in interactive mode using this syntax: ssh admin@portal.example.org
Demo data
The following servers are freely available, without external registration,
it makes it easier to quickly test sshportal
without configuring your own servers to accept sshportal connections.
ssh portal host create new@sdf.org
ssh sdf@portal
ssh portal host create test@whoami.filippo.io
ssh whoami@portal
ssh portal host create test@chat.shazow.net
ssh chat@portal
Shell commands
# acl management
acl help
acl create [-h] [--hostgroup=HOSTGROUP...] [--usergroup=USERGROUP...] [--pattern=<value>] [--comment=<value>] [--action=<value>] [--weight=value]
acl inspect [-h] ACL...
acl ls [-h] [--latest] [--quiet]
acl rm [-h] ACL...
acl update [-h] [--comment=<value>] [--action=<value>] [--weight=<value>] [--assign-hostgroup=HOSTGROUP...] [--unassign-hostgroup=HOSTGROUP...] [--assign-usergroup=USERGROUP...] [--unassign-usergroup=USERGROUP...] ACL...
# config management
config help
config backup [-h] [--indent] [--decrypt]
config restore [-h] [--confirm] [--decrypt]
# event management
event help
event ls [-h] [--latest] [--quiet]
event inspect [-h] EVENT...
# host management
host help
host create [-h] [--name=<value>] [--password=<value>] [--comment=<value>] [--key=KEY] [--group=HOSTGROUP...] [--hop=HOST] [--logging=MODE] <username>[:<password>]@<host>[:<port>]
host inspect [-h] [--decrypt] HOST...
host ls [-h] [--latest] [--quiet]
host rm [-h] HOST...
host update [-h] [--name=<value>] [--comment=<value>] [--key=KEY] [--assign-group=HOSTGROUP...] [--unassign-group=HOSTGROUP...] [--logging-MODE] [--set-hop=HOST] [--unset-hop] HOST...
# hostgroup management
hostgroup help
hostgroup create [-h] [--name=<value>] [--comment=<value>]
hostgroup inspect [-h] HOSTGROUP...
hostgroup ls [-h] [--latest] [--quiet]
hostgroup rm [-h] HOSTGROUP...
# key management
key help
key create [-h] [--name=<value>] [--type=<value>] [--length=<value>] [--comment=<value>]
key import [-h] [--name=<value>] [--comment=<value>]
key inspect [-h] [--decrypt] KEY...
key ls [-h] [--latest] [--quiet]
key rm [-h] KEY...
key setup [-h] KEY
key show [-h] KEY
# session management
session help
session ls [-h] [--latest] [--quiet]
session inspect [-h] SESSION...
# user management
user help
user invite [-h] [--name=<value>] [--comment=<value>] [--group=USERGROUP...] <email>
user inspect [-h] USER...
user ls [-h] [--latest] [--quiet]
user rm [-h] USER...
user update [-h] [--name=<value>] [--email=<value>] [--set-admin] [--unset-admin] [--assign-group=USERGROUP...] [--unassign-group=USERGROUP...] USER...
# usergroup management
usergroup help
usergroup create [-h] [--name=<value>] [--comment=<value>]
usergroup inspect [-h] USERGROUP...
usergroup ls [-h] [--latest] [--quiet]
usergroup rm [-h] USERGROUP...
# other
exit [-h]
help, h
info [-h]
version [-h]
Healthcheck
By default, sshportal
will return OK
to anyone sshing using the healthcheck
user without checking for authentication.
$ ssh healthcheck@sshportal
OK
$
the healtcheck
user can be changed using the healthcheck-user
option.
Alternatively, you can run the built-in healthcheck helper (requiring no ssh client nor ssh key):
Usage: `sshportal healthcheck [--addr=host:port] [--wait] [--quiet]
$ sshportal healthcheck --addr=localhost:2222; echo $?
$ 0
Wait for sshportal to be healthy, then connect
$ sshportal healthcheck --wait && ssh sshportal -l admin
config>
portal alias (.ssh/config)
Edit your ~/.ssh/config
file (create it first if needed)
Host portal
User admin
Port 2222 # portal port
HostName 127.0.0.1 # portal hostname
# you can now run a shell using this:
ssh portal
# instead of this:
ssh localhost -p 2222 -l admin
# or connect to hosts using this:
ssh hostname@portal
# instead of this:
ssh localhost -p 2222 -l hostname
Scaling
sshportal
is stateless but relies on a database to store configuration and logs.
By default, sshportal
uses a local sqlite database which isn't scalable by design.
You can run multiple instances of sshportal
sharing the same MySQL database, using sshportal --db-conn=user:pass@host/dbname?parseTime=true --db-driver=mysql
.
See examples/mysql.
Under the hood
- Docker first (used in dev, tests, by the CI and in production)
- Backed by (see dep graph):
- SSH
- https://github.com/gliderlabs/ssh: SSH server made easy (well-designed golang library to build SSH servers)
- https://godoc.org/golang.org/x/crypto/ssh: both client and server SSH protocol and helpers
- Database
- https://github.com/jinzhu/gorm/: SQL orm
- https://github.com/go-gormigrate/gormigrate: Database migration system
- Built-in shell
- https://github.com/olekukonko/tablewriter: Ascii tables
- https://github.com/asaskevich/govalidator: Valide user inputs
- https://github.com/dustin/go-humanize: Human-friendly representation of technical data (time ago, bytes, ...)
- https://github.com/mgutz/ansi: Terminal color helpers
- https://github.com/urfave/cli: CLI flag parsing with subcommands support
- SSH
Testing
Install golangci-lint and run this in project root:
golangci-lint run
Perform integration tests
make integration
Perform unit tests
make unittest
Contributors
Code Contributors
This project exists thanks to all the people who contribute. [Contribute].
Financial Contributors
Become a financial contributor and help us sustain our community. [Contribute]
Individuals
Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]
Stargazers over time
Top Related Projects
The easiest, and most secure way to access and protect all of your infrastructure.
Repository for BLESS, an SSH Certificate Authority that runs as a AWS Lambda function
Cloudflare Tunnel client (formerly Argo Tunnel)
Transparent proxy server that works as a poor man's VPN. Forwards over ssh. Doesn't require admin. Works with Linux and MacOS. Supports DNS tunneling.
Boundary enables identity-based access management for dynamic infrastructure.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot