[切换到中文]
This article is machine translated
SSH terminal of OnTheSSH (version 1.6 and later) has been redesigned for Web programming, featuring secure and controllable account passwords, and capable of recording user behaviors. The following is a detailed description of a usage scenario:
In a cloud server rental center, the main business is to rent cloud Linux servers to users. Here are two users, user A and user B. Among them, user A rents Server 1 and Server 2, and user B rents Server 3 and Server 4. The basic security requirement is that user A can only access the server rented by themselves and not the server rented by user B, and vice versa. Secondly, for security reasons, cloud service providers need to update server passwords regularly (frequently), and at the same time, they hope to record the logs of users logging into the server and every instruction entered by users in the SSH terminal.
Using the traditional SSH terminal cannot meet the requirements of this scenario because two problems will be encountered:
- When the rental center updates the server password, it needs to inform the rental users of the password. During the notification process, it is inevitable to encounter the problem of password leakage. At the same time, frequent password updates will cause dissatisfaction among users, and users prefer to change the password themselves. In addition, for security reasons, server passwords are usually rather complex. Users are prone to enter them incorrectly when logging in, which can also cause dissatisfaction among users.
- The information transmission between the SSH terminal and the Linux server is encrypted and cannot record the user’s login and usage process through means such as listening or interception. The SSH transmission protocol has sufficient security and cannot intercept information on devices such as firewalls and switches.

The SSH terminal of OnTheSSH (version 1.6 and later) was redesigned to meet this requirement. As shown in the above figure, the architecture supports embedding an “interface machine” between the terminal and the Server. This interface machine is the server for SSH terminals and the client for Linux servers. It can not only record the logs of user login and the use of SSH commands, but also maintain a password mapping table. The main changes are as follows:
- When logging in at the user terminal, the password of the Server is not used (for security reasons, users will never know the password of the Server). For example, user A logs in with the password 1234. After the interface machine receives the password 1234, it converts it into the real password of the Server according to the mapping table and then logs in to the Server using the SSH protocol.
- The Server password can be modified at any time as long as it is synchronized to the password mapping table. This change is imperceptible to the user’s usage, and the user can still use the original password 1234.
- All communication between the SSH terminal and the Server is forwarded by the interface machine. In this way, user logs can be conveniently recorded on the interface machine, down to every command entered by the user.
When the SSH terminal of OnTheSSH (version 1.6 and later) is used as an App program, its structure is as follows:

The program is divided into two parts. One part is the interface module part written in Qt language, and the other part is the core module part written in Rust language. The core module serves as the dynamic link library and the interface module to form the application program. The core module has been encapsulated “sufficiently” to enable the interface module to undergo the following changes:
- The interaction mode of the SSH terminal has been changed from the original two-way interaction to one-way interaction, making the interface module suitable for HTTP interaction and facilitating the embedding of the terminal into web pages for operation.
- The original complex xterm control sequences of the SSH terminal are converted into a tag format similar to html, which greatly simplifies interface programming and is suitable for implementing the terminal interface with JavaScript.
- It has shielded the hard-to-understand concepts such as the default buffer, spare buffer, keyboard application mode, and cursor key application mode of SSH, making the interface programming habits more inclined towards Web programming.
The design of the core module takes into account secondary development, and the interface module and the core module are loosely coupled. After simple encapsulation, Socket interfaces or http interfaces can be added to the core module. To meet the requirements of the previous scenarios, the following architecture can be established:

