それマグで!

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

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

tcpdump で UDP のパケットを表示する

tcpdump を使って UDP を指定する

tcp は syn ack があってパケットがたくさん出てきますが、 UDP はそうでもない。

tcpdump -i eth0 udp

UDPIPアドレスを指定する

tcpdump のコマンドは、フィルタ単体というより、いくつかのフィルタを組み合わせて使うのが便利。

tcpdump -i eth0  dst 192.168.2.206 and udp

and をつかって dst /src のIPなどと組み合わせてやれば、リアルタイムにパケットをきれいに見ることができる。

Number と parseInt()の挙動の違い / 数字に変換するとひと言でいうが奥深い

parseInt と Number の挙動の違い。

parseInt と Number という2つがある。文字列 → 数値の型変換の関数を使おうとしてみんな一度くらいこの違いが気になるんじゃない?

違いをパパッと確認しよう

parseInt と Number の差異が如実に顕出するのは、次の例ではないでしょうか。

// 文字列が含まれる
parseInt("64GB")   //  64
Number("64GB")  // NaN
// 少数
parseInt("0.1")  //  0
Number("0.1")   // 0.1

IntがほしいならparseInt が便利。

parseInt の結果を見てほしい

parseInt("1")      //  1
parseInt("10")     //  10
parseInt("0.1")    //  0
parseInt("010101") //  10101
parseInt("64GB")   //  64
parseInt("¥64")   // NaN
parseInt("64円")   // 64
parseInt("第64回") // NaN
parseInt("2e1")    // 2
parseInt("0xFF") // 255
parseInt("0xFF times")// 255

少数が処理できないという、parseInt の名前の通りの仕様を除けば、概ね楽ちんに変換できる。

事前に文字列を処理して、必要なフォーマットに変換する手間がない。

parseInt は関数の名前( parseInt =Int に解釈する )の通りの動作だったり。

Number は本当の意味で型変換

Number は JS の Number 型であり、Number型の変数を返すので、本当の意味で型変換だと思うの

Number("1")    // 1
Number("10")   // 10
Number("0.1")   // 0.1
Number("010101") // 10101
Number("64GB")  // NaN
Number("¥64")  // NaN
Number("64円")  // NaN
Number("第64回") // NaN
Number("2e1")  // 20
Number("0xFF") // 255
Number("0xFF times") // NaN

個人的な結論

parseIntは、単位が含まれたりする入力値してぱぱっと数字へ変換したいとき → 10px とか 100円とか、CSSの値を数値にしたいときに便利

Numberは厳密に文字列事前処理し、その結果を数字に正確に変換するときに使う。

基本はNumberを使う、事前処理などを無精するときはparseIntもまだまだ許容されると思う。

少数にならないCSSの文字列 element.style.width とか処理をするなら重宝する。

tcpdump コマンドで ping の応答 ( icmp echo reply ) だけに絞り込む

tcpdumpping の 応答パケットだけを取り出す。

tcpdumpLinuxルーターのなかで実行しているときに、デバッグしてるときにパケットを見ます。

ネットワーク間の forward が正しく動いているか、iptables の設定が正しいかどうか、NATできてるかどうか。など。

ちょっとした調査でping を打ち込んで調べることが多いと思います。そういうときに、icmp だけ取り出しても表示が多すぎて面倒くさい。

reply だけを表示する

tcpdump  icmp[icmptype] = icmp-echoreply'

指定のホストから reply が戻ってきたか調べる

IP を指定と組み合わせて使うと便利

tcpdump  src 192.168.1.1 and icmp[icmptype] = icmp-echoreply'

指定のホストに echo リクエストが転送されか調べる

逆も同じ

tcpdump  'dst 192.168.100.1 and icmp[icmptype] = icmp-echo'

組み合わせで便利。

バイスを指定したり、IPを指定で便利になる。単純に icmp を見るよりいいと思う。echo / echo-reply を表示するターミナルを開けておいて、設定を反映させる。

設定を変えたあと、画面にログが表示され始めたら、ネットワーク設定が正しく行えたことがわかる。

ログが流れないなら、設定ミスってるってわかるので視覚的にわかりやすくていい。中身見なくていいのが強い。

設定ミスしがちな「戻りパケット」の経路設定の切り分けをするときに、明確に分かれるから面白い

参考資料

https://hackertarget.com/tcpdump-examples/

ssh のポート転送をipv6 / ip6 宛にする

