TenForward

技術ブログ。はてなダイアリーから移転しました

ShiftFS ふたたび 〜 Ubuntu 19.04で導入された ShiftFS を試してみた

ちょうど 2 年ほど前、Open Source Summit で話を聞いて ShiftFS について試したことがありました。

tenforward.hatenablog.com

その後はとりあえずカーネルにパッチを当てたりはしてましたが、あまり使わないままでした。少し前に gihyo.jp の Ubuntu の記事を読んでいると、

discoのカーネルフリーズが4月4日に迫る中,興味深いパッチが投稿されています。パッチの中身は「ShiftFS」と呼ばれる,コンテナ環境でのセキュリティ機能を提供するためのラッパーファイルシステムです
https://gihyo.jp/admin/clip/01/ubuntu-topics/201903/29

なんて書かれています。その後の記事で

ShiftFSは, 前回取り上げた後,4月4日に無事にマージに辿り着いています。
https://gihyo.jp/admin/clip/01/ubuntu-topics/201904/19

と書かれていたので、また変わった所がないか調べて試してみたいなと思っていました。

そこでようやく重い腰を上げて、Ubuntu 19.04 環境を用意して試してみました。

ShiftFS について

詳しくは先に紹介した 2 年前の記事を参照してください。

簡単に言うと、非特権コンテナを起動する場合、どの uid/gid で起動するかは一般的に決まっているわけではないですが、世間で流通しているコンテナイメージ内のファイルの所有権は作成時点で一意に決まりますし、自作のコンテナイメージでも同様でしょう。

そこで非特権コンテナを起動するときには、それを起動するユーザの uid/gid に合わせて chown してあげる必要があります。

この問題を解消するために考えられたのが ShiftFS です。

ShiftFS は OverlayFS のように重ね合わせのファイルシステムとして実装されているようです。元のファイルシステムを「下層」(lower filesystem)とし、その上に「上層」(upper filesystem)のファイルシステムを重ねて所有権を調整しているのでしょう(たぶん)。

この ShiftFS は Ubuntu 19.04 の 5.0 カーネルにパッチを適用して使えるようにしており、upstream のカーネルには導入されていない機能です(されそうなのかしら?)。

Ubuntu は 12.04 だったか 14.04 の頃も、まだ upstream な Linux カーネルに導入されていない OverlayFS を先取りして入れていました(カーネルに入ったときには仕様が変わっていて LXC にパッチ送ったりしたのはいい思い出)。また 16.04 なんかでも、かなり後のカーネルで導入される機能がバックポートされていたりして、かなり意欲的に自分たちの求める機能を入れてきます。

ShiftFS によるマウント

マウント方法は2 年前の記事と大きく変わっていません。マウントオプションが増えた程度でしょうか。

マウントは 2 段階で行います。

ShiftFS がないとき

これも2 年前の記事と同じなのですが、簡単に紹介しておきましょう。

ここではファイルシステムとして LXC コンテナのイメージを展開して使用しています(alpineイメージ)。検証のために一部ディレクトリの所有権などをいじっています。root 権限で作成されたコンテナです。

コンテナファイルシステムの root(/)は /var/lib/lxc/ct01/rootfs です。

$ sudo ls -l /var/lib/lxc/ct01/rootfs
total 68
drwxr-xr-x  2 root root 4096 Jul  1 13:00 bin
drwxr-xr-x  3 root root 4096 Jul  2 07:17 dev
drwxr-xr-x 19 root root 4096 Jul  2 07:17 etc
drwxr-xr-x  2 root root 4096 Jun 19 17:14 home
drwxr-xr-x  6 root root 4096 Jul  1 13:00 lib
drwxr-xr-x  5 root root 4096 Jun 19 17:14 media
  : (snip)

上の例のように rootfs 以下は root 所有です。

現在のユーザーをコンテナ内の rootマッピングして User Namespace を作成します。

