Login

Navigation

This articles is published 463 days ago and last updated 463 days ago, some information may be out of date.

Debian_Logo.png

pic from unsplash


0.0 前前言

這篇優秀的貼文我是轉載自uselibrary在Github,非常感謝原作者uselibrary.
同時感謝咕咕鸽該我看到你(原作者)的轉載及不問自取地放在自已BLog.

本文的首要目的是給予Linux初學者一個簡單、易學的教學,以便在看完本文後對Linux系統有一個基礎的認識(而非系統級的深入),可以對常見的軟體和功能進行組態,甚至可以自己寫一寫一鍵指令碼。

本教學寫於2021年下半年,採用的系統為Debian GNU/Linux 11 (bullseye)。

0 前言吐槽CentOS

解釋使用Debian而不是CentOS的原因

國內首批接觸Linux系統的人主要集中在科研院校,大多數是延續了Unix-like的背景,在千禧年前後才有了真正意義上的Linux使用者:純Linux平台開發、運行服務和應用,他們或直接或間接地推廣了Linux系統。紅帽(Red Hat, Inc.)在1994年就開始發佈了同名的作業系統:Red Hat Linux(後改組為Red Hat Enterprise Linux,縮寫為RHEL)。得益於紅帽優秀的團隊和商業支援,RHEL這一發行版迅速佔領了國內市場。彼時的國內電腦市場遠不如今日繁榮,在口口相傳和紅帽的推廣中,RHEL成為了Linux入門的主流選項,即使後來號稱使用者友好的Ubuntu出現了,絕大多數嘗鮮的人依然能看到眾多網站裡面只提供RHEL版本的教學。

CentOS是根據RHEL的原始碼重新編譯的,等於換商標版本的RHEL,軟體層面上,兩者無本質區別。但CentOS是反人類的,至少是反入門使用者的。使用RHEL的基本為商業使用者,可以付費獲得紅帽的技術支援,或者乾脆有一個自己的維護團隊;而CentOS作為一個社區自發形成的作業系統,擁有落後的軟體源/包,繁瑣的組態,和對個人使用者而言根本沒有必要的SElinux等。舉個例子,很多入門者修改SSH連接埠的時候,發現所有的操作都沒有問題,但是死活無法生效,最終發現是沒有在SElinux裡面放行。如果你想安裝個軟體,你就得考慮是從落後主流版本好幾代的軟體源/包裡面安裝,還是自己下載原始碼進行編譯以獲取主流的使用體驗。對於入門者而言,CentOS的安全性和穩定性是個虛假的概念,畢竟讓一個剛接觸Linux的人去自己編譯原始碼安裝,無異於讓小學生上戰場,輸了就說是小學生戰鬥力太弱。

所以本文以Debian GNU/Linux(後續簡稱為Debian)來演示,也有著推廣Debian的意思在裡面,畢竟相比於Ubuntu往系統裡面塞包括snap在內的一系列私貨而言,Debain始終遵循著一個純淨的Linux的要求。而其他一些發行版,要麼是專用性太強(如SUSE),要麼是入門者不友好(如 Arch Linux),權衡之後,選擇了寫本文時,最新的Debian系統,即Debian GNU/Linux 11 (bullseye)。

1 環境搭建

1.1 系統選擇與安裝

Debian的安裝包有一系列的前綴或者後綴,例如在默認的下載地址https://www.debian.org/download中的是debian-11.0.0-amd64-netinst.iso。其中,

  • 11代表大版本是11,代號是bullseye,各版本代號都來源於電影《玩具總動員》中的角色名稱;
  • amd64是指系統為64位的,i386或者x86是32位的,amd64或者x86-64是64位的,32位系統已經被逐步棄用,目前僅在特定行業中使用;
  • netinst是網路安裝版本,只是個安裝器,安裝過程需要聯網,而DVD後綴的是完整版(如:debian-11.0.0-amd64-DVD-1.iso),如果系統太大,會在DVD後面加數字,默認DVD-1是完整版本,其後數字的是軟體源/包;
  • 帶firmware前綴的是包含第三方非開放原始碼驅動程式的(如:firmware-11.1.0-amd64-DVD-1.iso),其中就包含intel和Realtek等公司的閉源網路卡驅動。

VPS全稱為virtual private server(虛擬專用伺服器),如果需要安裝純淨版的Debian 11系統,推薦使用vicer的Linux一鍵重裝指令碼(如下):

bash <(wget --no-check-certificate -qO- 'https://raw.githubusercontent.com/MoeClub/Note/master/InstallNET.sh') -d 11 -v 64 -p "自訂root密碼" -port "自訂ssh連接埠"

1.2 常用的命令

cat 用於查看文字檔的內容,如cat /etc/os-release 將顯示系統資訊,如下:

PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

touch 新建文字檔,如touch /home/hello.py 將在home 資料夾下新建一個Python檔案。

ls 列出所有檔案,但默認只是顯示出最基礎的檔案和資料夾,如果需要更詳細的資訊,則使用ls -la,這將列出包括隱藏檔案在內的所有檔案和資料夾,並且給出對應的權限、大小和日期等資訊。

cd 進入指定資料夾,如cd /home 將進入home目錄。返回上層目錄的命令是cd ..,返回剛才操作的目錄的命令是cd -

mkdir 新建資料夾,如mkdir /home/Python 將在home 資料夾下新建一個Python 資料夾。

mv 移動檔案和資料夾,也可以用來修改名稱,如mv /home/hello.py /home/helloworld.py 將上文的hello.py重新命名為helloworld.pymv /home/helloworld.py /home/Python/helloworld.pyhelloworld.pyhome資料夾移動到了次級的Python資料夾。

cp 複製檔案,cp /home/Python/hellowrold.py /home/Python/HelloWorld.pyhelloworld.py複製為HelloWolrd.py。注意:Linux系統嚴格區分大小寫,helloworld.pyHelloWolrd.py是兩個檔案。如果想複製整個資料夾,則需要帶r,即cp -r,但此命令無法複製隱藏資料夾,需要使用cp -r pathA/. pathB 注意這個點.是靈魂。

