世紀末の墓

お気持ち.log

IT系寄りの雑記

ISUCON8予選参加記

ルール諸々

isucon.net

使用可能言語

Perl, Ruby, Python, PHP, Go, Node.js, Rust

事前にしたこと

(事前準備なんて)ないです

やること

webアプリのチューニング
鯖が用意されるから、SSHしてコードやDBゴリゴリ速くしようぜっていう感じ

感想

何もしてねぇ

そもそもノリで参加したのはいいものの、webアプリ特有の色々とかAPI仕様とかDBの挙動とか、全然知識ない状態だったので手を付けようにもつけられず、Googleと対話するコンテストになってしまった。
過去問とか結構大事だったみたい。
言語ある程度わかるし行けるっしょでは無理だった。(あたりまえ)

せいぜい小手先の高速化くらいしかできなかった。

抱負

初参加でだめだめだったけど雰囲気がつかめた感じがあった。
過去問とか大事っぽかったし、webアプリ周りの知識をもっと付ける必要がある。
まだまだ学生枠なので、来年は本戦出場していき!

【BEENOS】インターンに行ってきました

タイトル通り、インターンに行ってきたのでその所感等を書いていき

場所

BEENOSさん
beenos.com
この中には複数のグループ会社さんがあって、僕はその中のtenso株式会社さんというところでインターンさせていただいた

期間

2018/8/27~2018/8/31
1週間5営業日

やったこと

1週間ということもあって、実際の業務ではなくAWS周りのことを触らせてもらった
AWSの構築をterraformというやつで書いていく

AWS

Amazon Web Serviceの略
Amazonが提供しているクラウドサービスですね
クラウドならアマゾン ウェブ サービス - AWS

Terraform

インフラ周りの構成をコード化しておいて再現性をもたせようぜっていうやつ
コード化しておくことで何度でも同じ環境が完璧に建てられるし、一回書いたら何回でも使いまわしできるので嬉しい

HashiCorpっていう会社が提供してる
Go言語をラッピングしていてHCL(Hashicorp Configuration Language)という文法で書かれる
www.terraform.io

最終的にできたもの

f:id:silmin:20180913002053p:plain
こんな感じのネットワーク構成ができた
appサーバにはApachePHPを入れてWordpress環境を建てた
Autoscalingでappサーバの数を適宜調整していく感じ
HTTPリクエストはELBで負荷分散し、SSHは直接入れないように踏み台としてbastionを用意した
図にはないが、ルーティングテーブルを書いたりセキュリティグループを設定したりと裏にいくつか隠れている

Terraformよき

これだけでもオンプレで作ったらまあ面倒だし、AWSコンソール(GUI)から作ってもそれなりに面倒
しかしTerraformを使うことでコーディングは確かに面倒だが、汎用性の高い構成を2回目以降はほぼノータイムで建てられることはとても大きい
実際に構築中に何度も破棄と再構築を繰り返し、身をもって体験した

全体としての感想

1週間という短い期間だったが、得られたものは結構あった

技術面

ネットワークの知識はあったが、こういうインフラ周りに今まで大して触れてこなかったため新鮮だった
AWSなんてほぼ初めてである程度知見を吸収できたと思う
Terraformも初めてだったがGoは少しわかるし、AWS以外でも使えるとのことなのでこれからお世話になりそう

それ以外

インターン自体初めてでIT企業ってこんな感じかーって思った
雰囲気もいい感じに緩くて、作業しやすい環境だったと思う
今まで自分は個人での開発経験しかなかったので、多人数で進捗確認しながらじわじわ進めていく感じが新鮮だった(今回も個人だが周りを見ていて)
社内Slackにレビュー依頼や対応依頼とかが飛び交ってて、良くも悪くも手間がかかってるなぁと(金がかかってるので当然といえば当然)

最後に

全体的に楽しかったし、来年の春にも来ていいことになったので楽しみにしている
f:id:silmin:20181021003321j:plain
↑左から、チューターの加治さん、僕、人事の笠松さん
なぜか片足のすそが捲れてるぼく

【write-up】OverTheWire bandit Level0~10 を解いてみた

OverTheWire banditとは

