それマグで!

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

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

macでwq-quick のDNS設定使うとDNS問い合わせがおかしくなる

mac で wireguardをコマンドから使うと・・・

wg-quick を使って設定からDNSを設定しているのですが、DNSがおかしくなるのです。

wireguard のコマンド wg-tools をhomebrew でインストールし、それを使ってWiregurard接続をした。

接続は問題なく稼働する。だが、接続切断後後にDNS設定が元に戻されない。

調査してみた。

up / down を繰り返して表示されるログを確認した。

wg-quick up wg0
wg-quick down wg0

接続に使った設定は次の通り。

[Interface]
PrivateKey = YE7mc**************
Address = 172.16.4.3
DNS= 192.168.1.1

[Peer]
PublicKey = Dgh8*********s=
EndPoint= mydns.example.com: 12345
PresharedKey= 9YnmaD4***********fPvY=
AllowedIPs = 0.0.0.0/0

wg-quick の設定に DNS を設定している。

接続コマンドの実行結果

上記設定で実行すると、接続とDNS設定はうまくいくのだが、、、、DNSの書き換えが乱暴

takuya@wireguard$ wg-quick up wg0
(略
[#] networksetup -setdnsservers Bluetooth PAN 192.168.2.1
[#] networksetup -setdnsservers Wi-Fi 192.168.2.1
[#] networksetup -setdnsservers USB 10/100/1000 LAN 192.168.2.1
[+] Backgrounding route monitor

すべてのネットワーク接続設定に対し、set DNSが発行されています。

この設定はあまりにも乱暴だと思うんです。

切断後も残る。

切断してみると。DNS設定を削除していないことがわかります。

takuya@wireguard$ wg-quick down wg0
Warning: `/usr/local/etc/wireguard/wg0.conf' is world accessible
[+] Interface for wg0 is utun2
[#] rm -f /var/run/wireguard/utun2.sock
[#] rm -f /var/run/wireguard/wg0.name

接続時にはDNSを設定して、切断後にはDNS設定を消してないんですね。

設定が残ってしまった。これを確認する。

本当に設定が残ってしまったのか、確認してみます。

IFS=$'\n'; for i in $( networksetup  -listallnetworkservices | \grep -v aster); do echo "networksetup -getdnsservers  $i";networksetup -getdnsservers  $i  ;done

networksetup -getdnsservers  Bluetooth PAN
192.168.1.1
networksetup -getdnsservers  Thunderbolt ブリッジ
192.168.1.1
networksetup -getdnsservers  PPPoE
192.168.1.1
networksetup -getdnsservers  mopera
192.168.1.1
networksetup -getdnsservers  USB 10/100/1000 LAN
192.168.1.1
networksetup -getdnsservers  iPhone USB 3
192.168.1.1

これは残ってますね。これではVPN(Wiregurard)を接続していないと何もできなくなります。というかWiregurardのPeer先をIPでなくホスト名(ドメイン名)で指定していると二度と接続できなくる。

未削除で残存するDNS

マジか。こりゃ大変だ。ローカルDNSを参照したら詰む。

これは wg-quick のバグですね。

設定を削除します。

これでは大変なので、設定を一旦リセットしました。

IFS=$'\n'; for i in $( networksetup  -listallnetworkservices | \grep -v aster);do ;networksetup -setdnsservers $i "Empty" ;done

wg0.conf からDNSの設定を削除します。

原因は、wg-quick の設定でDNSエントリでのネットワーク設定が、妙ちくりんなで、それを使ったためです。

ということは、DNS設定は、マニュアルで PostUp / PostDown で書くしかありません。

wg0.conf

[Interface]
PrivateKey = XXXXXXXYE7mc=
Address = 172.16.0.3
### !ここが今回のエラーの原因。
# DNS= 192.168.1.1

[Peer]
PublicKey = XXXXXXXXXXXjs=
EndPoint= mydns.example.com:12345
PresharedKey= XXXXXXXXXfPvY=
AllowedIPs = 0.0.0.0/0

PostUp/PostDownをDNSの代わりに使います。

networksetup  -listallnetworkservices | \grep -v as  |  xargs -d '\n' -n 1 echo networksetup -setdnsservers $i "Empty" 

私は、GNU Xargsを使っているので、 -d のデリミタオプションで解決している。しかし、BSDPOSIX xargs だともっと大変になるだろう

PostUp   = bash -sc 'networksetup  -listallnetworkservices | \grep -v as  |  /Users/takuya/.bin/xargs -d "\n" -n 1 -I@  networksetup -setdnsservers @ "192.168.1.1"'
PostDown = bash -sc 'networksetup  -listallnetworkservices | \grep -v as  |  /Users/takuya/.bin/xargs -d "\n" -n 1 -I@  networksetup -setdnsservers @ "Empty"'

wireguard のDNS設定は危ういですね。

sed で改行削除/sedで全文(複数行マッチ)

sed で改行を消してCSVにしたい。

コマンドの結果の改行を消してCSVのようなカンマ区切りに変換したい。

他の置換ツールや python / rubyワンライナーに回せばいいと思うけど、sedでできたほうが汎用性が高そう。そのためsedで改行を置換、改行を別の文字に変えてCSVのような文字区切りをやってみる。

sed は行ごとの処理

sed は、「行ごと」で処理するのが基本動作なので、改行にマッチとか、改行を削除することはできない。

grep でもそうなんだけど、行処理が暗黙の前提なものを全体マッチにするときは、ちょっとオプションを見てあげると解決。

全体にマッチする。

マッチする箇所を「全体」に設定してあげるといい。

networksetup  -listallnetworkservices | \grep -v as | sed -z 's/\n/,/g'

-z オプション

-z オプションを使って、複数行に亘るマッチングができる。z は「全文・全体」と覚えれば絶対に忘れない。

bsd sed / gnu sed

macos で試したが、 -z があるのは GNU sed のみ。

macos などのBSDななsedでは、次のように。

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'

macの場合は、brewgnu sed ( gsed ) をインストールしてもいいですね。

参考資料

https://orebibou.com/ja/home/201607/20160714_003/

マルチコアの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で使い切ったほうが絶対早い。

参考資料