2023年10月10日 星期二

Python 開發筆記 - Ping 與 WakeOnLan (WOL) 的應用

這假期恰逢公司機房斷電,復電後在想該怎樣把重要的機器喚起。由於 VPN 等相關機器群健康運作(如套裝 NAS 機器),因此得以遠端回去做事。

下一刻就是回顧有哪些機器要遠端啟動,這時就多虧了強者同事有良好的筆記習慣,平時有撰寫 WIKI 管控機器群(包括 MacAddress),就這樣,可在指定機器上不斷發動 WOL 來喚醒。例如有些 router 本身就提供網頁介面幫忙,可以直接靠他們。若有 Ubuntu 機器,就來個 wakeonlan 工具:

$ dpkg -l | grep wakeonlan
ii  wakeonlan                              0.41-10                                 Sends 'magic packets' to wake-on-LAN enabled ethernet adapters

在這邊 ubuntu.pkgs.org/20.04/ubuntu-main-arm64/wakeonlan_0.41-12_all.deb.html 也能查看到,甚至瀏覽一下工具原始碼 github.com/jpoliv/wakeonlan ,而 WOL 的原理可以查看 WIKI 就習得實作技能 en.wikipedia.org/wiki/Wake-on-LAN 或詢問 chatGPT 也會很佛心。

假期期間,就弄個 python 工具 ping-before-wakeonlan ,目的是為了記錄此次喚起了幾台機器,可以限縮每次喚起的機器數量,避免一堆機器一起起來而造成電力需求過大而跳電,另外再加入把清單亂數排一下,避免前面清單的機器都無法喚起,又讓清單後面的機器沒機會被叫起來:


使用方式,主要為 `pip install ping-before-wakeonlan` 即可,以下是 venv 用法:

% python3 -m venv venv
% source venv/bin/activate
% pip install ping-before-wakeonlan
% ./venv/bin/ping-before-wakeonlan
% cat /tmp/device.json
[
   {
       "ip": "192.168.1.1",
       "mac_address": "00:00:00:00:00:01"
   },
   {
       "ip": "192.168.1.2",
       "mac_address": "00:00:00:00:00:02"
   },
   {
       "ip": "192.168.1.3",
       "mac_address": "00:00:00:00:00:03"
   }, ...
]

% ping-before-wakeonlan --device-info /tmp/device.json
Process: 1 / 7: Device: {'ip': '192.168.1.3', 'mac_address': '00:00:00:00:00:03'}
Process: 2 / 7: Device: {'ip': '192.168.1.2', 'mac_address': '00:00:00:00:00:02'}
Process: 3 / 7: Device: {'ip': '192.168.1.1', 'mac_address': '00:00:00:00:00:01'}
Process: 4 / 7: Device: {'ip': '192.168.1.4', 'mac_address': '00:00:00:00:00:04'}
Process: 5 / 7: Device: {'ip': '192.168.1.5', 'mac_address': '00:00:00:00:00:05'}
{
    "count": 5,
    "device": {
        "failed": [],
        "handled": [
            {
                "ip": "192.168.1.3",
                "mac_address": "00:00:00:00:00:03"
            },
            {
                "ip": "192.168.1.2",
                "mac_address": "00:00:00:00:00:02"
            },...
        ],
        "input": [
            {
                "ip": "192.168.1.3",
                "mac_address": "00:00:00:00:00:03"
            }, ...
        ],
        "online": [],
        "skip": [
            {
                "ip": "192.168.1.6",
                "mac_address": "00:00:00:00:00:06"
            }, ...
        ]
    },
    "info": [
        "..."
    ],
    "maxCount": 5,
    "ping": "ping -c 1 -W 3",
    "status": true,
    "version": "1.0.0"
}

2023年10月4日 星期三

Python 開發筆記 - 使用 Gitlab API 列出 Projects、Branches 和 Commits

剛好碰到需要製作 Gitlab 整合類服務,開發完後就把很基礎的項目整理成小工具來支援 JSON 輸出,未來可以跟 jq 做一堆連續技:

用法:

% virtualenv venv
created virtual environment CPython3.11.5.final.0-64 in 120ms
...

% source venv/bin/activate
(venv) % 
(venv) % pip3 install gitlab-api-helper
(venv) % ./venv/bin/gitlab-api-helper 
{
    "info": [
        "config file not found: .env",
        "--api empty"
    ],
    "result": null,
    "version": "1.0.0"
}
usage: gitlab-api-helper [-h] [--apiSetupConfig APISETUPCONFIG]
                         [--apiAccessToken APIACCESSTOKEN] [--api API]
                         [--sinceType {day,week,month}]
                         [--sinceNumber SINCENUMBER]
                         [--lookup {project,branch,commit}]
                         [--lookupProjectID LOOKUPPROJECTID]
                         [--lookupBranch LOOKUPBRANCH]

A Simple Tool for Gitlab API Usage