rm 刪除,即江湖傳說中rm -rfr為遞迴,可以刪除資料夾中的檔案,f為強制刪除。rm /home/Python/helloworld.py 可以刪除剛才的helloworld.py 檔案,而想刪除包括Python 在內的所有檔案,則是rm -rf /home/Python

du -lh 查看當前資料夾下,各檔案、資料夾的大小,l是永久連結(軟連接類似於快捷方式),h是讓檔案自動使用K/M/G顯示而不是只有K。

1.3 基礎文字編輯器nano、vim

Linux系統的一大優勢(同時也是劣勢)是默認不需要GUI,因此節省了大量的性能開支,無GUI版本的Debian 11可以在512M甚至更小記憶體的VPS上正常啟動和運行。但缺少GUI加大了入門者修改檔案的難度,所幸Debian 11自帶了簡便易用的nano文字編輯器。以下以修改系統的更新源為例

nano /etc/apt/sources.list #打開sources.list檔案,在Linux系統中,#是註釋符,其後的內容會被忽略

nano_ui

如圖所示,即為nano打開sources.list後的介面,最下面兩行為提示,比如Ctrl+E為退出,如果文件被改動了,則會出現下圖,詢問是否保存。如果沒有被更改,則會直接退出。

nano_ctrl_e

Y則保存,N則不保存,Ctrl+C取消操作。此處輸入Y,則會如下圖:

nano_yes.jpg

此時按下Enter鍵就會保存了。

這裡多提一句關於Debian 11的更新源內容,一般是以下6行。

deb http://deb.debian.org/debian bullseye main contrib non-free
deb-src http://deb.debian.org/debian bullseye main contrib non-free

deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib non-free

deb http://deb.debian.org/debian bullseye-updates main contrib non-free
deb-src http://deb.debian.org/debian bullseye-updates main contrib non-free

deb表示為已經編譯好的安裝包,類似於Windows上的MSI安裝包,deb-src是原始檔,萬一沒有打包好,提供自己本地編譯安裝的機會。總共分三大行,第一行是系統主檔案,第二行是安全性更新,第三個是一些更新補充,推薦三個都寫上。在每行的末尾都有main contrib non-free字樣,其中main是官方給的包/源,嚴格遵守相關開源協議;contrib是包/源本身遵守相關開源協議,但是它們的依賴則不是;non-free是私有的軟體,比如上文提到的Realtek的WiFi驅動等。除此之外,其實還有個Backports作為第四大行,是將比較陳舊的軟體移植過來的,很少會用到,一般默認不寫上。

nano雖然好,但是功能簡單,只適合一些簡單的文字檔編輯功能,而發展自vi的vim則被成為編輯器之神(Emacs被稱為神之編輯器,Linux之父Linus Torvalds就在用)。系統會自帶vi但是不帶vim,正好我們可以使用上述修改過的更新源來安裝vim作為示例。

apt update # 更新一下源
apt install vim -y #安裝vim這個軟體 -y是確認安裝

使用vim /etc/apt/sources.list打開更新原始檔,如下圖所示:

vim_ui

vim功能眾多,使用複雜,得慢慢說。左下角是此檔案的路徑和名稱,右下角是游標此時的行數和列數。此時是無法直接輸入,要先按下insert或者i鍵變成插入模式才行。此時,左下角如下圖,變成了INSERT/插入模式。

vim_s1

然後就是該怎麼寫就怎麼寫,一些快速鍵去百度Google必應吧,說的肯定比我詳細。但是必須提到如何保存檔案:insert模式下按esc鍵(一般是鍵盤最左上角,99%的人可能都不怎麼用的一個鍵),INSERT會消失不見,如下圖:

vim_s3

這個時候再按下:鍵,介面上也會出現一個冒號,如下圖。注意,這個冒號是半形的,全形冒號是沒用的。

vim_s2

這個時候,按下wq這兩個鍵,即可保存內容。w是write/寫入的意思,q是quit/退出的意思。如果你不想保存,則只輸入q鍵即可,但是有時候因為檔案已經被修改了,vim不讓退出,這時候輸入q!就可以了,驚嘆號是強制執行的意思,執行後檔案不會被修改並且會退出vim。

1.4 更新系統

至此,不管是使用nano還是vim都可以對更新源進行編輯了,讓我們來具體瞭解一下如果更新系統和相關指令。

apt update
apt list --upgradable
apt upgrade -y

以上三行,分別是和更新源同步,顯示出哪些軟體可以更新,以及進行更新。

如上文中,安裝了vim,若想解除安裝vim,則有以下兩個命令,任意一個即可,但之間存在差別。

apt remove vim -y
apt purge vim -y

第一個會址解除安裝vim軟體本身,組態檔案仍然會本留下;第二種連帶著組態檔案和相關依賴一起解除安裝了,所以存在一定風險。除此之外,apt autoremove是對整個系統進行整理,將不需要的依賴解除安裝了,不針對於特定軟體。

2 SSH連接和基礎組態

一般VPS供應商都會提供SSH的連結方式,包括使用者名稱,密碼和連接埠號,一些注重安全性的會修改連接埠號甚至只有採用金鑰才能登陸VPS。這裡使用純淨版的系統和默認組態進行演示。

2.1 連接SSH的軟體和相關操作

SSH軟體有開放原始碼的和不開放原始碼的,有付費的和免費的,整理了一個常見SSH客戶端(Windows平台)的對比表格和相關資訊。其實在2021年,macos、Linux和windows 10都自帶SSH功能,這裡先不討論。個人目前主用mobaxterm,偶爾使用xshell。

名稱免費與否下載地址
Xshell家庭/學校免費https://www.netsarang.com/zh/free-for-home-school/
MobaXterm家庭版免費https://mobaxterm.mobatek.net/download.html
FinalShell基礎功能免費https://www.hostbuf.com/t/988.html
electerm免費+開源https://github.com/electerm/electerm/releases
PuTTY免費+開源https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

