2022年8月25日 星期四

使用 curl 指定 Server IP 檢驗 SSL 憑證 (SKIP DNS LOOKUP)

原先是想要做 curl -I https://IP 檢驗時,在想怎樣處理憑證檢驗,像是多塞 "Host: test.com" 是不是有用,最後查了一下,要反過來想,可以多增加 --resolve 參數去指定,如此就可以測試指定的機器了

% man curl 
...
       --resolve <[+]host:port:addr[,addr]...>
              Provide a custom address for a specific host and port pair. Using this, you can make the curl requests(s) use a specified
              address and prevent the otherwise normally resolved address to be used. Consider it a sort of /etc/hosts alternative
              provided on the command line. The port number should be the number used for the specific protocol the host will be used for.
              It means you need several entries if you want to provide address for the same host but different ports.

              By specifying '*' as host you can tell curl to resolve any host and specific port pair to the specified address. Wildcard is
              resolved last so any --resolve with a specific host and port will be used first.

              The provided address set by this option will be used even if --ipv4 or --ipv6 is set to make curl use another IP version.

              By prefixing the host with a '+' you can make the entry time out after curl's default timeout (1 minute). Note that this
              will only make sense for long running parallel transfers with a lot of files. In such cases, if this option is used curl
              will try to resolve the host as it normally would once the timeout has expired.

              Support for providing the IP address within [brackets] was added in 7.57.0.

              Support for providing multiple IP addresses per entry was added in 7.59.0.

              Support for resolving with wildcard was added in 7.64.0.

              Support for the '+' prefix was was added in 7.75.0.

              This option can be used many times to add many host names to resolve.

              Example:
               curl --resolve example.com:443:127.0.0.1 https://example.com

              See also --connect-to and --alt-svc.

這用法可以用在 load balancer 或 GeoDNS 後面的機器群測試,也能拿來測試某機器的 SSL 憑證是否設定正常。

2022年8月23日 星期二

Cloudflare 1.1.1.1 FOR FAMILIES 提供阻擋惡意網站與成人網站的 DNS 查詢服務


最近跟朋友聊天,才發現 Cloudflare 除了提供 1.1.1.1 反應速度極快的 DNS 查詢服務外,還有提供阻擋惡意網站、成人網站的 DNS 查詢服務!當發現是惡意網站時,直接給予 0.0.0.0 (查不到) 的回饋,如此使用者在瀏覽網站時,不小心點擊到的惡意連結也不會瀏覽到,對於家裡有長輩、小孩的環境來說,真的很不錯。

大概五六年前在幫公司做 使用者生成內容 (User-generated content) 時,再加上規劃權限機制,打算從大家公開的資料中,整理出熱門的網站/影片連結出來,這時就會踩到有人擺了色情網站等問題,那時則是做了一套 URL Checker/Filter (SPAM) 機制,透過網域黑名單做的。現在,單純用 Cloudflare 提供的 DNS 來查詢也能直接達到類似的效果。

Cloudflare 1.1.1.1 FOR FAMILIES: https://one.one.one.one/family/
  • 1.1.1.1
    • 與 Google 8.8.8.8, 8.8.4.4 同樣效果但標榜更快、更注重隱私
    • 2018.04.01 開始的服務
  • 1.1.1.2, 1.0.0.2
    • 可阻擋惡意網站: Malware Blocking Only
  • 1.1.1.3, 1.0.0.3
    • 可阻擋惡意網站+成人網站: Malware and Adult Content Blocking Together
如此,在疫情後常態在家上課時,小孩拿手機平板連到家裡的 WIFI AP ,這時在 WIFI AP 的 DHCP 設置 DNS = 1.1.1.3 , 1.0.0.3 後,就可以簡單防護到所有連到此 WIFI AP 的設備,可防止小孩誤點、誤連到惡意網站和成人網站內容,畢竟有不少惡意網站/成人網站仍會買流量的,立即能避開一堆奇怪廣告。當然,對長輩來說也有一樣的效果。

圖:TP-Link WIFI AP 之 DHCP 設定 主要 DNS / 次要 DNS

其他:

2022年8月20日 星期六

Go 開發筆記 - 簡易 WebSocket Client 練習,WSS 與 Skip SSL Check

公司的 WebSocket Server 使用 node.js Primus 建構服務,最近正在調整架構,弄隻 WebSocket Client 交叉比對,這時就想到 Golang 可以練一下 XD 預設先以 PTT 的 WebSocket 為例 wss://ws.ptt.cc/bbs 練習,而 PTT WebSocket 連線時,有檢查 Request Header 的 Origin 欄位的,完整的用法請直接使用 https://term.ptt.cc 。

實作上,直接用 Gorilla WebSocket 即可,用他建制 WebSocket server 跟 client。

此外,對於 WebSocket over SSL (wss) 連線瑣事上,若要處理 SKIP SSL Check 這件事,可以這樣處理:

// https://pkg.go.dev/crypto/tls
type zeroSource struct{}
func (zeroSource) Read(b []byte) (n int, err error) {
    for i := range b { 
        b[i] = 0 
    }   
    return len(b), nil 
}

func main() {

// ...

    var dialer ws.Dialer
    if *skipSSLCheck {
        fmt.Println("[IFNO] Skip SSL check")
        // https://github.com/gorilla/websocket/blob/master/client.go
        // https://github.com/gorilla/websocket/blob/master/tls_handshake.go
        dialer = ws.Dialer{
            Subprotocols: []string{},
            ReadBufferSize: 2048,
            WriteBufferSize: 2048,
            TLSClientConfig: &tls.Config{
                Rand: zeroSource{},
                InsecureSkipVerify: true,
            },
        }
    } else {
        dialer = ws.Dialer{
            Subprotocols: []string{},
            ReadBufferSize: 2048,
            WriteBufferSize: 2048,
        }
    }
    fmt.Println("[IFNO] try to connect to: ", connectToURL)

// ...

}

