如何使用Python WebSSH从你的浏览器连接到一个终端

616 阅读11分钟

简介

通常情况下,你使用终端中的命令行程序或包含 SSH 客户端的终端仿真软件连接到 SSH 服务器。一些工具,如Python的WebSSH,使得通过SSH连接并直接在你的Web浏览器中运行一个终端成为可能。

这在很多情况下都很有用。它对现场演示或示范特别有帮助,因为在这种情况下,以一种有视觉意义的方式共享一个普通的终端窗口是很困难的。在教育环境中,当授予命令行新手访问权时,它也很有帮助,因为它避免了他们需要在机器上安装软件(特别是在Windows上,那里的默认选项是有注意事项的)。最后,Python的WebSSH尤其具有很好的可移植性,除了Python之外,不需要其他依赖性就可以启动和运行。其他基于网络的终端堆栈可能要复杂得多,而且是针对Linux的。

在本教程中,你将设置WebSSH并在浏览器中通过SSH连接。然后,你将选择用SSL证书保护它,并在Nginx反向代理后面运行它,以进行生产部署。

前提条件

  • 有一个运行SSH服务的Windows、Mac或Linux环境。在本地运行WebSSH可能很有用,但如果你没有在本地机器上运行SSH服务,你可以使用远程Linux服务器。

  • Python编程语言与pip ,其软件包管理器一起安装。

  • 另外,为了在浏览器中启用HTTPS,你需要SSL证书和自己的域名。

第一步 - 安装WebSSH

如果你已经安装了Python和pip,你应该能够从PyPI,即Python软件库中安装Python包。WebSSH 被设计成可以直接从命令行中安装和运行,所以你不需要像《如何安装 Python 3 和设置编程环境》中讨论的那样设置另一个虚拟环境。虚拟环境在处理你自己的项目时更有用,而不是在安装全系统工具时。

使用pip install 来安装 WebSSH 包。

sudo pip3 install webssh
Output

Successfully built webssh
Installing collected packages: tornado, pycparser, cffi, pynacl, paramiko, webssh
Successfully installed cffi-1.15.1 paramiko-2.11.0 pycparser-2.21 pynacl-1.5.0 tornado-6.2 webssh-1.6.0

通过sudo 安装将在全局安装wssh 命令。你可以通过使用which wssh 来验证这一点。

which wssh
Output
/usr/local/bin/wssh

现在你已经安装了WebSSH。在下一步,你将运行并连接到它。不过,首先,你需要添加一个防火墙规则。WebSSH默认运行在端口8888上。如果你使用ufw 作为防火墙,allow 该端口通过ufw

sudo ufw allow 8888

你将在本教程的后面重新审视该防火墙规则。

第2步 - 运行并连接到WebSSH

如果你在本地机器上运行WebSSH,你可以自己运行wssh ,不需要额外的参数来启动。如果你在远程服务器上运行WebSSH,你需要添加--fbidhttp=False 标志以允许通过普通的HTTP进行远程连接。如果你通过一个不受保护的网络进行连接,这并不安全,但对于一个演示来说是很有用的,而且你将在本教程的后面保护WebSSH。

wssh --fbidhttp=False

现在你可以连接到WebSSH并登录了。在网页浏览器中导航到 your_domain:8888(如果你在本地运行,用localhost 来代替你的域名)。你会看到WebSSH的登录页面。

WebSSH login page

提供你的常规SSH凭证。如果你遵循DigitalOcean的初始服务器设置指南,你将使用基于密钥的认证而不是密码。这意味着你只需要指定你要连接的服务器的Hostname ,你的服务器的Username ,以及你的SSH密钥,它应该位于你的本地主目录下的.ssh/ (通常名为id_rsa )。

**注意:**正如你可能从必须手动指定一个主机名中猜到的那样,WebSSH也可以用来连接到它所运行的服务器以外的服务器。在本教程中,它是在你所连接的同一台服务器上运行的。

点击 "连接"按钮,你应该会看到默认的终端欢迎提示。

WebSSH command line

在这一点上,你可以正常地使用你的终端,就像你通过SSH连接一样。多个用户也可以同时通过同一个WebSSH实例进行连接。如果你在本地机器上运行WebSSH只是为了流媒体或捕捉视频,这可能就是你所需要的。你可以在启动WebSSH的终端(而不是WebSSH终端)中输入Ctrl+C ,在完成后停止WebSSH服务器。

