Twitter Facebook github

Category “AWS”

AWS認定SysOpsアドミニストレーターになりました

先週はソリューションアーキテクトになったのですが、目標としてた試験をクリアしてしまうと更に高みを狙いたくなってしまうもの。他のAWS認定資格も集めたくなって、挑戦してみました。

Read More »

AWS認定ソリューションアーキテクトになりました

アソシエイトレベルの方でプロフェッショナルではないです!

じゃんっ

2年くらい前にこの存在は知っていて、ずっと憧れてた資格の一つでした!早速レポします!

Read More »

SixのエラーでAWS CLIをMacにインストールできない

めっちゃハマったのでメモ。環境は Mac El Capitan (10.11.3) 。

周りの人はすんなりインストールできてたりするので、どうしてこうなったのか原因が分からないのだが、うまく抜け出せたので書き留めておきたい。

AWS CLIをMacにインストールしようとした

Macなら初めからpythonが入ってるから2コマンドでいける……らしい。

普通ならこれだけでインストールできる。

1行目でpythonパッケージマネージャーのpipを入れて、2行目でawscliをインストール。

これがエラーなく完了すればいいけど、手元の環境ではなぜか2行目でコケてしまった。

Operation not permitted

こうなった。

よく見るとDeprecatedなSixっていうパッケージをアンインストールしようとしてエラーになってるぽくて、
手動で sudo pip uninstall six ってやっても同じエラーが出てしまう。

解決策

うまくいった!

ちなみにSixっていうのはpython2系と3系の差異を埋めてくれるユーティリティライブラリみたいなものらしい。やっぱり自分で入れた覚えはなくてちょっと謎。

ELBに証明書を登録できない時はAWS CLIを試す

AWS ELBに証明書を登録しようとしたときにエラーになったので、その回避策をメモ。

AWS ELBではHTTPSで行われた通信をELBデコードして、バックエンドのサーバーとはHTTPで通信することができます。
こうしておくと証明書更新などで複数台のEC2を直接手を入れることなく、またウェブサーバー側のSSL通信に関わるオーバーヘッドも無くなるため、AWS内で構築する場合には採用することが多いかと思います。

この構成を取る場合、証明書、証明書の秘密鍵をELBにアップロードする必要があります。

Read More »

RDS上のMySQLでKILLは使えない

軽い内容だけど備忘録として。

要はRDSのMySQLでは、プロセスを殺すためのKILLが使えないよーっておはなし。

KILLできない

例えばSleepプロセスを、root以外の管理ユーザーから殺したいと思ってKILLコマンドを許可する SUPER 権限をそのユーザーに与えたかったのだけど、それができない。

今の設定がどうなってるか確認してみると、そもそもroot(※インスタンス起動時に登録したマスターユーザー)にSUPER権限が与えられていない。

試しに他のユーザーのプロセスをKILLしてみる

 
やっぱりダメぽい…。

どうするか

AWS公式のドキュメントでこんなのを見つけた。

mysql.rds_kill – Amazon Relational Database Service

どうやらKILLが使えない代替策で mysql.rds_kill を使えってことらしい。

うまくいった。
これを一般ユーザーで使えるようにするためには、一般的なストアドプロシージャの許可と同じようにする。

補足

上表のユーザーリストで rdsadmin となっているのはAWSがRDSインスタンスの監視に使うユーザーであり、私たちはログインできない。
推測になるが、これらRDS管理系のシステム仕様上SUPER権限はユーザーに与えられていないのだろう。そういった類の特権処理について、AWS側の制約により実行できないものは別途ストアドプロシージャが提供されていて、これを介して使うことができるようだ。

それらのストアドプロシージャーはこのRDSのリファレンスページに纏められている。

所感

シェルからKILLを流し込むスクリプトなど、他の環境で使っていたものを流用するときは十分注意したいです。こういった制約とその代替策がいかにもAWSらしいような、そんな気がします。

CloudWatchのアラームをSlackに通知する

以前から挑戦したかったAWSの課題のひとつを解決してみようと思います。

AWS EC2やRDSなどのステータスを監視してアラームを上げてくれる、大変便利なCloudWatchですが、管理コンソール以外からアラームを確認する方法としては、SNSトピックに通知した後に自分でSNS連携のアプリケーションを作るなどして対応する必要がありました。

今回はこのアラームを、Slackの任意のチャンネルにポストすることをゴールにしてみます。

Read More »

git-secretsでAWSの不正利用を防ぐ

最近、アプリケーションなどから利用するAWSの認証情報(credentials)をgithubなどの公開リポジトリに誤ってコミットしてしまい、不正利用され高額な使用料を請求されるケースが増えています。
いくらルートアカウントを無効化してIAMユーザーを使おうが、2段階認証を導入しようが、認証情報をヒューマンミスで公開してしまっては意味がありません。

