CloudflareのIPアドレスを自動的にiptablesに設定する方法

Cloudflare とは、無料で簡単に使えるCDN(コンテンツ・デリバリー・ネットワーク)サービスです。
Cloudflareを導入すると、ウェブサーバへのアクセスが、すべてCloudflare経由になります。そのため、ウェブサーバのiptablesの設定で、ウェブサーバへのHTTPとHTTPSのアクセスをCloudflareのIPアドレスに制限することができます。

そこで、CloudflareのIPアドレスを自動的に取得して、iptablesに設定するようにしてみました。

まず、CloudflareのIPアドレスは、 Cloudflareの「IP Ranges」のページ に載っています。そのページにある通り、IPv4のアドレスのリストだけのページが https://www.cloudflare.com/ips-v4 に用意されています。

次に、IPアドレスのリストを取得して、iptablesを設定する方法が、Cloudflareのブログ記事「How do I whitelist Cloudflare’s IP addresses in iptables?」に載っています。

しかし、今回は、そのブログにある方法ではなく、以下のようなスクリプトを作成して、設定しました。

可用性を考えて、IPアドレスのリストの取得に失敗した場合は、すべてのIPアドレスからのHTTPとHTTPSのアクセスを許可しています。
スクリプトの設定方法は、以前の記事「Debianでのiptables設定」の通りに行いました。

Debianでのiptables設定

Debian(stretch)でのiptables設定について、調べたことをまとめてみます。

以前は、以下のようなスクリプトを /etc/network/if-pre-up.d/ に置いて、iptables設定を行っておりました。
(外部からは、IPアドレスが「192.168.1.2」の管理用PCからと、httpとhttpsの通信のみを許可する例です。)

しかし、インターフェースが複数ある場合に、同じ設定が2重に設定されるという状況になってしまいました。
Debian 管理者ハンドブックの「14.2.4. 起動時にルールを適用する」 を見てみたところ、 /etc/network/interfaces に設定する方法が推奨されていたので、その方法で設定することにしました。

まず、上のスクリプトを /usr/local/etc/iptables.sh に置きます。このとき、置くディレクトリは任意の場所、ファイル名は任意のもので構いません。

次に、以下のように、 /etc/network/interfaces の中の最後のインターフェースのところに「up /usr/local/etc/iptables.sh」と書きます。

以上で設定は終わりです。
この設定に変えてからは、同じ設定が2重に設定されることはなくなりました。

NetworkManagerなどを利用している場合は、設定方法が変わりますので、NetworkManagerのマニュアルなどを調べる必要がありそうです。

OWASP Flagshipプロジェクトまとめ

先日、OWASPのイベント「OWT2017JP」に参加してきました。

ご存知でない方のためにOWASPとは何かについての説明を、OWASP Japanチャプターのホームページより引用します。

OWASP – Open Web Application Security Project とは、Webをはじめとするソフトウェアのセキュリティ環境の現状、またセキュアなソフトウェア開発を促進する技術・プロセスに関する情報共有と普及啓発を目的としたプロフェッショナルの集まる、オープンソース・ソフトウェアコミュニティです。

その日のトレーニング(講演)で、OWASPのさまざまなプロジェクトについての説明がありました。そのおかげで、いままで知らなかった、多くの役に立つプロジェクトがあることを知りました。OWASP Projectのページ を見るとわかるように、OWASPにはとても多くのプロジェクトがあります。そこで、トレーニングで学んだ内容をふまえて、OWASPの主なプロジェクトである、Flagshipプロジェクトについて表にまとめてみました。

Tools

プロジェクト 日本語訳 簡単な説明
OWASP Zed Attack Proxy Project OWASP ZAP マニュアル Ver.2.1.0版 無料のペネトレーションテストツール。Webアプリケーションに対して自動診断を行う。腕を磨けば手動での診断にも利用できる。
OWASP Web Testing Environment Project OWASP WTE。OWASPのアプリケーションセキュリティツールとドキュメントの詰め合わせ。VM、Debianパッケージ、ブータブルISOイメージなどの配布形式がある。
OWASP OWTF OWASP Testing GuideやPTES(Penetration Testing Execution Standard)などのセキュリティ基準に沿った効率的なペネトレーション検査ができるツールを開発するプロジェクト。
OWASP Dependency Check Webアプリケーションの中から脆弱性のあるコンポーネントを発見するスキャナー。Java, .NET に対応。Ruby, Node.js, Python, C/C++ は試験的な対応。
OWASP Security Shepherd Webとモバイルのアプリケーションセキュリティのためのトレーニングツール。セキュリティを学ぶためのハンズオン環境。CTFモード、オープンフロアモード、トーナメントモードなどを備える。