如果你在一个远程服务器上运行,你不会想在一个不安全的HTTP连接后面的生产中使用WebSSH。虽然你仍然会受到SSH服务认证机制的保护,但在HTTP上使用SSH连接会带来很大的安全风险,而且很可能会让其他人窃取你的SSH凭证。在接下来的步骤中,你将保护你的WebSSH实例,使其不比普通的SSH连接更安全。

第3步 - (可选)用SSL证书保护WebSSH

要完成这一步,你应该已经获得了自己的域名和SSL证书。一种方法是在独立模式下使用LetsEncrypt

当LetsEncrypt检索证书时,默认情况下,它将其存储在 /etc/letsencrypt/live/your_domain.检查以确保你有这些证书。

sudo ls /etc/letsencrypt/live/your_domain
Output
README  cert.pem  chain.pem  fullchain.pem  privkey.pem

要运行支持HTTPS的WebSSH,你需要提供一个证书的路径,以及一个密钥的路径。这些是fullchain.pemprivkey.pem 。默认情况下,WebSSH在4433端口提供HTTPS访问,因此也要在防火墙中打开该端口。

sudo ufw allow 4433

接下来,你需要允许

然后,用你的证书和钥匙的路径运行WebSSH。

sudo wssh --certfile='/etc/letsencrypt/live/your_domain/fullchain.pem' --keyfile='/etc/letsencrypt/live/your_domain/privkey.pem'

在一个网页浏览器中,导航到 https://your_domain:4433,你应该看到与上一步相同的界面,现在支持HTTPS了。现在,这已经是一个安全生产配置的足够设置。然而,你仍然直接从你的终端运行wssh 应用程序,并且你从一个不寻常的端口在浏览器中访问它。在本教程的最后两步,你将消除这两个限制。

步骤4 - (可选)在Nginx反向代理后面运行WebSSH

将Nginx这样的Web服务器放在其他面向Web的应用程序前面,可以提高性能,并使网站的安全更直接。你将安装Nginx并将其配置为 反向代理请求到WebSSH,这意味着它将负责处理从用户到WebSSH的请求,然后再返回。

刷新你的软件包列表,然后使用apt 安装Nginx。

sudo apt update nginx
sudo apt install nginx

如果你使用的是ufw 防火墙,在这一点上,你应该对防火墙配置做一些修改,以便能够访问默认的HTTP/HTTPS端口,80和443。ufw 有一个名为 "Nginx Full "的库存配置,它提供了对这两个端口的访问。

sudo ufw allow “Nginx Full

Nginx允许你在一个名为sites-available/ 的子目录中添加每个站点的配置。使用nano 或你喜欢的文本编辑器,在/etc/nginx/sites-available/webssh 创建一个新的Nginx配置。

sudo nano /etc/nginx/sites-available/webssh

将以下内容粘贴到新的配置文件中,确保将 your_domain替换成你的域名。

/etc/nginx/sites-available/webssh

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name your_domain www.your_domain
    root /var/www/html;

    access_log /var/log/nginx/webssh.access.log;
    error_log /var/log/nginx/webssh.error.log;

    location / {
        proxy_pass http://127.0.0.1:8888;
        proxy_http_version 1.1;
        proxy_read_timeout 300;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Real-PORT $remote_port;
    }

    listen 443 ssl;
    # RSA certificate
    ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

    # Redirect non-https traffic to https
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

你可以把这个配置理解为有三个主要的 "块"。第一个区块,在location / 行之前,包含一个Nginx的模板配置,用于在默认的HTTP端口80上为网站提供服务。location / 块包含一个配置,用于将传入的连接代理给WebSSH,在内部运行于8888端口,同时保留了SSL。文件末尾的配置,在location / 块之后,加载你的LetsEncrypt SSL密钥对并将HTTP连接重定向到HTTPS。

保存并关闭该文件。如果你使用的是nano ,按Ctrl+X ,然后在提示下按Y ,然后回车。

接下来,你需要激活这个新配置。Nginx的惯例是,在你决定启用或禁用时,从sites-available/ 中的文件创建符号链接(像快捷方式)到另一个名为sites-enabled/ 的文件夹。为了清楚起见,使用全路径,建立这个链接。

sudo ln -s /etc/nginx/sites-available/webssh /etc/nginx/sites-enabled/webssh

默认情况下,Nginx包含另一个配置文件,位于/etc/nginx/sites-available/default ,链接到/etc/nginx/sites-enabled/default ,该文件也提供默认的索引页。你要从/sites-enabled ,禁用该规则,因为它与新的WebSSH配置冲突。

