部落格搬遷 - 記錄從零開始的架站步驟(更換域名、更換 VPS、更換 Arch Linux server)

前言

簡單而言,就是一次網站的大遷移。

未命名

看到這一篇也表示我已經順利的把 ank.pw 搬遷到 ankmak.com 了,雖然表面看似只有域名變了,但實際上裡裡外外都重新整頓了一遍,會有這樣的改變其實是有幾個原因的,首先是我剛好找到一個 .com 後綴的域名,雖然比之前的域名長了一點,但對我來說比較好記憶而且跟 我在 Github 上的名稱一樣,而且 .com 也比較大眾化一點。

另外一個更重要的原因,就是我在過去這 2 年裡,為了探索自己喜歡的部落格功能、風格、工具等,安裝了各種不同的套件,也更改了各種配置文件,試了又試,最終在伺服器上存在了各種有用跟沒用的東西,雖然運作是正常,但不管是站在安全的角度,還是我的強迫症,我都很想推倒重造,所以干脆一拼連域名來個大更改。

其實這樣的轉變還是多少帶來了一些負面影響,其中影響最大的是搜尋排名(SEO),這樣的改動讓原本已經為數不多的流量又回歸起點。現時系統搬遷到全新的 Arch Linux 伺服器上,也讓系統盡量的最小化,加上現在部落格已大致固定,所以我估計未來應該也不會有大的改動,搜尋排名(SEO) 就慢慢累積就好,在此展望目前的架構能至少穏定運行 5 年以上吧。

下面是記錄我更動了的地方和過程:

VPS

從 hostwinds 換到 Linode

Linode 相關設定

由於我原先是使用 hostwinds 這家的 VPS,現在想換回 linode,所以這裡我選擇了影響比較少的做法,就是在 linode 上重新建立一個新的 VPS,然後再把資料搬家,雖然同時會在 2 台不同的伺服器上出現 2 份一樣的資料,但這樣的做法比較保險而且轉移途中不會影響原伺服器。

圖片

這裡我系統選擇 Arch Linux、地區選擇 Fremont、配置為 $5 美金/月的最低規格(因為窮)。

Server OS

從 CentOS 換到 Arch Linux

選擇 Arch 的原因除了我本來是 Arch linux 的用戶之外(詳見這裡),它還能提供一個穏定和最小化內容的系統,作為伺服器來相當合適。

以下我是自己認為最少程度需要的環境設置,具體還是自己用的舒心便可,僅供參考。

1.設定正確時間

設置時區

ln -sf /usr/share/zoneinfo/Asia/Macau /etc/localtime

查看時間與時區

date
timedatectl

2.更新 pacman

pacman -Syyu

更新後重啟

reboot

3.新增擁有管理員權限的帳戶

新增一名叫 your_user_name 的使用者帳戶(-m 擁有家目錄)

useradd -m your_user_name 

更改密碼

passwd your_user_name 

加入管理員組:

usermod -a -G root your_user_name 

新增管理員權限

vim /etc/sudoers

root ALL=(ALL:ALL) ALL 這句話下方加上

your_user_name ALL=(ALL:ALL) ALL

登出並改用新建立的用戶登入

4.停用 root 帳號

鎖住 root:

sudo passwd -l root

編輯 /etc/shadow

sudo vim /etc/shadow

或者直接把密碼的 hash 值改成 !

root:!*:14871::::::

5.安裝 oh-my-zsh Shell

sudo pacman -S git zsh
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

更改主題和插件

vim .zshrc

ZSH_THEME="robbyrussell" 換成 ZSH_THEME="ys"

plugins=(git) 換成 plugins=(git sudo)

6.配置 vim

複製默認配置到家目錄

sudo cp /usr/share/vim/vim82/defaults.vim ~/.vimrc

更改 owner

sudo chown your_user_name:your_user_name ~/.vimrc

編輯 ~/.vimrc

加入以下配置(按個人喜好)

if has('mouse')    " 使用 putty 時可用滑鼠右鍵進行貼上
        set mouse-=a
endif

set number    " 顯示行號
set relativenumber    " 顯示相對行號
inoremap jk <Esc>    " 同時按 jk 相當於按 Esc