$ id -u && id -g
1000
1000
$ unshare --pid --user --map-root-user --mount --mount-proc --fork -- /bin/bash
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
# ls -l /var/lib/lxc/ct01/rootfs/
total 68
drwxr-xr-x  2 nobody nogroup 4096 Jul  1 13:00 bin
drwxr-xr-x  3 nobody nogroup 4096 Jul  2 07:17 dev
drwxr-xr-x 19 nobody nogroup 4096 Jul  2 07:17 etc
drwxr-xr-x  2 nobody nogroup 4096 Jun 19 17:14 home
drwxr-xr-x  6 nobody nogroup 4096 Jul  1 13:00 lib
drwxr-xr-x  5 nobody nogroup 4096 Jun 19 17:14 media
  : (snip)

上のように uid/gid=1000/1000 のユーザーをコンテナ内の uid/gid=0/0 にマッピングしただけなので、マッピングされていない uid/gid については nobody/nogroup の 65534/65534 となってしまっています。

ShiftFS があるとき

まずはコンテナの root(/)である /var/lib/lxc/ct01/rootfs を ShiftFS の下層(lower filesystem)としてマークします。この場合、マウントオプションに mark を指定します。

$ sudo mount -t shiftfs -o mark /var/lib/lxc/ct01/rootfs /var/lib/lxc/ct01/rootfs
[sudo] password for ubuntu: 
$ grep shiftfs /proc/self/mountstats 
device /var/lib/lxc/ct01/rootfs mounted on /var/lib/lxc/ct01/rootfs with fstype shiftfs

ShiftFS としてマウントされています(このイメージは root 所有なので、ここでは root ユーザーで mark しています)。

ここで、さきほどと同じように User Namespace を作成します。

$ unshare --pid --user --map-root-user --mount --mount-proc --fork -- /bin/bash
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)

そしてさきほど mark した ShiftFS マウントを使って、権限のあるディレクトリに ShiftFS マウントしてみます。

# mount -t shiftfs /var/lib/lxc/ct01/rootfs/ /home/ubuntu/mnt
# grep shiftfs /proc/self/mountstats 
device /var/lib/lxc/ct01/rootfs mounted on /var/lib/lxc/ct01/rootfs with fstype shiftfs
device /var/lib/lxc/ct01/rootfs mounted on /home/ubuntu/mnt with fstype shiftfs

マウントされています。マウント先の /home/ubuntu/mnt を確認してみると、

# ls -l /home/ubuntu/mnt
total 68
drwxr-xr-x  2 root root 4096 Jul  1 13:00 bin
drwxr-xr-x  3 root root 4096 Jul  2 07:17 dev
drwxr-xr-x 19 root root 4096 Jul  2 07:17 etc
drwxr-xr-x  2 root root 4096 Jun 19 17:14 home
drwxr-xr-x  6 root root 4096 Jul  1 13:00 lib
drwxr-xr-x  5 root root 4096 Jun 19 17:14 media
  : (snip)

ちゃんと root 所有になっており、ShiftFS が効いていることがわかります。

ちなみにこの「下層」(mark)のマウントはホストのNamespaceで行っているので、ホストから見えますが、ホストでは「上層」は見えません。

$ grep shiftfs /proc/self/mountstats (ホスト上で実行)
device /var/lib/lxc/ct01/rootfs mounted on /var/lib/lxc/ct01/rootfs with fstype shiftfs
$

コンテナ起動後は、余計な情報を見せないためにホスト上ではこの mark 用 ShiftFS は umount できます。

動きは 2 年前の変わっていないようです。

passthrough オプション

Ubuntuのパッチでは ShiftFS のオプションとして passthrough オプションが追加されているようです。2 年前の記事の時点ではおそらくなかったオプションだと思います。

さきほどの例では何も指定していませんので、passthrough=0 が指定されているのと同じ意味になるようです。

さきほどの例でマウントした ShiftFS で 1 が指定されていない効果を確認してみます。

# stat -f /home/ubuntu/mnt/root
  File: "/home/ubuntu/mnt/root"
    ID: ad6dc6d23bfb15c1 Namelen: 255     Type: UNKNOWN (0x6a656a62)
Block size: 4096       Fundamental block size: 4096
Blocks: Total: 4111327    Free: 3014986    Available: 2801214
Inodes: Total: 1048576    Free: 972147

ファイルシステムタイプとして Type: UNKNOWN と返っています。

(2 の指定は気軽に試すには私にはハードルが高そうなので、)とりあえず 3 を指定してみます。

