SELinux を有効にしたまま CentOS 7 で OpenStreetMap のタイルサーバを構築する
Qiita で OpenStreetMap のタイルサーバを構築する記事が公開されていました。
OS が CentOS なので SELinux を無効にする記述がありましたので、とりあえず SELinux を有効にしたままタイルサーバを動かせないか試してみました。
とりあえず動くことは動いたんですが、rendoer.sock
の SELinux コンテキストを意義的に正しく設定できてないのでセキュリティホールになっている可能性が否めません。
目的を達成できているか不明確ですが、隠して置いても正しい設定が見つかるわけじゃないのでとりあえず公開してみます。
最初には SELinux を有効にして動かす差分的なもの、後半には自分が試した記録を載せています。
SELinux の設定
先の設定方法でブラウザから地図を確認できたら SELinux を再度有効にします。
$ sudo vi /etc/selinux/config SELINUX=enforcing #SELINUX=disabled
再起動すると /var/run
に作成したディレクトリが消されてしまうので設定ファイルを書きます。
$ sudo vi /etc/tmpfiles.d/renderd.conf d /var/run/renderd 0777 root root
再起動
$ sudo reboot
サーバが上がってきたら動作確認のために一時的に SELinux の状態を確認して Permissive にします。
$ getenforce Enforcing $ sudo setenforce 0 $ getenforce Permissive
フォアグランドで動かして試します。
$ sudo /usr/local/bin/renderd -f
http://%サーバーIP%/
へアクセスして地図が表示されれば OK。
動作していることがわかったら SELinux を Enforcing に戻します。
$ sudo setenforce 1 $ getenforce Enforcing
そのまま http://%サーバーIP%/
へアクセスするとタイル画像へアクセスできない Openlayers の地図もどきが表示されます。
audit.log の中で `type=AVC‘ から始まる denied された renderd のログを確認できるはずです。
$ sudo cat /var/log/audit/audit.log | grep renderd
renderd.sock へのアクセスが制限されないように SELinux への登録を行います。
まずは必要なパッケージのインストール
$ sudo yum -y install policycoreutils-python
ログから renderd に関する記述を抜き出して audit2allow
で設定ファイルを作成します。
できた設定ファイルを semodule に食わせると SELinux 側に登録されます。
$ cd ~/src $ sudo ausearch -m avc | grep renderd | audit2allow -M renderd $ sudo semodule -i renderd.pp
もう一度 renderd を動かしてタイルが表示されるか確認します。
$ sudo /usr/local/bin/renderd -f
タイルが表示されたら renderd をバックグラウンドで走らせておけばOKです。
$ sudo sh -c "/usr/local/bin/renderd -f > /var/log/renderd.log 2> /var/log/renderd.log &"
こんな感じで SELinux が有効でもタイルサーバを動かすことができました。
試した記録
ここからは自分が今回テストした環境と設定の全部です。全部見る必要はないです、長いし。
VirtualBox で新しい CentOS をセットして試しています。
Ruby から Slack の WebHooks URI を叩いてメッセージをポストする
Ruby スクリプトで Slack の WebHooks URI を叩いてスクリプトの実行結果などをポストさせたかった時に調べました。
Ruby Gems には WebHooks を叩くための gems がいくつかあります。例えば slcak-notifier などなど。
今回は本当にスクリプトから Slack に対してポストできれば良かったので
res = Net::HTTP.post_form(URI.parse('http://www.example.com/'), {'payload'=> %JSON%})
とかやっちゃえばおしまいです。
実際に実装した時はクラスとか作りましたがこんな雰囲気で。
WebHooks は URI 叩けば反応してくれるので楽でいいですね。
コマンドの終了を通知(?)してくれるコマンド
1000個ある Excel のファイルを PDF に変換するとか結構時間かかるんだけど、それが終わったら別のコマンド実行したいとかたまにあるので、コマンドレットの後ろに付けて一連の実行終了を教えてくれるような PowerShell スクリプトです。
Push-Notification
を実行すると Invoke-RestMethod で Slack の Webhook を殴ってるだけです。
Slack 側の設定でスマホなりデスクトップ通知なりをやっておけばコマンドの終了を知ることができるはず。
PS> . .\Push-Notification.ps1 PS> Get-ChildItem -Recurse | Out-File ..\list.txt -Encoding utf8 | Push-Notification
あー、終了時刻を入れさせたけど Slack のタイムスタンプ見れば一目瞭然かー。
自分の管理下にある Tasking Manager でログインできなくなった話
OpenStreetMap でそれなりに広いエリアを編集したい時は HOT の Tasking Manager を利用しています。
OSC 2017 Tokyo Spring で出展中にこの自分の管理下にある Tasking Manager を使って編集をしようと思いましたが、ログインしようとするとエラーになるので使うのを一時的にあきらめました。
原因の調査
落ち着いて作業できる状況になったところで動作のログを確認すると次のようなものが表示されていました。
SSLHandshakeError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
SSL の証明書関係でエラーが出ているようです。
そういえば先月あたりに OpenStreetMap Foundation が管理する Web サイトの証明書が Let’s Encrypt のものになったというニュースがありました。きっとこれです。
問題の修正
Tasking Manager のリポジトリでも同じエラーによる issue が上がっていて解決法も示されていました。
virtualenv の環境で pip パッケージの更新をすればよいようです。
$ ./env/bin/pip install --upgrade httplib2 $ ./env/bin/pip install --upgrade urllib3[secure]
さらに起こった悲劇(?)
これで無事にログインできるようになったのですが、ここで「Tasking Manager も更新しちゃえ」と git pull
したのが運の尽き、今度は Tasking Manager 自体が動かなくなってしまいました。
git pull
以後のログを確認すると「project
テーブルに requires_validator_role
カラムなんてねーよ」という感じのエラーが出ていました。
解決方法の模索
カラムがないならカラムを追加すればいいじゃないと思ったのですが、カラムの型がわからないので手の出し様がありません。
仕方なく docker で一時的な Tasking Manager を立ち上げてデータベースを比較します。構造の比較方法なんて知らないので手動で確認しました。
ざっくり次のような形で新しい Tasking Manager で使われている project テーブルを確認しました。
new$ sudo -u postgres psql -d newosmtm newosmtm=# \d project; <snip> id | integer | not null default nextval('project_id_seq'::regclass) status | integer | area_id | integer | created | timestamp without time zone | author_id | bigint | last_update | timestamp without time zone | license_id | integer | zoom | integer | imagery | character varying | priority | integer | done | double precision | validated | double precision | entities_to_map | character varying | changeset_comment | character varying | private | boolean | josm_preset | character varying | due_date | timestamp without time zone | requires_validator_role | boolean | not null default false requires_experienced_mapper_role | boolean | not null default false <snip>
既存の Tasking Manager には requires_validator_role
と requires_experienced_mapper_role
のカラムがありません、これを boolean で false を持った状態で追加させればなんとかなりそうです。
current$ sudo -u postgres psql -d osmtm osmtm=# ALTER TABLE project ADD requires_validator_role boolean DEFAULT false NOT NULL, ADD requires_experienced_mapper_role boolean DEFAULT false NOT NULL;
\dt;
を実行したところ新しい方の Tasking Manager ではテーブルも3つ増えていました。
プロジェクトへラベルを付与できるようになったのかそんな感じの名前のテーブルがありました。これらのテーブルスキーマを取り出してやればよさそうです。
new$ sudo -u postgres pg_dump -d osmtm -s -t project_labels > project_labels.sql new$ sudo -u postgres pg_dump -d osmtm -s -t labels > labels.sql new$ sudo -u postgres pg_dump -d osmtm -s -t labels_translation > labels_translation.sql
3つのファイルをどうにかして既存のサーバーにコピーして取り込みます。
current$ sudo -u postgres psql -d osmtm < project_labels.sql current$ sudo -u postgres psql -d osmtm < labels.sql current$ sudo -u postgres psql -d osmtm < labels_translation.sql
これでやっと動くようになりました。ながかった…。
既に誰かがやってそうな誰もお前を愛さない sl コマンドを作った
ls
コマンドのタイプミスとして sl
とタイプしてしまった時に機関車の AA が流れるのは有名なジョークコマンドだと思います。
Twitter でよく流れる 誰もお前を愛さない
を表示するものを作ってみました。
sudo でやってるのを見て書いたコマンドですが、きっと誰かが既に作ってそうな気もします。
GitHub からクローンできます。
Ruby が入ってれば OK です。
$ git clone https://github.com/KMR-zoar/sl-and_nobody_loves_you.git $ echo "alias sl='`find ${PWD} -name "sl.rb"`'" >> ~/.bashrc $ source ~/.bashrc $ sl And nobody loves you.
Amazon.co.jp で2段階認証を設定した
アメリカの Amazon では以前からできていた2段階認証ですが、最近日本でも2段階認証が設定できるようになったとえっちゃんに教えてもらったので設定してみました。
2段階認証はユーザーIDとパスワードの認証を通過した後に携帯電話の SMS やスマホの認証アプリに表示される数桁の認証コードを入力することで万が一ユーザーIDとパスワードが流出しても簡単にログインさせないようにする認証方式とかそんないい感じのシステムです。
Google や Microsoft が提供する認証アプリが使えるようです。
まずはサインイン
まず普通にサインインしてアカウントサービスを開きます。
アカウント設定からスタート
アカウント設定
の中にあるアカウント設定を変更
をクリックします。
アカウント設定を変更
の一番下に高度なセキュリティ設定
があるので右側の編集
をクリックします。
2段階認証の説明と設定が必要な理由が表示されます。
2段階認証ができるようになった時点でログイン時に設定を促す画面を出してくれた方がいいと思いますが…。
設定を開始
をクリックして設定をスタートしましょう。
コードの受け取り方の選択
認証コードの受け取り方がテキストメッセージか認証アプリを選べます。
いつも使っている認証アプリを選択しました。
画像では豪快に消していますが、 QR コードが表示されるのでこいつをスマホの認証アプリで読み取ります。
読み取りを行うと認証アプリに Amazon
が追加され、6桁の認証コードが表示されるので、下側にあるテキストボックスへコードを入力してコードを確認して続行
をクリックします。
バックアップ手段を追加
万が一スマホの認証アプリが使えなくなった場合に備えて認証コードを受け取るための予備の手段を設定します。
他のサービスも方法は違えど認証コードがなくてもサインインやログインできるようするなど、一つ目の手段がダメだったときの手段が用意されていることがほとんどです。
最初はテキストメッセージを選択して電話番号を入力したのですが、12時間以上経ってもコードが送られてこないので音声電話
を選択して音声でコードを受け取りました。
今回この音声は音質が悪く、微妙にどんな数字を言っているのかわかりませんでしたが、なんとか数値を聞き取って入力することができました。
最後の確認
最終的に2段階認証を有効にする前に2つの注意事項(?)が表示されます。
- 認証コードを入力する画面が出ない端末ではパスワードの後ろに認証コードを追加してサインインする
- よく使う端末ではコードの入力を不要にする
といったところです。
必要であればこの端末ではコードの入力は不要です。
にチェックを入れます。
自分はよく使う端末でも毎回コード入力をするようにしています。面倒なんですけどね。
同意して2段階認証を設定にする
をクリックすれば設定が完了します。
おしまい
一度サインアウトしてもう一回サインインしようとすると認証コードの確認が必要になっているはずです。
いくつかのサービスで多要素認証、2段階認証を利用していれば簡単だと思える操作です。
というか2段階認証を使えることになったとアナウンスしてくれてもいいと思うんですが、自分の見落としでしょうか…。
以前より安心してサービスを使えるようになりますね。
おまけ
ちょっと書きましたがバックアップ手段を追加
の段階でテキストメッセージを受け取れずに設定を停止していました。
翌日別の端末でバックアップ手段を追加
の段階から再開することができていますが、なんで送られてこなかったのかはわかりません。
ちゃんと最後の同意して2段階認証を設定する
をクリックするまでは2段階認証が有効にならないので設定を途中で抜けても中途半端な状態で2段階認証が始まるということはなさそうです。