AWSでDockerコンテナからメタデータサービスへのアクセスをブロックする

概要

環境

  • Ubuntu 18.04.1 LTS (ami-0eeb679d57500a06c)
  • Docker 18.09.7

Docker セットアップ

[host] # apt-get update
[host] # apt-get install docker.io
[host] # systemctl start docker
[host] # systemctl enable docker
[host] # gpasswd -a ubuntu docker  # デフォルトの ubuntu ユーザーで docker コマンドを実行できるように; 設定後再ログイン

確認

  • 何も制限しない状態で Docker コンテナからメタデータサービスへのアクセスを確認してみる
[host] $ docker run -it --rm ubuntu:18.04
[container] # apt-get update
[container] # apt-get install netcat
[container] # nc -vz 169.254.169.254 80
instance-data.ap-northeast-1.compute.internal [169.254.169.254] 80 (?) open    # 接続できた

ファイアウォールを設定する

  • docker のネットワーク設定確認
[host] $ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6471516562dc        bridge              bridge              local
305df41ba1c0        host                host                local
5ec5bac00e37        none                null                local
  • Docker コンテナ用に 172.17.0.0/16 がブリッジネットワークとして設定されている
$ docker network inspect bridge | jq '.[].IPAM'
{
  "Driver": "default",
  "Options": null,
  "Config": [
    {
      "Subnet": "172.17.0.0/16"
    }
  ]
}
  • iptables のルールを確認
    • Ubuntu では ufw 等のファイアウォール設定ツールも用意されているが、ここでは iptables を利用する (単純に慣れてるので)
    • filter テーブルの FORWARD チェーンで、DOCKER-USER -> DOCKER-ISOLATION-STAGE-1 -> DOCKER-ISOLATION-STAGE-2 -> DOCKER の順に参照される
[host] # iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
  • iptables の設定を永続化するため、iptables-persistent をインストール
    • 途中で聞かれる選択肢で Yes を選択すると、/etc/iptables/rules.v4, /etc/iptables/rules.v6 に現在の設定が保存される
[host] # apt-get install iptables-persistent
  • DOCKER-USER チェーンの先頭に、docker ブリッジネットワーク (172.17.0.0/16) からリンクローカルアドレス (169.254.0.0/16) へのアクセスを破棄するルールを一時的に追加する
[host] # iptables -I DOCKER-USER 1 -s 172.17.0.0/16 -d 169.254.0.0/16 -j DROP
[host] # iptables -nL DOCKER-USER
Chain DOCKER-USER (1 references)
target     prot opt source               destination
DROP       all  --  172.17.0.0/16        169.254.0.0/16
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
  • Docker コンテナからアクセス確認
    • リンクローカルへのアクセスはブロックされる
    • それ以外のアクセスは通る
[container] # nc -w 1 -vz 169.254.169.254 80
instance-data.ap-northeast-1.compute.internal [169.254.169.254] 80 (?) : Connection timed out
[host] # /etc/init.d/netfilter-persistent save

$ man シェル芸botのman

はじめに

普通の Linux 環境では、$ man コマンド のように実行することで、コマンドのマニュアルを見ることができますが、シェル芸botman コマンドを実行しても、(2019.7.17 時点では)マニュアルを見ることができません。

これは、Ubuntu の Docker イメージで設定されているものをうまく利用し、シェル芸bot の Docker イメージサイズの低減を図っているためで、ここではそのあたりの仕組みを解説してみます。

環境は ShellgeiBot-Image のベースに使っている ubuntu:19.04 (86f1f717b6d8) を想定しています。

Ubuntu Docker イメージの man

素の ubuntu:19.04 の Docker イメージからコンテナを起動します。

(Host)$ docker run -it --rm ubuntu:19.04

bash が起動するので、man ls を実行すると、ls コマンドのマニュアルの代わりに、次のような固定のメッセージが出力されます。

(Container)# man ls
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, including manpages, you can run the 'unminimize'
command. You will still need to ensure the 'man-db' package is installed.

実際の man の中身を見てみると、単純なスクリプトファイルが置かれているだけです。

(Container)# cat $(which man)
#!/bin/sh
echo "This system has been minimized by removing packages and content that are"
echo "not required on a system that users do not log into."
echo ""
echo "To restore this content, including manpages, you can run the 'unminimize'"
echo "command. You will still need to ensure the 'man-db' package is installed."