Xshell:傳播廣泛,自帶中文,個人使用完全免費,但是會話窗口限制最多隻能打開四個SSH連接,再多之後就會自動新建會話窗口了,傳輸檔案需要配合Xftp才行。目前國區被臭名昭著的思傑馬克丁代理了,如需使用,請前往官網下載,在輸入郵件和姓名後,會收到一封郵件,郵件裡面給出下載連接。

MobaXterm:只有英文版本,偶爾會反應慢半拍,除此之外沒缺點。功能極其強大,傳輸檔案、性能監控、序列埠通訊、X11支援、IP檢測、宏、WSL、遠端桌面等,能想到的功能都有,而且個人使用免費。

FinalShell:國人開發,所以本地化很好,全中文,日常需要的功能也都有。有一些進階功能需要付費,也可以雲端保存SSH帳號,雖然也是付費功能。缺點的話,和MobaXterm一樣,JAVA寫的東西,總是讓人覺得慢半拍。

electerm:日常所需功能都有,完全開源和免費,還可以通過GitHub實現免費的雲端保存SSH帳號功能,適合自己折騰和魔改。基於electron開發的,從而實現了跨平台,Windows、Mac和Linux都有客戶端。不過缺點也顯而易見,electron本質上是個瀏覽器,佔記憶體和硬碟空間。

PuTTY:由Simon Tatham開發和維護的,老牌中的老牌,但是缺少人性化設定,不推薦。

2.2 SSH組態檔案介紹和修改

SSH的組態檔案在/etc/ssh/sshd_config中,是一個純文字檔,可以使用nano或者vim打開和編輯。打開檔案後,在前幾行就能看到#Port 22字樣,這個代表使用了默認的22連接埠作為SSH連接使用。因為大家都在使用22連接埠,所以會有一些掃描機器使用弱密碼不斷嘗試登錄,使用lastb命令可以查看登錄失敗的記錄,如下圖。233333是嘗試登錄的帳號,144.214.xxx.xxx是發起者的IP,最後面是嘗試登錄的時間。

ssh_lastb

因此,我們可以改成高連接埠,比如35261這種沒有特殊含義/排列的隨機數,以減小被攻擊的可能。要注意連接埠只能在0-65535之間,並且很多低位數的連接埠,已經被共識的程序佔領了,比如80連接埠是http的,443連接埠是https的,就如22是SSH的一樣。此處,我們修改/etc/ssh/sshd_config中的連接埠數後,還需要重啟SSH服務才行,否則只會在系統下次重啟後才啟用新的連接埠。

systemctl restart ssh #重啟SSH服務

systemctl是systemd的命令,用於啟動和監控系統服務的,在系統核心啟動後,systemd就會開始服務,restart即重啟的意思。關於systemd的相關內容,後文會詳細說明。

除此之外,把密碼改的複雜一些,也可以有效的降低系統被黑的風險,使用passwd root命令,即可修改root帳號的密碼,會提示New password:,此時輸入新密碼,注意這裡是看不見任何輸入反饋的,隨後在顯示Retype new password:後再次輸入一遍,如果兩次密碼相同,就會更新root密碼了。

2.3 使用金鑰登陸SSH

即使更改了連接埠,但因為使用密碼即可登錄,考慮到不是所有人都會使用強密碼,所以SSH提供了使用金鑰登錄的功能,可以簡單理解成是一長串複雜的並且可以相互驗證的密碼。以root使用者為例,演示如何將SSH由密碼登錄改成金鑰登錄。

輸入ssh-keygen -t rsa ,隨後一路enter鍵,如下圖

ssh_key

在顯示完成後,在/root/.ssh/資料夾下,你將看到id_rsaid_rsa.pub兩個檔案,id_rsa是私鑰,下載下來並妥善保存,id_rsa.pub是公鑰,放在伺服器上的。將id_rsa.pub寫入到SSH的金鑰檔案中:

touch authorized_keys
cat id_rsa.pub >> authorized_keys

除此之外,還需要給檔案和相關資料夾合適的權限:

chmod 600 authorized_keys
chmod 700 ~/.ssh

這裡有個~,它代表的是當前使用者,比如現在是root使用者,那~就是root,所以chmod 700 ~/.ssh等於chmod 700 /root/.ssh

現在金鑰已經配對好了,還需要修改SSH的組態檔案,打開/etc/ssh/sshd_config檔案,尋找並修改如下:

PubkeyAuthentication yes # yes表示允許金鑰登陸
AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2 # 指定金鑰的檔案位置,這裡是去掉了開頭的#
PasswordAuthentication no # 不允許使用密碼登陸,等測試金鑰登陸成功了再修改此條,以防無法登陸

使用systemctl restart ssh重啟SSH服務,此刻,你將只能使用金鑰才能登錄,一旦私鑰遺失了,就再也進不去了。

3 Linux檔案系統

3.1 檔案系統格式

與Windows分割硬碟(甚至一個硬碟被劃分成了好幾個)不同,Linux的是將所有硬碟都掛載在了一起。簡單來說,Windows分C盤D盤等,還針對軟碟額外給予了A盤和B盤,Linux把所有的硬碟都放在了/下,即根目錄,這也是Linux中root帳戶的權限最大的原因,root即為根,如同樹根一樣,所有的內容都要基於根才有了可能。檔案系統是另外一個極其複雜的內容,這裡只提到Windows使用的是NTFS,而Linux普遍採用EXT4格式,這兩種檔案系統互不相容,裝在Linux系統上的硬碟,在Windows上是無法直接讀寫的,必須使用額外的軟體才能訪問。反過來,在Linux上讀取Windows下的硬碟中的內容,需要安裝ntfs-3g才行。這兩種檔案系統各有優缺點,一般人用就行了,不要問,問就是用默認。實際上,目前在廣泛使用的檔案系統種類繁多,所有需要在它們之間交換檔案的時候,會使用exFAT格式的USB 隨身碟/硬碟(exFAT是FAT的替代品,因為FAT下單個檔案最大不能超過4G)。

3.2 檔案樹、資料夾功能和權限