options:
  -h, --help            show this help message and exit
  --apiSetupConfig APISETUPCONFIG
                        Read Default Info from config file
  --apiAccessToken APIACCESSTOKEN
                        Using Gitlab API with private_token.
  --api API             Gitlab API URL
  --sinceType {day,week,month}
                        commit date range type
  --sinceNumber SINCENUMBER
                        commit date range value
  --lookup {project,branch,commit}
                        query result
  --lookupProjectID LOOKUPPROJECTID
                        Gitlab Project ID
  --lookupBranch LOOKUPBRANCH
                        Branch Name

剩下就看 github.com/changyy/gitlab-api-helper 或 pypi.org/project/gitlab-api-helper/ 的簡介囉

2023年10月3日 星期二

PHP 開發筆記 - 用 Matomo Analytics HTTP API 取代 GA4 Measurement Protocol 服務 @ Ubuntu 22.04


由於 Google Analytics 4 在後端端數據搜集情境已殘,可能起源於 GA4 著重隱私等設計(?),現況數據收集已強調必須先從 Web or App 開始,透過 JS SDK 或 APP SDK 做事,而後端回報為輔助而已,在 Web & App 端可以做隱私宣告。如此,使得純後端回報幾乎無法妥善使用 GA4 的功能,包括無法區分 new user / old user 屬性等等,也不像 GA3 可以把 remote client 的 IP 回報出去而顯示使用者的世界全貌。

架設 Matomo 方式還滿簡單的,就 Web Server + PHP + MySQL ,並且官方也有 docker 安置方式:

由於看到別人的文章提到要記得設置定期分析任務,不然久久登入網頁會很卡的,推論也是從網頁端發送查詢資料,過程中也一同處理資料分析。這個用瀏覽器時,從開發者工具中也可以看到定期在發送 ajax 的 requests。


目前就先弄個 Matomo project 出來,根據上頭的指示很簡單就埋好 js script code 去追蹤網站流量,可以看得到 Matomo 比 GA 提供更多細膩的資訊,這就像隱私的那些規劃,在 GA 上頭只能很粗略地觀看到“趨勢”,而在 Matomo 上頭,則是可以細到把指定的 client 展開出他的 Profile:


我認為跟 GA 相比有滿明顯的設計差距。

接著,關於透過 REST API 回報數據與查詢回報的方式,可以參考:

回報 PageView/Event:

% cat test.php
require 'report.php';

print_r(matomoPageview(
[
[
'url' => 'http://localhost/page1',
'action_name' => 'PageView 01 - Title',
'uid' => '123456789012',
//'cip' => getUserIP(),
],
[
'url' => 'http://localhost/page2',
'action_name' => 'PageView 02 - Title',
'uid' => '123456789012',
//'cip' => getUserIP(),
],
[
'url' => 'http://localhost/page3',
'action_name' => 'PageView 03 - Title',
'uid' => '123456789012',
//'cip' => getUserIP(),
'e_c' => 'Service',
'e_a' => 'Auth',
'e_n' => 'Login',
],

]
,'idSite'
,'MatomoAPI'
));

% php test.php
Array
(
    [status] => 1
    [error] => 
    [info] => Array
        (
            [0] => Array
                (
                    [apiResult] => {"status":"success","tracked":1,"invalid":0}
                )

        )

)

得到 Report:

% cat test.php
require 'report.php';

print_r(matomoQueryReport(
        [   
                'idSite' => 1,
                'period' => 'day',
                'date' => '2023-10-01,2023-10-03',
                'method' => 'VisitsSummary.get',
        ]   
        , 'https://your-matomo.example.com/'
        , 'access_token'
));

% php test.php
Array
(
    [status] => 1
    [data] => Array
        (
            [0] => Array
                (
                    [2023-10-01] => Array
                        (
                        )

                    [2023-10-02] => Array
                        (
                        )

                    [2023-10-03] => Array
                        (
                            [nb_uniq_visitors] => 1
                            [nb_users] => 1
                            [nb_visits] => 1
                            [nb_actions] => 2
                            [nb_visits_converted] => 0
                            [bounce_count] => 0
                            [sum_visit_length] => 1
                            [max_actions] => 2
                            [bounce_rate] => 0%
                            [nb_actions_per_visit] => 2
                            [avg_time_on_site] => 1
                        )

                )

        )

    [error] => 
    [info] => Array
        (
        )

)

2023年9月26日 星期二

[Linux] OpenSSL AES-128 加解密 @ macOS 13.2.1, OpenSSL 3.1.2 1 Aug 2023

總覺得我是不是以前也寫過這類筆記? 查了下快十年前 XD 用的是 openssl des3 

由於工作中太常接觸 AES-128 加解密了,想要筆記一下方便未來查詢,而透過 openssl command 也方便交叉驗證程式是否正確,這次就仿 openssl des3 筆記:

明文:

% cat /tmp/input.txt
Hello World
% md5 /tmp/input.txt
MD5 (/tmp/input.txt) = e59ff97941044f85df5297e1c302d260
% hexdump /tmp/input.txt 
0000000 6548 6c6c 206f 6f57 6c72 0a64          
000000c

產生加解密的 Key 值:

% dd if=/dev/urandom of=/tmp/password bs=1 count=32
32+0 records in
32+0 records out
32 bytes transferred in 0.000303 secs (105611 bytes/sec)
% md5 /tmp/password 
MD5 (/tmp/password) = 92eeb8e1bec70865650e1f96e5cd1819
% hexdump /tmp/password 
0000000 cf23 5006 70d0 bf1e 0e9e a70c 10f0 ecd6
0000010 dc01 e156 d818 bff2 2e3e f859 28c9 a91d
0000020
% hexdump -v -e '/1 "%02x"' -n 16 /tmp/password 
23cf0650d0701ebf9e0e0ca7f010d6ec

產生加解密的 IV 值(其實同 Key 值產生即可,目前改用另一招):

% date | md5
5d6476c85eca3ec56fda4913f5578b83

使用 OpenSSL AES-128 加密:

% openssl enc -e -aes-128-cbc -in /tmp/input.txt -out /tmp/encrypt.txt -K 23cf0650d0701ebf9e0e0ca7f010d6ec -iv 5d6476c85eca3ec56fda4913f5578b83
% hexdump /tmp/encrypt.txt
0000000 c3d4 cb0a d845 182c 319e afdf b29c c484
0000010

使用 OpenSSL AES-128 解密:

% openssl enc -d -aes-128-cbc -in /tmp/encrypt.txt -out /tmp/output.txt -K 23cf0650d0701ebf9e0e0ca7f010d6ec -iv 5d6476c85eca3ec56fda4913f5578b83
% md5 /tmp/output.txt 
MD5 (/tmp/output.txt) = e59ff97941044f85df5297e1c302d260
% cat /tmp/output.txt 
Hello World

工作上很容易 Key 值是一個 32 bytes 的 binary 檔案,且不加入輸出至檔案的方式,可以立即看解密的內容,連續動作如下:

% openssl enc -d -aes-128-cbc -in /tmp/encrypt.txt -K $(hexdump -v -e '/1 "%02x"' -n 16 /tmp/password) -iv 5d6476c85eca3ec56fda4913f5578b83
Hello World

收工

2023年9月20日 星期三

Windows 開發筆記 - 使用 Command Line / CMD / ssh 與 PHP 8.2 / Composer / Git / VIM 開發環境 @ Windows 11

幫同事看了一下 Windows 開發環境,要在此環境使用 PHP8.2 與 PHP Laravel v10 framework,由於之前採用 xampp 管理套件被環境變數卡住。這些問題描述,瞬間拉回到學生時代在那邊設置 Windows %PATH% 環境變數 XD 我也忘了那時在幹嘛?推論是配置 Java 環境吧

目前就把手邊的 Windows 11 筆電拿來遠端,但懶得打開它。並且實際在 command line 測試會碰到幾個問題。

1. 從 https://windows.php.net/download/ 下載 VS16 x64 Non Thread Safe ,並解壓在 C:\php 目錄中,必須在設置 php.ini 。想要知道自己的 php.ini 位置,可以用 php.exe --ini

C:\php>php.exe --ini 
Configuration File (php.ini) Path: 
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

接著把 C:\php\php.ini-development 複製到 C:\php\php.ini 使用:

C:\php>copy php.ini-development php.ini     
複製了         1 個檔案。

後續就編輯 php.ini 開啟一些項目,在此就靠 C:\cygwin64\bin\vim.exe 當編輯器(若碰到滑鼠圈選文字難複製,記得關掉滑鼠模式 :set mouse-=a),主要打開一些 php.ini 註解:

; Directory in which the loadable extensions (modules) reside.
; https://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir = "ext"
; ...
extension=curl
extension=fileinfo
extension=gd
extension=intl
extension=mbstring
extension=exif
extension=mysqli
extension=openssl
extension=sqlite3

C:\php>php.exe --ini 
Configuration File (php.ini) Path: 
Loaded Configuration File:         C:\php\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

2. 下載 composer 後,預設會失敗:

C:\php>php.exe composer.phar self-update

In Factory.php line 648:
                                                                                                                          The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can   
   disable this error, at your own risk, by setting the 'disable-tls' option to true.                          

self-update [-r|--rollback] [--clean-backups] [--no-progress] [--update-keys] [--stable] [--preview] [--snapshot] [--1] [--2] [--2.2] [--set-channel-only] [--] [<version>]

設置後:

C:\php>php.exe composer.phar self-update 
You are already using the latest available Composer version 2.6.3 (stable channel).

3. 在管理專案時,透過 C:\php\php.exe composer.phar install 時,會需要 GIT 指令,解法就是去官方安裝一下,安裝完的目錄位置在 C:\Program Files\Git 位置

C:\>"C:\Program Files\Git\bin\git.exe" --version
git version 2.42.0.windows.2

4. 回過頭來,更新環境變數 %PATH% 

C:\>git
'git' 不是內部或外部命令、可執行的程式或批次檔。
C:\>echo %PATH%
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Docker\Docker\resources\bin;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\Users\user\AppData\Local\Microsoft\WindowsApps;
C:\>set PATH=%PATH%;C:\Program Files\Git\bin\
C:\>git --version
git version 2.42.0.windows.2

如此在 Windows 的 command line (PowerShell) 環境下,也可以靠純指令做一點事了