Code

プロジェクト 日本語訳 簡単な説明
OWASP ModSecurity Core Rule Set Project ModSecurityで使える一般的な攻撃検知のためのルールセット。(ModSecurityはApacheのモジュールとして動作するオープンソースのWAF。)
OWASP CSRFGuard Project クロスサイト・リクエストフォージェリ(CSRF)対策ライブラリ。
OWASP AppSensor Project アプリケーションレイヤーに対する侵入検知と自動応答のためのフレームワーク。アプリケーションに防御層を実装する。「OWASP AppSensor Guide」(ガイド)と「OWASP AppSensor Reference Implementation」(コード)を含む。

Documentation

プロジェクト 日本語訳 簡単な説明
OWASP Application Security Verification Standard Project OWASPアプリケーションセキュリティ検証標準 ASVS。アプリケーションのセキュリティ要件またはセキュリティテストの項目。セキュアなアプリケーションとは何かを定義するこができる。アプリケーションのセキュリティ評価のための検査標準。自動または手動のセキュリティテスト及びコードレビュー方式の要件。
OWASP SAMM Project ソフトウエアセキュリティ保証成熟度モデル Software Assurance Maturity Model (SAMM)。ソフトウェアセキュリティ保証成熟度モデル。リスクに合わせたソフトウェアセキュリティ戦略を実装するためのフレームワーク。開発ライフサイクルをよりセキュアにする。より成熟したセキュア開発を行うことを支援するドキュメント。
OWASP AppSensor Project アプリケーションレイヤーに対する侵入検知と自動応答のためのフレームワーク。アプリケーションに防御層を実装する。「OWASP AppSensor Guide」(ガイド)と「OWASP AppSensor Reference Implementation」(コード)を含む。
OWASP Top Ten Project OWASP Top 10 – 2013 日本語版 Webアプリケーション脆弱性トップ10。主要な脆弱性10個を説明するもの。
OWASP Testing Project OWASP テスティングガイド Webサイト/アプリケーションのテストガイド「OWASP Testing Guide」。各脆弱性、機能別のテスト方法。

なお、「OWT2017JP」のスライド資料は https://speakerdeck.com/owaspjapan にて公開されております。

Sphinxでグリッドテーブルに全角記号を使った場合のエラー

ドキュメントの作成に、ドキュメントが簡単に作れるツール Sphinx を気に入って使っています。

先日、グリッドテーブル(Grid Table)に全角記号を入れるとエラーになるということに気がつきました。
具体的には、以下のようなものがエラーになってしまいます。

しかし、次のようにするとエラーなく処理されます。

横幅がそろっていないとエラーになるはずが、そろっているとエラーになり、ずらすとエラーがなくなるいう状態です。

困って調べたところ、Pythonのdocutilsパッケージが原因であることがわかりました。

グリッドテーブルが正しい形式になっているかを確認するときに、docutils内で、グリッドテーブルの各行の長さを計算しています。そのとき、ひらがなや漢字などの全角の文字は、半角2文字分の幅を取っているので、見た目と合わせるために、長さを2として計算されます。しかし、「→」などの全角記号が長さを1として計算されているため、見た目とずれてしまっています。

これを修正するために、以下のようにしました。環境はDebian9(stretch)です。

システム側のdocutilsを変更しないで済ませるために、ユーザのホーム以下のディレクトリにコピーをします。ここでは「.pythonlib」というディレクトリ名にしましたが、これは任意の名前で構いません。

このディレクトリを、モジュールファイルのデフォルトの検索パスに追加するために、環境変数を設定します。bashならば、以下の行を環境設定ファイル(「.profile」など)に記述します。

環境設定ファイルを読み込めば有効になります。

コピーしたdocutilsディレクトリ配下の「statemachine.py」の

のように変更します(「A」を追加)。

また、今回の修正には直接関係ありませんが、整合性をとるため、コピーしたdocutilsディレクトリ配下の「utils/__init__.py」の

のように変更(「1」を「2」に変更)しておくといいと思われます。

以上で、全角記号を含んだグリッドテーブルで、見た目がそろっていればエラーが出ずに処理できるようになりました。

レコード毎のINSERT文になるようにmysqldumpでダンプする方法