/目錄下,使用ls -la會顯示出所有的檔案和資料夾(如下圖所示),a是列出所有檔案,l是顯示詳細資訊。

root_files

第一列是檔案/資料夾的權限,一共有10個字元,第一位是檔案類型,比如d代表資料夾,l代錶鏈接。之後,三個為一組,總共3組。r是讀,w是寫,x是執行,也可以通過數字來區分,r是4,w是2,x是1,所以有了常見的一把梭chmod +777。第二列是永久連結數量,即這個檔案/資料夾下有多少真實放著的檔案。第三列和第四列是這個件分別屬於誰,以及這個人是哪個組的。這裡的概念來源於最開始的unix是個多使用者系統,所有會把使用者分類,比如某軟體使用者放一個組,系統維護人員放一個組等。第六列是檔案/資料夾大小,默認單位是K。第七八九列是修改的日期。最後一列是檔案/資料夾的名字。我們會發現有一些->的字樣,這是指軟連結。軟連接類似於Windows上的快捷方式,而硬連接類似於複製了一份(但並不會真的佔用空間)。

  • bin或者usr/bin:應用程式,比如Python的主程序就在這裡
  • boot:系統啟動檔案
  • dev:外部硬體裝置,Linux下一切皆檔案,所以外部硬體裝置也是以檔案形式出現
  • etc:系統的組態檔案,比如上述提到的SSH的組態檔案就在這裡
  • home:使用者目錄,類似於Windows上的桌面
  • initrd.img:啟動檔案,可以看到它被軟連接到了boot目錄中
  • lib:庫檔案,類似於Windows的dll,程序的依賴都在這裡
  • lost+found:丟失尋找檔案,系統被強迫關機後,會在這裡記錄下來
  • media:媒體檔案,如果系統發現了光碟之類的,會自動掛載到這裡
  • mnt:臨時掛載目錄,上述的光碟,還有USB 隨身碟硬碟,如果手動掛載,都會選擇這裡
  • opt:系統額外軟體的安裝位置,極少使用,比如甲骨文的資料庫會放一些東西在這裡
  • proc:系統處理程序/核心會把一些資訊放到這裡,本質上是反應系統狀態而不是檔案
  • root:root使用者的“桌面”,普通使用者在home中
  • run:系統啟動後存放臨時檔案
  • sbin:root使用者的"bin"
  • srv:放服務運行而需要的檔案
  • sys:檔案系統,裡面包括處理程序資訊,裝置資訊和終端資訊
  • tmp:臨時檔案
  • usr:共享資源,類似於Windows安裝軟體的默認目錄
  • var:不斷變化的檔案會放在這裡,比如日誌
  • vmlinuz:啟動檔案,可以看到它被軟連接到了boot目錄中

如果我們自己寫了一個程序,還放在系統裡面運行,那一般是在/usr/local/中新建目錄,這遵循著Linux系統的默認規則。

3.3 示例:掛載USB 隨身碟

如果是Ubuntu桌面的話,會自動掛載USB 隨身碟,但是無GUI版本的Linux大機率不會,所以會需要手動掛載,又或者加了一塊新的硬碟,需要我們自己掛載。

fdisk -l
mkdir /mnt/usb
mount /dev/sda1 /mnt/usb
umount /mnt/usb

fdisk -l是顯示出所有的儲存,會顯示出來類似於/dev/sda1等,mkdir /mnt/usbmnt目錄裡面新建一個資料夾,即掛載點,假設sda1就是我們插入的USB 隨身碟,mount /dev/sda1 /mnt/usb將這塊USB 隨身碟掛載到了/mnt/usb中,這時候我們就能在/mnt/usb中看到USB 隨身碟裡的檔案。如果不再需要了,要手動移除這個USB 隨身碟,使用umount /mnt/usb命令。

4 Shell/Dash入門

讓人頭大,Shell本身就能寫一本書了,少說得有300頁!這裡面夾雜著從Unix開始的一大堆事情,shell的發展,bash和dash的區別與聯絡,本身的命令,呼叫系統的命令,互動方式。累了,姑且先把它當成一堆命令拼湊起來的指令碼吧。

還是寫個例子,簡單介紹一下實際內容,等以後有時間了再繼續補充。比如我們想寫一個查看CPU和記憶體使用率的指令碼:

#!/bin/bash

echo "which useage do you want to konw?"
echo "1 for CPU, 2 for RAM"
read choice

if [ $choice -eq 1 ]
then
   echo "CPU usage"
   grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}'
elif [ $choice -eq 2 ]
then
   echo "RAM usage"
   free -m | grep Mem | awk '{print ($3/$2)*100 "%"}'
else
   echo "WRONG INPUT"
fi

細說每一行內容

#!/bin/bash是指定此檔案由/bin下面的bash這個程序來執行。

在Debian 11里面,bash其實是dash,別問dash是什麼,就寫bash,天王老子來了也寫bash。Bash全稱是GNU Bourne-Again Shell,bash被從NetBSD(一個Unix的分支)上移植到Debian上,所以叫dash (Debian Almquist Shell)。

echo "which useage do you want to konw?"是輸出冒號內的文字

echo "1 for CPU, 2 for RAM"
read choice

把輸入內容賦值給choice這個變數,即數字1或者2。rcho -p "1 for CPU, 2 for RAM" choice也可以實現相同功能。

if [ ... ]
then
    ...
    ...
elif [ ... ]
then
    ...
    ...
else
    ...
fi

這是一個if...elif...else的判斷語句,先經過兩次判斷,如果都不能成功,那就執行最後一行。

$choice -eq 1把剛才的choice這個輸入變數和數字1對比,注意,要有$才代表變數,不然就默認是文字,-eq是等於的意思。判斷是否等於1,是的話就給出CPU使用量,如果不等於1,那就繼續判斷是否等於2,是的話就給出RAM使用量,如果不等於2,那就輸出錯誤提醒,然後結束。grep是抓取有關鍵詞的那一行,$2是這一行的第幾個內容,如下:

grep