ssh のポートフォワーディングのやり方IPv6アドレス編

ssh のポート転送は便利で手軽に使えるものです。

ipv6 でも同じです。

ssh -L 8080:[2001:a253:838xxxxxx]:80  root@192.168.100.1

sshでもIPv6の指定はcurlなど同じ

[v6 addr]:port のように、ブラケットで囲めばいい。

[2011:123:ff:]:port

関連資料

takuya-1st.hatenablog.jp

tcpdump で icmp (ping)のパケットを表示する

icmp で ping の受信を見たい

tcpdump を使って届いてるパケットを見ることが出来る。 ping の応答が返ってこないしとしても、応答パケットのルーティング設定が間違っている可能性もある。

そのため、ping の宛先でパケットがちゃんと届いているかチェックするとルーティングテーブルの問題を切り分けやすい。

tcpdump icmp

これで、ping パケットを見ることが出来る。

icmp を送信元で絞る

ping パケットが指定したホストから送信されているかどうかを見るには、tcpdump のフィルタリング機能で、フィルタすると便利。

tcpdump src 192.168.1.123 and icmp

and 条件で送信元を絞ることが出来る。

知っておくとネットワークトラブルでパニクらずに住む

関連資料

tcpdump でパケットをのぞき見る方法まとめ。10分で僕にも出来た。tcpdumpの使い方 - それマグで!

initramfs の本体 init.rd を展開して、busybox をみたり、起動設定を見直してみる。

init.rd を展開してみる

init.rd は initramfs を起動するためもの。/boot のパーティションに存在している。

update-initramfs で起動する。grub から起動される最小限のlinux

展開してみる・・・?

initrd ファイルはcpio なので 、cpio で展開しようとしてみる。

あれれ

cd `mktemp -d` && sudo cat /boot/initrd.img-`uname -r` | cpio -ivd
.
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/AuthenticAMD.bin
62 ブロック

1ファイルしかない?そんな馬鹿な

takuya@d001:/tmp/tmp.On03d1x9GP$ tree . 
.
└── kernel
    └── x86
        └── microcode
            └── AuthenticAMD.bin

3 directories, 1 file

調べてみたら、このcpio ファイルはいくつかの組み合わせなのでうまく行かない。

linux - Why is it that my initrd only has one directory, namely, 'kernel'? - Unix & Linux Stack Exchange

そうだね。cpio ってtar みたいなもんだもんな

binwalk コマンドをいれて、中身を見てみると。。。末尾にgzip 圧縮されたものがある。

takuya@d001:/tmp/tmp.On03d1x9GP$ binwalk /boot/initrd.img-`uname -r` 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: ".", file name length: "0x00000002", file size: "0x00000000"
112           0x70            ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
232           0xE8            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
356           0x164           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
488           0x1E8           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/AuthenticAMD.bin", file name length: "0x00000026", file size: "0x00007752"
31184         0x79D0          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
31744         0x7C00          ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
31864         0x7C78          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
31988         0x7CF4          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
32120         0x7D78          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/.enuineIntel.align.0123456789abc", file name length: "0x00000036", file size: "0x00000000"
32284         0x7E1C          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x0024CC00"
2443952       0x254AB0        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
2444288       0x254C00        gzip compressed data, from Unix, last modified: 2019-10-18 08:19:18

ここから、bs がわかるので、それを取り出してみる。

takuya@d001:/tmp/tmp.On03d1x9GP$ dd if=/boot/initrd.img-`uname -r`  bs=2444288 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x  13 root     root            0 Oct 18 17:19 .
drwxr-xr-x   2 root     root            0 Oct 18 17:19 bin
-rwxr-xr-x   1 root     root         9424 Feb  1  2019 bin/cpio
-rwxr-xr-x   1 root     root         5751 Feb 14  2019 bin/cryptroot-unlock
-rwxr-xr-x   1 root     root       108760 Jan 14  2019 bin/date
-rwxr-xr-x   1 root     root         9624 Feb  1  2019 bin/dd
-rwxr-xr-x   1 root     root         8792 Feb  1  2019 bin/dmesg
-rwxr-xr-x   1 root     root         9992 Feb  1  2019 bin/fstype
-rwxr-xr-x   1 root     root         8920 Feb  1  2019 bin/halt
-rwxr-xr-x   1 root     root        19872 Feb  1  2019 bin/ipconfig

お、ファイルが見えるぞ。

それではこのファイルを取り出してみる