至於跟 node.js Primus WebSocket server 溝通時,會有 PING/PONG 的 heartbeat 檢驗,目前偷懶等收到 server 詢問時才回,此外,實際上可以靠 messageType (Control Messages) 來判斷:

    go func() {
        defer func() {
            wg.Done()
        }()
        for {
            _, p, err := conn.ReadMessage()
            if err == nil {
                cmd := string(p)
                fmt.Println("SERVER> ", cmd)

                    if strings.Index(cmd, "\"primus::ping::") >= 0 {
                        text := fmt.Sprintf("\"primus::ping::%d\"", time.Now().UnixMilli())
                        fmt.Println("CLIENT:AUTO> [",text,"]")
                        conn.WriteMessage(ws.TextMessage, []byte(text))
                    }

            } else {
                fmt.Println("SERVER:ERROR> ", err)
                break
            }
        }
        fmt.Println("[IFNO] server error")
    }()

更多完整的資訊,就直接參考 github.com/changyy/go-ws-client

2022年8月8日 星期一

PHP 開發筆記 - 在 Windows 10 上配置 cmd line 開發環境


這個故事說來話長,我本身不會在 Windows 開發,但為了同事只好配置環境出來,交叉比對運作的問題。就筆記一下,這次要做的事就弄到純 cmd line 開發環境:

安裝:

如此,在 cmd 就可以靠純指令工作,像是 composer install ,而在 cmd line 中有 vim 編輯器,可以快速編輯小東西。

2022年8月3日 星期三

PHP 開發筆記 - 關於 CodeIgniter4 starter app / PHP Coding Standards Fixer v3.9.5 / PHP 7.4 @ macOS 與 Windows

之前初探 PHP Coding Standards Fixer (php-cs-fixer) 時,略知預設跑下去已經有一定水準的 Coding Style 制約機制,然而,工作上引導同事在使用時,碰到了一些雷區。

首先是用 CodeIgniter 4 官方文件建立出的資料後,要跑 PHP Coding Standards Fixer 時會出現要修正語法的問題

```
// https://www.codeigniter.com/user_guide/installation/installing_composer.html
% composer create-project codeigniter4/appstarter project-root
% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.9.5 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
.....F......................................F.............                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error
   1) app/Config/Logger.php (ordered_imports)
   2) app/Views/errors/html/error_exception.php (braces, unary_operator_spaces, not_operator_with_successor_space)

Checked all files in 1.104 seconds, 16.000 MB memory used
```

然後故意降版本到 v3.8.0 又可以正常

```
% mv composer.json composer.json-bak
% composer require friendsofphp/php-cs-fixer:3.8.0 --dev
% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.8.0 BerSzcz against war! by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config default.
Using cache file ".php-cs-fixer.cache".
..........................................................                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

Checked all files in 0.303 seconds, 14.000 MB memory used
```

為了避免未來同事不同平台開發的困局,就來安分地寫一下 .php-cs-fixer.dist.php 檔案吧!也順道研究到 CodeIgniter 也有個 CodeIgniter/coding-standard 規範,接著參考 github.com/CodeIgniter/coding-standard#setup 一步一步測試

```
% cat .php-cs-fixer.dist.php
<?php

use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;

return Factory::create(new CodeIgniter4())->forProjects();

% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.9.5 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
.....F......................................F.............                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error
   1) app/Config/Logger.php (ordered_imports)
   2) app/Views/errors/html/error_exception.php (braces, unary_operator_spaces, not_operator_with_successor_space)

Checked all files in 1.104 seconds, 16.000 MB memory used
```

開始先找一下怎樣略過那兩個檔案的用法:

```
% cat .php-cs-fixer.dist.php
<?php
use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;
use PhpCsFixer\Finder;

// https://github.com/codeigniter4/CodeIgniter4/blob/develop/.php-cs-fixer.dist.php
$finder = Finder::create()
->files()
->notPath([
'app/Config/Logger.php',
'app/Views/errors/html/error_exception.php',
]);

// https://github.com/NexusPHP/cs-config/blob/develop/src/Factory.php
//return Factory::create(new CodeIgniter4())->forProjects();
return Factory::create(new CodeIgniter4(), [], [
'finder' => $finder,
])->forProjects();

% ./vendor/bin/php-cs-fixer fix --dry-run .
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".

Checked all files in 0.032 seconds, 14.000 MB memory used
```

接著去 Windows 跑:

```
C:\path>.\vendor\bin\php-cs-fixer fix --dry-run .
PHP CS Fixer 3.9.1 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "C:\path\.\.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF          56 / 56 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

   1) app\Common.php (line_ending)
  ...
  55) tests\_support\Libraries\ConfigReader.php (line_ending)
  56) tests\_support\Models\ExampleModel.php (line_ending)

Checked all files in 1.187 seconds, 16.000 MB memory used
```

最後再加個 line_ending 來處理一下:

```
% cat .php-cs-fixer.dist.php
<?php
use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;
use PhpCsFixer\Finder;

// https://github.com/codeigniter4/CodeIgniter4/blob/develop/.php-cs-fixer.dist.php
$finder = Finder::create()
->files()
->notPath([
'app/Config/Logger.php',
'app/Views/errors/html/error_exception.php',
]);

// https://github.com/NexusPHP/cs-config/blob/develop/src/Factory.php
//return Factory::create(new CodeIgniter4())->forProjects();
return Factory::create(new CodeIgniter4(), [], [
'finder' => $finder,
// https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/3955
'lineEnding' => PHP_EOL,
])->forProjects();
```

收工!