grep Mem抓取到了第二行,即真實記憶體這一行,$2是記憶體總量,$3是已經使用了的記憶體,因此($3/$2)*100就是已經使用了百分之多少的記憶體,

5 Crontab定時任務

Crontab用於定時任務,比如設定週五晚上運行指令碼備份網站,又或者每分鐘檢查一下CPU使用率等。但除此之外,crontab還有個@reboot功能,即可以在系統啟動的時候自動運行指定程序。

推薦crontab -e,其中的-e是指當前使用者,不建議直接使用crontab。首次運行crontab -e的時候,會讓選擇使用何種編輯工具,這個隨便,nano和vim basic都行,什麼順手和習慣就用什麼。

crontab_eg

如上圖,將每隔15分鐘,就會使用位於usr/bin中的python3運行位於/usr/local/weather中的weather.py程序。前五個星號其實是設定的時間,推薦去 https://crontab.guru/ 這裡直接設定時間(如下圖)。第一個星號是分鐘,第二個星號是小時,第三個星號是天,第四個星號是月份,第五個星號是每週的第幾天。

crontab_set

6 系統權限

6.1 root和user,以及sudo

上述已經簡單的減少了root來源,由於root的權限太高,以至於在實際使用中發現並不安全,而且作為一個初始目的是多使用者多終端的作業系統,Linux主要操作都不需要發生在root使用者上的。所以這裡就有了user這個角色,如果使用者多了起來,為了便於管理,也會把某些使用者分組,就有了group的概念。以下演示使用root使用者新建一個user使用者並進入此使用者:

adduser

如圖所示,adduser mjj為新建一個叫做mjj的使用者,由於此前並沒有除了root之外的使用者,所以會使用這個名字作為group/組的名字,並且在/home資料夾裡面生成一個mjj資料夾,即mjj的”桌面“。所以輸入兩次密碼,之後會問一堆問題,都是例行的,一路enter就好,最後會問一下資訊對不對,輸入y就完成新增新使用者了。

但此時,mjj這個使用者的權限是很小的,四捨五入等於沒有,連某些資料夾都不能進去更別說執行軟體了。使用su mjj切換到mjj使用者中,可以在終端中看到已經從root@rn變成了mjj@rn,rn是這台伺服器的名字,即為某某在rn這台伺服器上。查看以下root資料夾下有些什麼東西,結果發現權限不夠而被拒絕訪問/Permission denied。

sudo

所以我們要給一個能夠臨時使用root權限的能力,這被稱為sudo

su root #切換回root帳號
apt install sudo -y #有些時候,純淨安裝的Debian系統是沒有sudo的,所以要安裝一下
usermod -aG sudo mjj ##給予mjj使用者sudo權限

此時,我們再切換到mjj使用者上,在剛才的命令前加上sudo,臨時獲取root權限,就可以查看了:

sudo_root

在使用者首次使用root權限的時候,系統會提示三個準則,也請謹記:

  1. 尊重他人隱私;
  2. 輸入之前請三思;
  3. 能力越大,責任越大。

6.2 chmod和chown

chmod的全稱是change mode,是針對於資料夾或者檔案,改變它們的權限,這樣就可以讓某些使用者正常使用了。這裡不深入探討chmod的使用詳解,僅演示一些常見的內容。chmod +x helloworld.py 這裡的x在上面說過,是執行的意思,即賦予此程序被執行的權限,多見於一鍵指令碼裡面,讓指令碼能夠正常運行。+是新增權限,如果是-則是去除對應的權限。chmod -R 755 folder/ -R如上述的rm -rf中的r一樣,是遞迴,即從這裡開始,下面不論多少層資料夾,都執行這個命令。755是換算下來,則是root使用者可以讀寫執行(1+2+4=7),使用者和使用者組只能讀和執行(1+4=5),不能對檔案進行更改。某些程序會對檔案的權限有著極其嚴重的控制,比如上說的SSH金鑰,分別給authorized_keys600的權限和.ssh資料夾700的權限,意味著只能被所有者/owner讀寫,在例子中即為只能被root帳戶讀寫。這種設計讓沒有相應權限的人無法修改金鑰登陸的方式,換而言之,隔絕了使用者之間的操作,從而增強安全性。

chown的全稱是change owner,是用於設定檔案所有權的。由於歸屬者的概念並沒有檔案這個概念常見,所有chown比較少見到,大多數人接觸到的時候,大概是建網站的時候用chown -R www-data:www-data-group /var/www/html來確定檔案關聯。這句的意思是,將/var/www/html這個資料夾及裡面的所有檔案都歸給www-data-group使用者組的www-data使用者。這樣做的目的是實現權限分離,檔案分離,從而讓伺服器可以更方便的被維護,以及明確使用途徑。不過考慮到mjj大部分都是使用VPS的,可能很難遇到需要chown的情況吧。

不要chmod +777!不要chmod +777!不要chmod +777人才是伺服器安全的最大漏洞!

7 Systemd入門和組態

7.1 開機自啟和處理程序守護

Systemd是由Redhat家的Lennart Poettering開發的,其人以創造性和不靠譜聞名,Systemd在最開始的時候,和init相比沒有明顯優勢,經過多次迭代才有了今天的穩定性和適用性,現在就讓老舊的init進入歷史垃圾桶吧。事實上,在Linux系統啟動的時候,一旦kernel運行了,Systemd就會跟隨啟動,之後由Systemd喚醒並維護各個程序的正常運行,比如網路卡,顯示器,SSH服務等。你會在/etc/systemd/system/資料夾中發現一個叫做sshd.service的檔案,並且還是enable模式的,這意味著SSH是開機自啟的,並且系統會一直監控這這個程序,如果程式當掉,系統會嘗試自動重啟它以確保能夠正常運行。

以著名的內部網路穿透frp的伺服器端的Systemd檔案為例(下節將詳細介紹如何搭建frp),將frps.service放到/etc/systemd/system/資料夾中,使用以下命令

systemctl enable frps.service
systemctl start frps.service
systemctl status frps.service
systemctl restart frps.service

