MBSD Cybersecurity Challenges 2017 に参加した

初めまして、 焼きそばメロンパン と申します。

先日 MBSD Cybersecurity Challenges 2017 に参加したので、次に参加する方の為に今回の大会について自分たちがやったことを書いておこうと思います。

目次

  • 提出したレポートと発表したスライド
  • 大会について
  • 本選の流れ
  • 問題概要・環境
  • 脆弱性を探す上での工夫
  • 審査基準・反省
  • 感想

提出したレポートと発表したスライド

提出したレポート (元がWordなので若干レイアウトが崩れている)

大会について

三井物産セキュアディレクション(MBSD) という会社が運営している、専門学校と高専が対象のセキュリティ大会です。 予選では VitrualBox にすぐ import 出来る CentOS7 が入った OVA ファイルが配布され、このサーバに対して攻撃を行いレポートを書きます。 期限は確か 1 ヶ月ほどあり、家にいる時も学校にいる時も常にこいつの脆弱性を探すために攻撃施行していました。

サーバにはパスワードが掛かっており、起動すると JSON を返す API サーバが起動するという物です。 今回の大会ではこの API サーバ及び、サーバそのものの脆弱性を探してレポートを記述するという形でした。

参考リンク: 専門学校・高等専門学校対象セキュリティコンテスト MBSD Cybersecurity Challenges 2017|専門学校と経営:専門学校の経営者・広報・就職担当者の情報サイト

本選の流れ

レポートの評価が良いと予選突破ということで、本選に出場しプレゼンを行うことが出来ます。 本選ではプレゼン大会を行い、上位3チームが表彰されます。