Docker は、アプリケーションを動かすためだけの環境として使われることが多く、そのような用途ではコマンドのドキュメント類はほとんど不要なのでしょう。 できるだけ配布するイメージを軽量化するために、man のようなドキュメント類は削除されているようです。

man を復活させる

メッセージに書かれている通り、削除されたパッケージ類を復元する手段として、unminimize スクリプトが用意されています。 unminimize を実行すると、概ね以下のような処理が実行されます。

  1. /etc/dpkg/dpkg.cfg.d/excludes にある、パッケージ除外設定ファイルを削除して無効化
  2. apt-get update, apt-get upgrade を実行し、パッケージを更新
  3. /usr/share/man/, /usr/share/doc/, /usr/share/locale/ 以下にファイルを配置するパッケージ類を(シェルワンライナーごりごりで)検索し、対象のパッケージを再インストール
  4. /usr/bin/man.REAL に待避させてあった man のバイナリを /usr/bin/man に戻す

あとは、apt-getman-db パッケージをインストールすれば、man コマンドが利用可能になります。

シェル芸bot の Docker イメージでは

シェル芸の実行にあまり必要でないパッケージは、なるべく Docker イメージに含めないようにし、ビルド時間があまり長くならないようメンテナンスしてきました。 Docker イメージに含めるデータ容量が増えると、データの転送にかかる時間にも結構影響してしまうため、軽量化にも気を配るようにしています。

man については、あまりシェル芸で参照する意味がないのではと考え、unminimize を実行せず、ドキュメント類は基本的に含めないようにしています。 ただ、該当する man がない場合のエラーメッセージを利用したシェル芸ができるよう、/usr/bin/man.REAL/usr/bin/man に戻す処理だけ実行しています(参考)。 man-db パッケージは、おそらく何か他のパッケージの依存で入っていると思います。

コマンドの使い方を調べたい場合は、手元の PC で調べてもらうか、ウェブ上のマニュアルを参照してもらえばと思いますが、シェル芸bot でのデータソースとしてや、textimg 等を併用してシェル芸bot で出力できた方が良いという声があればこの限りではなく、シェル芸bot オーナーの意向に沿っていきたいと思います。

Docker イメージにドキュメント類を含めない仕組み

unminimize の処理の中に、/etc/dpkg/dpkg.cfg.d/excludes の削除があります。 このファイルは以下のような設定が入っています。

# Drop all man pages
path-exclude=/usr/share/man/*

# Drop all translations
path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo

# Drop all documentation ...
path-exclude=/usr/share/doc/*

# ... except copyright files ...
path-include=/usr/share/doc/*/copyright