sudo rm /etc/nginx/sites-enabled/default

注意:本教程中的Nginx配置是为单个应用程序(WebSSH)服务的。你可以按照Nginx的文档,扩展这个Nginx配置,在同一台服务器上为多个应用程序服务。

接下来,在重启Nginx之前,运行nginx -t 来验证你的配置。

sudo nginx -t
Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

现在你可以重启Nginx服务,这样它就会反映你的新配置。

sudo systemctl restart nginx

最后,你可以删除之前创建的直接访问WebSSH的防火墙规则,因为现在所有的流量都将由Nginx通过标准的HTTP/HTTPS端口处理。

sudo ufw delete allow 8888
sudo ufw delete allow 4433

在命令行中重新启动webssh

wssh

这次你不需要提供证书和密钥的路径,因为Nginx正在处理。然后在网页浏览器中导航到你的域名。

注意,WebSSH现在通过Nginx提供HTTPS服务,不需要指定端口。在这一点上,除了启动wssh 本身,你已经自动完成了所有工作。你将在最后一步做这个。

第5步 - (可选)为WebSSH创建一个Systemd服务

部署不在后台自动运行的服务器端应用程序,一开始可能并不直观,因为你每次都需要直接从命令行启动它们。解决这个问题的办法是建立你自己的后台服务。

要做到这一点,你将创建一个单元文件,可以被你的服务器的init系统使用。在几乎所有的现代Linux发行版上,init系统被称为Systemd,你可以通过使用systemctl 命令与它进行交互。

如果WebSSH仍然在你的终端中运行,请按Ctrl+C 来停止它。然后,使用nano 或你喜欢的文本编辑器,打开一个名为/etc/systemd/system/webssh.service 的新文件。

sudo nano /etc/systemd/system/webssh.service

你的单元文件至少需要一个[Unit] 部分、一个[Service] 部分和一个[Install] 部分。

/etc/systemd/system/webssh.service

[Unit]
Description=WebSSH terminal interface
After=network.target

[Service]
User=www-data
Group=www-data
ExecStart=wssh

[Install]
WantedBy=multi-user.target

这个文件可以分解为以下几个部分。

  • [Unit] 部分包含对新服务的纯文本描述,以及一个After 钩子,该钩子指定了系统启动时的运行时间,本例中是在服务器的网络接口启动后。

  • [Service] 部分指定了实际应该运行的命令,以及应该由哪个用户来运行它。在本例中,www-data 是Ubuntu服务器上的默认Nginx用户,wssh 是该命令本身。

  • [Install] 部分只包含WantedBy=multi-user.target 一行,它与[Unit] 部分的After 一行一起工作,确保在服务器准备接受用户登录时启动服务。

保存并关闭该文件。现在你可以start 你新的WebSSH服务,并enable ,使其在启动时自动运行。

sudo systemctl start webssh
sudo systemctl enable webssh

使用systemctl status webssh 来验证它是否成功启动。你应该收到与你第一次在终端运行该命令时类似的输出。

sudo systemctl status webssh
Output
 webssh.service - WebSSH terminal interface
     Loaded: loaded (/etc/systemd/system/webssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-08-11 22:08:25 UTC; 2s ago
   Main PID: 15678 (wssh)
      Tasks: 1 (limit: 1119)
     Memory: 20.2M
        CPU: 300ms
     CGroup: /system.slice/webssh.service
             └─15678 /usr/bin/python3 /usr/local/bin/wssh

Aug 11 22:08:25 webssh22 systemd[1]: Started WebSSH terminal interface.
Aug 11 22:08:26 webssh22 wssh[15678]: [I 220811 22:08:26 settings:125] WarningPolicy
Aug 11 22:08:26 webssh22 wssh[15678]: [I 220811 22:08:26 main:38] Listening on :8888 (http)

现在你可以重新加载 https://your_domain浏览器,你应该再次得到WebSSH界面。从现在开始,WebSSH和Nginx将自动与你的服务器一起重启,并在后台运行。

总结

在本教程中,你安装了WebSSH,这是一个在Web浏览器中提供命令行界面的便携解决方案。通过添加SSL,然后添加Nginx反向代理,最后为WebSSH创建一个系统服务,改进了你的部署。这是部署小型服务器端Web应用程序的一个很好的模式,对于SSH来说尤其重要,因为它的安全依赖于密钥对。