takuya@d001:/tmp/tmp.IrvVwlLK99$ dd if=/boot/initrd.img-`uname -r`  bs=2444288 skip=1 of=img.cpio.gz
takuya@d001:/tmp/tmp.IrvVwlLK99$ gunzip img.cpio.gz 
takuya@d001:/tmp/tmp.IrvVwlLK99$ cpio -idv < img.cpio 
takuya@d001:/tmp/tmp.IrvVwlLK99$ ll 
合計 194292
drwx------ 13 takuya takuya      4096 10月 18 17:35 ./
drwxrwxrwt 21 root   root        4096 10月 18 17:35 ../
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 bin/
drwxr-xr-x  3 takuya takuya      4096 10月 18 17:35 conf/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 cryptroot/
drwxr-xr-x 11 takuya takuya      4096 10月 18 17:35 etc/
-rw-rw-r--  1 takuya takuya 198891008 10月 18 17:34 img.cpio
-rwxr-xr-x  1 takuya takuya      7077 10月 18 17:35 init*
drwxr-xr-x 10 takuya takuya      4096 10月 18 17:35 lib/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 lib64/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 run/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 sbin/
drwxr-xr-x 10 takuya takuya      4096 10月 18 17:35 scripts/
drwxr-xr-x  7 takuya takuya      4096 10月 18 17:35 usr/
drwxr-xr-x  4 takuya takuya      4096 10月 18 17:35 var/

取り出せました。

chroot してみる

takuya@d001:/tmp/tmp.IrvVwlLK99$ sudo chroot . /bin/sh


BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu7) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# 

更に単純な方法

takuya@d001:/tmp/tmp.gTlrfnehcs$ unmkinitramfs /boot/initrd.img-`uname -r`  . 

systemd.path で path(パス) を監視する。

systemd でパス監視機能を使う

systemd.path を試していきます。

パスの監視というと理解しくいかもしれませんが、フォルダの監視です。フォルダを監視してなんかやります。もちろんファイルも監視できます。

inotify でアプリを書くより手軽です。

はじめに

systemd でパスを監視することができる。

xxxx.path と xxxx.service をペアで作成し登録すればオッケ。

制限事項

再帰的(recursive)なパス監視はできない。

inotify を使っているので、 nfsなどネットワーク越しでは使えない。

gvfs/gio でマウントしていると inotifyが発動するはずなので cifs でもつかそう

ユーザー空間にファイルを作って作って試す

今回は、次のファイルを作って試していきます。

~/.config/systemd/user/desktop.service
~/.config/systemd/user/desktop.path

systemd のユーザー空間について、過去の資料を参考に

~/.config/systemd/user/desktop.service

[Unit]
Description=DesktopSample

[Service]
WorkingDirectory=/home/takuya/Desktop
ExecStart=/bin/echo Hello From Service 

[Install]
WantedBy=default.target

~/.config/systemd/user/desktop.path

[Unit]
Description=DesktopSample

[Path]
## PathModified と PathChanged は別物
## 再帰的( recursively ) にパスの監視はできない。
## inotify をベースにしている
PathChanged=/home/takuya/Desktop
#PathModified=/home/takuya/Desktop
[Install]
WantedBy=default.target

ロードする

systemctl --user daemon-reload

起動する

enable して

systemctl --user enable desktop.service
systemctl --user enable desktop.path

restart しておく

systemctl --user restart desktop.service
systemctl --user restart desktop.path

コレで起動するので、あとはログを見ながら、動作する様子を見る

journalctl でログを開いておく

path の監視が起動したときのログ

journalctl --user -f  -u desktop.path

service が起動したときのログ

journalctl --user -f  -u desktop.service

-f をつけているので、ログは tailf と同じく following される。

動作を実験してみる。

いくつか、ファイルを作成したり、ファイルを更新したりして パスを書き換える実験をしておく

cd ~/Desktop/
echo 更新テスト > a 
echo 更新テスト2 > a 
echo 更新テスト3 > a  
echo 更新テスト4 >> a  
echo 更新テスト5 >> a  
rm a 
touch a 
chmod 777 a 
rm a 
mkdir  a 
rmdir a 

あとは、ログを見ながら、このタイミングでイベント発火するとか確認しておけばいい。

再帰的監視はできない

ディレクトリを再帰的に監視する機能は使えないようです。

代わりに、PathChanged を複数書くことができます。

このように複数書くことができます。