# ... and Debian changelogs
path-include=/usr/share/doc/*/changelog.Debian.*

ubuntu wikiReducingDiskFootprint - Drop unnecessary files あたりで説明されている通り、path-include=... の記載により、dpkg がパッケージをインストールする際に、これらの指定にマッチするパスにファイルを配置しないようになっているようです。 そのため、/etc/dpkg/dpkg.cfg.d/excludes が入ったままの状態では、ドキュメントを含む deb パッケージを追加でインストールしても、ドキュメント類が配置されません。

おわりに

シェル芸bot の Docker イメージをいじくってたら、Ubuntu のこんな面白い仕掛けにたどり着いてしまいました。 楽しい機会を与えてくれたシェル芸界隈の皆さま、そしてシェル芸bot を運用しながら、毎度説明不足な私の Pull Request を見ていただいているふるつき氏に感謝です。

$ owari kan --giko -aso

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        終        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|        so        |
|_________|
    ∧∧ ||
   ( ゚д゚)||
    /   づΦ

(たのしい)

第42回シェル芸勉強会 松江サテライト レポート

6/15(土) に開催された第42回シェル芸勉強会 松江サテライト会場の様子をレポートします。

案内

松江サテライト

いつもは大阪サテライトの会場担当をしていますが、今回は大阪会場を同僚氏にお任せし、初めて松江サテライト会場を開いてみました。 参加者が集まるか不安でしたが、松江は4名、大阪は6名の方に参加いただきました。ありがとうございます。

平和な松江サテライト会場の様子。

午後の部

今回は午前の部がお休みだったので、午後の部のみ。 が、

ということらしく、会長が気合いを入れて難しい問題を作って来られたので、松江で初めて参加したメンバーはことごとく死んでおりました。

私の方でも解き方のヒントを少し解説し、あとは Twitter に投稿される回答をターミナルに打ち込んでみることで、少しずつコマンドの新しい使い方を学んでくれているようでした。

大阪/松江サテライト LT

録画

youtu.be

大阪会場と松江会場をハングアウトで繋ぎ、YouTube で配信しました。 あまり慣れておらず、途中映像が抜けててすみません。

「シェルでフジエアー」 - MSR さん

speakerdeck.com

フジエアーというメーカーの家電に搭載された面白い日本語訳と、それを再現する自作の fujiaire コマンド の紹介。

謎の誤訳をスラスラと読み上げるのに、笑いが止まりませんでした。お待ちンス。

fujiaire コマンドは早速シェル芸bot に追加されていました。

「難読化dateコレクション ~ 難daコレ ~」 - たいちょー さん

github.com

難読化された date コマンドをいろいろ解説されましたが、さっぱりわからんぜ。Bash の機能を使い倒していてすげえ...。

「シェル芸botイメージのチューニング」 - so

github.com

5月の連休頃からシェル芸botの Dockerfile をいじくって Pull Request を送っていたら、シェル芸bot 作者のふるつき氏もよくわからないと状態になってしまったので、説明してみました。 Dockerfile のベストプラクティスをいくつか実践してみたという内容です。

そのた

シェル芸bot の Docker イメージはとてもサイズが大きく、ビルド / push / pull にとても時間がかかっているので、割と真面目にダイエットに取り組んでいます。 LT 後に sayhuuzoku コマンドなんとかしたいなーと呟いたら、sayhuuzoku で使われている形態素解析kagome の中の人がすぐに修正 Pull Req を送っていただいて、即マージされていました。ありがてぇ。これででかい辞書データをダウンロードしなくて済むようになったよ!

そのうち、よく使われるコマンド類だけを切り出した Mini 版をビルドできるようにして、シェル芸勉強会中に環境構築しなきゃならん手間を減らせと良いなーと目論んでます。

次回もよろしくお願いします!

unko.puzzle コマンドを作った

経緯

第41回シェル芸勉強会 東京会場の LT で、鈴木光宏 さんがシェル芸でターミナルなどを動かす方法を紹介されました。

www.youtube.com

また、たいちょー さんが作成された bigunko.show という、💩のドット絵を CLI で表示するコマンドがあります。

この2つを使って遊びたいなと思い、💩スクリプトを書きました。

つくったもの

複数のターミナルエミュレータを使った、スライディングブロックパズルです。

LT では xwit と xdotool が紹介され、そのうち xwit のデモがありましたが、macOS では Homebrew で xdotool が簡単にインストールできるようだったので、xdotool を使って実装しました。 macOS の xdotool は X11 上でしか動作しないようなので、XQuartz と、ターミナルエミュレータとして xterm が必要になります。 一応、Ubuntu でも動作するようにしてみましたが、Gnome 端末は画面サイズをあまり小さくできなかったため、xterm でのみ動作します。

super_unko リポジトリPR を送ってみたら、マージされました。 あと、これで遊びたいがために bigunko.show をキレイにする PR を送ったら、マージしていただきました。 ありがとうございます。

是非💩を切り刻んで、遊んでみてください。

使い方

一応、ドキュメント を追加したのでこちらをみてください。

感想

しばらく仕事が忙しくてあまり勉強できていなかったのですが、連休初日のシェル芸勉強会でいろいろと刺激を受けて、時間もあるのでじっくり作ってみました。 だいたい、構想と調査に半日、単純な実装に1日、そこからリファクタリングに1日といったところ。 あまり新しいことはできていないですが、それでもいろいろ調べて実装したので良い勉強になりました。

💩を切り刻むのにミスると、結構酷い絵ができあがりますが、これはこれで楽しい。

xdotool でウィンドウを動かすと、なぜか下にずれていく現象があったので、計算した移動先の座標に手元の macOSUbuntu 上で試したオフセット値を加える処理を入れましたが、環境によって異なりそうなので、もしかしたらずれるかもしれません。

謝辞

💩素材をお借りしました。 💩ライセンスなので良いかな?ありがとうございます。

第41回シェル芸勉強会 大阪サテライト レポート

シェル芸勉強会 大阪サテライト会場担当の so です。 4/27(土) に開催された第41回シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

午前の部

umidori.github.io

6回にもわたって開催された文字コードの勉強会の最終回、Unicode の結合文字について話していただきました。 講師の鳥海さんは「馴染みがないため忌避されているが、結合文字列には慣れるしか選択肢がない」と話されていましたが、シェル芸人には結構おもちゃにされてきたためか、(珍しく)すんなりと理解することができました。

何も知らなかった頃は Mac の NFD で正規化されたファイル名に振り回されて憤慨していましたが、背景の仕組みを知ることができればちゃんと対応できますね。 すごく学びの多い勉強会でした。大変ありがとうございました。

大阪サテライトの様子

今回も9名の方に参加いただきました。うち、はじめましての方は2名。 参加者が多すぎて会場探しに奔走することもなく、少なすぎて寂しくなることもなく、毎回ちょうど良い感じで来ていただけるのはありがたいことです。 勉強会のタイトル補正が効いているんでしょうか。

LT

3名の方に発表していただきました。ありがとうございます。

録画

www.youtube.com

gei-cli-suggest の紹介」 - taka さん

入力中のコマンドをインタラクティブに実行した結果を表示する Node.js 実装の自作コマンドを紹介されました。 正規表現をリアルタイムで評価して、試行錯誤したくなることありますね。 rm も躊躇なく実行してしまうのは危険が危ない。

「発掘、邪道シェル芸ツールズ|!」 - nmrmsys さん

nmrmsys.github.io

邪道(!?)シェル芸で使える、いろんなデータ処理ツールを紹介されました。 JS ライブラリの AlaSQL は約束された勝利の剣。

邪道だろうが何だろうが、望む出力が得られれば良いんだ。シェル芸では。

「シェル芸をドット絵にして思いを伝えよう!」 - たいちょー さん

www.slideshare.net

毎回ツールを作ってきて紹介されていますが、今回は CLI からドット絵画像を出力するコマンド、t2p を紹介されました。

その発表スタイルに、毎度爆笑させられます。

そのた

Youtube の配信画像がとても見やすかったです。ありがとうございます。 感動する大阪のシェル芸人達。

次回もよろしくお願いします!

第40回シェル芸勉強会 大阪サテライト レポート

2/16(土) に開催された第40会シェル芸勉強会 大阪サテライト会場の様子をレポートします。

案内

本家東京

usptomo.doorkeeper.jp

大阪サテライト

atnd.org

長崎サテライト

shell-nagasaki.connpass.com

問題と解答

b.ueda.tech

大阪サテライトの様子

今回は11名の方に参加していただきました。 募集ページの参加コメントがとても酷かったので、これは新しい人はこないかなーと思ってました。

f:id:horo1717:20190216230943p:plain

が、3名が初めての方でした。ありがとうございます。

初めましての方に休憩時間にちょっと聞いてみたところ、案内の

難易度は入門レベル~難しいものまであり、初心者・玄人の区別なく参加していただけます。

に騙された〜と言われてました。全然初心者向けではないと。まぁそうですよね。

私の方もついていくので精一杯なので、あまりサポートができる状況ではないです。 そんななので、参加してちょっと興味を持って、あとは自分で勝手に調べてくれるような猛者向けといったところでしょうか。

案内ページの文言は、忘れてなければ次回修正しておきます。

LT

録画

youtu.be

www.slideshare.net

前回のLTで、ワタナベ難読化シェル芸 を披露し、noc コマンドで TL をカオスに染め上げたたいちょーさんによる、ワタナベ姓の歴史講座と、noc コマンドのアップデート(日本語もちゃんと扱えるようになった!!)、新作の owari コマンドの紹介でした。

owari コマンド、いろんなオプションがあって楽しい。

twitter.com

go で書かれていると導入が楽で、すぐ試せて良いですね。 ふるつき氏により早速シェル芸 bot にも導入されて、TL が楽しかったです。

Piping Server の紹介 @小原 一哉 さん

最近話題になっていた Piping Sever と、ブラウザで受信できるようにした拡張を紹介していただきました。 CLI だけでネットワーク越しにいろいろ送受信できると、とても捗りそう。

ブログなど

qiita.com

その他

配信

午前の部の配信映像・音声がたまに乱れていた件、何度も対応していただいて、ありがとうございます。 サテライト会場では YouTubeTwitter が頼りなので、勝手なお願いですが、以下留意いただけると大変助かります。

  • 明るい背景だと白飛びしてしまって、文字が見えにくかったので、暗めの背景でお願いします
  • 画面の左右両端が取り込めていないと、欠けた部分のコマンドを想像で補完する必要があり、ハードモードでした
    • 画面全体を配信していただくか、Twitter にキャプチャ画像をあげてもらえると助かります

Google ハングアウトで発表者の画面を共有してもらって、それを取り込んで配信するのは綺麗にできそうだったので、大阪の LT でもやってみました。 実際綺麗に配信できてたようだし、慣れたら割とうまくできそうだったので、次からもこの方式でやってみようと思います。

空調

また社に空調の予約するのを忘れてました。 途中空気が悪くなっててすみません。 次からわすれないよう対策します。

ありがとうございます

今回もとても楽しく、また学びの多い勉強会でした。 主催のかいちょーさん、午前講師の鳥海さん、参加いただいた皆さま、運営をサポートしていただいたスタッフ各位、ありがとうございました。

お気をつけて

シェル芸勉強会はとても疲れるので、帰りが大変です。 こんなことにならないよう、気をつけてお帰りください。

twitter.com

$ owari kanban --giko | sed 's/N H K/  so  /'

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        終        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|       so       |
|_________|
   ∧∧  ||
  ( ゚д゚)||
  / づΦ

第38回シ҈ェ҈ル҈芸҈勉҈強҈҈会 大阪サテライト レポート

11/3 に開催された第38回シ҈ェ҈ル҈芸҈勉҈強҈҈会 大阪サテライト会場の様子をレポートします。

本家東京 usptomo.doorkeeper.jp

大阪サテライト atnd.org

福岡サテライト atnd.org

勉強会タイトルが謎のもやもや*1に包まれていて検索にひかっかりにくかったり、他の勉強会とも結構かぶっていたりで人数少なめになるかなと思っていましたが、今回も 8 名の方に参加していただきました。

午前の部

鳥海さんによる文字コードの話の第3回目でした。

www.youtube.com

午後の部

【問題のみ】jus共催 第38回҈҈҉҈҈҉シ҈҉ェ҈҉ル҈҉芸҈҉勉҈҉強҈҉会 | 上田ブログ

www.youtube.com

www.youtube.com

徳が高いんだか低いんだかよくわからないカオスなタイムラインが形成されていました。

大阪サテライト LT

今回は自分も含めて 3 人の発表でした。ありがとうございます。

www.youtube.com

自分は割と思いつきで Docker コンテナで dockerd の UNIX ドメインソケットをマウントして、再帰的に docker コンテナを作ってみる遊びをしていました。 資料はちゃんと作ってません。再帰危険。

たいちょー (@xztaityozx_001) さん

www.slideshare.net

~/.bashrc を魔の手から守りつつ、過度に難読化することで攻撃者の精神を破壊する芸。こわい。

MSR (@msr386) さん

gitpitch.com

Google Colaboratory をシェル芸の練習に使うのは間違った使い方なんですね。 危ないところでした。教えていただいてありがとうございます。

おわりに

今回もシェル芸文化にどっぷり浸かる祝日を過ごすことができました。 なかなか自分のシェル芸は上達しないですが、勉強会では普段使わないコマンドの使い方を知ることができてとても面白いですね。 ちょこちょこ上手い人のを真似しながら、ぼちぼち続けていければそのうち上達するんじゃないかなと思ってます。

主催いただいた会長さん、講師の鳥海さん、参加いただいたみなさま、ありがとうございました。

大阪サテライト会場は午後の運営スタッフの確保に失敗してしまい、ご不便をおかけしてすみませんでした。 皆さん協力的に動いていただき、助かりました。

次回は年末頃ですかね。

*1:

きゃろさんの LT より、大きな数を表すキリル文字だとか。