先日、WordPressで作成したサイトのサーバ移設作業をしていたのですが、mysqldumpで作成したダンプファイルを移設先サーバのMySQLにロードしようとしたところ、「Got a packet bigger than ‘max_allowed_packet’ bytes」というエラーが出ました。

解決策を調べたところ、MySQLサーバの「max_allowed_packet」という値を変更する方法が見つかったのですが、今回その方法は使えませんでした。mysqldumpで生成したダンプファイルのエラーになった箇所を調べたところ、大きいテーブルのすべてのレコードをひとつの「INSERT INTO」文によって挿入するようになっていたため、この文のサイズが「max_allowed_packet」を超えているのがエラーの原因であることがわかりました。

そこで、mysqldumpでダンプファイルを生成するときに、レコード毎のINSERT文にする方法を調べました。具体的には、

のように生成されるのを、

のように生成されるようにする方法です。

その方法ですが、mysqldumpを実行するときに、「--skip-extended-insert」というオプションを付けるだけです。例えば、以下のように実行します。

このように生成したダンプファイルの難点は、ロードするのに時間がかかることですが、場面により、適宜使っていこうと思います。

WordPressで日本語名のファイルをアップロードするには

お客様から「日本語名のファイルをアップロードしようとしたらファイル名が文字化けしてしまった、どうにかならないか」とお問い合わせをいただき対策を行いました。

WP Multibyte Patch プラグインが影響

「WP Multibyte Patch」プラグインを有効化しているため起こった現象でした。「WP Multibyte Patch」プラグインを有効化していると、日本語のファイル名を md5ハッシュ値に変換するためだそうです。正確には文字化けではなく変換されたハッシュ値のようです。

対策

以下の通り、設定変更を行いました。

  1. wp-content/plugins/wp-multibyte-patch/wpmp-config-sample-ja.php を wp-content にコピーします。
  2. wp-content にコピーした wpmp-config-sample-ja.php を wpmp-config.php というファイル名に変更します。
  3. wpmp-config.php から $wpmp_conf[‘patch_sanitize_file_name’] の行を探し、値を「true」から「false」に変更します。

参考

以下のリンクを参考にさせていただいました。
WordPressで日本語のファイル名をアップロードする方法

Linuxをメインの作業環境としていると「ファイル名は英数字」と固定観念があり全く気づきませんでした。調べてみたところ、立ち上げ時にアップロードしたファイルはすべて英数字になっていました。習慣ってすごいですね。

WordPressで投稿した記事を自動的にTwitterに投稿するには

WordPressで投稿した記事を自動的にTwitterに投稿する方法です。
上記の機能を実現するプラグインはたくさんありますが、画像を一緒に投稿できる NextScripts: Social Networks Auto-Poster プラグインを使用しました。

プラグインのインストールと設定

  1. NextScripts: Social Networks Auto-Poster プラグインをインストールします。
  2. インストールが完了したら、サイドメニューの「設定」→「{SNAP} Social Networks Auto Poster」をクリックします。
  3. 連動するTwitterアカウントを登録します。「Add new account」をクリックします。
  4. 「Add NEW Network」から「Twitter」を選択します。
  5. Twitterアプリケーションの情報を入力します。
    ※事前にTwitterアプリケーションを作成しておく必要があります。Twitterアプリケーションの作成方法
  6. 連動するために作成されたTwitterアプリケーションをクリックします。
  7. 「Keys and Access Tokens」タブをクリックします。「Consumer Key(API Key)」および「Consumer Secret(API Secret)」に記載された情報をWordPressの設定に入力します。更に、画面をスクロールして「Your Access Token」にある「Create my access token」ボタンをクリックします。「Access Token」と「Access Token Secret」に記載された情報をWordPressの設定に入力します。

    Twitterに画像も一緒に投稿する場合は、WordPressの設定画面で「Attach Image to Twitter Post」をチェックします。

    すべての入力が完了したら「Update Settings」ボタンをクリックします。
  8. アカウントが追加されたことを確認してください。
  9. WordPressから投稿してTwitterに自動的に投稿されれば設定完了です。

Twitterアプリケーションの作成方法

Twitterアプリケーションは https://dev.twitter.com/ から作成します。
※Twitter ホームの「開発者」をクリックすると同じところに移動します。

  1. 画面右上の「My apps」をクリックします。
  2. 画面右上の「Create New App」をクリックします。
    ※既に登録済みのアプリケーションがある場合はその一覧も一緒に表示されます。
  3. 各項目を入力します。入力が完了したら、画面左下の「Developer Agreement」をチェックして「Create your Twitter application」をクリックします。

    ※Twitterアカウントに「携帯の電話番号」が登録されていない場合はエラーになります。
    その場合は、Twitterアカウントの「設定」→「モバイル」の「携帯の電話番号」に電話番号を追加してから有効化されたのを確認して、再度、設定してみてください。
  4. アプリケーションが一覧に作成されれば作成完了です。