万が一、認証情報を公開してしまった場合は、一刻も早くAWSの管理コンソールから公開してしまった認証情報のアクセス権限を取り消しましょう。もしそれが会社で使っている認証情報だとしたら本当に1分1秒を争いますので、深夜だろうが構わずにAWSを管理しているエンジニアを電話で叩き起こして助けを求めてください。放置すると高確率で首が飛びます。

こういった大事故を防ぐためにAWSが公開している git-secrets というgitのプラグインがあります。

https://github.com/awslabs/git-secrets

インストールする

つい先月末までは、インストールするためにソースをローカルにクローンしてきた後で make install する必要がありました。しかし、先月の26日にformulaがHomebrewのmasterにマージされ、brew経由でより簡単にインストールできるようになりました。

昔からhomebrewを使っていた人は、formulaの一覧を更新しないとインストールできないため、まずupdateしてからinstallします。

git secrets コマンドが使えるようになっているはずです。

リポジトリへ設定

git-secretsはまだ有効になっていません。

リポジトリ単位で有効化する必要があるので、ここでは適当に新しいリポジトリを作ることにします。

リポジトリの中にcdしたら –install で有効化。

見ての通り、pre-commitをフックして実現しています。

拒否ルールの設定

次にどのルールにマッチしたとき、コミットを拒否するか指定します。AWSの認証情報については、 --register-aws パラメータを使えます。

設定された拒否ルールは、 --list パラメータで確認できます。

上の出力3行目では、大文字英数20文字にマッチして拒否しているようですね。乱暴じゃないかと思いましたが、実際プログラミングをしていて大文字固定で20文字も打ちませんからね。

6,7行目はAWSの公式ドキュメントなどでも使われている、サンプルのアクセスキー/シークレットキー(Allowed patterns for example AWS keys)だそうです。

実際に使ってみる

ちゃんと弾いてくれるか確認してみます。

適当にそれっぽいのを書いて、これでコミット。

弾いてくれました!

まとめ

実際の運用では、認証情報やパスワードなど本当に外部に漏れてマズいものは、環境変数にセットするのが個人的にはオススメです。そもそもファイルに書かない運用であれば、ファイルの取扱い不備でリークする可能性がゼロになり、セキュリティリスクを減らせます。

とはいえ、実情そんなこと言ってられないケースも多いですので、ファイル+.gitignoreで気をつけて運用するのが一般的でしょうか…。万が一のためにAWS内外問わず、トークンごとに権限設定ができるものは必要最小限の付与に留めるようにしましょう。AWSの場合、ルートキーでないと使えないAPIがあったりもするみたいですが……。

今回のgit secretsは他にも、既にインデックスされているファイルの中にキーが混ざっていないかどうかをスキャンしたりすることもできます。詳しく知りたい方は公式のドキュメントをどうぞ。

所感

AWSなんかは凄い勢いで請求額が増えていくサービスが山ほどあります。ルートキーなんかが漏洩したと思うとゾッとしますね……。従量課金制のクラウドサービスを使う際には、そのセキュリティにはより一層の注意を払って取り扱いたいですね。

EC2起動後に行うべき設定

標準のAmazon Linux AMIを前提に進めていきます。

AWS EC2はデフォルトでrootログイン禁止、オプトイン方式のインバウンドセキュリティポリシー、公開鍵認証のキーペア生成など、適当に使っていてもある程度セキュアになりますが、少しの手間でより堅牢なサーバーにできます。是非取り組んで欲しいです。

 

とりあえずアップデート

AmazonLinuxの場合大抵最新のパッケージが入っていますが、念のために更新しておきます。

以下の指定にすることでセキュリティパッケージの更新のみを適用できるため、すべてのパッケージを更新したくない場合、最低限こちらだけでも実行しましょう。

 

 

タイムゾーンの変更

EC2は起動したリージョンにかかわらずUTCの設定になっています。最近は世界を目指すプロダクトではアプリケーションやDBクロックを日本時間に変えずUTCのまま使用し、表示時にアプリケーションが変換するなど、UTCスタンダードなモデルもよく聞きますね。とはいえ日本に住む以上日本時間で統一したくなるのも事実。

設定が終わったら再起動して全てのプロセスに反映させます。

再起動後はdateコマンドで日本時間になっているのを確認します。

 

rootパスワードの設定

適切にインスタンスを起動した場合、接続に必要な鍵が適切に管理されていれば通常安心ですが、万が一の漏洩に備えてrootにパスワードを設定しておきましょう。

 

管理用ユーザーの変更

デフォルトではec2-userというユーザーが管理用に作られていますが、セキュリティを高めるために別の名前のユーザーを使うことをお勧めします。その際、AmazonLinuxでは他Linuxによくあるwheelグループなどの管理グループ全体にsudoを付与しているわけではなくユーザー単位に設定されているため、新規で追加したユーザーにも個別にsudo権限を付与するようにしましょう。

まずは新しいユーザーを追加して、管理(sudo)権限を付与します。

cloud-initファイルを次のように変更します。

