For IT and software teams, granting and managing server access is a major sticking point. Of course, team members need access to servers in order to do their jobs (install software, build deploy pipelines, find production bugs). However, no team member should be given more access than needed, and when access is no longer needed, permissions need to be cleaned up regularly.
The magnitude of the problem grows when you consider outside software vendors who may also need server access to install and provision their services. This is a common problem for IT teams that are implementing third-party solutions but still want some level of governance over what the outside vendor is doing on the server.
On top of all these issues, recent botnet attacks have specifically targeted SSH as a means for getting access to servers. Once inside, the botnet adds itself to the server's authorized_keys, making the challenge of governance and permissions cleaning all the more important.
In this article, we'll explore some of the challenges of SSH and the ways companies have historically tried to address them. Ultimately, we'll propose an alternative to SSH that still grants secure terminal access while offering audit trails and better permissioning.
Challenges of Other Approaches to Server Access
SSH has been around since the 1990s. It emerged to give stronger authentication and a confidential connection between users and servers. Over the following decades it grew massively in popularity, and it is now the dominant technology for granting terminal access to remote servers.
The SSH client allows users to establish a connection, authenticate, and pass encrypted communications to a remote server. However, in order to connect, the user's access credentials or public key must be stored on the remote server for authentication. Additionally, when the user connects, they'll be granted access to a specific username on the remote machine, and permissions are granted based on that user.
Over the years, companies have addressed the challenges of storing credentials and managing user permissions in multiple ways. But each of those approaches has drawbacks.
Deploy vs Sudo Users
To avoid the headache of setting up different users for each individual who may SSH into a server, most companies simply create two or three users with various permissions levels. The most common setup is a single user to run the application on the server and another user with sudo access for development and maintenance purposes.
If a software developer, Alice, needs access to the server, her public key will be added to the list of SSH authorized keys for the sudo user. Alice can now connect as the sudo user.
However the major drawback is auditability. When multiple people on Alice's development team have access to log in as a single user, it's difficult to say who made which changes. All commands appear to have been run by a single user. Additionally, cleaning permissions becomes a big task because you have to go through and delete SSH access keys regularly.
Jump Servers or VPN
When I worked at Apple, we made extensive use of jump servers to access secure environments. SSH into the jump server and it in turn allows access to the production servers. With the jump server as middleman, you restrict access to production servers to as little exposure as possible. Similarly, companies might use VPNs to restrict access to production machines to only trusted devices on a private network.
The challenge of course is the same. Even with a middleman (jump server) or private network (VPN), these connections still run commands as shared users with limited governance and auditability. Most jump servers also make use of automated provisioning (see below), but even so adding a middleman only marginally increases security and auditability while arguably making the system more complex and difficult to use.
A little bit better, in terms of maintainability, is automated provisioning of permissions and access. Using Ansible or code snippets, companies can automate the process of adding and updating public keys that are allowed to SSH in.
Using an Ansible config file or just a simple JSON/YAML, companies can keep more metadata about which keys belong to which individuals, which servers those individuals need access to, and what level of access they hold on each server.
These config files provide greater auditability for users and their respective permissions. As part of the deploy process, these scripts can even auto-provision separate SSH users for each person, granting governance over who runs which commands.
This is clearly a big improvement over manually provisioned permissions with shared users on the server. The drawback of automated provisioning is the config file's static nature. Any time you deploy a server, the script has to run as overhead to establish or clean up permissions. Moreover, any time a user or key changes, you have to rerun the script across the entire environment to update all your servers.
3rd Party Remote Access
We often hear about clients who purchase software from third-party vendors. In order to install and provision the software, companies will install remote access software on servers along with exceptions to firewall rules to allow those remote connections.
Most IT professionals will immediately see the drawback to this access control approach. By allowing a third party to directly connect, you add a level of risk. For example, the retailer Target allowed one such trusted refrigeration software vendor, Fazio Mechanical, to connect to their network. When hackers compromised Fazio, they were able to pivot to Target's point-of-sale data, creating a major breach.
If Target had better governance and replayability of Fazio's commands, detecting and possibly even preventing the breach might have been possible.
Manage, Audit, & Connect to Devices with Level
Level can fulfill all the requirements of SSH with greater visibility, automation, and control over access to your servers.
Level's connections are still end-to-end encrypted. But now access to the terminal is behind a fully built-out authentication system. Add two-factor authentication, password requirements, and IP restrictions to your company's Level accounts, then simply have everyone who needs SSH access sign up for Level.
No need for individuals to send their public keys. Just invite them to Level, and if they have permissions they'll see all the servers they have access to. Accessing the terminal on those machines happens through secure peer-to-peer connections instead of SSH. When you need to manage permissions, just change the settings within Level. If the Level agent is installed on all your servers/devices, the permissions will update seamlessly without needing to redeploy.
What about governance and auditability? Level produces audit trails of every change made in a session as well as logging the commands run in a session to log files. Eventually, we'll also support replaying the logs, so that you can see every change made and their output as they happened originally.
Level also has the benefit of allowing vendors to access your servers but on your terms. No need to punch a hole in your firewall for a vendor, and you can even restrict the vendor's permissions or types of commands they can run.
Better than SSH
We're excited about Level's ability to provide seamless access to all your servers with easy permissions and detailed audit trails. So excited, in fact, that at Level we use the Level agent to access our servers. We believe it's time for server access to enter the 21st century. It should be easy and intuitive to access your machines, and terminal access is just the beginning of what Level can do!
Sign up for our newsletter
Get our latest articles and our most exciting updates delivered straight to your inbox.