用意されたサーバにsshで入って、その中からflagを探すCTF用のサイト
bandit0にはbandit1にloginするためのpassが隠れていて、bandit1にはbandit2にloginするためのpassが隠れているっていう感じ。

それぞれのLevelにbanditが対応している。
Level2ならbandit2のユーザが使えるみたいな感じ。

一応、各番号のサイトにはflagの特徴や条件等いろいろなヒントが書かれていたりなかったりする。

今回はbandit0~10を復習がてらやってみたので解説
OverTheWire: Bandit

環境

host: windows10
VirtualBox:Ubuntu16.04 LTS
仮想マシンUbuntu環境です。

Level0

書かれている文章を読むとsshして繋げたらおkらしい。
ちなみにアドレスはbandit.labs.overthewire.orgでポートは2220、アカウント名とパスワードは両方 bandit0 でいいらしい。
よって

$ ssh bandit0@bandit.labs.overthewire.org -p 2220

で入って

bandit0@bandit.labs.overthewire.org's password:

って聞かれるから

bandit0

を打って完了です。

Level0 → Level1

ホームディレクトreadmeっていうファイルの中に次のレベルのパスワード入ってるよ
って書かれてるので、念のため

$ ls

してみると、readmeっていうファイルがある。

そしたら

$ cat readme

で、ファイルの中身を見る。
するとなんかすごい文字列がでてくるが、これがキーらしい。
これを次のbandit1のパスワードにするとbandit1に入ることができる。

Level1 → Level2

ホームディレクト- って名前のファイルにキーがあるで。って書かれてる。

愚直に

$ cat -

をすると、- がオプション記号(?)として扱われてしまうのでうまくいかない。

最初に - が来ないようにpath指定してあげればよさそうなので

$ cat ./-

で無事中身を見ることができた。

Level2 → Level3

スペースを含むファイル名のファイルの中にキーがあるで。って書かれてる。

愚直に

$ cat space in this filename

をすると、空白区切りで別のファイル名として扱われてしまう(space というファイル、in というファイル、thisという...)。

これを避けるためにエスケープ文字というものを使う
スペースの前に \ (バックスラッシュ)を付けることで、スペースをファイル名に含まれる空白として認識してくれる。

$ cat space\ in\ this\ filename

ちなみに、Tabキーでファイル名を補完する機能があるため、Tabキー押してあげると自動で入力される。

Level3 → Level4

inhere っていうディレクトリの中にあるよ。って書かれてる。

とりあえず、inhere/に移動してみる

$ cd inhere/

そして中身を確認

$ ls 

あれ、なにも表示されない。

でも問題文にinhere/にあると書かれているので、嘘ではないだろう。
なら隠しファイルの可能性を疑って全表示してみる。(lsだけでは通常隠しファイルは見えない)

$ ls -a

すると、.hiddenというファイルが見える。
中身を見てみる

$ cat .hidden

と、無事キーを入手することができた。

ちなみに、移動せず

$ cat inhere/,hidden

でもOK

Level4 → Level5

inhere/の中の一つだけ読めるファイルにキーが書かれてるよ。とある。

inhere/の中身を見てみると-file00~-file09が格納されている。
この中から読めるものを探すわけだが、読めるということはASCIIで書かれていそう。
なので、ファイルの形式を調べてみようと思う。