7.建立防火牆規則

先觀察防火牆是否已有設定

sudo iptables -L

默認是沒有建立任何規則:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

編輯默認的防火牆規則檔案

sudo vim /etc/iptables/iptables.rules

建立規則,只開放 80(http), 443(https), SSH(22), ICMP 服務

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow SSH connections
#
#  The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

#  Allow ping
-A INPUT -p icmp -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT

啟用 iptables 並運行

sudo systemctl enable iptables.service
sudo systemctl restart iptables.service

查看是否生效

sudo iptables -L

8.安裝 fail2ban

查看登入失敗的使用者

lastb

發現已經有不少人在亂試帳號/密碼。

root     ssh:notty    43.134.201.172   Fri Apr 22 13:27 - 13:27  (00:00)
root     ssh:notty    167.71.207.160   Fri Apr 22 13:27 - 13:27  (00:00)
34       ssh:notty    43.154.191.35    Fri Apr 22 13:25 - 13:25  (00:00)
34       ssh:notty    43.154.191.35    Fri Apr 22 13:24 - 13:24  (00:00)
root     ssh:notty    143.198.209.48   Fri Apr 22 13:24 - 13:24  (00:00)
user1    ssh:notty    167.71.207.160   Fri Apr 22 13:23 - 13:23  (00:00)
user1    ssh:notty    167.71.207.160   Fri Apr 22 13:23 - 13:23  (00:00)
admin    ssh:notty    43.134.201.172   Fri Apr 22 13:23 - 13:23  (00:00)
admin    ssh:notty    43.134.201.172   Fri Apr 22 13:23 - 13:23  (00:00)
senju    ssh:notty    43.154.191.35    Fri Apr 22 13:23 - 13:23  (00:00)
senju    ssh:notty    43.154.191.35    Fri Apr 22 13:23 - 13:23  (00:00)
felipe   ssh:notty    143.198.209.48   Fri Apr 22 13:23 - 13:23  (00:00)
felipe   ssh:notty    143.198.209.48   Fri Apr 22 13:23 - 13:23  (00:00)
gp       ssh:notty    167.71.207.160   Fri Apr 22 13:22 - 13:22  (00:00)
root     ssh:notty    43.134.201.172   Fri Apr 22 13:22 - 13:22  (00:00)
gp       ssh:notty    167.71.207.160   Fri Apr 22 13:22 - 13:22  (00:00)
root     ssh:notty    43.154.191.35    Fri Apr 22 13:21 - 13:21  (00:00)
root     ssh:notty    143.198.209.48   Fri Apr 22 13:21 - 13:21  (00:00)
root     ssh:notty    43.134.201.172   Fri Apr 22 13:21 - 13:21  (00:00)

可以發現嘗試 root 的比例最高,所以千萬不要讓 root 可以 ssh 連線

安裝 fail2ban

pacman -S fail2ban

複製原始配置文件

cp /etc/fail2ban/jail.{conf,local}

/etc/fail2ban/jail.local 裡找出 [sshd] 的區塊,加入 enabled = true 以啟用

[sshd]

#mode   = normal
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

啟用 fail2ban 並運行

sudo systemctl enable fail2ban.service
sudo systemctl restart fail2ban.service

查看 fail2ban 的運行狀態

sudo fail2ban-client status

如果看到以下訊息,表示 fail2ban 已經在運作 sshd