[Path]
PathChanged=/home/takuya/Desktop
PathChanged=/home/takuya/Desktop/.hidden
PathChanged=/home/takuya/Desktop/.gitignore
PathChanged=/home/takuya/Desktop/.git

更新について

PathModifiedとPathChanged がある。man systemd.path を見るとあれこれ書いてある。

PathChanged について

PathChanged= may be used to watch a file or directory and activate the configured unit whenever it changes. It is not activated on every write to the watched file but it is activated if the file which was open for writing gets closed.

PathModified については

PathModified= is similar, but additionally it is activated also on simple writes to the watched file.

たぶん、次のようなことだと思う。 - PathChanged は open → close されたら発動 - PathModified append された発動

open されたまま、追記されていくデータファイルやログファイルを追いかけるでもない限り PathChanged で問題ないと思われる。

その他の監視モード

  • パスが存在したらなにかする。
  • パスに変更がアレばなにかする。
  • ディレクトリが空っぽ以外になったらなにかする。
  • ファイルを指定をglob でやる

などがある。それぞれ次の名前で定義されている

PathExists=, PathExistsGlob=, PathChanged=, PathModified=, DirectoryNotEmpty=

簡単に実装できて便利。

「できる」だけであり、痒いところまで手が届くような使い勝手がいいものではない。

ただ、systemd のユーザー空間と組み合わせて、ユーザー空間で独自にぱぱっと関する程度ならお手軽でいいと思う。

細かい部分まで実装したいなどの用途に向かない。

例えば、ファイルが新規作成された、更新された、truncate されたとか、ディレクトリ内部に作成されたファイル名が知りたい。などなど。 細かい点について作業をしたいもののが欲しいなら inotify 系の python や npm/fsevent 系を使って細々書いておき、書いたpython を service 化するほうがずっといいだろうな。

systemd.path はgnome デスクトップなどで作成されるファイルを手軽に監視して同期したいなどで重宝すると思います。

参考資料

  • man systemd.path

関連資料

https://takuya-1st.hatenablog.jp/entry/2019/08/09/004829

ubuntu を4kディスプレイで拡大率125%や150%などの任意解像度をwindowsやMacみたいに選ぶ

4K モニタを使っていると、しんどい。

ubuntu で 4k ディスプレイを使っていると、解像度が細かすぎてしんどい。

windows 10 からは拡大率150% などが選べるが、 ubuntu はデフォルト設定では 200%/100%しか選べなかった。

125%と150% を有効にする。

gsettings で 実験的機能を有効にしてあげると、解像度の拡大倍率を指定できて、MacOSretina モードみたいなことができるようになる。

gsettings set org.gnome.mutter experimental-features "['scale-monitor-framebuffer']"
gsettings set org.gnome.mutter experimental-features "['x11-randr-fractional-scaling']"

設定するとこの通り、150%が出現する。これで快適になる。

f:id:takuya_1st:20191021180026p:plain
解像度

もとに戻すとき

もとに戻すには reset を使う

gsettings reset org.gnome.mutter experimental-features

参考資料

https://www.linuxuprising.com/2019/04/how-to-enable-hidpi-fractional-scaling.html?m=1

NetworkManagerがunmanaged(管理なし)になった問題を解決した

network-manager で管理できない。

network-manager で unmanaged になって、ubuntu desktop (gnome) からネットワークが管理できなかった。

依存関係が多くて、問題がわかりにくい。

ubuntu は 1年前から、 netplan が導入されているので、ubuntu server は systemd-networkd で管理、 ubuntu desktop は NetworkManager で管理することになっている。

それでは、/etc/network/interfaces はどうなったのか?

network-manager のときは、 network-manager が /etc/network/inteface をparsing して管理デバイスを見つけた上で除外し、残ったデバイスを管理するようになっている。

ただし、この設定はキャッシュされるらしい。(マジだったら、コレはホントめんどくさいわ)

networkd のときは、 networkd の起動後に /etc/network/intefaces を取得して管理する。こっちも面倒くさい。

デスクトップubuntu では networkd はいらない

使ってもいいんだけど、依存関係が多くて面倒くさいので、除外して切り分ける

sudo systemctl stop systemd-networkd.service
sudo systemctl disable systemd-networkd.service
sudo systemctl mask systemd-networkd.service

netplan の設定をシンプルにする。

netplan は networkmanager を使う設定にして、シンプルにする。