$ sudo mount -t shiftfs -o mark,passthrough=3 /var/lib/lxc/ct01/rootfs /var/lib/lxc/ct01/rootfs
$ grep shiftfs /proc/self/mountinfo 
540 28 0:53 / /var/lib/lxc/ct01/rootfs rw,relatime shared:294 - shiftfs /var/lib/lxc/ct01/rootfs rw,mark,passthrough=3

passthrough=3 付きでマウントされています。

では User namespace を作成しましょう。

$ unshare --pid --user --map-root-user --mount --mount-proc --fork -- /bin/bash
# mount -t shiftfs -o passthrough=3 /var/lib/lxc/ct01/rootfs /home/ubuntu/mnt
# stat -f /home/ubuntu/mnt/root
  File: "/home/ubuntu/mnt/root"
    ID: ad6dc6d23bfb15c1 Namelen: 255     Type: ext2/ext3
Block size: 4096       Fundamental block size: 4096
Blocks: Total: 4111327    Free: 3019139    Available: 2805367
Inodes: Total: 1048576    Free: 972149

stat コマンドで確認すると Type: ext2/ext3 と返ってきています。

2 の ioctl() 周りですが、ShiftFS のパッチ(の一部) を見る限りでは、

static long shiftfs_ioctl(struct file *file, unsigned int cmd,
              unsigned long arg)
{
    switch (cmd) {
    case FS_IOC_GETVERSION:
        /* fall through */
    case FS_IOC_GETFLAGS:
        /* fall through */
    case FS_IOC_SETFLAGS:
        break;
    default:
        return -ENOTTY;
    }

    return shiftfs_real_ioctl(file, cmd, arg);
}

static long shiftfs_compat_ioctl(struct file *file, unsigned int cmd,
                 unsigned long arg)
{
    switch (cmd) {
    case FS_IOC32_GETVERSION:
        /* fall through */
    case FS_IOC32_GETFLAGS:
        /* fall through */
    case FS_IOC32_SETFLAGS:
        break;
    default:
        return -ENOIOCTLCMD;
    }

    return shiftfs_real_ioctl(file, cmd, arg);
}

のような実装になってるので、ここに挙がってるリクエストは許可されているのでしょう(知らんけど)。

LXD

ちなみに LXD ではすでに ShiftFS が使えるようになっています(3.12以降)。

github.com

使い方は次で説明されています。

discuss.linuxcontainers.org

セサミ mini を導入してみた(2)

先日設置したセサミ mini ですが、先日も少し書いたとおり、ちょっとだけ問題がありました。

tenforward.hatenablog.com

うちの鍵は

  • サムターンが縦(12時)方向で解錠
  • サムターンが縦から右に45度回転した状態でチェーンがかかった状態
  • サムターンが横(3時)方向で施錠

となります。

サムターンの施錠、解錠状態はそれぞれ少々の遊びがあって、縦から少し行き過ぎた状態と少し手前の状態をぐらぐら動く感じです。

そしてセサミ mini のサムターンアダプターとサムターンの間には少し隙間があり、セサミ mini のつまみ自身も色々な方向に少し遊びがあります(設置が少しズレたときの対応や、色々な鍵への対応を考えてそういう設計になっているようです)。

色々な所に余裕と遊びがある関係で、うちに設置すると:

解錠状態: セサミ mini のつまみがちょうど縦になる状態だと、鍵のサムターンが解錠状態の縦にならず、少し手前で止まってしまい、開場されずにチェーンがかかった状態になる。そこで解錠状態は少し縦より行き過ぎた状態で設定する。

f:id:defiant:20190520233705p:plain
解錠状態のセサミの角度

これくらいの角度を解錠に設定します。こちらが問題になることはありません。

施錠状態: 問題は施錠状態です。

セサミのつまみが真横になった状態を「施錠状態」に設定すると、鍵のサムターンは横(3時)の少し手前で止まってしまい、きちんと施錠されずにチェーンがかかった状態になります

そこで少し行き過ぎたところ(次の画像の通り)あたりに設定します。セサミアプリを使って施錠するとこれで施錠できます

f:id:defiant:20190609133745j:plain
セサミの施錠状態のつまみ角度