systemctl是systemd在系統中的程序名字,enable是指讓這個程序能夠開機自啟,start為讓程序現就運行,status是查看這個程序現在的狀態,restart是重啟程序。

當然,我們也可以自己寫systemd的service檔案,這裡以 https://github.com/cnsilvan/UnblockNeteaseMusic 解鎖網易雲音樂的程序做參考

[Unit]
Description=UnblockNeteaseMusic
After=network.target
Wants=network.target

[Service]
Type=simple
WorkingDirectory=/usr/local/UnblockNeteaseMusic
ExecStart=/usr/bin/node app.js -e http://music.163.com -s -p 8888
RestartPreventExitStatus=23
Restart=always

[Install]
WantedBy=multi-user.target

一共分為三組,分別為Unit,Service和Install。Unit是這個服務的名稱,示例中為UnblockNeteaseMusicAfterWants指明的network.target意味希望這個程序在網路服務啟動後再啟動,畢竟是個網路功能,不能還沒有網就啟動了。Service是核心部分,Type指定了類型,Simple是默認的類型,發現有網了就啟動。此外,常見的還有forkidle,前者意味著程序依賴於另外一個程序的運行,通常還會組態PIDFile,後者是等系統空閒了再啟動,屬於一點都不急的。WorkingDirectory是工作目錄,ExecStart是執行的命令,實例中,是用位於/usr/bin/的nodejs執行位於工作目錄的app.js這個檔案,並且還帶了參數http://music.163.com -s -p 8888RestartPreventExitStatus是指如果報錯資訊為23則不會再重啟了,具體報錯資訊是運行的程序決定的。Restart=always指只要不是23的報錯資訊,那就一旦服務停了,Systemd就會去重啟。最後一部分,Install中的WantedBy=multi-user.target指網路服務已經正常啟動,也可以讓使用者登錄了,但是並沒有開啟GUI服務,這個部分不用去探究。

7.2 Timer代替Crontab

我寫了一個自動登錄百度貼吧並簽到的shell指令碼,想每天都運行一次幫我拿積分,但是又不想用crontab實現定時任務,那麼Systemd也是有類似的功能的,名字叫做Timer,即定時器。這個功能需要兩個檔案,比較繁瑣。

需要再/etc/systemd/system/中寫兩份組態檔案,tieba.servicetieba.timer,前綴必須一樣,後綴不同。

前者很簡單,就是個指令碼(如下),名字和程序的路徑:

[Unit]
Description=Tieba Sign

[Service]
ExecStart=/home/tieba.sh

後者tieba.timer需要詳細解釋:

[Unit]
Description=Tieba Sign Timer

[Timer]
OnCalendar=*-*-* 12:00:00

[Install]
WantedBy=timers.target

Timer的名稱需要是service名字後面加一個Timer,用以提高精準性。OnCalendar類似於corntab* * * * *,實例中的意味每天中午12點的時候執行以下tieba.service中的位於/home資料夾的tieba.sh這個程序。此處的WantedBytimers.target,指明是個定時器。

8 手動組態系統:以frp為例

frp是個內部網路穿透軟體,可以將區域網路裝置通過frp伺服器端對應出來,實現公網服務,常見的有SSH、http/https服務等。這裡以將內部網路裝置的SSH對應到有公網IP的伺服器上為例,從而不在家也能服務家裡面的伺服器了。

在這裡下載最新版的安裝包 https://github.com/fatedier/frp/releases

frp_tar

如圖所示,0.38.0是版本號;後面的是系統,darwin是MacOS,freebsd是UNIX的一個分支,這裡我們選擇linux;緊跟著的是CPU架構,由於本次伺服器的客戶端是裝了64位系統的樹莓派4B(arm架構的CPU),所以選擇frp_0.38.0_linux_arm64.tar.gz,而伺服器端是普通的VPS,所以選擇frp_0.38.0_linux_amd64.tar.gz

伺服器端組態

注意:版本號和CPU架構須按照實際情況決定。

wget https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_amd64.tar.gz
# 使用wget下載軟體包
tar -zxvf frp_0.38.0_linux_amd64.tar.gz
# 解壓下載的軟體包
cd frp_0.38.0_linux_amd64/
# 進入解壓後的資料夾
mkdir /etc/frp/
# 新建一個frp的資料夾
mv frps.ini /etc/frp/frps.ini
# 把伺服器端的組態檔案放到剛才新建的資料夾
mv frps /bin/
# 把伺服器端軟體放到/bin中
mv systemd/frps.service /etc/systemd/system/frps.service
# 放置Systemd檔案
systemctl enable frps.service
# 設定開機自啟
systemctl start frps.service
# 立即運行

客戶端組態

wget https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_arm.tar.gz
tar -zxvf frp_0.38.0_linux_arm.tar.gz
cd frp_0.38.0_linux_arm/
mkdir /etc/frp/
mv frpc.ini /etc/frp/frpc.ini
mv frpc /bin/
mv systemd/frpc.service /etc/systemd/system/frpc.service

上述與伺服器組態類似,就不重複了,但需要額外修改伺服器端的組態檔案,讓它知道該和誰連接,打開/etc/frp/frpc.ini組態檔案

[common]
server_addr = 伺服器ip
server_port = 7000

[raspi]
type = tcp
local_ip = 127.0.0.1
local_port = 本地伺服器的SSH連接埠
remote_port = 遠端連接埠

其中,需要填寫伺服器端的IP,7000連接埠是握手和保活用的,默認就好了。[raspi]是客戶端的名字,不可以重複,local_port是客戶端的SSH連接埠,remote_port是遠端的連接埠,此處假設是6000。

systemctl enable frpc.service
systemctl start frpc.service

設定開機自啟並立即運行,此時在SSH軟體上,通過 伺服器IP:6000 就可以連接到這台內部網路的樹莓派了。

9 網站環境搭建

網站搭建,說簡單也簡單,安裝一個nginx放個html頁面就算是了,但也可以做的極其複雜以至於需要一個團隊,比如淘寶。這裡提供了兩個搭建網站的方法:面板和手動搭建。對於小白使用者,還是推薦用用面板吧,不然出問題,網站被黑都不知道如何解決。

