有些時候開演練環境要進行教育訓練,需要有指令界面的操作。但別人不能用 ssh 連公司外部的 22 port,但可以連網頁。
這樣子得弄個中介跳板,不只用瀏覽器充當 Putty 功能,還要讓 22 port 的存取由跳板發動。而桌面電腦只有用瀏覽器連接網頁,不涉及直接連線 22 Port。
這樣子得弄個中介跳板,不只用瀏覽器充當 Putty 功能,還要讓 22 port 的存取由跳板發動。而桌面電腦只有用瀏覽器連接網頁,不涉及直接連線 22 Port。
這邊是一款挖到一個 Python 的怪怪工具~webssh
使用方式:用這個 python 寫的瀏覽器程式,訪問內網網路的 22 port。
外網單一跳板搭配 self-signed SSL 憑證開連結讓瀏覽器連接。
這樣子就不是從外網直接存取 22 port,而是透過網頁操作,實際上的 22 port 連線只發生在內網網路中。
這邊在 GCP 上設置。並預計以外網 IP 上用網頁連線,在於網頁工具內以內網 IP 連線其他環境。
使用方式:用這個 python 寫的瀏覽器程式,訪問內網網路的 22 port。
外網單一跳板搭配 self-signed SSL 憑證開連結讓瀏覽器連接。
這樣子就不是從外網直接存取 22 port,而是透過網頁操作,實際上的 22 port 連線只發生在內網網路中。
這邊在 GCP 上設置。並預計以外網 IP 上用網頁連線,在於網頁工具內以內網 IP 連線其他環境。
GCP 雲端環境前置步驟
現在的雲端環境比較精細,會切割 VPC,我還不太會,直接使用 default VPC。
但是 default VPC 為了方便測試(紀錄年度:2023~2024),防火牆規則允許了有點寬鬆的規則:允許外網可以連 SSH。
不過各大公有雲的 Cloud Console 還會有網頁版 SSH 功能,在 GCP 稱作 Identity-Aware Proxy。不過這對 VPC 來說也是外部網路,因此需要有 SSH port 允許規則。
為了避免不必要的麻煩(被駭會噴摳摳還有來自咕狗的警告信),這邊筆記一下
- 關掉這條 SSH 全開的規則:可以不用刪掉,用停用的就好。
- 開通針對 IAP 的規則,照著這邊作就可以了:Using IAP for TCP forwarding | Identity-Aware Proxy | Google Cloud
接著就開一個 VM,並且準備一個帳號,避免用 root OS 帳號啟動這程式。就算只是測試環境,被跳板還是有法律責任ㄉ。。所以可以多想到的就多準備一點。
Note:通常雲端 SSH 會用登入雲端的帳號(信箱)作為 sudoer 進入 VM,這邊方便紀錄,切換到 root 底下執行。
[root@web-based-ssh ~]# groupadd webssh
[root@web-based-ssh ~]# useradd webssh -g webssh
還有把 SSH 的密碼登入開啟
[root@web-based-ssh ~]# sed -e 's/^PasswordAuthentication=.*/PasswordAuthentication=yes/g' -i /etc/ssh/sshd_config [root@web-based-ssh ~]# service sshd restart [root@web-based-ssh ~]#
準備 Self-Signed SSL 憑證
因為需要在網路上奔跑,還是要用悄悄話溝通。
自己當 CA 單位:就是作莊的意思ㄅ~用藍字代表
[webssh@web-based-ssh ~]$ mkdir root
[webssh@web-based-ssh ~]$ openssl genrsa -out root/ca.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
..........................................................................................++++
...............................................................................................................................................................................................................................++++
e is 65537 (0x010001)
[webssh@web-based-ssh ~]$ ls root/
ca.key
[webssh@web-based-ssh ~]$
頒發一個憑證給自己的 CA 單位~恭喜
[webssh@web-based-ssh ~]$ openssl req -new -x509 -days 365 -sha256 \ -subj "/C=TW/ST=Taipei/O=your_company/OU=your_department/CN=localhost" \ -key ./root/ca.key \ -out ./root/ca.crt [webssh@web-based-ssh ~]$ ls root/ ca.crt ca.key [webssh@web-based-ssh ~]$
長一個「這台電腦」的憑證金鑰,這步驟其實跟第一條一樣,只是一人分飾二角
[webssh@web-based-ssh ~]$ mkdir server [webssh@web-based-ssh ~]$ openssl genrsa -out server/server.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) .......................................................+++++ ............+++++ e is 65537 (0x010001) [webssh@web-based-ssh ~]$
長一個「這台電腦」要拿給 CA 單位加持的 CSR 符咒~(或許應該說要拿去祭改拜拜的衣服~)
[webssh@web-based-ssh ~]$ openssl req -new -key ./server/server.key \
-subj "/C=TW/ST=Taipei/O=your_company/OU=your_department/CN=$(hostname -f)" \
-out ./server/server.csr
[webssh@web-based-ssh ~]$ ls server/
server.csr server.key
[webssh@web-based-ssh ~]$
把「這台電腦」的 CSR 符咒,交給自以為的 CA 單位簽署(加持),順利孵出一張憑證
[webssh@web-based-ssh ~]$ openssl x509 -req -CAcreateserial -days 300 -sha256 \
-CA ./root/ca.crt -CAkey ./root/ca.key \
-in ./server/server.csr \
-out ./server/server.crt
Certificate request self-signature ok
subject=C = TW, ST = Taipei, O = your_company, OU = your_department, CN = webssh-based-ssh.c.gcp-project-name-1327.internal
Getting CA Private Key
[webssh@web-based-ssh ~]$
最後可以使用的憑證在這邊。
[webssh@web-based-ssh ~]$ ls server/ server.crt server.csr server.key [webssh@web-based-ssh ~]$
設置 WebSSH 程式
如之前的習慣,這邊以 python venv 來準備環境。
[root@web-based-ssh ~]# mkdir -p /opt/webssh [root@web-based-ssh ~]# chown -R webssh. /opt/webssh [root@web-based-ssh ~]# su - webssh [webssh@web-based-ssh ~]$ python3 -m venv /opt/websshpython3 -m venv /opt/webssh [webssh@web-based-ssh ~]$ ls /opt/webssh/ bin include lib lib64 pyvenv.cfg [webssh@web-based-ssh ~]$
進入 venv 後,安裝這東西
[webssh@web-based-ssh ~]$ source /opt/webssh/bin/activate (webssh) [webssh@web-based-ssh ~]$ pip3 install webssh Collecting webssh Downloading webssh-1.6.2.tar.gz (182 kB) |████████████████████████████████| 182 kB 1.3 MB/s Collecting tornado>=4.5.0 Downloading tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (435 kB) |████████████████████████████████| 435 kB 12.5 MB/s Collecting paramiko>=2.3.1 Downloading paramiko-3.4.0-py3-none-any.whl (225 kB) |████████████████████████████████| 225 kB 50.4 MB/s Collecting pynacl>=1.5 Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) |████████████████████████████████| 856 kB 49.4 MB/s Collecting bcrypt>=3.2 Downloading bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl (698 kB) |████████████████████████████████| 698 kB 31.5 MB/s Collecting cryptography>=3.3 Downloading cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl (4.4 MB) |████████████████████████████████| 4.4 MB 28.6 MB/s Collecting cffi>=1.12 Downloading cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (443 kB) |████████████████████████████████| 443 kB 28.5 MB/s Collecting pycparser Downloading pycparser-2.21-py2.py3-none-any.whl (118 kB) |████████████████████████████████| 118 kB 32.8 MB/s Using legacy 'setup.py install' for webssh, since package 'wheel' is not installed. Installing collected packages: pycparser, cffi, pynacl, cryptography, bcrypt, tornado, paramiko, webssh Running setup.py install for webssh ... done Successfully installed bcrypt-4.1.2 cffi-1.16.0 cryptography-41.0.7 paramiko-3.4.0 pycparser-2.21 pynacl-1.5.0 tornado-6.4 webssh-1.6.2 WARNING: You are using pip version 21.2.3; however, version 23.3.2 is available. You should consider upgrading via the '/opt/webssh/bin/python3 -m pip install --upgrade pip' command. (webssh) [webssh@web-based-ssh ~]$ (webssh) [webssh@web-based-ssh ~]$ pip3 list Package Version ------------ ------- bcrypt 4.1.1 cffi 1.16.0 cryptography 41.0.7 paramiko 3.3.1 pip 21.2.3 pycparser 2.21 PyNaCl 1.5.0 setuptools 53.0.0 tornado 6.4 webssh 1.6.2 WARNING: You are using pip version 21.2.3; however, version 23.3.2 is available. You should consider upgrading via the '/opt/webssh/bin/python3 -m pip install --upgrade pip' command. (webssh) [webssh@web-based-ssh ~]$
簡易啟動 webssh 程式:這會是一個 web service,可以看到會一直吐 log
這邊搭配剛剛自己作莊的 Self-Signed SSL 憑證服用。
(webssh) [webssh@web-based-ssh ~]$ wssh --help Usage: /opt/webssh/bin/wssh [OPTIONS] Options: --help show this help information /opt/webssh/lib64/python3.9/site-packages/tornado/log.py options: --log-file-max-size max size of log files before rollover (default 100000000) --log-file-num-backups number of log files to keep (default 10) --log-file-prefix=PATH Path prefix for log files. Note that if you are running multiple tornado processes, log_file_prefix must be different for each of them (e.g. include the port number) --log-rotate-interval The interval value of timed rotating (default 1) --log-rotate-mode The mode of rotating files(time or size) (default size) --log-rotate-when specify the type of TimedRotatingFileHandler interval other options:('S', 'M', 'H', 'D', 'W0'-'W6') (default midnight) --log-to-stderr Send log output to stderr (colorized if possible). By default use stderr if --log_file_prefix is not set and no other logging is configured. --logging=debug|info|warning|error|none Set the Python log level. If 'none', tornado won't touch the logging configuration. (default info) /opt/webssh/lib64/python3.9/site-packages/webssh/settings.py options: --address Listen address --certfile SSL certificate file --debug Debug mode (default False) --delay The delay to call recycle_worker (default 3) --encoding The default character encoding of ssh servers. Example: --encoding='utf-8' to solve the problem with some switches&routers --fbidhttp Forbid public plain http incoming requests (default True) --font custom font filename --hostfile User defined host keys file --keyfile SSL private key file --maxconn Maximum live connections (ssh sessions) per client (default 20) --origin Origin policy, 'same': same origin policy, matches host name and port number; 'primary': primary domain policy, matches primary domain only; '<domains>': custom domains policy, matches any domain in the <domains> list separated by comma; '*': wildcard policy, matches any domain, allowed in debug mode only. (default same) --policy Missing host key policy, reject|autoadd|warning (default warning) --port Listen port (default 8888) --redirect Redirecting http to https (default True) --ssladdress SSL listen address --sslport SSL listen port (default 4433) --syshostfile System wide host keys file --tdstream Trusted downstream, separated by comma --timeout SSH connection timeout (default 3) --version Show version information --wpintvl Websocket ping interval (default 0) --xheaders Support xheaders (default True) --xsrf CSRF protection (default True) (webssh) [webssh@web-based-ssh ~]$
[webssh@web-based-ssh ~]$ source /opt/webssh/bin/activate
(webssh) [webssh@web-based-ssh ~]$ wssh --address=$(hostname -i) --port=8080 --sslport=8443 --certfile='./server/server.crt' --keyfile='./server/server.key'
[I 240110 08:14:17 settings:125] WarningPolicy
[I 240110 08:14:17 main:38] Listening on 10.128.0.16:8080 (http)
[I 240110 08:14:17 main:38] Listening on :8443 (https)
連接進去長這樣,這樣就能打內網帳密登入了
設置成 SystemD 啟動檔。
# /etc/systemd/system/webssh-1.6.2.service [Unit] Description=WebSSH, Web based ssh client After=syslog.target network.target [Service] Type=simple User=webssh Group=webssh Environment=SSLKEYPATH=/home/webssh/server ExecStart=/opt/webssh/bin/wssh --address=%H --port=8080 --sslport=8443 --certfile=${SSLKEYPATH}/server.crt --keyfile=${SSLKEYPATH}/server.key ExecStop=/bin/kill -- $MAINPID Restart=on-abnormal TimeoutSec=300 [Install] WantedBy=multi-user.target
這樣只要設定開機啟動就可以惹~
[root@web-based-ssh ~]# systemctl daemon-reload [root@web-based-ssh ~]# chkconfig webssh-1.6.2 on [root@web-based-ssh ~]# service webssh-1.6.2 start
參考資料
GitHub - huashengdun/webssh: :seedling: 🌱 Web based ssh client
这款 Web SSH 客户端工具超牛逼!爱了 - 知乎
How to Connect to a Terminal from Your Browser Using Python WebSSH | DigitalOcean
self-signed 憑證的教學:基本上都是看這篇的
[SSL] 自簽憑證過程| 薛惟仁筆記本
[SSL] 數位簽名與驗證的過程| 薛惟仁筆記本
SystemD 呼叫 Python venv 的程式
Using Systemd to Start a Python Application with Virtualenv
How to enable a virtualenv in a systemd service unit? - Stack Overflow
How to run a command inside a virtualenv using systemd - Unix & Linux Stack Exchange
How to write a custom systemctl Linux service for Python scripts with virtualenv and .env file | by R | Medium
SystemD unit file 取得 hostname 的方式
How to get the machine IP address in a “systemd” service file - Super User
沒有留言:
張貼留言