ところが鍵を使って施錠すると、鍵のサムターンは横(3時)を向きますが、セサミ miniのつまみは真横のちょっと手前の状態で止まります。

f:id:defiant:20190609133721j:plain
鍵で施錠した際のセサミの角度

この状態だとセサミは施錠状態のところまでつまみが回っていないと認識し、アプリで見ると "Unlocked" という表示のままです。

この状態でアプリをタップすると、施錠状態に移行します。再度タップすると解錠されます。つまり 2 度タップしないといけないことになります。

上記ツイートを行うと、公式に補足され、ありがたいことにタダでアダプターを作成し送ってくれるとのことですので、サムターンの詳細なサイズを送りました。

届いたのでアダプターを装着しました。装着したアダプターとセサミのサムターンアダプターとの間にも少し隙間があります。

f:id:defiant:20190609132335j:plain
届いたアダプターを装着

そして設置。写真のようにアダプターをつけてもサムターンとの間には隙間があります。

f:id:defiant:20190609133839j:plain
作ってもらったアダプターを付けて設置

このため、

サムターン←(すき間)→作成してもらったアダプター←(すき間)→セサミ miniのサムターンアダプター

という状態になり、やはりいくら調整してもセサミ mini の施錠状態の角度と鍵を使った時の施錠状態の角度の間に差が出来てしまい、症状は改善されませんでした。

とはいうものの、便利さが勝っていますので、作ってもらったアダプターは取り外し、元の状態で再度装着して使っています。

アプリでの対応が待たれますね。

セサミの公式サポート手厚すぎですね。安心できる対応ですね。

セサミ mini を導入してみた

だーいぶ前に mizzy さんのブログでスマートロックなるものを知って、これはいいなと思いつつずっと買ってなかったのですが、最近は Qrio 以外にもセサミスマートロックという競合製品もあるってのを知って、これは良さげだなと思ってそろそろウチにも導入するかなーということで導入しました。

セサミはちょっと横幅もあって、結構ドアノブ(というのかこれは?)が上下に長くて設置できる幅が限られるウチでは無理じゃないかなと思ってたら、mini なるコンパクトなモデルがあるということを知ったのですが、クラウドファンディングは終わったばかりのころに気づいたので、さらにそこから待ってようやく購入しました。

f:id:defiant:20190520225314j:plain
うちのドアノブと鍵付近

Wifiアクセスポイントもあると便利そうなのでこちらとセットになったものが19,800円。

うちは鍵がふたつあるのですが、とりあえず片方の鍵に取り付けてみました。

鍵のつまみの形状や大きさに応じて高さやつまみを挟み込む部分の幅を調整しなければいけません。その場合は付属ドライバーで調整します。その調整さえすめば、あとは両面テープでぺたっと貼るだけなので 5 分もかからずに取り付けはできそうです。私はちょっと水平器でまっすぐつけたりしていたのでもう少しかかりましたが。

f:id:defiant:20190519153728j:plain
裏側

まずはアプリにセサミを登録。このときアプリから Bluetooth でつなぐのですが、なぜか私はセサミが全くアプリに表示されずに、何度か本体リセットしたり、スマホを再起動したりしてるといつの間にか表示されるようになっていました。Why??

取付後はアプリからつまみの調整を行って完了です。うちの鍵はつまみが縦になっているときが解錠状態、横になっているときが施錠ですが、これ以外に45度の時にちょうどチェーンをかけて扉を細く開けるような状態になります。つまみには少し遊びがあるので、縦よりもう少し進んだ11時方向あたりを解錠、横も4時方向に近いあたりを施錠状態として設定しました(12時を解錠、3時を施錠とすると中途半端に止まって45度状態になってしまうことがあったので)。

f:id:defiant:20190520233705p:plainf:id:defiant:20190520233647p:plain
解錠・施錠

この後はWifiアクセスポイントの登録に。これもアプリから簡単にできましたが、2.4GHz しか対応していないということでそちらを登録。

f:id:defiant:20190520105759j:plain
Wifiアクセスポイント