takuya@:~$ cat /etc/netplan/01-netcfg.yaml 
network:
  version: 2
  renderer: NetworkManager

netplanの設定を再生成してあげる

sudo netplan generate

これで、余計なものは動かなくなる。

ただし、場合分けのために除外し過ぎくらい除外してる。なので、netplan apply すら動かない。

この辺は、正直言ってubuntu の問題だろうなぁ。 networkmanager を指定してるのに 一旦 networkd を経由しようとしている。

takuya@:~$ sudo netplan generate 
takuya@:~$ sudo netplan apply 
Failed to start systemd-networkd.service: Unit systemd-networkd.service is masked.
Traceback (most recent call last):
  File "/usr/sbin/netplan", line 23, in <module>
    netplan.main()
  File "/usr/share/netplan/netplan/cli/core.py", line 50, in main
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 44, in run
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 153, in command_apply
    utils.systemctl_networkd('start', sync=sync, extra_services=netplan_wpa)
  File "/usr/share/netplan/netplan/cli/utils.py", line 82, in systemctl_networkd
    subprocess.check_call(command)
  File "/usr/lib/python3.7/subprocess.py", line 363, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['systemctl', 'start', '--no-block', 'systemd-networkd.service']' returned non-zero exit status 1.

NetworkManager の設定は多ファイルに分割されている

NetworkManager の設定ファイルは、/etc/NetworkManager だけでなく、 /usr/lib/NetworkManager などにデフォルト設定あったりして、それらがマージされて /etc/NetworkManager で上書きするようになっている。

takuya@:~$ sudo NetworkManager  --print-config
# NetworkManager configuration:
 /etc/NetworkManager/NetworkManager.conf (lib: 10-dns-resolved.conf, no-mac-addr-change.conf)
(run: netplan.conf) 
(etc: 10-globally-managed-devices.conf, default-wifi-powersave-on.conf)


## 略

/etc/NetworkManager で設定ファイルを見てもすべてが記載されているわけでじゃないので、 --print-config で最終的な設定を確認するのがポイント

ifupdown を使わないようにする。

ifupdown は /etc/network/interfaceを管理するので、 ifupdown も切り分けのために一旦無効化する。

sudo apt uninstall ifupdown
sudo apt uninstall ifupdown2
sudo apt uninstall netscript-2.4 

NetworkManager.conf でunamanged デバイスをすべて上書きして無効化する。

設定方法は、いくつか考えられるのだけど、umamanged になる問題を解決するために、すべての設定をOFFにしたり消していく。

takuya@:~$ cat /etc/NetworkManager/NetworkManager.conf 
[main]
#plugins=ifupdown,keyfile
plugins=keyfile
dns=default

[keyfile]
unmanaged-devices=
#[ifupdown]
#managed=true

[device]
wifi.scan-rand-mac-address=yes

ちなみに、ifupdownのmanaged は ifup/ifdown で管理される /etc/network/intefacesを nmcli で管理するかどうか。

restart する

あれこれ、余計なものを排除した結果動くようになる、

takuya@:~$ sudo systemctl status network-manager.service 
● NetworkManager.service - Network Manager
   Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-10-21 17:20:33 JST; 10s ago
     Docs: man:NetworkManager(8)
 Main PID: 4474 (NetworkManager)
    Tasks: 4 (limit: 4915)
   Memory: 4.0M
   CGroup: /system.slice/NetworkManager.service
           └─4474 /usr/sbin/NetworkManager --no-daemon

10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9682] device (enp3s0): state change: ip-config -> ip-check (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9809] device (enp3s0): state change: ip-check -> secondaries (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9813] device (enp3s0): state change: secondaries -> activated (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9819] manager: NetworkManager state is now CONNECTED_LOCAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9832] manager: NetworkManager state is now CONNECTED_SITE
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9834] policy: set '有線接続 1' (enp3s0) as default for IPv4 routing and DNS
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9876] device (enp3s0): Activation: successful, device activated.
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9885] manager: NetworkManager state is now CONNECTED_GLOBAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9892] manager: startup complete
10月 21 17:20:34 j5005 NetworkManager[4474]: <info>  [1571646034.0348] bluez5: NAP: added interface 00:09:DD:50:6C:BF

管理下に置かれる

takuya@:~$ nmcli d
DEVICE  TYPE      STATE     CONNECTION 
enp3s0  ethernet  接続済み  有線接続 1 
lo      loopback  管理無し  --         