9.1 寶塔解人憂

寶塔面板是個偽開放原始碼的一鍵式建站面板,國內版可以在 https://www.bt.cn/ 中找到安裝方式,目前的安裝命令是wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh 。需要注意的是,國內版需要登陸並且驗證手機號後才能操作,寶塔也有強制後台升級的前科。

aapanel

除此之外,還有國際版的叫做aapanel,安裝地址為 https://www.aapanel.com/install.html ,安裝命令是wget -O install.sh http://www.aapanel.com/script/install_6.0_en.sh && bash install.sh。相對而言,國際版的隱私保護會更好一些,不會要求手機號等資訊,但是默認語言是英文,如果會哪怕一點點英文,都推薦使用國際版的。

寶塔有一點不好的地方是動輒編譯(原先是在CentOS上開發的,所以有這個臭毛病),面板是python3寫的,安裝起來很快,但是要安裝一些服務的話,如果VPS性能不好,則需要花費相當長一段時間來編譯安裝,普遍30分鐘起步。

9.2 手動搭建

寶塔面板是將網站搭建可視化了,本質上和手動搭建沒有區別。這裡主要是介紹常見的相關軟體和Let's Encrypt組態SSL證書的方法。

9.2.1 Apache和Nginx

Apache和Nginx都是Web伺服器。前者是老牌Web伺服器軟體,對PHP有著優秀的支援,並且動態響應優秀,但是對性能和記憶體要求高。後者是俄羅斯出品,對靜態網站支援良好,性能消耗也更小,反代和簡單的網站都傾向於使用Nginx,甚至還有一系列基於Nginx衍生出來的版本,比如Tengine就是淘寶從Nginx衍生出來的,用以支撐淘寶的各種服務。除此之外,還有個Caddy也用的比較多,這是由golang語言寫出來的,所以對多執行緒高並行的支援很好,並且自帶SSL證書申請的功能。

入門使用者首選Nginx,畢竟網站沒有什麼服務,對VPS的性能消耗也少點。當然,選擇Apache也完全可以,入門使用者其實很難用到需要對比選擇Apache和Nginx的時候。Caddy的話,先不推薦入門使用者了。

安裝Apache使用以下命令

apt install apache2

安裝Nginx使用以下命令

apt install nginx

這兩個軟體安裝完後,都會開機自啟和立刻運行,瀏覽器中輸入http://ip就可以看到默認的網頁,比如Nginx的是這樣:

nginx

9.2.2 PHP

安裝了Nginx之後,可以實現靜態網頁,但是常見的網站平台,比如Wordpress和typecho都是PHP寫的,所以還需要安裝PHP才能運行。

apt install php-fpm

安裝完php還不算完事,還得讓Nginx知道,也就是需要更改Nginx的組態檔案。

進入目錄/etc/nginx/sites-available/中,將默認的檔案default重新命名為網站的域名,比如mjj.hostloc.com,即mv default mjj.hostloc.com,打開mjj.hostloc.com,在下述的第二行末尾加入index.php

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php; # 注意加入了index.php

並且將下述的_改成網站域名

server_name _;
# 改成 server_name mjj.hostloc.com;

隨後,重新軟連結,並重啟Nginx

rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/mjj.hostloc.com /etc/nginx/sites-enabled/mjj.hostloc.com
systemctl restart nginx

注意域名不要填錯了,重啟完後,Nginx將能夠和PHP一起支援動態網站。

9.2.3 MySQL和MariaDB

MySQL是一個市場佔有率極大的資料庫軟體,應用場景極其廣泛,最開始是SUN公司開發的,2009年被甲骨文收購。甲骨文作惡多端,所以MySQL的一部分作者則獨立出來,直接做了一個復刻版的,被命名為MariaDB,Maria是作者女兒的名字,Linux社區逐步放棄MySQL而採用MariaDB。所以在近期發佈的各Linux版本中,默認是沒有MySQL的,一律採用MariaDB。

apt install mariadb-server # 安裝資料庫
mysql_secure_installation # 首次組態

由於是首次使用,所以在如下提示中,直接enter鍵就可以了,因為資料庫的root使用者此時並沒有密碼

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 

隨後,會詢問是否要設定資料庫的root密碼,怎麼說呢,反正就建個站而已(不涉及多使用者多服務),有沒有無所謂,我習慣性的不設定(輸入N)

OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] N

現在,新建一個使用者和對應的資料庫

mysql # 進入資料庫,如果有root密碼,則是mysql -u root -p

CREATE DATABASE name; # 新建資料庫,name是資料庫名字
Query OK, 1 row affected (0.00 sec) #此段為mySQL反饋提示,不需要輸入。

CREATE USER user@localhost; # 新建使用者,user是使用者名稱字
Query OK, 0 rows affected (0.00 sec) #此段為mySQL反饋提示,不需要輸入。

SET PASSWORD FOR user@localhost= PASSWORD("密碼"); # 給使用者設定一個密碼
Query OK, 0 rows affected (0.00 sec) #此段為mySQL反饋提示,不需要輸入。

GRANT ALL PRIVILEGES ON name.* TO user@localhost IDENTIFIED BY '密碼'; # 把name這個資料庫和user這個使用者關聯
Query OK, 0 rows affected (0.00 sec) #此段為mySQL反饋提示,不需要輸入。

FLUSH PRIVILEGES; # 完成設定
exit # 退出資料庫

9.2.4 Let's Encrypt,SSL/TLS

http連接,由於不是加密的,所以任何人都可以查看內容,這對於一些金融服務有著巨大的危害,比如使用信用卡在網上購物的時候,帳號和密碼會被獲知。所以網景(Firefox瀏覽器的前身)提出了SSL(安全套接層/Secure Sockets Layer)這個概念(後來演變升級為TLS,即傳輸層安全性協議/Transport Layer Security),http變成了https,電腦會內建證書,而網站也會有一個證書,只有兩者相互驗證成功,才能正常瀏覽玩網頁,並且全程加密(DNS部分並不是加密的,所以有個DoH,dns over https)。