ec2-userのsudo権限は /etc/sudoers.d/cloud-init に書かれており、/etc/sudoersからロードされています。引数なしのvisudoでは編集できません。また、sudoersファイルを直接viなどで編集するのは危険なのでやめましょう。ここではec2-userの権限を剥奪し、またsudo実行時にパスワードを求めるように(NOPASSWD非設定)しました。

すべて完了したら、一度ログアウトして外部からnewuserでログインしてみましょう。鍵もコピーされていますので、ssh接続時はユーザー名だけを変更すればOKです。正しく接続できて、sudoがパスワード入力後に実行できれば完了です。

最後にec2-userを削除して終わりです。ec2-userでログインできないことを確認しましょう。

 

ポート番号の変更

定番のセキュリティ対策ですね。SSHのポート番号をデフォルトの22番から別のものに変更します。簡単で単純ですが、効果は高いです。

ここでは仮に22922に変更します。また、待ち受けポートは1つという縛りはないため、下記例のように変更前のポート22でも待ち受けるようにしたまま進めると万が一の特に困らないでしょう。

終わったらreloadして設定を反映させます。また、iptablesが稼働中であれば不正なルーティングによって弾かれる可能性があるので停止されているのを確認してください。

SSHのポートを変更しますので、AWSのEC2に紐付いているセキュリティポリシーも変更する必要があります。新しく設定したポート番号のTCPを、自分のIPアドレスから通すように設定を変更しましょう。

これで新しいポートを用いて接続できるようになりました。一度ログアウトして、新しいポートへのSSH接続が成功すれば完了です。sshd_configを開いて Port 22 の記述を削除したあとでreloadしましょう。AWSのセキュリティポリシーからもTCP:22のルールを削除して完了です。

万が一新しいポートで接続できない場合は、落ち着いて22ポートで接続して、設定を再確認してください。ポートが正しく待ち受けられているかチェックするにはnetstatコマンドが有効です。

 

SSHをもっとセキュアに

  • iptablesでアクセスできる回数を制限
  • 認証試行回数の設定
  • アクセス試行ログの通知

もろもろ考えましたが次の観点からこれらを講じる意味はないと思っているので割愛します。

  • 鍵認証が強制になっていること(デフォルト)
  • rootログインができないこと(デフォルト)
  • ユーザー名を変更したこと
  • SSHポートを変更したこと
  • EC2のセキュリティポリシーにより、SSHポートは信頼されたIPにしか公開されていないこと

これだけの対策を講じていれば、上述の更なる対策はあまり意味がありません。

鍵の管理だったり、権限を持つ内部からの不正アクセスリスクの方が高いはずなので、その辺の対策(運用体制などの整備)に時間を割く方が良いでしょう。

 

そのほか

nginxやその他サーバー類の個別なセキュリティ対策についてはまた別に書こうと思います。

特にエンタープライズでのウェブサイト改竄や情報流出などの危機管理が取り沙汰されている昨今、エンジニアである以上最前線で食い止めていきたいですね。

 

  • 2015-11-18 公開
  • 2015-11-25 加筆

 

EC2にサクっとnginxとphpの環境を整える

そういうメンテ済みのAMIを拾ってくるっていう話はなしで、普通にキレイなAmazonLinuxAMIをベースに入れていきます。

既にインスタンスは起動していて、sshで接続しているのを前提にします。また、インスタンスに紐付いているセキュリティポリシーで外部からHTTP(TCP 80)へ通信が通るようにしてください。

nginxとPHPをインストール

PHPモジュールはphp56とphp56-fpmが必須です。他は任意で選択してください。

 

nginxの設定

nginxはデフォルトでphpファイルをハンドリングしないため、インデックスパスへの追加とphpファイルへアクセスした際にphp-fpmへソケットで受け流す設定にします。

php-fpmの設定

こちらは主にapacheで使用する設定からnginxで使用する設定に変更し、ソケット通信を用いるようにします。

起動

設定ファイルの変更が終わったらいよいよ起動です。

OSを再起動したときに自動起動する設定にしておきます。

動作確認

それぞれのURLでアクセスでき、正しくechoの中身だけが出力されていればOKです。

もし繋がらないときは、設定ファイルを見直して、nginxとphp-fpmが正しく起動されているか確認してください。見落としやすいミスとして、AWS上で起動したインスタンスに紐付いているセキュリティポリシーでHTTPのアクセスを弾いていることがあります。またインスタンス上でiptablesが実行されている場合は次のコマンドで停止させてください。

さいごに

これらの設定は最速で動かすことを目指して書いています。実際にはこれらをインストールする前にLinuxのセキュリティ設定を行うべきですし、nginxのセキュリティ設定やチューニング、アプリケーション側のnginx対応などを行う必要があります。

それらについてはまた別に書きますが、上の設定のまま実際にウェブサイトを公開することは危険です。必ずセキュアな状態にした上で公開してください。