unmanaged だったのが

f:id:takuya_1st:20191021172309p:plain

managed になる。

f:id:takuya_1st:20191021172202p:plain

なんでこんなにめんどくさいのか

過渡期とはいえ、systemd 関連の更新と整合性を保つために、あれこれ機能が追加されている。

あれこれ過渡期だからでしょうね。 nmcli や netplan を諦めて /etc/network/interfacesだけに戻すか、素直にnetworkd だけにしたほうが将来的に楽なのかなぁ。

今回驚いたのは ifup/down のコマンドを提供するパッケージが3つもあったことだった。ネットワーク周りはカオスですね。

NetworkManager でDHCPで取得したDNSの設定を/etc/resolv.confに書き込む

ubuntu デスクトップのネットワーク設定は NetworkManagerから

Ubuntu のネットワーク周りはカオス。というか、最近のLinuxのネットワーク周りはディストリ間でsystemdによる共通化を受容している段階なのでややこしい。

Ubuntuのデスクトップ版は主にNetworkManagerで管理しているんだけど、DNSの設定は、resolv.confに直接書かずにリンクになってたりする。これがちょっと不満なので、直接 /etc/resolv.confに書き込んでほしい。

/etc/NetworkManager/NetworkManager.conf

[main]
plugins=ifupdown,keyfile
dns=default

設定したら再起動

再起動して、DNS設定をDHCPから取得し直す。

sudo systemctl restart network-manager

もし。/etc/resolv.confがsymlinkになって利すると面倒なので、いったん/etc/resolv.confを空にしておくといいかも

sudo rm /etc/resolv.conf;
sudo touch /etc/resolv.conf

再起動後は、直接取れる。

再起動後、DHCPで割り振られたDNSサーバーが直接参照できるようになる。

takuya@:~$ ll /etc/resolv.conf
-rw-r--r-- 1 root root 89 2019-10-11 15:38 /etc/resolv.conf

/etc/resolv.conf

# Generated by NetworkManager
search local
nameserver 192.168.2.1
nameserver 192.168.2.5

network-managerのDNS設定

https://qiita.com/onokatio/items/af0035d1563acbbfeed2

これによると、次のようになる。

  • dnsモード 振る舞い
  • default 取得したDNSサーバーをそのまま使います。
  • dnsmasq キャッシュ用にdnsmasqをサブプロセスとして起動します。DNSサーバーは127.0.0.1を使います。
  • unbound 上のunboundバージョン
  • systemd-resolved 上のsystemd-resolvedバージョン
  • none NetworkManagerはDNSに関して何もしません。また次に書いてあるrc-managerも無効になります。

ネットワーク周りは面倒くさい。

dns の設定だけでも、

  • network-manager
  • /etc/resolv.conf
  • /etc/resolvconf.conf
  • systemd networkd-resolved

と、相互に依存しながら編集してるので、注意しないとデフォルト設定がどこに流れているのかわからなくなるよね。。。