As shown in the above figure: The terminal interface program can be encapsulated as a regular application or embedded in a web page. Network communication can adopt TCP/Socket or HTTP/HTTPS. The password mapping and user log functions discussed in the previous scenarios can be implemented in the Socket API or HTTP API. The core module takes the encapsulability of the interface into consideration in the design. Therefore, the implementation of the Socket API and the HTTP API is not difficult for programmers with a little ability.
The HTTP API can also be implemented using another open-source project, Module Proxy, written by me. (https://gitee.com/dyf029/module-proxy)
View descriptions similar to html tags
A large amount of conversion work has been done for the core module, making the development of the SSH terminal interface part much easier. The most important change is that the interface description has been changed from the original complex (xterm control sequences) to a tag structure (very similar to html). The following figure shows the interface information after logging into Ubuntu:

The source code of the page information is as follows:
<head><seq>0</seq><rows>28</rows><cols>118</cols><cxy>27;16</cxy><cs>1</cs><bell>0</bell></head>
<body>Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 6.8.0-60-generic x86_64)<br/><br/> * Documentation: https://help.ubuntu.com<br/> * Management: https://landscape.canonical.com<br/> * Support: https://ubuntu.com/pro<br/><br/>Expanded Security Maintenance for Applications is not enabled.<br/><br/>88 updates can be applied immediately.<br/>4 of these updates are standard security updates.<br/>To see these additional updates run: apt list --upgradable<br/><br/>2 additional security updates can be applied with ESM Apps.<br/>Learn more about enabling ESM Apps service at https://ubuntu.com/esm<br/><br/>New release '24.04.2 LTS' available.<br/>Run 'do-release-upgrade' to upgrade to it.<br/><br/>Last login: Wed Jun 11 03:23:11 2025 from 192.168.152.1<br/><b><fc#4><bc#11>dyf@dyf-virtual-machine</bc></fc></b>:<b><fc#6><bc#11>~</bc></fc></b>$ <br/></body>
The basic structure of the page consists of the section and the section. The section has the following tags:
<head>
<seq>0</seq>
<rows>28</rows>
<cols>118</cols>
<cxy>27;16<cxy>
<cs>1</cs>
<bell>0</bell>
</head>
The meanings of each tag in are as follows:
- <seq> – Window sequence, this is an important concept and will be elaborated on later.
- <rows> – The number of rows on this page. Here, 28 indicates that the terminal window has a height of 28 lines of text.
- <cols> – The number of columns on this page. Here, 118 indicates that the terminal window has a width of 118 columns of text.
- <cxy> – The row and column positions of the cursor (value range: 0; 0 ~ cols; rows). The 27;16 indicates that the cursor is in row 17 of column 28.
- <cs> – Whether the cursor is displayed or not, 1 indicates the cursor is displayed, and 0 indicates the cursor is not displayed. When the terminal executes some commands (such as top), the cursor is not displayed.
- <bell> – Whether it rings or not, 1 rings, 0 doesn’t ring. A ring is usually an alert reminder from an SSH terminal. For instance, when editing via vim, if you want to move the cursor from the beginning of a line to the left, a ring will ring as a prompt.
The meanings of each tag in are as follows (except for <br/>, all other tags appear in pairs) :
- <br/> – line feed
- <b> – Bold
- <u> – Underline
- <fc> – Foreground color. For example, in <fc#3>, #3 is the color code (the colors represented by the color code are different under different color schemes)
- <bc> – Background color
- <f> – The words flicker.
- Escape symbol – Because it is a label description, if the characters ‘<‘ or ‘>’ appear in the text, the core module converts them to ‘<’ or ‘>’, this is the same as the conversion of html.
Suitable for interaction via HTTP
When commands such as ping or top are executed, new content is constantly output. This new content generated by the server needs to be fed back to the terminal interface in real time. However, the http protocol does not support this “push” interaction method. Therefore, the core module is also responsible for converting the two-way communication mode into a question-and-answer communication mode suitable for the http protocol.
The interface cache is maintained inside the core module. The latest interface information generated by the Linux server is first saved in the cache. When the terminal interface requests the information, it is returned to the terminal interface. See the following figure:

Question-and-answer conforms to the http communication method, but it is necessary to promptly feedback changes in the interface content. The frequency of question-and-answer should be high. Such high-frequency polling may result in a large amount of “junk” information transmission because in most cases, the page content does not change. The tag is used to solve this problem: In the core module, the change of this seq value will be recorded. Whenever the page content in the buf changes, the seq value will increase.
When the interface terminal sends a request to the core module, it will be accompanied by a seq parameter. If the request parameter seq is consistent with the seq recorded by the core module, it indicates that there is no change in the interface. Different values indicate that there is new content in the interface. The information returned by the core module contains the latest seq. The interface terminal will record the update of seq and use the updated seq parameters in the next request.
If the requested seq is the same as that of the core module (the interface content remains unchanged), the core module only returns a simple structural information:
<head><seq>1</seq></head>
At this point, the returned interface information does not contain <body>, and there is only one tag <seq> in <head>. Such a structure can reduce the pressure on network transmission during polling.
The important interfaces provided by the core module
1. Create a session
- Parameters — Linux server address, SSH service port, account, password
- Return — session id
- Description — This interface is used to create a secure SSH connection between the core module and the Linux server and to verify user login. If the execution is successful, return the session id representing this SSH session; if it fails, return an error message.
2. Create a shell channel
- Parameters — session id, window character width, window character height
- Return — Channel Number
- Description — In the SSH protocol, after a session is created, several channels can be created within this session. Each channel can run one type of application. Here, a shell application channel is created, and the parameters include the width and height of the terminal window.
3. Close the shell channel
- Parameters — session id, Channel Number
4. Close the session
- Parameters — session id
5. Input
- Parameters — session id, Channel Number, text or instructions input via the keyboard
- Description — The information input by the user in the SSH terminal program. includes: text input via the keyboard, control for operating the cursor, and function Key signals such as ctrl+Key
6. Output
- Parameters — session id, Channel Number
- Return — The page information of the tag structure constructed by <head> and <body>.
- Description — This interface requires continuous calls (polling) from the terminal interface program.
7. Window scrolling
- Parameters — session id, Channel Number, Number of rolling lines
- Description — Control the movement of the window view on the core module buffer.
8. Change of window size
- Parameters — session id, Channel Number, window character width, window character height
- Description — Changes in the size of the terminal window or the font size will cause variations in the width and height of the window characters. The core module needs to recalculate the content display of the window view according to the new window size.
Precautions for developing terminal window programs
The core module encapsulates a large number of logical details, making the development of terminal window programs much easier. However, SSH terminals do have their complexity after all, and attention still needs to be paid during development:
1. Due to the habit of using SSH shell in daily life, the cursor input and display are mixed together. Many people think that the entire shell window is just a large text editing box, which is a wrong understanding. The SSH shell program is what we call a pseudo-terminal. The history of terminals can be traced back to the 1970s and 1980s. Whether it is a terminal or a pseudo-terminal, an important point is that input and output are separate, as shown in the following figure:

The left picture shows a traditional terminal. The information sent by the keyboard is converted in the terminal and directly sent to the computer host. The screen receives the information sent by the host and displays it. Note the key point: Keyboard output is not directly printed on the screen. The right picture shows the SSH pseudo-terminal. Similarly, the information input through the keyboard is directly sent to the remote Linux host, and all the information displayed on the screen is sent from the remote host.
Therefore, the screen display is read-only. Although it seems that there is an input cursor flashing on the screen, in fact, no matter how the text is displayed or where the cursor flashes, it is controlled by the information and instructions sent from the remote host.
2. The text output and layout of the screen are calculated by the core module, and the text width and height of the terminal window are the necessary parameters for the calculation. The width and height are influenced by the window size of the terminal, the selected font, and the font size. Therefore, any changes in the terminal window, such as alterations in window size caused by mouse dragging or changes in font size, should be promptly notified to the core module of the changes in window width and height. The window width and height here are not the pixel width and pixel height. The terminal window program needs to calculate how many rows and columns of the current characters can be accommodated under the current window size.
When displaying text, the following points should also be noted: 1. Use equal-width fonts. 2. Each English or numeric character occupies one column, while each Chinese character and other East Asian characters occupy two columns.
Which characters occupy two columns? How to judge? Please refer to OnTheSSH Terminal V1.6 (Qt source code) shell/util.cpp
3. The input text generated by the keyboard is sent to the core module in ACSII or Unicode codes, and these texts do not require special consideration in programming. However, some control commands required by SSH, such as cursor movement, Home, End, Backspace and other function keys, as well as Ctrl+Key and other function keys, have special command encodings in the SSH shell.
The instruction encoding can refer to OnTheSSH Terminal V1.6 (Qt source code) shell/inputkeys.cpp. In fact, the control sequence of SSH shell encodes these function keys more complex. The core module encapsulates and simplifies these encodings.
One more point to note: The Tab key is a command completion instruction in the shell, but in window programs, it is generally used to switch the focus. When programming, the focus switching function needs to be disabled and only the ‘\t’ encoding should be sent.