家族の分の登録はちょっと戸惑いました。アプリを起動してメールアドレスを登録するとすぐにセサミを追加する画面になりますが、家族分はここでペアリングさせるのか、それとも最初に登録した「オーナー」が「マネージャー」を追加するだけでよいのか。結局、マネージャー登録をすると、各スマホに登録したセサミが表示されたので、きっとこれが正しい方法なのでしょう(どっかにちゃんと書いてあるのかもしれませんが見つけられなかった&色々やるほうが早いと思った)。

簡単に感想を。機能を十分に理解しておらず、もしかしたら勘違いしてる部分はあるかもしれません。

  • 解錠、施錠の反応は良く、すぐに解錠・施錠動作が開始され、2秒程度で状態が変わります。
    • ただしアプリを起動して、BT、Wifi、インターネット経由で鍵に接続できるまでに 5 秒〜 10 秒(もしくはそれ以上)かかる場合もあるので、結構時間がかかってしまう場合があります。家の扉の前でスマホ取り出してから解錠しようとしたりする場合、鍵をポケットから出したほうが早い場合もあります。家のちょっと手前でスマホを取り出して準備するとちょうど良い感じです
    • BT は別のスマホが接続されていると接続できないので家族が短時間のうちに操作しようとするとバッティングするかも。まああまりそういうことはないでしょうが
  • Bluetooth でペアリングする代わりに、Wifi アクセスポイントと同じ Wifi につながるとそれでも解錠ができるようですが、アクセスポイントは 2.4GHz のみ対応で、イマドキはスマホは 5GHz でつなぐようにしているので、同じ Wifi につながることはなく、自宅にいてもインターネット経由で Wifi アクセスポイントを使って解錠、施錠することになってます(と思う)
    • アクセスポイントの 5GHz 対応が待たれますね
  • 何度か実際の鍵の状態と違う状態がアプリに表示されていました。もちろん、実際に操作するときは表示通りなので、施錠したつもりがされてないというようなことはありません。鍵の状態を確認しようとしたときの話です
    • 家を出て施錠してすぐにアプリを見ると Unlocked と書かれてました
    • この状態で施錠操作するとモーター動いてる音しましたが、無理な力かかって壊れない?
  • 鍵の状態が変わったらスマホに通知を送ることが出来ます。手動で操作した場合も通知が飛んできます
  • 家に近づいたら自動的に解錠とか、ノック解錠は使ってません(Android だし)
  • 解錠後、一定時間経つとオートロックできますが、その時間も設定できるので便利
    • オートロックに関してはうっかりスマホも鍵も持たずに郵便箱を見に行ってしまい閉め出されたのでオフにしました😂

家の Google Home と IFTTT を連携させて、「オッケーぐーぐる。開けごま」とかいうのも試してみました😂設定は公開されてる通りにやれば簡単でした。「開けごま」は Google アシスタントに別のキーワードとして登録されているのか、キラキラした絵文字が返事として返ってくるだけで「オープンセサミ」「クローズセサミ」でちゃんと解錠、施錠されていました。

比較的窓際に Google Home 置いてるので、外から解錠できたりしたら怖いので、5 分ほど遊んで無効化しましたけど。

xkbのファイルを書き換えてキーマップを調整する

Plamo 7.0 環境で、USB 切替器を使って USB キーボードを切り替えると、切り替え後に fcitx のオンオフができなくなってハマっていました。つまり USB キーボードを抜き差ししたあとに fcitx のオンオフができなくなっていました。

fcitx のオンオフはこのように設定していました。HHKB を使ってます。

  • Command キー(スペースの横)を "Super_L" に割り当てている
    • .Xmodmap ファイルに書いて、fcitx の "X Keyboard Integration" Addon で、その .Xmodmap を読み込ませていた
    • xmodmap -e "keycode 102 = Super_L" みたいな
  • オンオフキーを Super+Space に割り当てていた

よくよく調べると xmodmap で行った変更設定が切り替え後に消えていてデフォルトの Muhenkan に戻っていることがわかりました。

最初は udev イベントでキーボードさされたのを検知して xmodmap を実行しようかと思ったら、現在開いているデスクトップ環境と実行する環境のセッションも違うし、DISPLAY 環境変数与えたりしてもイマイチうまくいかないので、キーマップ書き換えてしまえ、ということでやりました。

