それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

マルチコアのCPUを使い切って圧縮を速くする

gzip の限界 = CPU 1コア

マルチコア・マルチスレッドのCPUがあるのに、gziplzma(xz)や bzipといったメジャーな圧縮は、CPUを1コアで処理するんですね。

CPU使用率を見てみたら、CPU利用率は100%を超えないんですね。

HDD・SSDの書き込み速度に限界があるからそれでも良かったんだろうが。いまはメモリが一般的に64GBもある時代です。うちのマシンでもメモリが12GBもあるのに3GB程度の圧縮に、5分とか耐えられません。もうちょっと速くしたい。

cpu利用率が100%で頭打ちになる。gzip

gzipを使ってると、CPU利用率が100%で止まるんですよね。lzma などの他の圧縮でも同じ。

f:id:takuya_1st:20210413030211p:plain

gzip/ gunzip をマルチで処理する pigz / unpigz

Pigz のマニュアルには次のように書いてある。スレッドを使って並列処理をするっぽい。

Pigz  compresses using threads to make use of multiple processors and cores.  The in‐
       put is broken up into 128 KB chunks with each compressed in parallel.  The individual
       check  value  for  each chunk is also calculated in parallel.  The compressed data is
       written in order to the output, and a combined check value is calculated from the in‐
       dividual check values.

実際にやってみると

cpu の利用率が、グンと上がる。CPUが余ってるなら、圧縮でもCPUをフルに使ったほうが良さそう。

f:id:takuya_1st:20210413031647p:plain

インストール

gzip の場合

sudo apt install pigz

bzip の場合

sudo apt install pbzip2 

xzの場合

sudo apt install pixz

まとめてインストールできない感じなのが辛い。piXXだとか pbzip2 とか表記が揺れているのも辛い。

詳しくは、参考資料に上げたURLに記載されているコマンドを必要に応じてインストールする必要がある。

7z でも マルチスレッド対応らしいが、time 7z a -mmt=on sample.gz ./sample を見た感じだと、gzipなどはマルチコア・マルチスレッドを使わないようだ。

実行速度比較

使用したCPU

takuya@livaz:~$ 7z

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,
64 bits,4 CPUs Intel(R) Pentium(R) CPU N4200 @ 1.10GHz (506C9),ASM,AES-NI)

使用したファイル

takuya@livaz:/var/lib/libvirt/images$ ll -h sample
-rw-r--r-- 1 takuya takuya 3.6G Apr 13 02:04 sample

gzip での速度

takuya@livaz:/var/lib/libvirt/images$ time gzip sample

real    4m10.198s
user    3m58.115s
sys     0m5.359s

pigz での速度

takuya@livaz:/var/lib/libvirt/images$ time pigz sample

real    1m38.232s
user    4m56.837s
sys     0m9.070s

比較

real で比較

コマンド real user
gzip 4m10.198s 3m58.115s
pigz 1m38.232s 4m56.837s

CPUを4スレッド使うことで、ちゃんと約4倍の時間を稼げていることがわかる。もちろん分散のオーバーヘッドが入るので、完璧に1/4にはならないのですが。

まとめ

CPUが余ってるなら マルチスレッドをCPUで使い切ったほうが絶対早い。

参考資料

OPNSense でAPIを使う。

opnsense でAPIを使う。

APIを使うには、キーが必要

APIのリクエストのエンドポイント(OPNSenseのアドレス)

APIのリクエストのパス(ドキュメントから)

キーの作成

APIの認証キーの作成は、管理画面から行える。

ユーザーをクリック、編集、APIキー作成を選んで作成。作成するとキーファイルがダウンロードされる。

ユーザを選んで

f:id:takuya_1st:20210412173639p:plain

キーを作成。

f:id:takuya_1st:20210412173703p:plain

ファイルがダウンロードされる。

f:id:takuya_1st:20210412173724p:plain

かんたんにリクエストを投げてみる。

作成されたファイルは、イコールで結ばれたキーバリューなのでそのままソースコードBashに貼り付けて使える。

key=XXX
secret=XXX

これを curl コマンドとして作成。

f:id:takuya_1st:20210412173818p:plain

あとはリクエストを投げるだけ。