会場は大手町のビルで行われ、会場の雰囲気は結構ゆるふわな感じで、プレゼン中に笑いが起きることもあって楽しい感じでした。 プレゼン中、僕はずっとツイッターをしていましたが、ハッシュタグが無かったためあまり参加者の目には届かず寂しかったです。 次回は是非ハッシュタグが欲しいところですね。 ( #MBSD2017 というハッシュタグが一部参加者で利用されていた模様 )

問題概要・環境

出来ることなら問題は公開したいところでしたが、公式サイトで配布は禁止とあったので公開しません。

問題環境については僕がチームで共有していた Qiitaのprivate記事 をご参照下さい。

脆弱性を探す上での工夫

チームでの情報共有は Slack と上述した Qiita の private 記事を利用しました。
使用したツールは下記の通りです。

  • nmap (ポートスキャン)
  • Vlus (脆弱性スキャン)
  • Nessus (脆弱性スキャン)
  • BurpSuite (ローカルプロキシ)
  • Charles (ローカルプロキシ)

脆弱性を探す手順は下記の通りです。
スキャンの結果は スプレッドシート で共有しました。

  • 一通りの機能試す
  • 考えられる脆弱性を全て上げて検証
  • 各種スキャンツールでスキャン

また、一つの工夫として、VirtualBox仮想マシンは中身のファイルを任意に編集可能なので、root のパスワードを書き換えて root ログインが可能な状態にしていました。

他校のプレゼンについて

他校では下記のような団体がいました。

  • スピーカを使ってゆっくりに喋らせる
  • 脆弱性の実証を動画を使って解説
  • OSコマンドインジェクション
  • IPv6 の時のみに再現出来る脆弱性
  • 現状の環境では発火しない潜在的脆弱性
  • 報告した脆弱性が100件以上
  • プレゼンに考察を含める

審査基準・反省

審査基準は 公式サイト にある内容が本当に重視されていて、単なる技術勝負じゃないことが伺えました。 (実際、入賞していたチームはプレゼンがとても上手く、スライドの内容も論理的で、テーマも一貫していた)

僕達のチームの反省点として、次回はこれをしたいということをまとめました。

  • CVSSによる評価 ( スコープは自分で決める、数値にあまり意味はなく相対的表現に使う )
  • CWEによるカテゴリ分け
  • グラフ等を使うと良いかも
  • 潜在的脆弱性 ( Tomcatとか )
  • 実証は埋め込み動画の方が良い
  • 脆弱性の考察 ( 設計の仕方等でフレームワークを持ち出す )
  • 他のチームとの差別化 ( SQLインジェクションとか絶対被る )
  • プレゼンの構成が悪かった ( LTとは違う )
  • レポートの報告数 ( 30件以上が多い )
  • どういう流れ、観点で脆弱性を探したのか
  • 脆弱性って何?APIサーバって何?っていうのが無駄だった
  • 一つのテーマに絞ったほうが良い ( 結局何が言いたいのかわからなかった )
  • Webの場合、IPv6についても検討するべきだった
  • 図があるべき
  • 攻撃者の目的を示す

感想

今回の大会を通して、自分がまだまだ勉強不足であることが改めてわかりました。
これからの1年間でもっと勉強して、来年もまた出場したいと思います。

また大会後の懇親会で仲良くなった人達と大会が終わってからサイゼリアに行ったのですが、その時に話したプログラミングやインフラの話がとても楽しかったので、もし来年に参加する方は是非懇親会で同士を見つけてサイゼリアに行くと良いでしょう。

非同期処理が難しい - SwiftでAlamofireの結果を受け取る -

概要

Alamofireとは、SwiftでHTTP通信を行うライブラリです。
ios Swift で下記のアーキテクチャAPIクライアントを作ろうとしたら、非同期処理に苦しめられました。

ViewController(表示を変える)
↓
UseCase (ビジネスロジック) → Domain (値オブジェクト)
↓
Repository (HTTP通信)

Twitterで例えるなら、

  1. ツイート読み込みイベントが発火する
  2. ViewControlle でツイート読み込み操作を受け取る
  3. UseCase のツイート読み込み処理を実行
  4. Repository のツイート取得APIを叩く処理を実行
  5. ツイートが入った JSON を UseCase に返す
  6. UseCase で JSON を ツイートを Domain に変換
  7. Domain を ViewController に返す
  8. ViewController で Domain からツイートを取り出し、タイムラインに表示

みたいなことをしようと思いました。

しかし、Repository でツイート取得API を叩く処理 ( Alamofire ) が実は非同期処理で、結果が上手に受け取れないということが起こりました。
コードで表すなら下記の様に実装していました。(だいぶ簡略化してます)

class Timeline {
  var tweet: String  

  init(json: JSON) {
    self.tweet = json['tweet']
  }
}

class TimelineApiRepository {
  func request() -> JSON {
    var timelineTweets: JSON

    Alamofire.request("TwitterAPIのURL").responseJSON { response in
       if let result = response.result.value {
         timelineTweets = JSON(result);
       }
    }

    return timelineTweets
}

class TimelineUseCase {
  func exec() -> Timeline {
    // TODO: ここが問題!!!!!!!!!!!!!!!!!!!!!!
    return Timeline( TimelineRepository().request() )
  }
}

class ViewController: UIViewController {
  @IBOutlet weak var message: UILabel!

  override func viewDidLoad() {
      super.viewDidLoad()

      Timeline timeline = TimelineUseCase().exec()
      self.message.text = timeline.tweet     
   }
}

上記コードの Timeline( TimelineRepository().request() ) が非同期の為うまく動作しませんでした。
わかりやすく UnitTest で表現すると、下記のようにして動作すると思い込んでいました。(同期処理だと思っていた)

...
let repository = TimelineRepository()
...
expect( repository.request() ).to(equal(' TwitterAPIから受け取ったJSON(Mockから受け取る) '))
...

実行直後は処理が完了していない為、上記のテストはエラーになります。

非同期処理について

非同期処理についていろいろ調べていて、下記の単語がごっちゃになったのでざっくり調べました。

  • 非同期処理/並行処理/並列処理
  • プロセス/スレッド/タスク
  • promise/future
  • async/await

非同期処理 / 並行処理 / 並列処理

  • 同期処理: 処理が順番に行われる処理
  • 非同期処理: 処理が順不同に行われる処理
  • 並列処理: マルチスレッド、計算負荷を分散させる
  • 並行処理: シングルスレッド、処理が順不同に行われる

プロセス / スレッド / タスク

  • プロセス: 一つのプログラムの処理
  • スレッド: プロセスに含まれる、タスクを実行する
  • タスク: スレッドに含まれる、処理の単位

タスク分けされた処理はスレッドにいい感じに分散されて実行されます。(スレッドプール?)

promise/future

非同期処理をいい感じに行うデザインパターン

  • future: 待ち, 成功, 失敗のどれかの状態を持ち、非同期処理が終わっていれば成功か失敗の値を受け取れる
  • promise: futureを生成する、成功時, 失敗時の値を定義する

async / await

  • async: 非同期で処理を行う
  • await: 非同期処理が終わるまでメインスレッドをブロッキングする

何故通信処理が非同期なのか

  • ios では描画処理がメインスレッドで行われる
  • メインスレッドで重い処理を行うと描画処理が止まってしまう
  • なので、通信中も描画が行われるように非同期にする
  • 通信が終わるまでメインスレッドをブロッキングするとアプリは固まる
  • この解決方法としてはコールバックを渡して処理をする

HTTP通信のレスポンスを受け取るには

上述したように、Repository にクロージャ (コールバック) を渡せば良さそうなことがわかりました。

class Timeline {
  var tweet: String  

  init(json: JSON) {
    self.tweet = json['tweet']
  }
}

class TimelineApiRepository {
  func request(closure: closure){
    // TODO: そもそもここのクロージャを Presenter で定義しても良いかも
    Alamofire.request("TwitterAPIのURL").responseJSON { response in
       if let result = response.result.value {
         // TODO: レスポンスが返ってきたら、クロージャにレスポンスを渡す
         // TODO: このクロージャ内でツイートがviewに設定され、画面に反映される (はず)
         closure(Timeline(result))
       }
    }
}

class TimelineUseCase {
  func exec(closure: closure) {
    // TODO: 受け取ったクロージャを Repository に渡す
    TimelineRepository().request(closure: closure)
  }
}

class ViewController: UIViewController {
  @IBOutlet weak var message: UILabel!

  override func viewDidLoad() {
      super.viewDidLoad()
      
      // TODO: クロージャを定義
      let closure = { timeline in
        self.message.text = timeline.tweet
      }

      // TODO: UseCase にクロージャを渡す
      TimelineUseCase().exec( closure: closure )
   }
}

上記のようにすることで API のレスポンスを view に反映させることが出来るはずです。
(各層の依存関係がおかしくなってしまったので別途修正します)

ただ、このままだとコールバック地獄とかいろいろ辛くなると思うので、その場合は BrightFutures というライブラリを使うと Scala の Future のような感覚で非同期処理が扱えるようになるようです。

因みに、UnitTest は下記のようになりました。

...
var json: Json
let closure = { (result: JSON) -> () in
  json = result
}
let repository = TimelineRepository()
...
repository.request(closure: closure)
expect( json ).toEventually(equal(' TwitterAPIから受け取ったJSON(モックから受け取る) '), timeout: 5, pollInterval: 1, description: "")
...

まとめ

  • 非同期処理は難しい
  • メインスレッドを止めて値を受け取る処理はUI処理も止めてしまうので絶対ダメ
  • でもクロージャを渡せばノンブロッキングでなんとかなる
  • クロージャは Presenter から UseCase を通り、Repository で実行される
  • クロージャ実行時は Presenter のプロパティを操作出来るので問題無い
  • BrightFuture はクロージャだけでやるとコールバック地獄が辛いので使う
  • 非同期処理を一杯書いてるとグチャグチャになりそうだから注意する

非同期処理をちゃんと書いたのは初めてだったのでとても苦労しています。
この記事も間違っているかもしれないので、マサカリありましたら投げて頂けると幸いです。

OOPにおける依存とは

概要

OOPではよく「抽象に依存させる」「依存性の逆転」等、 "依存" という言葉が出てきます。 この "依存" とはどういう意味なのか、最近やっとわかってきたのでメモを残したいと思います。 (Javaで解説します、Javaアレルギーの方は我慢して下さい)

この記事は僕が思っていることなので、間違いがありましたらコメント頂けると幸いです。

依存とは

依存とは、実装の詳細を知っていることです。

コード上での依存とは、下記のようにnewしている状況を指します。
下記コードでは A が B を new しているので、 A は B に依存しているということになります。

class B { ... }

class A {
  public void example() {
    B b = new B();
  }  
}

依存している状況では、依存先が変更された場合依存元も変更が強いられます。

抽象に依存させる

抽象とは抽象クラスやインタフェースを指します。
new して受け取る型を new するクラスの抽象クラスやインタフェースの型にします。

interface C { ... }

class B implements C { ... }

class A {
  public void example() {
    C c = new B();
  }
}

抽象に依存させることのメリットは、実装が変わったとしても依存元は実装の詳細を知らないので影響を受けないことです。 これにより、変更に強いコートを生み出すことが出来ます。

依存性の注入(DI)とは

最近良く聞く奴です、クラス内で new するのではなくすでに new した物を受け取ることで実現します。

下記コードでは A の生成元である D で B を new して A のコンストラクタ引数に渡しているので、A は B には依存していません。
その代わり、D は A と B に依存することになります。(このような方法をコンストラクタインジェクションというそうです)

class B { ... }

class A {
  private B b;  

  A(B b) {
    this.b = b;
  }
}

class D {
  public void test() {
    A a = new A( new B() );
  }
}

依存性の注入を行うことで、依存先が実装されていなくてもテストすることが出来ます。
DIコンテナは依存性の注入を肩代わりしてくれる奴だそうです。※要出典

CleanArchitectureのこと

CleanArchitectureは円状になっており、円の内側にしか依存させないという特徴があります。 円の一番外側にはDBにアクセスするようなクラスがありますが、これをビジネスロジックから利用するには依存性の注入を行います。

外側にDBにアクセスするクラスがあるのはDB等の実装はビジネスロジックよりも変化が激しい為、どこにも依存しないようにするためです。

まとめ

コードは常に変更に強くあるべきなので、なるべく抽象に依存させましょう。

学生LTについて [学生エンジニア限定LT大会]

概要

はじめまして、現在 IT 系の専門学校の2年で、web系ベンチャーでアルバイトをしている者です。
今回は自分が主催しているイベントの 「学生LT」 について紹介したいと思います。

学生LT とは

今年の6月に開催したばかりの比較的新しいイベントで、関東圏の学生エンジニアさんがお互いにLTをして交流を深めることを目的としています。

開催したキッカケは、学生向けのIT勉強会があまり見当たらないと思ったことからです。

LTのテーマは自由で、プログラミングの美しさについて話す方もいれば、便利なインフラツールについて話してくれる方もいました。 中には技術とは全く関係のない話をする人もいて、とてもテンションが👆👆👆となるイベントとなりました。

LT大会の後はみんなで集まって🍣を食べながら TwitterFacebook を交換するなど、積極的に交流が出来たのではないかと思います。

目的

私達学生エンジニアは、基本的に周りに同じ志を持つ仲間が居ないことが非常に多いです。

工業科ではなく、普通科に通っている人は特にそう感じているでしょう。

学生LTの目的は、全国から技術が大好きな人を集めて、お互いに向上心を刺激しあうことです。

もし、学生エンジニアの仲間を探している学生がいたら、一度「学生LT」に参加してみませんか?

LTとは?

LTとはライトニングトークの略で、「5分きっかりで行うプレゼン」です。
5分でプレゼンは終了するため一つのプレゼンを集中して見ることができ、登壇する人のハードルもグッと下げることが出来ます。
前述した通り今回はテーマが決まっていないので、自由に話していただいてOKです。

参加条件は?

参加条件は学生 ( 小・中・高・大・院 ) であることのみで、技術力に自身が無くても熱意の有る方なら大歓迎です!
また、LTに抵抗がある方は「参加枠」の方に登録していただくと、LTをしないでイベントに参加することも可能です。

また、今回は社会人の方も参加出来る「学生じゃない枠」も用意しているので、熱意ある学生に興味のある大人の方も是非ご参加下さい!

まとめ

次回の開催は 7/29 (土) ですので、興味がある学生エンジニアの方は是非ご参加下さい!

student-lt.connpass.com

1年間プログラミングのバイトをしてみて

初めまして、自分は4年制IT専門学校に通っている学生エンジニアです。
去年高校を卒業してからプログラミングのバイトを始め、ちょうど1年が経ちましたので、1年間を振り返って記事を書いてみようと思いました。

今回はなすこと

  • 入社のキッカケ・業務内容
  • 学んだ技術
  • 苦労したこと
  • バイトで気がついたこと
  • バイトで教わったこと
  • 人生で初めてLTをした話
  • まとめ

バイト先へ入社したキッカケ・業務内容

そもそもプログラミングのバイトをやろうと思ったキッカケは、高校の頃に理科研究発表会というイベントに参加して、周りの学生のレベルの高さに挫折したことでした。
当時自分は同級生よりもプログラミングが出来たので、自分のことを神だと思っていました。
しかし、このイベントに参加して自分のレベルの低さをしり、もっと上を目指したいと思いプログラミングのバイトをやろうと考えました。
この辺の詳細は下記の記事にまとめてあります。

学生プログラマはプログラミングバイトをしよう

業務内容は、Rails と js で自社サービスの機能追加とバグ修正で、タスクの管理は Redmine で行われています。
社内のコミュニケーションツールは Slack で、ソースコードの共有は GitHub で行われていました。

学んだ技術

バイトを通して学んだ技術、ツールです。他にも有る気がします。

苦労したこと

初めてのプログラミングバイトで苦労したことです。

開発に慣れない

自分は入社当時、開発のことをほとんど知らなかったので GitHubRails の使い方に慣れるのに苦労しました。
まだ慣れない時は GitHub で master に push して怒られたりすることもありました…。

集中力が持たない

また、長時間椅子に座ってコードを書いた経験も無かったので、集中力を保たせることも大変でした。
うっかり気を抜くとすぐに手が止まっていたり、Twitterを開いていたりしていました。
今では集中するコツを掴み、Twitter/etc/hosts でブロックすることで対策することが出来ています。

質問を上手く伝えられない

自分は今やっていることを論理的に説明した上で質問するということが下手くそだった為、質問した時に「何を言っているのかわからない」と言われることもあり、時間を取らせてしまうことも多くありました。
これについては未だに上手く出来ている自信が無いのですが、最近はよりシンプルに伝えることが一番の近道ではないかと考えて、シンプルな質問をすることを心がけています。

バイトで気がついたこと

バイトを通じて気がついたことです。

エンジニアはコードを書くだけじゃない

自分はプログラミングのバイトをするまで、エンジニアはコードを無言で書き続ける人だと思っていました。
しかし実際に現場を見てみると、コードを書いてる時間と同じくらい、コミュニケーションを取っている時間がありそうだなぁという印象を受けました。
コミュニケーションの内容は仕様の確認、検討、質問、問題の共有等で、活発な情報交換が行われています。
これを見て、エンジニアは 問題解決力 と自分のやってることを 論理的に説明する力 が大事なのだなと感じました。

コードを書いて終わりではなく、有るべき姿を追求する

プログラミングは成果物が出来上がればそれでいいと思っており、テストを書いた経験もありませんでした。
しかし実際はそうではなく、その実装方法や設計が本当に正しいのかを追求する必要があるのだと思いました。
自分が書いたコードは将来誰かが手を加えるので、常により良い実装を意識し続けることが大切であると思います。

自分が今まで見ていた世界はとても狭かった

正直、自分はかなり技術があると思っていたので、バイト先の先輩達の技術力を目の当たりにして衝撃を受けました。
また、先輩たちの仕事に対する姿勢を見ていて、自分の考えていることはとても小さなことなのだと思いました。
それを踏まえ、今では広い世界を見ることを心がけ、自分が興味の無い分野にも目を向けるようにしています。

健康でないとコードは書き続けられない

プログラミングは長時間椅子に座っての作業なので、尻と腰を痛めます。
自分も最初はとても辛く集中力を削がれていましたが、オライリーの出している「ヘルシープログラマ」という本に書いてある姿勢で椅子に座ってみると、腰はかなり楽になりました。
尻については、家からクッションを持ってくることで対策することが出来ました。 (最近は椅子がいい感じのになってクッションが無くても大丈夫になりました)
ほかにも、食生活についても意識する必要があります。
自分はバイト先ではいつもカップ麺を食べていましたが、毎日カップ面だと体に悪いと先輩に指摘され、今ではおにぎりを持っていって食べています。
健康を害してしまうとコードを書くことが出来なくなってしまうので、若いうちから気を付ける必要があると思いました。

バイトで教わったこと

バイト先で先輩から教えてもらったことです。

  • 仕事の技術は実践と応用、知識0では意味がない (学ばなければバイトをしてる意味がない)
  • 5分考えて駄目だったら質問する
  • なぜこうしたのか、自分で説明出来るようにする
  • 問題をどんどん小さくしていくことで、大きな問題を解決する
  • 学びとは、過去に戻れるとしたら何が出来るか考え、次はどうするか考えること
  • 人脈が大事で、話のネタを多く持ってると自然と人脈を広げることが出来る
  • 今悩んでることは人生単位で見たら些細なことで、より良い人生を送ることを考えて物事を選択するべき

人生で初めてLTをした話

ある日、社内で勉強会をやるという話になりました。
自分は人前で話すのが恐ろしく苦手で、いつも喉は渇ききって全身は震えだしてしまいます。
ですが、そろそろ人前で話せるようにしないといけないと思い、思い切って登壇者として参加しました。
参加した枠は自己紹介LTというもので、自分について5分間話し続けるというものでした。
話した内容は、プログラミングバイトをやって感じたことです。 (この記事の内容に近いです)
たった5分といえど、自分にとってはとても長く、ましてや大勢の大人たちの前で一人で話すとなると途中で逃げ出したくてたまらなかったです。
いざ話してみると5分はあっという間でしたが、終わった後の達成感は物凄かったです。
この経験が自分にとって大きな自信となり、今では学内で勉強会を開いて登壇することも出来るようになりました。
人生初めてのLTでは、挑戦することの大切さを学ぶことが出来たと思います。

まとめ

こうして振り返ってみると、とても長い1年間だったと感じます。
今まではプログラミングバイトが初めてだったこともあり、環境になれることに精一杯でしたが、これからは今よりもっと現場の技術を吸収していきたいと思っています。
また、技術だけでなく、自分にとっての気付きや学びをより多く得られるよう積極的に行動していこうと思います。

ICTトラコン7に参加した

ICT の トラブルシューティングコンテスト に参加してきました。
先輩は前回も参加したようですが、自分は初参加でしたのでめっちゃ緊張しました。
問題の範囲はネットワークとサーバで、自分が解いた問題はサーバなのでサーバ問題について触れようと思います。
※この記事はガチ解説ではなく、ざっくりと自分が解いた問題についてと、その感想について書いてあります。

全然関係無いですが、懇親会でこんなスライドやった人です。(Twitter@ice_arr)

問題について

・A社 から G社 まであり、それぞれの会社が起こすトラブルを解決するという形
・問題サーバに問題が置いてあり、トラブルが解決出来たらそこに解答を送信する
・A社, C社, D社, F社がサーバ系 (のはず)
・各社2, 3問ずつあって、1問目を解かないと次へ行けない
・OS は ubuntu (多分) と CentOS7 があったが、なんとなく CentOS7 のほうが多かった気がする

担当した問題

・A-1:apt-get が出来ないトラブル、/etc/resolve.conf で参照しているDNSサーバが駄目っぽかったから 8.8.8.8 にした
・A-2:apt-get が出来ないトラブル、過去に実行されたaptによってDBがロックされたままだったから解除した
・A-3:webサーバに SSH 出来ないトラブル、IP制限&ルーティングミス だと思っていたが全く見当違い、正解はWoLとかいうのを使うらしい
・C-1:Docker のコンテナからインターネットにアクセス出来ないトラブル、ホストの iptables の設定が悪かったらしい (iptables の書き方がわからず死ぬ)
・C-2:辿り着けず…
・D-1:DNS で名前解決が出来ないトラブル、解決方法は全く検討がつかなかった
・D-2:辿り着けず…
・F-1:NFS でマウント出来ないトラブル、設定ファイルのIP設定でホスト部ワイルドカード(*) を使ってたのが駄目っぽかったから、実際にアクセスするクライアントのIPにした
F-2:辿り着けず…
・F-3:キャッシュサーバがあるけどキャッシュからデータを取得しないトラブル、設定ファイルが駄目だったらしい (時間が足りず死ぬ)

問題の進め方

・その問題にどれだけ時間を掛けるか、最初に決めておく
・トラブルの原因予想を Evernote に書き出す
・トラブルが解決したら Slack で適当に投げて、解答を送信する人にいい感じにまとめて送信してもらう
・1時間ぐらい詰まったら廊下に出てコーヒー飲む (タバコを吸いに行くメンバーも居た)
・進捗はホワイトボードに ○ △ ☓ で書いて共有する
f:id:yakimelon:20170306020548j:plain

感想

・順位は下から数えてかなり上位…、正直自分がそこまで出来ないとは思ってなかったのでかなり悔しい
・自分はwebが本業なので web が全く出ない今回のトラコンはかなり辛かった (MySQL の問題はあったらしい)
・サーバの勉強はもちろんしたが、DNSとネットワーク周りがカバーしきれていなかった
・Dockerも使ったことあったけどネットワークがどうなってるのかは知らなかった、ツールは使えるだけじゃなくてアーキテクチャも大事なんだなと身を持って思い知った
WoL は初めて聞いた、でも半分近くのチームが解答出来てたみたいで本当に学生なのか?と思った
・今までほとんど Linux 触ってなかったので深く学ぶ為のいい機会になった
・次回のトラコンは8月にあるらしいので、その時までには目をつぶってArchLinuxをインストール出来るぐらいになりたい
・運営の方々には感謝してもしきれないです、本当にありがとうございました!

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38) の対処

MacBook ProMySQL を起動しようとしたら、下記のエラーが出ました。

$ mysql

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

この対処法はネットで検索してすぐに出てきて、下記のコマンド打てば解決します。

$ touch /tmp/mysql.sock

しかし、自分の場合はこの後に別のエラーが出てしまいました。

$ mysql

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)

ネットで調べても原因がなかなか出てこなくて悩んでいてなんとなくプロセスを確認してみたところ、 なんとすでに MySQL が動いていました。

$ ps -ax | grep mysql

_mysql            1548   0.0  2.7  3085236 459960   ??  S     8:41PM   0:01.07 /usr/local/Cellar/mysql56/5.6.29/bin/mysqld --basedir=/usr/local/Cellar/mysql56/5.6.29 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/Cellar/mysql56/5.6.29/lib/plugin --user=mysql --log-error=/usr/local/var/mysql/user-no-MacBook-Pro.local.err --pid-file=/usr/local/var/mysql/user-no-MacBook-Pro.local.pid

すぐさま kill して再びMySQLを起動してみると、今度はちゃんと成功しました。

$ sudo kill 1548
$ sudo mysql.server start

Starting MySQL
.. SUCCESS!