在 bash script 裡,可以用 ${RANDOM} 取亂數,例如
echo "random number: ${RANDOM}"
就會出現一個隨機的數字。
那如果想限制在 20~40 這個範圍內的話,可以怎麼做呢?這時候可以用 bash 的 % ,取餘數的運算子來做,例如
echo "random number(0~10): $((20 + RANDOM % 20))"
Just thinking more…
在 bash script 裡,可以用 ${RANDOM} 取亂數,例如
echo "random number: ${RANDOM}"
就會出現一個隨機的數字。
那如果想限制在 20~40 這個範圍內的話,可以怎麼做呢?這時候可以用 bash 的 % ,取餘數的運算子來做,例如
echo "random number(0~10): $((20 + RANDOM % 20))"
說明一下為什麼會要這樣作。
因為環境關係,DNS protocol 出不去,只有 A 主機可以透過 HTTP 出去。
因此方案如下:
cloudflared 蠻好安裝的,就一個執行檔,下載以後,改個權限就可以執行了 (安裝方式)
那如果要用 systemd 來啟動,也很容易,安裝方式裡就有提供範例:
[Unit]
Description=DNS over HTTPS (DoH) proxy client
Wants=network-online.target nss-lookup.target
Before=nss-lookup.target
[Service]
Environment=http_proxy=http://<proxy>:3128
Environment=https_proxy=http://<proxy>:3128
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5533
[Install]
WantedBy=multi-user.target
設定好,用 firewall-cmd 設定好防火牆 (TCP 5533) 以後,就可以去調整 BIND 的設定 /etc/named.conf。
修改既有的 forwarder 設定
forwarders { 127.0.0.1 port 5533; };
重新啟動 named 以後,就可以試試看了。
流程大致如下
--[DNS查詢]--> B 主機(53/UDP) ----> B 主機(5533/TCP) --[HTTP]--> A 主機(3128/TCP) --> 外部
需求是要找到從昨天到現在有變更的檔案,一時也想不出來怎麼做,利用 Google 找了一下,大多都是利用 find 的 -newer 參數。
find 的 -newer 參數要帶入的是一個檔案,表示會以這個檔案為基準來進行比對。
所以假設是要找 2023-11-11 之後的檔案,就先利用 touch 來建立一個基準檔案,其修改日期為 2023-11-11:
touch --date "2023-11-11" /tmp/base
然後再用
find . -newer /tmp/base -print
就可以找出在 /tmp/base 之後變更的檔案了。
find 也有一個 -newerXY 的參數,這個 XY 可以是以下內容
那要找比 2023-11-11 要新的檔案,就用以下指令
find . -type f -newermt 2023-11-11
要找特定一天的,就用以下指令
find . -type f -newermt 2023-11-11 ! -newermt 2023-11-12
執行 git clone 以後取得的修改時間是當下執行的時間,所以其實是沒辦法去判斷哪個檔案是七天前修改的,或是十天前修改的。
Stackoverflow 上有人問了相同的問題:Git clone changes file modification time – Stack Overflow
有人就回答了,其實 git 裡面沒有保留檔案修改時間的資訊,但可以有個 tricky 的方法,就是透過 git log 的資訊來變更檔案的修改日期:
git ls-tree -r --name-only HEAD | while read filename; do
unixtime=$(git log -1 --format="%at" -- "${filename}")
touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S')
touch -t ${touchtime} "${filename}"
done
這邊主要用到幾個指令,說明如下
git ls-tree 是取出檔案名稱git log -1 --format 是取出檔案提交的日期,這邊取出的是 timestamp 值date -d 將 timestamp 值,轉換為日期時間格式。touch -t 依據指定的日期格式去設定檔案的修改日期。這邊要注意,目錄的修改時間不會被更動到。
透過以上的腳本,就可以還原git簽出檔案的修改時間,然後再搭配 find 指令來找出七天前修改的檔案了。
若是想知道指定的套件會影響哪些套件,這時候可以怎麼做呢?
我第一個是想到可以用 rpm ,用 man rpm 可以查到 rpm 有以下參數
所以就試試看
rpm -q --whatrequires libweb
但結果卻不如預期,上網找到這篇 centos – Why does rpm –whatrequires fail to report dependencies? – Unix & Linux Stack Exchange
才知道正確用法是這樣,要先用 rpm -q --provides libwebp 去查到 libwebp 有提供什麼capability,然後再用 rpm -q --whatrequires <capability> 去找。
例如 libwebp
[root@workstation ~]# rpm -q --provides libwebp
libwebp = 1.0.0-5.el8
libwebp(x86-64) = 1.0.0-5.el8
libwebp.so.7()(64bit)
libwebpdecoder.so.3()(64bit)
libwebpdemux.so.2()(64bit)
libwebpmux.so.3()(64bit)
[root@workstation ~]# rpm -q --whatrequires "libwebp.so.7()(64bit)"
libwebp-1.0.0-5.el8.x86_64
gd-2.2.5-7.el8.x86_64
ImageMagick-libs-6.9.12.50-2.el8.x86_64
這樣就可以找到,但若是如此,就要寫腳本了。因為 libwebp 有提供多個 capability ,需要逐一去查才行。
有沒有更快的方法呢?
centos – Why does rpm –whatrequires fail to report dependencies? – Unix & Linux Stack Exchange 裡面有提到可以用 rpm -e --test ,直接模擬看看移除。
rpm -e --test libwebp 2>&1 | grep needed | awk '{print $6}' | sort | uniq
這樣就可以很快找出來了。
最近想試試看 wireguard,看了文件,都會提到用 ufw/firewalld 來配置網路,就想說,自家的 archlinux 都沒用防火牆,是不是該來用一下比較好。經過找 archlinux 文件以後,發現 archlinux 其實很自由,可以自由選 firewalld 或 ufw。在公司因為用 RHEL8 ,都是用 firewalld ,為了平衡一下還有家裡的其他電腦,決定就用 debian/ubuntu 的 ufw 。
ufw 的全名是 Uncomplicated firewall ,archlinux wiki 裡就有詳細的說明文件:https://wiki.archlinux.org/title/Uncomplicated_Firewall
用 yay 或 pacman 安裝
yay -S ufw
安裝好以後,先不要啟用,要先設定。
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw allow ssh
這幾行的意思是說,允許出去,禁止進來,只允許 ssh 服務的連線進來。
接著啟用
sudo ufw enable
sudo systemctl enable --now ufw
然後可以用 sudo systemctl status ufw 跟 sudo ufw status 檢查狀態。
接下來因為自己有用 http/https/gitlab/samba/squid 服務,也有使用 docker,所以要額外設置。
先允許 http/https 連線。
sudo ufw allow http
sudo ufw allow https
設置 docker 規則,docker 的部份有人寫好了,所以安裝套件以後再啟用即可。(ufw and docker),啟用以後,docker 容器有 expose 的 port 就會自動 allow。
yay -S ufw-docker
sudo ufw-docker install
再來是 samba,這也是有人寫好套件
yay -S ufw-extras
sudo ufw allow from 192.168.11.0/24 to any app samba
最後是 squid
sudo ufw allow from 192.168.11.0/24 to any port 3128 proto tcp
到這邊就設定完了,沒遇到什麼特別狀況。
因為好奇怎麼去查,就找到這篇:How to check if an RHEL system is vulnerable to a CVE ,文章裡面提到兩個方法。
第一個方法是用 rpm -q --changelog <套件> | grep <CVE_number>
舉個例子
rpm -q --changelog openssl | grep CVE-2021-3450
第二個方法是用 yum updateinfo info --cve <CVE_number>
舉個例子
yum updateinfo info --cve CVE-2021-3445
最後,想調查這台 RHEL 有受到哪些 Errata 影響,可以用
yum updateinfo info --summary
yum updateinfo info --list
若要帶入 CVE 資訊,可以用這兩個指令
yum updateinfo info --summary --with-cve
yum updateinfo info --list --with-cve
Red Hat 也有一篇 KB ,方法相似:https://access.redhat.com/solutions/3628301
不太一樣的地方是,指令是查看 rpm 的,所以是用
rpm -qp kernel-3.10.0-862.11.6.el7.x86_64.rpm --changelog | grep CVE-2017-12190
或者是用 yum list –cve <CVE_number>
yum list --cve CVE-2017-12190 | grep kernel.x86_64
想找到指定位置下的目錄,但不要再深入。指定位置下的目錄是這樣的
/tmp/location
+-- dir1
+ dir11
+-- dir2
+ dir21
foo.txt
我預期是只看到 dir1 跟 dir2,所以我用 find
find /tmp/location -type d -print
結果我找到的是
/tmp/location
/tmp/location/dir2
/tmp/location/dir2/dir21
/tmp/location/dir1
/tmp/location/dir1/dir11
find 的輸出跟我預期的不相符啊,我又不想用 ls 處理,後來找到 -maxdepth -mindepth 這兩個參數,搭配起來使用就可以了。
find /tmp/location -maxdepth 1 -mindepth 1 -type d -print
這樣就會是我需要的 dir1 跟 dir2
/tmp/location/dir2
/tmp/location/dir1
又學到一課,謝謝你 find 。
之前使用 enscript 來將文字檔轉為 pdf,但實測發現,若文字檔裡面是中文,那麼轉出來是亂碼。
只好找其他的方案,找到的是 paps: https://github.com/dov/paps
paps 比較麻煩的是需要自己安裝,安裝說明可以參考:https://github.com/dov/paps/blob/master/INSTALL.md
我的環境是 Ubuntu 20.04
第一個是需要 meson,這個直接用 apt-get 安裝就可以
sudo apt install meson
第二個是 fmtlib ,Ubuntu 20.04 內的 fmtlib 版本過舊,這邊需要借助 backports
sudo add-apt-repository ppa:savoury1/backports
sudo apt install libfmt-dev
最後就是編譯
https://github.com/dov/paps.git
cd paps
meson build
cd build && ninja
sudo ninja install
這樣就可以得到 paps 了。
因為客戶文件需要,得把一堆檔案輸出為pdf。懶人如我,當然要找一下是不是有好的方法可以達成這個需求。
第一個找到的是 pandoc ,這個工具好是好,但遇到 Ansible playbook ,pandoc 會以為檔案是設定檔,就沒辦法輸出。
第二個找到的是 enscript ,這工具就可以很輕易的將文字檔轉換為 postscript 檔案,同時還可以加上語法高亮效果,但可惜語法高亮效果不支援 Ansible playbook 。有了 postscript 檔案,接下來就可以用 ps2pdf 將 postscript 檔案轉換為 pdf。
# Ubuntu
sudo apt install ps2pdf enscript
enscript playbook.yml doc.ps
ps2pdf doc.ps doc.pdf
現在可以處理單一個檔案以後,接下來要想怎麼處理多個檔案,這裡透過 find, xargs 跟 enscript 的協作就可以做到
find . -name '*.yml' -print | xargs enscript --output=doc.ps
ps2pdf doc.ps doc.pdf
不免俗,還要加上頁首跟頁尾,頁尾也要加上頁次,這部份需要為 enscript 加上自訂的頁首跟調整頁尾的高度。
mkdir ~/.enscript
cp /usr/share/enscript/simple.hdr ~/.enscript/my.hdr
然後修改 ~/.enscript/my.hdr
% -- code follows this line --
%Format: fmodstr $D{%a %b %d %H:%M:%S %Y}
%Format: pagenumstr $V$%
%FooterHeight: 15
/do_header { % print default simple header
% Footer
gsave
d_footer_x d_footer_y HFpt_h 3 div add translate
HF setfont
user_footer_p {
d_footer_x d_footer_y moveto user_footer_left_str show
d_footer_w user_footer_center_str stringwidth pop sub 2 div
0 moveto user_footer_center_str show
d_footer_x d_footer_w add user_footer_right_str stringwidth pop sub
d_footer_y moveto user_footer_right_str show
} if
grestore
% Header
gsave
d_header_x d_header_y HFpt_h 3 div add translate
HF setfont
user_header_p {
5 0 moveto user_header_left_str show
d_header_w user_header_center_str stringwidth pop sub 2 div
0 moveto user_header_center_str show
d_header_w user_header_right_str stringwidth pop sub 5 sub
0 moveto user_header_right_str show
} {
5 0 moveto fname show
45 0 rmoveto fmodstr show
45 0 rmoveto pagenumstr show
} ifelse
grestore
} def
產出 postscript 的指令改為
find . -name '*.yml' -print | xargs enscript --fancy-header=my --header='$N||' --footer='|$%/%p|' --output=doc.ps
ps2pdf doc.ps doc.pdf
產出以後,會發現頁碼怪怪的,頁碼只有針對個別檔案,不是整份檔案,這下就傷腦筋了。經過Google 的幫忙,找到 pdftk 來幫忙。pdftk 是一個可以操作 pdf 的工具,可以作合併、加浮水印等等的功能。
最後的成果如下
DOC_PS=/tmp/doc.ps
RAW_DOC_PDF=/tmp/raw_doc.pdf
DOC_PDF=/tmp/doc.pdf
# 產出 postscript 檔案
find collections/ansible_collections/gov/twgcb/roles -name '*.yml' -print | xargs enscript \
--fancy-header=my \
--header='$N||' \
--footer='| |' \
--output=${DOC_PS}
# 前個步驟有產出 ps 檔案
if [[ -f ${DOC_PS} ]]; then
# 先轉為 pdf
ps2pdf ${DOC_PS} ${RAW_DOC_PDF}
# 取得頁數
number_of_pages=$(pdftk /tmp/doc.pdf dump_data | grep NumberOfPages | sed 's/NumberOfPages: //g')
# 印出
echo "number_of_pages=${number_of_pages}"
# 先產生一份空白的 pdf ,頁次重新編排,然後把這份 pdf 當作是前面產生的 pdf 的浮水印
# 這樣頁次就是對的了。
enscript -L1 --fancy-header=my --header='||' --footer '|$% / $=|' -o- < \
<(for i in $(seq 1 $number_of_pages); do echo; done) | \
ps2pdf - | \
pdftk ${RAW_DOC_PDF} multistamp - output ${DOC_PDF}
fi