:: krowemoh

Thursday | 26 DEC 2024
Posts Links Other About Now

previous
next

Using ScarletDME from the Web

2024-08-10

This post goes over connecting a server terminal to the web.

Preamble

I'm a big fan of consoles and having to build a web frontend to do data entry for a hobby project is way too much for me. I'd prefer to make a console application and ideally it's a command line application that takes data through flags. Think of something like the mail command where you can specify the subject, body and various other parts of an e-mail.

However, I need to be able to use these things I want to make from any computer and my phone. For example a project I'm currently working on is to build a calendar. I want to build a little calendar CLI which I can whip together in a couple hours but then trying to make accessible from everywhere is the pain in the ass. I was thinking about building a whole web app to do it.

Instead, I'm going to try an experiment. I'm going to expose a terminal over the web that is sitting on my server. It will just be a connection directly into ScalretDME sitting at TCL. I can then use my CLI tools immediately and I still have the option of making prettier GUIs if I need to.

This is going to use a couple different things and the set up is a bit involved but I'm looking forward to how this shakes out.

Requirements

You will need a few things:

nginx

gotty

I'm using my fork of ScarletDME which requires Zig and mbedtls.

scarletdme

Nginx is the reverse proxy, this simplifies the SSL set up. You can use gotty with SSL directly but this is what I'm more comfortable with. I use gotty in plaintext and nginx will be the ssl terminator.

gotty is a tool written in golang that exposes a terminal or terminal application on the server over the web. By default gotty will run on port 8080.

ScarletDME is a pick database and I'm using a fork that I am developing specifically. The general idea of the instructions though will work anything.

Installation

Installing the various requirements.

Nginx

This is straightforward as your package manager should have everything.

yum install nginx

gotty

Get the gotty binary friom the latest releases

wget https://github.com/sorenisanerd/gotty/releases/download/v1.5.0/gotty_v1.5.0_linux_amd64.tar.gz
tar xvf gotty_v1.5.0_linux_amd64.tar.gz 

Once downloaded and extracted, we can place the file in the right place:

mv gotty /usr/local/bin

You should now be able to use gotty:

gotty -version

outputs:

gotty version v1.5.0

ScarletDME

We're going to install my version of ScarletDME which requires Zig and mbedtls.

git clone https://github.com/Krowemoh/ScarletDME.git
cd ScarletDME
zig build
sudo utils/install.sh

Once ScarletDME is installed, create an account and set it all up how you like.

Configuration

Now for the configuration of setting up nginx and gotty to expose ScarletDME to the world wide web.

Nginx

We'll start on the nginx side.

Update /etc/nginx/conf.d/default.conf with the following:

server {
    server_name example.org;
    root /home/username/example.org;
    
    listen 443 ssl; 
    # SSL stuff managed by certbot is here
    
    location /tty/ {
	   proxy_set_header X-Real-IP $remote_addr;
	   proxy_set_header X-Forwarded-For $remote_addr;
	   proxy_set_header Host $host;
	   rewrite ^/tty/?$ / break;
	   rewrite ^/tty/(.*)$ /$1 break;
	   proxy_pass http://127.0.0.1:9100;
	   proxy_http_version 1.1;
	   proxy_set_header Upgrade $http_upgrade;
	   proxy_set_header Connection "upgrade";
    }
}

Make sure to use SSL as that's the whole point of using nginx here. I use letsencrypt via certbot to create certificates.

The core logic is that the /tty endpoint will pass through all data to the application running on port 9100. This is going to be where gotty runs.

Once the nginx configuration is done, restart nginx.

service nginx restart

gotty

Once we have gotty, we need to create a configuration file for it and a systemd unit file so that it starts up automatically with the right user.

The configuration for gotty is located at ~/.gotty and needs to have the following:

port = "9100"
permit_write = true
enable_basic_auth = true
credential = "username:password"
title_format = "tty at example.org"

This configuration changes the port gotty runs on to 9100. It also allows the tty to take input as the default is that nothing is sent back to the terminal through gotty.

We also enable basic auth here and set up the credentials for it. By using SSL, this is secure as the headers for basic authentication will be encrypted. If we didn't have nginx in front, using gotty with basic auth without certificates would be dangerous.

I also added a custom title for the gotty tab so that it's obvious what it is when I have it open in the browser.

Now for the systemd file, this will need to be created at: /etc/systemd/system/gotty.service:

[Unit]
Description=GoTTY Web Terminal
After=network.target

[Service]
User=username
Group=username
Environment="TERMINAL_EMULATOR=putty"
WorkingDirectory=/home/username/SYSPROG
ExecStart=/usr/local/bin/gotty qm "NSH"

[Install]
WantedBy=multi-user.target

This will create a unit file that will run gotty calling qm. I'm executing a BASIC program called NSH as well. This is also why I have the TERMINAL_EMULATOR variable getting set as I need it for NSH.

Once this file is created, we can then use systemctl to manage gotty.

systemctl enable gotty.service
systemctl start gotty.service

If everything worked, then we should be able to go to example.org/tty and see an instance of ScarletDME running ready to go!

Conclusion

I'll need to come back after actually using this for awhile to see how I feel. Mobile is probably going to still be a problem but one that I could work around. I definitely am excited to start using the CLI tools from the web and see if this results in my creating more one offs. Half the reason I don't start things is because to make something available everywhere really does require web stuff. This sort of hacks around that problem.

Other Art

You can use gotty with tmux so you can have multiple people connect to different things using one gotty instance:

https://jpmens.net/2022/05/03/one-gotty-per-user/