サンプルで投げたAPIリクエストは、 ファームウェアの更新状況が完了しているか見るもので、マニュアルはここ ( https://docs.opnsense.org/development/api/core/firmware.html ) にある。

設定をAPIでバックアップする

たとえば、設定をAPI経由でバックアップするのは、システムのファームウェアから、os-api-backup のパッケージを追加する。 すると、API経由でXMLがダウンロードできるようになる。

パッケージインストール

f:id:takuya_1st:20210412174507p:plain

リクエス

key=XXXX
secret=XXXX
host=192.168.1.1
curl -k -u $key:$secret https://${host}/api/backup/backup/download -o config.$(date -I).xml

これで設定のバックアップは自動化できる。pfsense/OPNsenseは良く出来てるよなぁ。

参考資料

Firmware — OPNsense documentation

https://forum.opnsense.org/index.php?topic=18218.0

SPFからGoogleのSMTPのIPアドレスをぱぱっと調べる。

Google GMAILSMTPIPアドレス範囲

以前、Google workspaceで のGmailに存在しないアドレスはローカルのSMTPサーバーで処理するように、メールのルーティングルールを書いたわけですが。

ルールをかいたので、ローカルのSMTPサーバーへは、Gmailからメールが転送されてくるわけです。

しかし、ローカルの「ポート25」を全部開放すると大変なことになるわけです。もちろんPostfixのフィルタやスパムフィルタで処理もしているのですが、やっぱり スパムはとんでもない量が飛んでくるために、Postfixが詰まってしまうし、スパムフィルタでCPU使用率も跳ね上がるわけです。

そこで、IPアドレス範囲を絞ってGmailSMTPリレー以外をドロップするようにFWに記述し、port 25 のアクセスをSPFベースで絞ったほうがマシであろうと思われるわけです。

Google IP address ranges for outbound mail servers - Google Workspace Admin Help

SFP を見てみる。

gmailSPFのTXTレコードは次のようになっている。

$ dig txt gmail.com +short | grep spf
"v=spf1 redirect=_spf.google.com"

gmailspf 一覧は _spf.google.com に書かれているとわかる。

SFPレコードからinclude を取り出す。

では、_spf.google.com を調べてみる。

dig txt  _spf.google.com +short | $(which grep) -Po '(?<=include:)[^\s]+'

SFPレコードを見てみると

$ dig txt  _spf.google.com +short
"v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"

これをgrep でマッチすることで、

dig txt  _spf.google.com +short | $(which grep) -Po '(?<=include:)[^\s]+'
_netblocks.google.com
_netblocks2.google.com
_netblocks3.google.com

ここで、include なので、3つのドメイン名のTXTレコードを合わせたものが、GmailSPFだとわかる。

spf レコードから IPアドレスを取り出す。

それでは、 _netblocks.google.com をさらに見てみる。

dig txt   _netblocks.google.com +short | $(which grep) -Po '(?<=ip4:)[0-9\./]+'

これを実際に実行してみると、次のようになる。

dig txt   _netblocks.google.com +short | $(which grep) -Po '(?<=ip4:)[0-9\./]+'
35.190.247.0/24
64.233.160.0/19
66.102.0.0/20
66.249.80.0/20
72.14.192.0/18
74.125.0.0/16
108.177.8.0/21
173.194.0.0/16
209.85.128.0/17
216.58.192.0/19
216.239.32.0/19

これで、IPアドレスが得られることがわかる。

gmailSPFのTXTレコードについて。

ここまでで、GmailSPFレコードは、次のような階層を用いて管理されているとわかる。

redirect → include  → ipv4:[address/mask address/mask address/mask]

まとめてIPアドレスがを取り出す。

for i in $( dig txt  _spf.google.com +short | \grep -Po '(?<=include:)[^\s]+' ); do 
  dig $i +short  txt  | \grep -Po '(?<=ip4:)[0-9\./]+'
done

これを実行することでSPFレコードに記載されたIPアドレスが得られることがわかる。

for i in $( dig txt  _spf.google.com +short | \grep -Po '(?<=include:)[^\s]+' ); do 
 dig $i +short  txt  | \grep -Po '(?<=ip4:)[0-9\./]+';
done | sort  -n | uniq
35.190.247.0/24
35.191.0.0/16
64.233.160.0/19
66.102.0.0/20
66.249.80.0/20
72.14.192.0/18
74.125.0.0/16
108.177.8.0/21
108.177.96.0/19
130.211.0.0/22
172.217.0.0/19
172.217.128.0/19
172.217.160.0/20
172.217.192.0/19
172.217.32.0/20
172.253.112.0/20
172.253.56.0/21
173.194.0.0/16
209.85.128.0/17
216.239.32.0/19
216.58.192.0/19

SPFレコードからIPアドレス範囲を得ることで、送信元のIPアドレスを見ることができる、そしてそのIPアドレスをから 送られてきたメールのみに絞ることができるが、FWのフィルタリングにも使えそうであるとわかる。

今回使った grep

上記の例で使ったGREPのコマンドは、GNU grep拡張正規表現を用いて、マッチした場所を取り出すオプションと、先読みを使っている。そのために随分とシンプルになって嬉しい。

参考資料

Google IP address ranges for outbound mail servers - Google Workspace Admin Help