SSL/TLS證書是個壟斷行業,電腦內建的證書就那麼幾家,如果想網站被大多數瀏覽器/系統接受,那就只能去申請其中某家的證書,這裡面層層簽發轉售,幾近無本萬利。不過好在還是有很多免費的SSL/TLS證書的,比如Let's Encrypt提供三個月的免費證書,而亞洲誠信通過第三方公司,提供一年免費的證書。這裡以Let's Encrypt為例演示,相關連結為 https://certbot.eff.org/instructions

ssl_tls

Let's Encrypt提供的SSL/TLS工具叫做cerbot,可以通過snap或者pip安裝。snap是Ubuntu強推的一種軟體部署和軟體包管理系統,把所有需要的東西都放一起。pip是通過python3的pip安裝,pip和snap沒有功能上的區別,不想被Ubuntu強推就使用pip。

snap安裝cerbot申請SSL/TLS證書

apt install snapd
snap install core
snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot --nginx

然後按照提示,輸入信箱和同意服務協議,並且在提示域名的時候,注意不要輸錯。

pip安裝cerbot申請SSL/TLS證書

apt install python3 python3-venv libaugeas0
python3 -m venv /opt/certbot/
/opt/certbot/bin/pip install --upgrade pip
/opt/certbot/bin/pip install certbot certbot-nginx
ln -s /opt/certbot/bin/certbot /usr/bin/certbot
certbot --nginx
echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null

相比於snap自動每三個月更新證書,pip需要通過crontab加一個定時任務(上述最後一行),另外,也需要偶爾檢查以下certbot有沒有更新,即使用此命令/opt/certbot/bin/pip install --upgrade certbot certbot-nginx

10 Docker快速入門

Docker的本意是“碼頭工人”,即搬運別人打包好的集裝箱。之所以取這個名字,是因為Docker的功能與此類似:將系統和裡面的應用一起打包好,別人“搬走”就能直接使用——可以將Docker粗略的理解成一個包含了系統和應用的虛擬機器(嚴格來說,Docker是使用了沙箱機制的虛擬化容器)。常見的例子就是別人把某一個軟體組態好了,使用者直接下載下來,簡單設定一下就可以使用了,不需要繁雜的組態過程,所以在批次服務中有著廣泛的應用場景。Docker分為社區版/CE(Community Edition,免費的)和企業版/EE(Enterprise Edition,收費的),兩者功能無本質區別,以下默認使用社區版。

10.1 安裝Docker環境

apt update # 同步更新源
apt install -y ca-certificates curl gnupg lsb-release # 安裝必要依賴軟體

新增GPG金鑰,注意這裡和上面一樣,必須是root權限(如下命令)。這裡簡單介紹一下GPG,全稱是GnuPG,真·全稱是GNU Privacy Guard,一個密碼學軟體,用來驗證通訊中的安全性,防止傳輸過程中被篡改,前身是Pretty Good Privacy/PGP。

curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

選擇使用穩定版,如果需要nightly或者test版,可以把下面的stable改成對應的版本。

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

更新並安裝Docker

apt update
apt install -y docker-ce docker-ce-cli containerd.io

期間會下載幾百兆的檔案,網路不好的話,可能會需要一段時間,當完成安裝後,使用docker run hello-world命令來測試功能是否正常,理論上會輸出下圖內容:

docker_hello

至此,系統已經安裝好了Docker環境,可以自己寫一個Docker的應用,或者直接拉取別人寫好的為自己所用。

10.2 安裝別人打包好的的Docker

先說一下常用的Docker命令,然後以安裝Docker版本的Nextcloud為例。Nextcloud是一個開放原始碼的網盤系統,類似於私有版本的百度雲,可以自己搭建從而確保資料都在自己手上而不會被8秒。

10.2.1 常用Docker命令

docker ps 列出所有正在運行的容器,如果需要查看所有的容器(包括未運行或者啟動失敗的)則使用docker ps -la,這點類似於lsls -la的區別。

docker start/stop/restart CONTAINER ID 開啟/停止/重啟特定容器,後面要加上指定的ID,CONTAINER ID見下文。

docker rm CONTAINER ID 刪除容器,如果是刪除鏡像,則需要把rm換成rmi

10.2.2 安裝Docker版Nextcloud

https://hub.docker.com/ 中直接搜尋Nextcloud,找到官方版本的鏡像,點選進去,在右側有拉取鏡像的命令,直接運行即可。

docker_nextcloud

安裝過程中會下載各個元件,等全部顯示Pull conplete即表示下載完成,之後會自動校驗並提示完成。

docker_pull_nextcloud

使用docker run -d -p 80:80 nextcloud 運行,此時使用docker ps可以查看到具體的詳細資訊

docker_nextcloud_status

CONTAINER ID類似於身份證號碼;IMAGE是身份證上的姓名;COMMAND是實際運行的程序;CREATED是建立的時間;STATUS是此時的運行狀態;PORTS是連接埠,上述我們把容器的80連接埠定向到伺服器的80,並且默認ipv4和ipv6都可以訪問,接受所有IP的訪問(0.0.0.0代表接受所有IP);NAMES是容器的名字,可以理解為外號。

之後就是通過IP或者繫結的域名訪問,進行最後的安裝。這裡就能看出來Docker的優勢了:使用者無需瞭解具體操作和搭建步驟,提供者負責維護,這可以極大的簡化使用者的使用步驟,還可以標準化環境,無論使用Debain還是REHL,鏡像/容器都是提供者給定的。

docker_nextcloud_install

如果不再需要Nextcloud,則首先停止容器,隨後再刪除:

docker stop c30d348f1ef1
docker rm c30d348f1ef1

10.3 建自己的Docker

Docker通過Unix socket與它的引擎進行通訊,出於安全考慮,一般只有root使用者和在docker組的使用者才能正常訪問Unix socket。所以,如果想建一個完善的Docker應用,那麼建議額外新增一個使用者,並加入docker使用者組。