-
Notifications
You must be signed in to change notification settings - Fork 0
Usage
Congratulations, If you set that up successfully, you're a boss. Although there is an example client, it needs to have some basic structure prepared to make it work. Currently, the client does not support user and access management.
Luckily, the API is written in the great FastAPI, which means that you can access interactive docs at https://servicehost:port/docs. This lets you test the full potential of Open Support Tool API.
There are some restrictions that limit the possibility to do something really stupid. Take this as a guideline of how to use it properly:
There are only two types of users: admins and non-admins. While admins can see and edit basically everything, non-admins first need to be in one or more User groups to see anything. Apparently, the number of admins should be very small (ideally one) and the person responsible should always use a non-admin account if admin privileges are not required.
A user group is a group that has certain levels of access to certain directories while the rule of "only one way of access" is enforced. That means a user group can never have two accesses to folders with any depth of parent-child relationship. If the access is to be added for a subdirectory of an already accessible directory, this query will result in an error. If the access is to be added for a top-level directory, all accesses to a child directories are removed. This way, an admin should never lose the track of accesses.
Typically, you would want to create user groups according to the level of trust and need-to-knows. For example, support (having access to customer's machines), developers (having access only to the lab and test machines), and possibly restricted for specially-trained personnel (having access to very important machines). If you trust someone enough, you can add them to all of these groups, the point is that as an administrator, you always know who has access where. Simply and clearly. You can also have a special directory admins only so you know where to find the machines that should only be visible to you.
Apart from admin (which is a type of account), users (via user group - directory access relationship) can have these levels:
- Reporter - Can only see the state of a machine and see the created tunnels
- Supporter - Can also create and destroy the tunnels
- Maintainer - Can also create new machines in the directory, modify them anytime and move them around in all the directories for which he has the same access. He still can not remove the machines to prevent an accident (that is something you really do not want to do)
Machines are organized in directories and subdirectories - you should always organize them in a way that the importance is at the top level.
For example, if you want to have internal (company, lab, etc.) and external (customers) machines in the same system and you need a totally different set of people to have the respective accesses, you should first create two top-level directories. If there are critical customers with special requirements, you can create a third directory. This way the user groups' access to them can be more clear. The next level of directories could be for example the country in which the machine is or the name of a customer...
Machines, therefore can not be isolated - all of them have to be in some directory. This makes access management easier.
As usual, after you first run the API and the database is created, a default user with credentials admin:admin is ready. Of course, you should change the password immediately.
First think through the next two steps carefully according to what is written higher. Yes, if this is only for your personal use, you need only one directory and one "Default" user group and you never need to create a new account
- First of all (after you have changed the password, of course), create some top-level directories (
machines/add_directory) - Create some user groups and add the respective accesses. (
users/user_group_create,users/update_access) - Now create the users you need to give the accesses and add them to the groups (
users/user_create,users/add_user_to_group) - Now anyone (including you, the admin) can log in to the example client and reign over the machines.
By creating a machine (/machines/add_machine), you will get a one-time link with which the install script is downloaded. I am planning to add more possibilities of how to install it fast, but right now only this one - tuned for the support personnel - is available:
## Script for Ubuntu Desktop Linux with systemd with included VNC
The script should be run from the main sudoer account and does the following:
- Installs python3 packages required for the agent
- Creates a user, namely "ost-agent" with a random password that won't be stored anywhere
- Downloads and unpacks the latest compatible version of an agent (directly from GitHub repo)
- Creates the
data.jsonfile for the agent with all the information needed to access the API as an agent - Creates a systemd service for the agent and enables it
- Downloads
x11vncserver and enables another systemd service for it. The VNC can be then accessed without a password from the localhost on port 5900. - Disables ssh access to the current sudoer from the localhost (including 172.0.0.1 and ::1)
Wait there a second, WTF?! You allow VNC from localhost but disallow ssh from localhost? Why? Well, first of all, You need to remember that when creating a reverse tunnel, any incoming connection through that tunnel is recognized as from localhost. So any time you open up the tunnel, anyone from anywhere can access it just like from the localhost. Now there is a very questionable practice that support personnel uses: A common password for a fairly large group of machines. That is understandable as their interventions are of a time-critical manner and it saves a considerable amount of nerves, especially if you are on-premises (which we won't block this way). Therefore, we can block i.e. a malicious ex-employee from accessing the sudoer account directly by trying the known port range. Although it should be discouraged, the aim of this API is not to introduce additional security issues. To see how the consequent SSH access should look like, read it below. At the same time, securing the VNC this way (allowed only from localhost) is your best bet. Yes, but if somebody creates a direct tunnel to the 5900 port, also anybody can access it from the outside and they do not even need to know any password. This is solved easily by not doing that. I know it is hard so the example client won't even let you open that particular port. It actually encourages you to create an SSH connection with local port forwarding for the VNC already in place and also a SOCKS forwarding so that you can access internal HTTP services securely from your browser.
The agent regularly sends a query to the API asking if there are any tunnels and sending its current stats. If a request for the tunnel is created on a server by an authorized user, the API:
- Randomly selects from the available ports
- Generates a disposable RSA key pair
- the public key goes to the authorized_keys file with the setting that restricts forwarding to only that selected port and a UTC timestamp of expiration so that the key can be cleared afterward by our cleaning lady.
- Creates a database entry with all the information so that every server can see the request
All the data (including the disposable RSA private key, host, and port of the SSH server bound to the original API server) are then sent as a tunnel request to the agent as a reply to his next query.
The agent now knows exactly to which host he should connect, which port to forward, what key to use, and after what time it has to close it. After the connection is successful, it sends that information back to the API.
For your in-general, in-home use... As you wish. But for the support use-case there is only one correct way: You should always forward only the ssh port. Anything else you can do from there.
Now look at the /tunnels/request_tunnel. When a user is requesting the tunnel, he sends which port he wishes to forward, for how long the port tunnel can be opened, and also his public key. This public key is then temporarily stored on the agent in his authorized_keys file and the user who requested the tunnel can connect there.
Remember when we created a new user in the script and generated the random password? And restricted the sudoer access from localhost? Well now if there are no other users, the only way to connect from localhost (which is how the machine perceives incoming connections from a tunnel) is to use the user's keypair :)
The example client encourages the user to connect this way:
ssh ost-agent@host -p PORT -L 5950:localhost:5900 -D 9050`
This at the same time opens the console (where the user can always go su [sudoer] with his beloved password), opens the - now secure - tunnel to VNC on local port 5950, and another secure SOCKS port he can use in his Firefox as a poor man's VPN.
Originally I have planned to also make an alternative to SSH tunnels: by abusing the ICE (WebRTC) protocol. However, when I started playing around with ICE, this happened on my faculty. Even though the problem was in the probes on our routers, it opened a whole range of new concerns and persuaded me not to continue right now. But I will pursue the goal in the future. AnyDesk has it, we can too!