pingでピングーが出てくるpinguコマンド

パケットが帰ってくるとピングーが出てくるpingコマンドを作りました
楽しいｗｗｗhttps://t.co/VxeVtIt2IB#golang #cli #ping pic.twitter.com/KoLlEou9Ou

— ((<9F><90><91>++)) (@Sheeeeepla)
June 11, 2022

可愛い
てことで手元でも動かしてみました．

sheepla/pingu: ping command but with pingu

$ go install github.com/sheepla/pingu@latest

Note

installしてから気づいたのですが，GitHubのreleaseにいくつかのバイナリがありました．
releaseに無いものはこんな感じで

$ git clone https://github.com/sheepla/pingu && cd pingu
$ GOARCH="arm" GOOS="linux" go build -o pingu_linux-arm main.go
$ GOARCH="amd64" GOOS="openbsd" go build -o pingu_openbsd-amd64 main.go
$ file ./pingu_*
./pingu_linux-arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=murva-OzxIcI_YixZ4Ug/cNCKM_axMOq6C247-ffX/ZvpTdtm8O3oDXPd__Lpl/cHptxGGRawpNVtoik-SP, not stripped
./pingu_openbsd-amd64: ELF 64-bit LSB executable, x86-64, version 1 (OpenBSD), dynamically linked, interpreter /usr/libexec/ld.so, for OpenBSD, Go BuildID=Q-bDgKXcAqG8C7jI1-AU/tFPAi4Y1vzFywav4YxWJ/RlLmE89x6Zh42bIsaKyQ/oVjfJQxr0rf9Z5byo_ZF, not stripped

早速実行するとpermission deniedで失敗します．

$ pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
[ERROR] an error occurred when running ping: socket: permission denied

SUID を設定してみたり，

$ cp -a $(which pingu) .
$ sudo chown 0.0 ./pingu
$ sudo chmod u+s ./pingu
$ ./pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
[ERROR] an error occurred when running ping: socket: permission denied

sudoでも駄目です．

$ sudo ~matoken/go/bin/pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
[ERROR] an error occurred when running ping: socket: permission denied

検索してみるとこのページを見つけました．

“Error listening for ICMP packets: socket: permission denied” while using this library in unprivileged ping · Issue #4 · go-ping/ping

ping コマンドが特別で通常は net.ipv4.ping_group_range の権限が必要なようです．
prettyping は動くのになと思ったけどこれは ping コマンドを呼んでいるので動くのですね．

net.ipv4.ping_group_range を確認すると 1 0 になっています．

$ sysctl -a 2>&1 | grep ping
net.ipv4.ping_group_range = 1 0
$ cat /proc/sys/net/ipv4/ping_group_range
1 0

0 0 に設定することで gid 0 で実行可能に

$ sudo id -g
0
$ sudo sysctl net.ipv4.ping_group_range="0 0"
net.ipv4.ping_group_range = 0 0
$ sudo ~matoken/go/bin/pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
... . ... .. .. ......... seq=0 32bytes from 127.0.0.1: ttl=64 time=242.773µs
... .... .. .. ... ..... .. .. seq=1 32bytes from 127.0.0.1: ttl=64 time=241.504µs
^C
───── localhost ping statistics ─────
PACKET STATISTICS: 2 transmitted => 2 received (0% loss)
ROUND TRIP: min=241.504µs avg=242.139µs max=242.773µs stddev=634ns

0 1000 に設定することで gid 1000 の一般ユーザでも実行可能に

$ sudo sysctl net.ipv4.ping_group_range="0 $(id -g)"
net.ipv4.ping_group_range = 0 1000
$ pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
... . ... .. .. ......... seq=0 32bytes from 127.0.0.1: ttl=64 time=149.711µs
... .... .. .. ... ..... .. .. seq=1 32bytes from 127.0.0.1: ttl=64 time=235.975µs
... ....... ... ... . ..... ####### seq=2 32bytes from 127.0.0.1: ttl=64 time=195.434µs
..... ........ .###############..... ... ##########. . seq=3 32bytes from 127.0.0.1: ttl=64 time=179.31µs
.... ........#####################. ... ########### seq=4 32bytes from 127.0.0.1: ttl=64 time=201.388µs
....... ######################.... ############ seq=5 32bytes from 127.0.0.1: ttl=64 time=242.148µs
. . .... ########################... ########### seq=6 32bytes from 127.0.0.1: ttl=64 time=219.127µs
.. ....#########################.. .########### seq=7 32bytes from 127.0.0.1: ttl=64 time=163.007µs
. #########################. .########## seq=8 32bytes from 127.0.0.1: ttl=64 time=136.878µs
.... .########################. ######## seq=9 32bytes from 127.0.0.1: ttl=64 time=203.288µs
..... . ####################. #######. seq=10 32bytes from 127.0.0.1: ttl=64 time=128.612µs
^C
───── localhost ping statistics ─────
PACKET STATISTICS: 11 transmitted => 11 received (0% loss)
ROUND TRIP: min=128.612µs avg=186.807µs max=242.148µs stddev=36.88µs

1001 1000 の様におかしな範囲に設定すると動かなくなります．

$ sudo sysctl net.ipv4.ping_group_range="1001 $(id -g)"
net.ipv4.ping_group_range = 1001 1000
$ pingu localhost
PING localhost (127.0.0.1) type `Ctrl-C` to abort
[ERROR] an error occurred when running ping: socket: permission denied

表 1. そのへんの端末の設定を見てみました

ディストリビューション | uname -r | net.ipv4.ping_group_range | pingu

Debian sid amd64

5.17.0-3-amd64

1 0

NG

Debian bullseye amd64

5.10.0-14-amd64

1 0

NG

Debian buster amd64

5.10.0-0.bpo.12-amd64

1 0

NG

Raspberry Pi OS bullseye armhf

5.15.32-v7+

0 2147483647

OK

Ubuntu 22.10 amd64(development branch)

5.15.0-33-generic

0 2147483647

OK

Note

sysctlは再起動でもとに戻るので永続化したい場合は /etc/sysctl.conf, /etc/sysctl.d/* 辺りに書いておきましょう．

pingu動いたけど色なしのテキストデータだとよくわからないのでスクリーンショットを．

ちなみに端末幅が狭いとこんな感じになるので広げてあげましょう(上の画像はcols 111)

不安定な回線だと行が減りピングーが縮みます(自宅でのpovo 2.0回線 )

不安定な回線だと prettyping がいいですね．

カラフルでかわいい prettyping – matoken’s meme

追記)

Asciinemaで録画してみました．

環境

$ pingu --version
pingu: v???-rev???
$ ls ~/go/pkg/mod/github.com/sheepla/
pingu@v0.0.1
$ dpkg-query -W linux-image-`uname -r` golang iputils-ping
golang:amd64 2:1.18~3
iputils-ping 3:20211215-1
linux-image-5.17.0-3-amd64 5.17.11-1
$ lsb_release -dr
Description: Debian GNU/Linux bookworm/sid
Release: unstable