$ file inhere/*

で全ファイルの形式がわかる。
すると、-file07だけASCII Textだとわかるので、

$ cat inhere/-file07

でキーが入手できる。

ちなみに

$ cat inhere/*

で全部の中身表示して読めるとこだけ取り出してもいいけど、前ファイルの末尾が偶然アルファベットとかありそうだから非推奨

Level5 → Level6

inhere/の中にあるファイルで、

  • 人間が読める
  • ファイルサイズが1033byte
  • 実行ファイルじゃない

の条件に当てはまるファイルだよ。って書いてある。

実際inhere/をlsしてみるとめっちゃファイルある。これを一つ一つ見ていくのは嫌だし、効率悪い。
ので、一番それっぽいファイルサイズを使ってみる。

#findコマンドを用いる場合
$ find -size 1033c

#find, grepを用いる場合
$ find -ls | grep 1033

すると./inhere/maybehere07/.file02が当てはまってるのでそれの中身みてキー入手。

find -ls
findで見つけたファイルをls -lの形式で出力する
| (パイプ)
左のコマンドの出力を右のコマンドの入力とする

Level6 → Level7

このサーバの全場所から

  • 所有ユーザがbandit7
  • 所有グループがbandit6
  • ファイルサイズが33byte

の条件に合うファイル探してねって書いてある。

これはさっきと同じ感じで、

#find
$ find / -group bandit6 -user bandit7 -size 33c

#find and grep
$ find / -ls | grep bandit7 | grep bandit6 | grep 33

でいける。
find / -lsはこのサーバ内の全ファイルをls -lの形式で列挙。
ls -lの形式には所有グループ、所有ユーザ、ファイルサイズ、権限情報などいろいろな情報が載っている。
それをみてgrepで絞り込む感じ。

Level7 → Level8

data.txtっていファイルのmillionthって単語の次にキーがあるぜ。って書かれてる。

これはもう

$ cat data.txt | grep millionth

しかないね

Level8 → Level9

data.txtの中のものは被りばっかで、被らないものは1つしかないらしい。
その被りないやつがキーらしい。


被りを消してくれるuniqコマンドを使いたいんだけど、連続してないといけないから先にsortしよう。

$ sort data.txt | uniq -u

uniq -u は重複を非表示にしてくれる。

するとキーが出てくると思う。

Level9 → Level10

何個かの'='の後にある読める文字列みたいな感じで書いてある。

中身を見てみるとバイナリで読めない。
でも人間が読める文字列って書いてあるのでstringsコマンドを使って可読部分を表示してもらう。

$ strings data.txt

これでもたくさんあって大変。
grepを使うんだ。

$ strings data.txt | grep '='

すると3つくらい出てくるけど、今までキーになってたみたいなやつがキーになる。

まとめ

一応、Level0~10まで書きました。
ここはまだ全然簡単で、uniqやstringsコマンドを久しぶりに使ったくらいの難易度でした。

気が向いたら11以降も書きます。

【インフラ勉強会LT記】ネットワークの基本の「き」(2018/02/04)

インフラ勉強会って?

インフラ勉強会とは非営利のインフラエンジニアのための勉強会オンラインコミュニティです。
DiscordというVCアプリ(?)を用いて行っています。
詳細はインフラ勉強会 Wikiを参照ください。

LTの内容

ネットワークの基本の部分の

をざっくりと説明しました。

形式

VC:Discord
画面共有:mixer.com

所感

僕の今まで勉強してきたことを、できるだけ初心者向けかつ体系的に伝えられるようにしたつもり。
なんか意外と刺さりが良かったというか好感触だったのでまたやりてぇってなった。

今までここの分野を講義というか人に教えるために整理したことがなかったので、良い復習になった。

ちなみにこのイベント
wp.infra-workshop.tech

まとめ


インフラ勉強会はいいぞ

NAPTとは

この記事の続きといえば続きです。
silmin.hatenablog.com

NATとの違い

アドレス変換テーブルを用いて変換を行う部分は同じなのですが、
変換するパラメータに「ポート番号」を追加します。

聞いたことがあるかもしれません。(80番ポートが一番有名かな?)

NATでは、IPアドレスのみでテーブルを作っていましたが、1対1の通信しか実現できませんでした。
※詳しくは上の記事参照

ですがNAPTでは1対多の通信を実現できます。

NAPTとは

例のごとく、このようなネットワークをモデルにします。
f:id:silmin:20180114234141p:plain
NAPTでは、ルーターはIPとポート番号をセットにしたアドレス変換テーブルを持ちます。

ポートについては詳しく記事にしようと思いますが、分からない人は今は「そんなのがあるんだ」くらいに思っておいてくれれば結構です。

では実際に流れを見ていきます。


PC2からサーバーの80番ポートにパケットを送っています。
f:id:silmin:20180114234131p:plain
ルーターはアドレス変換テーブルを見ながら、ヘッダ情報を書き換えます。
これでPC2からサーバーに送ることができました。
ここまではNATでも可能でした。

サーバーからPC2に送る時はどうでしょう。
f:id:silmin:20180114234150p:plain
サーバーは、G:S2から送られたと思っている(受け取ったパケットのヘッダ情報から読み取る)ので、G:S2宛にパケットを送ります。

受け取ったルーターは、アドレス変換テーブルにもとづいてヘッダ情報を変換します。

こうして、PC2に無事届けることができました。

こちらも、アドレス変換テーブルに無い宛先のパケットが来た場合は破棄されます。

これが俗に「IPマスカレード」,「ポートフォワーディング」というやつですね。

アドレス変換問題

一見完璧なように見える(かもしれない)NAPTですが、コレにも問題があります。

それは、ヘッダしか見ない(変換しない)こと です。

...宛先や送信元情報が書かれてるのはヘッダなんだからいいじゃんと思うかもしれません。

その通りなんですが、例外もあります。

ICMPなど、パケットのデータ部分に宛先情報等が載っているプロトコルも存在するため、データ部分まで見ないNAPTではカバーしきれないのです。

NAPTだけでも簡易的なセキュリティ対策にはなるのですが、今になっては無意味同然なので通常ファイヤーウォールと併用して運用します。(多分そう違ったらごめん)

NATとは

NAT(Network Address Translation) とは、一言でいうと

グローバルアドレスを節約するために、プライベートアドレスっての作って変換しようぜ

っていう話です。

これだと圧倒的説明不足感が拭いきれないのでちゃんと説明します。

NATのはじまり

ずばり、IPv4アドレスの枯渇対策です。

かつて、ネットワークに接続されている機器にはそれぞれに固有のアドレス(グローバルアドレス)が割り振られてました。
当時は、接続機器数も少なくて全然それで良かったのです。

今はどうでしょう。
当時とは比べ物にならないくらいインターネットが普及しました。
PCやネットワーク機器は勿論、スマホや家電だってインターネットに接続する時代です。

IPv4アドレスは32ビットで構成されているため、単純計算でも2の32乗で...約40億個しかありません。
到底足りません。


そこでグローバルIPの他にプライベートIPを作って、複数のプライベートIP→一つのグローバルIPっていう変換が出来ればいけんじゃね!?
っていうのがNATのはじまりです()

NATとは

NATは、プライベートIPとグローバルIPを相互変換する技術です。

画像で詳しく見ていきましょう。

例えば、このようなネットワークがあったとします。
f:id:silmin:20180114205915p:plain
インターネットにルーターを繋げて、そこにPC1~3を繋げている、ごくありふれた構成です。

ここで、各PCにはP1~3のプライベートIPが、サーバーにはXというグローバルIPが割り振られていることにします。

ルーターはこのP1~3をグローバルアドレスに変換するため、下のようなアドレス変換テーブルを持っています。
f:id:silmin:20180114205924p:plain

このテーブルを用いて、変換していきます。

では、PC2がサーバーに何かしらのデータを送りたいとします。

  1. PC2がIP: X宛にパケットを送ります。
  2. ルーターがパケットのヘッダの部分を見て、P2(送信元のプライベートIP)をG(グローバルIP)に変換します。
  3. ルーターは、サーバーに変換後のパケットを送ります。

f:id:silmin:20180114210807p:plain
※ヘッダ部分のIP表記がポート番号のようになってますが、スペースの問題上 送信元:送信先 と表記しています。

このように、複数のPCからでもプライベートIPを用いることで、グローバルIPを節約することができます。
ちなみに、アドレス変換テーブルに登録されていない宛先のパケットが来た場合は破棄されます。

NATの欠陥

このままでは欠陥があります。

プライベートなネットワークの中に、2つ以上のPC(端末)があると相手からの返答が受けられない。
です。

これは少し考えれば分かる話かと思います。

先程、PC2からサーバーまでは届きました。
それでは、サーバーからPC2まではどうでしょうか。

届かないのです。
サーバーは受け取ったパケットをヘッダを見て、IP: G から送られてきたということを知るため、Gに向けてパケットを送ります。
ですが、ルーターはどのIPに変換していいのやらさっぱりなので、2台以上のPC(端末)があった場合は通信不可となります。

よって、NATでは1対1の通信しか実現できません。

よく NATは1対1と言われてますしね。

この欠陥を克服するために、NAPT(Network Address and Port Translation)というものがあります。

察しの良い方はわかるかもしれませんが、名前にある通り「ポート番号」と言うものを使います。

これの記事も後々かきます。
書きました。
silmin.hatenablog.com

あけましておめでとうございます&2018年の抱負

あけましておめでとうございます。
2018年になりました。
年越しはコーディングしてました。

もう3ヶ月もしたら僕は北陸の民になります。(一人暮らし)

前年も色々あったけど、今年もたくさん頑張りたいということで抱負。

2018年の抱負

CTFをはじめ、いろんなことに挑戦してたくさん成果を生みたい

ということです。
やりたいことはたくさんあります。
野望もあります。
でも圧倒的に時間と金が足りなかった。

  • CTFで精進
  • ネットワーク・セキュリティ周りのおべんきょう
  • ゲームエンジンの習得
  • アプリケーション開発(ゲームでもなんでも)
  • 情報全般の知識・技能の底上げ

これらがさしあたってやりたいことです。

ゲームサークルを建てたいなぁってぼんやり考えてたりもする。
し、動画配信とかにも手を出していきたい感もある。


まあこんな感じで、2018年もよろしくお願いします!

pythonから書式制御文字でターミナルに色付けする

pythonから標準出力への色付けって、調べるとライブラリ使う系パリピ記事()がたくさんでてくるんですが、書式制御文字でもやれるで^^ということを紹介しようと思う。

まえがき

まあC/Ubuntuでやってる人いたから、python/Linux Mintでやろうっていうだけなんですがね。
www.mm2d.net
エスケープコードの細かい話はこの方の記事読んだら最強になれます。


本題

文字に色付け

print("\033[38;5;50mHello!\033[0m")

ってやると
f:id:silmin:20171204221826p:plain
って感じのがでてくるかな?

256色のリストを出してみる

for i in range(256): 
  print("\033[38;5;%dm%3d\033[0m " % (i,i), end="")
  if i % 16 == 15: print()

これで15ずつの表ちっくなのが出てくるかと思う。
↓こんなの
f:id:silmin:20171204220946p:plain

この値にそれぞれの色が対応してるって感じですね。
上の記事の人は16進でやってたので僕は10進でやりました。


まとめ

上の記事がぐう有能で正直あまり書くことなかったなら書くな
まあ今後その記事を発見できるかわからんので、メモってことで。
つかリンク貼ってるなら見失わないのでは

エスケープコード諸々は基本的に言語に関係なく使える(ターミナル側が解釈する)ので、ライブラリとかなくても全然色付け可能やで^^

ネットワークアーキテクチャはなぜ階層構造なのか

OSIプロトコルもといOSI参照モデルは7階層、TCP/IPは4階層です。

ではなぜ、階層構造になっているのでしょうか。
それぞれやくめが違うからといってしまえばそれまでですが、ちょっと説明させてください。

事前に

これらの記事を読んでおくと幸せになれるかも(露骨)
OSI参照モデルとは - 世紀末の墓
プロトコルとはなんだろう - 世紀末の墓

本題

いきなりネットワークアーキテクチャはなぜ階層構造?と考えるまえに・・・
これは通信においての、必要なプロトコルを階層に分類したものですよね。

もっと簡単にいうと、これは通信についてのことです。
通信というと硬そうだけど、「会話」や「手紙」だって通信です。

ここで、「会話をする」という通信を考えてみます。

会話をする

ここでは電話を使ってビーチの話をする男女を挙げようかと思います。

f:id:silmin:20171125233547p:plain

画像からもわかるように、共通部分がいくつかあると思います。

これらはどれも両者で共通していないと、会話という通信は成立しません。
男性の方はビーチの話をしているのに、女性の方はレストランの話をしていたとしたら
会話は成立しませんよね。

共通していればいいから・・・

共通していれば通信は成立するのだから、ということで一つ入れ替えてみましょう。

f:id:silmin:20171125234103p:plain

両者共に日本語を使っていたところを、英語を使うようにしてみました。

これも問題なく通信できますよね?
電話→メールにしても
ビーチ→レストランにしても
両方が共通していれば、通信は何ら問題なくできるはずです。

なにが言いたいの

勘の良い方は気がついたかもしれません。

これがコンピュータ同士の通信だとしたら、どうでしょうか。

コンピュータ同士でも同じなはずですね。
7層のうちの1層に変更があっても、他の層にはその変更は影響しません。

これが階層化されている理由です。


は?
そんなんで説明した気になるな、いまいちわからんぞ。

そうでしょうそうでし(殴
ちゃんと説明します。

各層はそれぞれ独立している

アプリケーション層~物理層は、それぞれ独立しています。
そのため、どれか一つが入れ替わっても他の層には影響しません。

1つの層が新しくなるたびに、毎回全部作り直していたら非効率すぎますし。


物理層を例にあげます。
通信につかわれるケーブルはたくさんありますよね。
LANケーブル(より対線)、同軸ケーブル光ファイバー...

これから新しい技術がでてきて、それに置き換わる可能性だってあります。

でも、それらにはアプリケーションの形式やアドレス体系などは影響されません(そのまま使い続けられます)よね。


これが階層構造となっている理由です。

まとめ

ネットワークアーキテクチャのそれぞれの層は独立していて、
特定の層の変更が他に影響を及ぼさないため、効率的!

OSI参照モデルとは

この記事では、OSI参照モデルについて僕が学習したことをつらつら書きます。
どうでもいいと思った項目は好きに飛ばしてください。

どうでもいい話

基本情報技術者試験とかにはバリバリ出てくるけど、中身よくわからんとか、
情報を勉強し始めたときに出てきたけど、正直なんのためにあるか知らんとか、
これって結構最初に出てきて大事なのに、よく知ってる人って少ない感じがしてます。

まあ知らなくても使えちゃいますしね(現に僕も使えてる)

そんな人達のためになったらいいなぁということで書いてます。
一応筆者は基本情報技術者は持ってる(応用は受けたけど受かってるか知らん応用も取る気ではいる)

歴史とか成り立ちとか

OSI参照モデルとは、元々OSIプロトコルという、ISO(国際標準化機構)によって標準化されたネットワークアーキテクチャから来ています。

ネットワークアーキテクチャ
プロトコルを階層構造で体系化したもの
プロトコルスタックプロトコルスイートとも呼ばれる


コンピュータ通信が始まった頃、メーカによって独自のネットワークアーキテクチャが乱立しました。
アーキテクチャの異なるネットワークとの通信は困難なため、

「ネットワークアーキテクチャ標準化しようぜ」

という動きに。

そこで登場したのが(大きく分けて)

の2つです。

まあ色々なんやかんやあって、TCP/IPが標準のネットワークアーキテクチャとなりました。
今でもTCP/IPが標準となっており、本もたくさんありますね。
※なんやかんやのところはまた追々。

それでも、OSIの論理モデルが色々を理解するのに優秀だったので、ネットワークの基本モデルとして普及します。

それが「OSI参照モデル」というわけですね。


OSI参照モデルの概要

OSI参照モデルは、7階層に分かれていて、通信機能を理解するのに有用です。

  1. アプリケーション層
  2. アプリケーション間通信に必要な固有の部分を決めてる(アプリケーション固有の形式等)
  3. プレゼンテーション層
  4. ネットワーク上で扱うデータの形式を決めてる(文字コードはマシンやOSによって違うけど読めるよね)
  5. セッション層
  6. 通信形式の決定やデータ転送のタイミングを決めてる(トランスポート層にコネクションに関する指示)
  7. トランスポート層
  8. アプリケーションの識別とデータ品質の保証をしてる(複数ソフト使っててもそれぞれに届くよね)
  9. ネットワーク層
  10. 終端ノード間(End-to-End)の通信を実現してる(IPアドレスとか経路制御とかしてる 一番働き者かも?)
  11. データリンク層
  12. 隣接ノード間(Link-by-Link)の通信を実現してる(具体的な通信手段やフレームの生成、MACアドレス周り)
  13. 物理層
  14. ビット列と信号との変換、ケーブルとかの規定をしてる
となっています。
上から「アプセトネデブ」とか言って覚えた記憶があります。

正直、()の中身がほぼその詳細です。
それぞれを規定してるのがプロトコルってことですね。
silmin.hatenablog.com
ちなみに、↑の記事で書いてるHTTPはセッション層、IPはネットワーク層プロトコルです。

それぞれの層やプロトコルについては、ちゃんと説明する記事を書こうと思ってるので、しばらくお待ちをば。
ググったほうが早そう