gitでリモートブランチをローカルブランチにチェックアウトする。(githubプルリクを手元にコピー

リモートにあるブランチをローカルに持って来たい

たとえば、github のプルリクなど、リモートのgit branch から自分の手元に、同じものを取り出したいときがあります。

git のリモートブランチを確認します。

git branch -a | \grep remote

たとえば、次のようにほしいブランチ名を確認します。

takuya@i$ git branch -a | \grep remote  | grep add
  remotes/origin/add_table_column
  remotes/origin/add_notify
  remotes/origin/createAddUpdateModel

これで、必要なリモートブランチ名を確認出来ました。github のプルリクをブランチベースでやっていると、プルリクに表示されてます。

git のリモートブランチが見つからない場合、

リモートブランチの名前が見つからないときは、次のように fetch します。

git fetch 

リモートブランチの名前が見つからないなんて、そんなことを起きるの?と疑問を感じるかもしれません。リモートブランチはfetch しない限り出てきません。gitは分散レポジトリなのでリモートブランチの更新を取り出す必要があります。

ローカルブランチ名を指定して、リモートブランチをコピー・チェックアウトします。

次のように、リモートブランチを取り出し、ローカルブランチの名前を付けます。別の名前も可能ですが、同じ名前にしておくのが無難だと思います。

takuya@$ git checkout -b  add_notify origin/add_notify

Branch 'add_notify' set up to track remote branch 'add_notify' from 'origin'.
Switched to a new branch 'add_notify'

これで、リモートブランチをローカルに取り出してソースコードを見ながら、実験できますね。

同じ名前を使うのであれば、次のように省略することも可能です。

git checkout -b origin/add_notify

というか、省略した此方を一般的に記事で紹介されるのではないでしょうか。ただこちらはローカルとリモートの対応がわかりづらく、ミスを誘発しやすいので最初は localと remote origin の両方を指定したほうがいいのかもしれません

さらなる短縮化が出来て

もちろん、さらなる短縮化が出来て、無意識のうちにこれを使ってる可能性があります。私もこれです。

Branch 'add_notice' set up to track remote branch 'add_notice' from 'origin'.
Switched to a new branch 'add_notice'

checkout のメッセージをよく読むと、
remote branch の add_notice が origin にあるのでそこから、追跡してブランチをセットアップするよ。(Branch 'add_notice' set up to track remote branch 'add_notice' from 'origin'.) と書いてありますね。つまり、このメッセージが出てきたらOK、省略したcheckout でもちゃんとoriginから取り出せたことが解るようです。

参考資料

Git - リモートブランチ

systemd の タイマーは enable してもstart をしないと動かない

systemd でタイマーを作ってみたんですよ。タイマーが動かないので悩んでたんです。

systemd でタイマーを作って、enableして見たんだけど。動かないんですよ。

タイマーを作る手順

  • service 作って
  • timer 作って service を起動する
  • start してチェック
  • enable する。

という手順なんだけど、start コマンド実行が大事。 timer はstart しないと動かないとか盲点でした。

dig するだけのサービスを試しに laravel で作ってみて、それでタイマーを動かすことに。

takuya@:~$ ln -sr  laravel_checkip.service /etc/systemd/system/
takuya@:~$ ln -sr  laravel_checkip.timer    /etc/systemd/system/

サービスファイルをチェックする。

takuya@:~$ sudo systemctl start laravel_checkip.service

サービスをenableにして、タイマーをenable にする。

takuya@:~$ sudo systemctl enable laravel_checkip.service
takuya@:~$ sudo systemctl enable laravel_checkip.timer

状態を確認する。

タイマーはenable してもそのままでは動かない。

takuya@:~$ sudo systemctl list-timers --all
NEXT      LEFT          LAST      PASSED       UNIT                         ACTIVATES
n/a       n/a             n/a          n/a          laravel_checkip.timer        laravel_checkip.service

8 timers listed.

start すると動き出す。

なんでかわからんけど start すると 動き出した。enable だけでいいと思ってたけど記憶違いだったらしい

takuya@:~$ sudo systemctl start  laravel_checkip.timer

動き出した。

takuya@:~$ sudo systemctl list-timers --all
NEXT          LEFT         LAST       PASSED       UNIT                                  ACTIVATES
Wed 2019-09-18 21:01:56 JST  56min left   n/a         n/a               laravel_checkip.timer        laravel_checkip.service

8 timers listed.
takuya@:~$

systemd でタイマー作るときは start timer を忘れない。

SystemCtrlのタイマーを作るときは、この手順をする。

takuya@:~$ sudo systemctl enable  laravel_checkip.service
takuya@:~$ sudo systemctl enable  laravel_checkip.timer
takuya@:~$ sudo systemctl start  laravel_checkip.timer

laravel のmodel を 外部から使う

laravel の Eloquent のモデルを別のプロジェクトからぱぱっと使う。

Consoleとかあるし、API作れば実現はできる。でも既存のものと組み合わせるときは、DBを直接書き換えたほうが早い時がある。

本当はプロジェクトの外部から直接触るのは良くないと思うし、プロジェクト側にAPIを作ったり、メンテナンス用のコマンドをプロジェクト内部につくったり、メンテナンス用のデータ復旧をMigration や Fixtgure / UnitTestと同様に作るべきなんだろうけど。

<?php
  /// laravel の Eloquent を外部から使う設定

// 必要なものをロード
  require_once __DIR__.'/vendor/autoload.php';
// DB の接続情報をいれる
  $capsule = new Illuminate\Database\Capsule\Manager();
  $capsule->addConnection([
                            "driver"   => "sqlite",
                            "database" => __DIR__."/database/database.sqlite",
                          ]);
  $capsule->setAsGlobal();
  $capsule->bootEloquent();

  ///
  /// AccessLogs モデルを保存してみる。
  require_once __DIR__.'/app/Model/AccessLogs.php';
  $al = new  App\Model\AccessLogs();
  $al->body = "Hello from  External World ";
  $al->save();

名前空間の解決

<?php
// 必要なものをロード
  require_once __DIR__.'/vendor/autoload.php';

今回は、$PROJECT_HOME/sample.php においたのでこのように書いている。

ただしくは、次のautoloadをlaravel で使っているのでこれを使う。(詳しくは laravel/public/index.php を見ればわかる。

<?php
$PROJECT_PATH/vendor/autoload.php

DB の解決

必要なロードが出来たので、DBを使うための初期設定をする。

ここでの目標は bootEloquent(); を実行することです。

<?php

// DB の接続情報をいれる
  $capsule = new Illuminate\Database\Capsule\Manager();
  $capsule->addConnection([
                            "driver"   => "sqlite",
                            "database" => __DIR__."/database/database.sqlite",
                          ]);
  $capsule->setAsGlobal();
  $capsule->bootEloquent();

最後にモデルをロードして利用する。

laravel で作っている model を 明示的にロードして、new して save する。

<?php
  /// AccessLogs モデルを保存してみる。
  require_once __DIR__.'/app/Model/AccessLogs.php';
  $al = new  App\Model\AccessLogs();
  $al->body = "Hello from  External World ";
  $al->save();

これですべて解決する。

シェルスクリプトで実行中の関数名を関数内部から知る(自分自身の関数名)

自分自身の関数の名前を知りたい。

関数名は、関数名を表す変数に入っている(BASHで確認)

echo ${FUNCNAME[0]}

これを使うと、自分自身の関数名を実行中に参照できる。

takuya@Desktop$ function sample() { echo ${FUNCNAME[0]} ;  }; sample
sample

便利。

なんで自分自身の関数名を知る必要があるのか。

実行後に関数を消したいから

関数を使い終わったら片付けたいときがあります。一時的な関数として、処理をブロックに分けるだけの目的で使うことがります。

function sample001() {
 # なにか処理
 
 ## 処理が終わったら自分自身消す。
 unset ${FUNCNAME[0]} ;
};

これを実行するとこのようになります。 実行後は関数が消えています。これで名前を汚さずに自分の関数をシェルスクリプトで使えます。

takuya@Desktop$ function sample001() {
>  echo ${FUNCNAME[0]} ;
>  unset ${FUNCNAME[0]} ;
> };
takuya@Desktop$ sample001
sample001
takuya@Desktop$ sample001
-bash: sample001: コマンドが見つかりません

なぜ名前を調べて消す必要があるのか。

bashrc のような dotfile で環境設定をする処理に使います。

環境設定するsample.sh をシェルスクリプトで書いた場合

function sample001() {
    ## なにか処理
    echo 環境設定をした
 };
sample001

source すると関数がENVに残ってしまう。

$ source sample.sh
$ sample001

そのために、長い処理をブロック単位に分けて書くとき無駄に関数を設定すると、unset を忘れがちになってしまう。

そこで、source するシェルの環境設定ファイルを書く場合に関数を自分自身で unset しておけば汚さずにすむ

function sample001() {
    ## なにか処理
    echo 環境設定をした
    ## 使い終わったら消す
    unset ${FUNCNAME[0]} ;
 };
sample001
$ source sample.sh
$ sample001 # not found 

このように、自分自身の関数名を知るノウハウは、シェルスクリプトで環境設定をブロック単位で管理することがしやすくなるので本当に便利りだ!!とおもった

nginx でSSHをプロキシして転送する 443 の再利用も可能

nginx でSSHの接続を転送することが出来ます。

nginx には ストリームをそのまま転送することが出来る機能があるので、TCP・IPのポートフォワードができて、ルーター的な動作が出来ます。

nginx.conf

stream {
  upstream ssh {
    server 192.168.2.8:22;
  }
  server {
    listen 2222;
    proxy_pass    ssh;

  }
}

なんと443 を再利用することも可能

まだ試してないのですが、 443 を ssh / ssl の両方で待ち受けることも可能になってるようです。今使ってる グローバルIP上の nginx が非対応なので試すのは少し先になりそう

Run Non-SSL Protocols on the Same Port as SSL in NGINX 1.15.2

関連資料

2022-04-08更新

NGINX で ssh TLSを同時に扱うときは次のようにします。

https://takuya-1st.hatenablog.jp/entry/2022/04/06/005007

参考資料