まず、現在使われいてるキーボードマップを調べます。

$ setxkbmap -print
xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)"  };
    xkb_types     { include "complete"   };
    xkb_compat    { include "complete"   };
    xkb_symbols   { include "pc+us+inet(evdev)"  };
    xkb_geometry  { include "pc(pc105)"  };
};

keycode は evdevalias を使っているということで、まず /usr/share/X11/xkb/keycode/evdev を見ると、keycode 102<MUHE> であることがわかりました。

        <MUHE> = 102;   // Muhenkan

これが定義されているところを xkb_symbolspc+us+inet(evdev) の方で調べると、

$ grep MUHE pc us inet
inet:    key <MUHE>   {      [ Muhenkan               ]       };

と出ますので、ここを強引に、

$ grep MUHE pc us inet
inet:    //key <MUHE>   {      [ Muhenkan              ]       };
inet:    key <MUHE>   {      [ Super_L               ]       };

のように書き換えて、.Xmodmap の読み込みを止めて再起動すると、無事、xmodmap なしで keycode 102Super_L になりました。

参考

Linux 4.14 で導入された Namespaced file capabilities(おまけ)

4.14 で設定した Namespaced file capability を 4.13 以前のカーネルに戻したら

まあ、こんな物好きなことをする人はいないでしょうが、確認してみました。

tenforward.hatenablog.com

の環境のまま、ホスト環境のカーネルを 4.13 に戻して、コンテナを起動し、コンテナ内で一般ユーザーとなって pingping2 コマンドを両方とも実行しました。

$ ./ping www.google.com
-su: ./ping: Numerical result out of range
$ ./ping2 www.google.com
-su: ./ping2: Numerical result out of range

構造体が変わっていたので読み取れないようですね。

Namespaced file capability に設定された id で User Namespace 外から実行してみる

tenforward.hatenablog.com

で、User Namespace 内の root の id が 200000 に設定されていたので、コンテナ内で設定した File capability も 200000 という情報が記録されていました。そこで User Namespace 内の root と同じ id を持つホスト上のユーザーから、file capability を設定したコマンドを実行してみました。

今回は unshare コマンドを使います。

  • ホスト上の uid: 1000 のユーザーを User namespace 内の rootマッピング

ちょっと色々試行錯誤しながら試したので変なことしてるようだったら教えてください。

ホスト上のユーザーは 1000:100 です。ここで unshare します。

$ id -u
1000
$ id -g
100
$ unshare --user --setgroups allow
nobody@borg:~$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

マッピングがまだできていないので、この時点では User namespace 内では nobody ユーザーになります。

ここで別のシェルからホスト上の rootマッピングを投入します。(Plamo なので gid がちょっと普通と異なるかな)

# echo "0 1000 65534" > /proc/22471/uid_map 
# echo "0 100 65534" > /proc/22471/gid_map

ここで元の User namespace 内のシェルに戻ると、無事 root になりました。

$ id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)

これで他の namespace が作れますので、Network namespace を作ります(これを作らないと file capability 設定しても ping 実行できなかったので)。

$ unshare --net
# ip link set lo up
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

ここで一般ユーザーになります。ping コマンドをコピーして実行してみます。当然失敗しますね。

$ su karma
$ id -u
1000
$ cd /tmp
$ cp /bin/ping .
$ ls -l ping
-rwxr-xr-x 1 karma users 56,920  32401:02 ping*
$ ./ping 127.0.0.1
ping: socket: Operation not permitted
$ exit

ここで User namespace 内の root で file capability を設定します。

# setcap cap_net_raw+ep /tmp/ping 
# getcap -n /tmp/ping 
/tmp/ping = cap_net_raw+ep [rootid=1000]

id:1000 で Namespaced file capability が設定されています。ここで再度一般ユーザーになります。

# su - karma
$ /tmp/ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.012 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.012/0.012/0.012/0.000 ms

User namespace 内で実行できましたね。ここでおもむろに namespace 外のシェルから、id:1000 のユーザーでこの ping を実行してみます。

$ id -u
1000
$ /tmp/ping 127.0.0.1
ping: socket: Operation not permitted

実行はできませんね。