简介
通常情况下,你使用终端中的命令行程序或包含 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的登录页面。
提供你的常规SSH凭证。如果你遵循DigitalOcean的初始服务器设置指南,你将使用基于密钥的认证而不是密码。这意味着你只需要指定你要连接的服务器的Hostname
,你的服务器的Username
,以及你的SSH密钥,它应该位于你的本地主目录下的.ssh/
(通常名为id_rsa
)。
**注意:**正如你可能从必须手动指定一个主机名中猜到的那样,WebSSH也可以用来连接到它所运行的服务器以外的服务器。在本教程中,它是在你所连接的同一台服务器上运行的。
点击 "连接"按钮,你应该会看到默认的终端欢迎提示。
在这一点上,你可以正常地使用你的终端,就像你通过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.pem
和privkey.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来说尤其重要,因为它的安全依赖于密钥对。