Status
|- Number of jail:      1
`- Jail list:   sshd

更多 /etc/fail2ban/jail.local 的設置:

重要的參數在[DEFAULT]

  • bantime = 被 Ban 多久(秒數),預設為 10 分鐘,-1 為永久封鎖。時間單位可以是 s、m、h
  • findtime = 多長時間內的目標(秒數),預設是 10 分鐘。時間單位可以是 s、m、h
  • maxretry = 在設定時間內,允許失敗的次數,預設為 5 次

也就是說,在默認規則上,當 10 分鐘內輸入 5 次錯誤密碼,便會停用 10 分鐘。

每次修改完配置,記得把 fail2ban 服務重新運行

sudo systemctl restart iptables.service 

可查看一共有多少 IP 被 BAN 了

sudo fail2ban-client status sshd

如果想讓系統更安全一點,建議使用 SSH Key Pair 以代替密碼方式登入

Web Server (使用 Nginx)

安裝

pacman -S nginx-mainline

啟用 nginx 並運行

systemctl enable nginx
systemctl restart nginx

測試

打開瀏覽器,輸入網址: ankmak.com

螢幕擷取畫面 2022-04-23 132348

如果看到上面的歡迎頁面,表示安裝成功。

Nginx 的配置文件位於: /etc/nginx/nginx.conf
默認的網站目錄位置: /usr/share/nginx/html

更改網頁

由於我自己已經有設計好的 Website 內容,現在進行簡單的複製搬遷

cp webpage /usr/share/nginx/webpage

更改一下 root 的位置,編輯/etc/nginx/nginx.conf

location / {
    root   /usr/share/nginx/webpage;
    index  index.html index.htm;
}

重啟 nginx:

systemctl restart nginx

螢幕擷取畫面 2022-04-23 141123

一個成型的主頁便弄好了~

Jekyll 靜態網站部格落

準備

更新系統和安裝必備的套件

pacman -Syyu
pacman -S base-devel
pacman -S ruby

使用以下指令進行檢查是否安裝完畢

ruby -v
gem -v
gcc -v
g++ -v
make -v

注意查看一下當前 ruby 版本是否在 3.0 以上

安裝 Jekyll

gem intall jekyll
gem install bundler

如果安裝過程出現 You don't have /root/.local/share/gem/ruby/3.0.0/bin in your PATH的提示信息,可以編輯 .zshrc 並加入:

export GEM_HOME="$(ruby -e 'puts Gem.user_dir')"
export PATH="$PATH:$GEM_HOME/bin"

再次安裝並查看:

zsh
gem install jekyll
jekyll -v

搬遷 Jekyll 的 TeXt 主題

從備份的地方複製過來

cp /backup/jekyll-TeXt-theme-tech ~/jekyll-TeXt-theme-tech

把 jekyll 格式的內容進行轉換成靜態文件,部署到 Web 上

jekyll build --source jekyll-TeXt-theme-tech --destination /usr/share/nginx/webpage/tech --trace

使用 Let’s Encrypt 取得免費的 SSL 憑證

1.安裝 Certbot

sudo pacman -S certbot

2.修改Nginx設定

編輯 /etc/nginx/nginx.conf 並在 server block 中加入:

server {
    server_name  ankmak.com www.ankmak.com;
}

檢查設定

sudo nginx -t

重啟 nginx

sudo systemctl restart nginx

3.申請憑證

sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: ankmak.com
2: www.ankmak.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Certificate not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/ankmak.com.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Attempt to reinstall this existing certificate
2: Renew & replace the certificate (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Deploying certificate
Successfully deployed certificate for ankmak.com to /etc/nginx/nginx.conf
Successfully deployed certificate for www.ankmak.com to /etc/nginx/nginx.conf
Congratulations! You have successfully enabled HTTPS on https://ankmak.com and https://www.ankmak.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(申請 SSL 憑證前) 螢幕擷取畫面 2022-04-23 164020

(申請 SSL 憑證後) 螢幕擷取畫面 2022-04-23 200528

4.重導向 www 子網域至主網域

編輯 /etc/nginx/nginx.conf 並在 server block 中加入:

if ($host = 'www.ankmak.com') {
        return 301 https://ankmak.com$request_uri;
}

這樣不管是 www.ankmak.com 還是 ankmak.com,最終都是呈現我的主域名 ankmak.com

5.自動更新憑證

sudo crontab -e 裡加入

30 2 * * 1 /usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"

設定成每天的 2 點 30 分自動去更新憑證並且重新啟動 nginx

Domain Name

把 ank.pw 指向 ankmak.com

由於我的網域服務供應商是 Google Domain,這邊我就單純地設定永久轉址

2022-04-23 21_13_51-Google Domains - 網站 — Mozilla Firefox

圖片 圖片

這樣便大功告成!!! 以上就是我搬遷網站的全過程了

donate