GitLabのサーバ移設

GitLabを別のサーバに移設しました。その際の手順を以下にまとめます。
前提条件として、移設元のGitLabと移設先のGitLabがOmnibusパッケージからインストールした同じバージョンのものであるとします。
この条件の元だと、簡単にサーバ移設ができました。

まず、移設元サーバで、以下のコマンドにより、バックアップを作成します。

バックアップが作成されるのは、gitlab.rb の以下の場所に定義されているディレクトリです。
該当の行がコメントアウトされていれば、デフォルトの場所に保存されます。

実行したところ、「1480838198_gitlab_backup.tar」というファイルが作成されました。

次に、移設先サーバにバックアップファイル(「1480838198_gitlab_backup.tar」)を移設元サーバからコピーして、移設先サーバの gitlab.rb の「backup_path」で定義されている場所に置きます。

以降は移設先サーバでの作業になります。

まず、コピーしたバックアップファイルに対して、すべてに「read」のパーミッションを付けておきます。

次のコマンドで、データベースに接続しているプロセスを止めます。

プロセスが止まっているか確認します。

バックアップファイルからリストアします。「BACKUP=」の引数はバックアップファイルのタイムスタンプで、今回のバックアップファイルの場合は「1480838198」になります。

GitLabをリスタートして、チェックを実行して、動作を確認したら、終了です。

expectコマンドを使用してscpの実行をCronで実装するには

パスワード認証のsshサーバからscpでファイルをコピーする作業は、手動の場合は非常に単純なものです。しかしこれをCronで実装するには、対話型でパスワードの入力を求められるため、作成するシェルスクリプトに少し工夫が必要です。

このような場合、expectコマンド(対話型アプリケーションの自動化)を使用して、シェルスクリプト中で「パスワードの入力を行う」処理を行います。
expectコマンド
まず前提として、転送元ファイルが置いてあるサーバ名をcrestとします。アカウント名をcrest-user、転送元ファイルが置いてあるディレクトリを/home/crestとし、コピーするファイル名をexm.txtとします。また、転送先のPC名をbozとします。転送先のディレクトリを/home/bozとします。boz上でファイルをコピーしてくるシェルスクリプトをCronで動作させます。

シェルスクリプトは以下のようになります。

このシェルスクリプトは、コマンドラインでは問題なく実行できます。そのため、このままCronで動作させようとしたのですが、うまく動作しませんでした。ログインとCronでは動作環境が異なるため起こる現象のようです。そのような場合は、20行目の「interact」を「expect eof exit」に変更します。

シェルスクリプトにはパスワードを記述するため、アクセス制限されたネットワークでの使用に限るなど、セキュリティ上、十分に注意する必要があります。

MySQLのTEXT型データで大文字と小文字を区別できるようにするには

既に使用を開始しているシステムで、TEXT型で定義しているデータの大文字と小文字を区別しなければならなくなりました。その時に調べた内容のまとめです。

まず、非バイナリ文字列とバイナリ文字列の性質の比較です。

文字列の種類 文字列検索 大文字/小文字の区別
非バイナリ文字列 CHAR、VARCHAR、TEXT 比較オペランドの照合順序
を使用
なし
バイナリ文字列 BINARY、VARBINARY、BLOB オペランドのバイトの数値
を使用
あり

参照:B.5.5.1 文字列検索での大文字/小文字の区別

バイナリ文字列に区分されている型を使用していれば問題なかったのですが、既に使用を開始していたため、TEXT型のまま大文字と小文字を区別できるようにしました。

まず前提として、「exmtable01」という名前のテーブルがあるとします。

exmtable01のテーブル定義情報は以下のようになっています。

valueフィールドの型を「TEXT BINARY」に変更します。

そうすると、exmtable01のテーブル定義は以下のように変更されます。

以上の変更により、TEXT型でも大文字と小文字を区別することができるようになりました。

また、テーブルを作成する時に「TEXT BINARY」を指定すると同様の定義となります。

phpMyAdminを使用している場合は、変更したいフィールドを選択し属性を「binary」に指定すれば、同様の変更を行うことができます。