カテゴリーアーカイブ インフラ

takahashi 著者:takahashi

Softbankの携帯回線大規模通信障害 原因は交換機のソフトウェアアップデート

昨日12/6、13時ごろから、Softbank系列のモバイル回線で、全国的にパケット回線や音声回線に接続できなくなる大規模障害が発生しました。
18時ごろから復旧が始まったとのことだったので、実に4~5時間ほど通信不能になっていたようで、期間的にもかなり長引いた印象でした。

ニュースを見ると、携帯が使えなくなったことで、一時的に公衆電話も復権したようですね。

嘘でしょ!?「公衆電話を初めて使った」という声にネットざわつく – NAVERまとめ

公衆電話の使い方がわからない…なんて話も。
自体の流れを感じます(;´∀`)

さて、今回の通信障害の原因ですが、後にSoftbankが公式に発表をしています。

2018年12月6日に発生した携帯電話サービスの通信障害に関するおわび – Softbank

ソフトバンク、通信障害の原因を公表 エリクソン製交換機ソフトの「期限切れ」- ITMedia

また、エリクソン社自身も同様の発表を行い、謝罪をしています。
Update on software issue impacting certain customers – Ericsson

Softbankは携帯基地局同士をつなぐ”コアネットワーク”に存在し、各携帯端末の通信状態や認証を管理する機器MMEにエリクソン社製の製品を使用しています。

【MME】- NTTPCCommunications用語解説辞典

複数の記事を読んでいくと、どうやらこの機器を動作させるためのソフトウェアにアップデートが行われ、そのアップデートに含まれている”証明書”が古いものであったために有効期限切れとなり、機器の動作障害を引き起こしたようです。
その証拠としてSoftbank以外の海外のキャリアで、エリクソン社製のMMEを利用している業者についてもほぼ同時刻に同様の不具合が発生していたようです。

また、エリクソン社のMMEの機能として、大量の端末を同時に管理できるようにするために、その処理の一部をクラウドサーバーに代わりに行わせることができる機能”vMME”もあるようです。

ソフトバンク、エリクソンのVirtual MMEとクラウドプラットフォームを導入 – Ericsson

今回の”証明書”がなんの証明書を指すのがは詳細に発表されていないのでわかりませんが、恐らく機器のソフトウェアの正当性(本物かどうか)を検証するためのソフトウェア署名の証明書か、vMMEと通信する際に通信先のクラウドサーバーが正しいサーバーかどうかを検証するための証明書あたりではないかなと思います。

いずれの場合であっても有効期限切れになってしまうことでシステムが正常に動かなくなってしまう問題なので、かなりヤバい状況だったのではないかなと思います。
結果的に、ソフトウェアを以前のバージョンにダウングレードしたことで、とりあえず復旧したようです。

今回の根本的な原因はエリクソン社のミスで、たまたまその機器を使用していてとばっちりを受けてしまったSoftbankにとっては大変な災難だったと言えそうです。

  • この記事いいね! (0)
takahashi 著者:takahashi

CentOS 7 にPHP7.1をインストールする方法

最近、徐々にPHP 7系を要求するアプリケーションやフレームワークが多くなってきました。
一方で、CentOS 7はデフォルトでは古めのパッケージのみを提供しているので

sudo yum -y install php 

としてもphp5.6系しかインストールできません。

しかし、CentOSで利用できる外部のリポジトリ”epel”と”remi”を用いることでphp7系をCentOS 7へインストールすることが可能になっています。
今回は、その方法をご紹介したいと思います。

まず、現時点で古いバージョンのPHPが入っている場合は、一度アンインストールが必要になります。
もし古いバージョンのPHPも必要な場合は複数のバージョンのPHPを共存させる必要となり、今回の手順ではセットアップできませんのでご注意ください。

PHPが既にインストールされているか確認します。

php -v

として

PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

のようになっていれば、既に古いバージョンがインストールされているので、一旦アンインストールします。

sudo yum -y  remove  php-cli php-common

epelリポジトリをインストールします。

sudo yum -y install epel-release

remiリポジトリをインストールします。

sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

ここまで行えば、php7.1のインストールが可能になっています。
次のコマンドでphp7.1をインストールしてみます。

sudo yum install --enablerepo=remi,remi-php71 php php-devel 

インストール完了後、再度php -vをして

php -v
PHP 7.1.24 (cli) (built: Nov  7 2018 18:45:17) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

となっていれば成功です。

なお、remiリポジトリからphpに入れた際、PHPモジュールの参照先が別の場所になってしまうことがあるようです。
その場合は、php.iniに次の記述を追加してください。

extension_dir = "/opt/remi/php71/root/usr/lib64/php/modules" 

※PHPバージョンによって異なります。”sudo rpm -ql インストールしたphpのパッケージ名”を実行してインストール先を確認してください。

  • この記事いいね! (0)
takahashi 著者:takahashi

WindowsのSSHクライアント”Rlogin”で多段SSH接続したときに定期的に接続が切れてしまうときの対処法

最近、複雑なネットワーク構成のサーバー(とくにAWS系のシステム)でしばしばSSHの多段接続が必要になることがあります。
多段接続とは、VNCやTeamviewerなどのリモートデスクトップに例えると、手元のPCからリモートマシンへ接続した後、さらにそのリモートPC内にあるリモートデスクトップソフトを立ち上げて、さらに別のマシンへ接続するような繋げ方をすることをいいます。

なんでこんなめんどくさいことをするかというと、最終的に接続するサーバーがインタ―ネットと直接使がっていない場合があり、そういった時はインタ―ネットと直接つながっている端末経由で接続する必要があるためです。

本当は直で繋げたいところですが、セキュリティ上の理由であったりグローバルIPの制約で公開できるサーバーの数が限られていたりなど様々な理由で敢えてこのような設計にせざるを得ない場合があります。
この場合、単純にシェルをたたくだけなら問題ないのですが、例えばFTPなどを使ってファイルをやり取りしたり、その他のアプリケーションやプロトコルで目的のサーバーと通信したいときなどはちょっと困ることがあります。

こういう時のために、Windows用のSSHクライアント”Rlogin”ではSSHプロキシ接続機能が用意されていて、あらかじめ設定しておけば、踏み台となるサーバーのSSHサーバーを経由して内部のサーバーに直接接続ができる経路を作ってくれる”トンネリング”を行うことができます。

今回は、Rloginで行えるSOCKS5プロトコル経由でプロキシした際に発生した”定期的にSSHが切断される”問題の解決方法をご紹介します。

実はSSHサーバーには、デフォルトで一定時間通信しない(idle状態にしておく)と接続を切ってしまう仕様になっているものがあります。
そのせいか、自分の手元の環境では、踏み台サーバーへのトンネルが一定時間後に切られてしまうことが結構ありました。

サーバーではバックグラウンドで長時間処理させることもしばしばあるので、肝心な時にコネクションが切れてしまうとなかなか大変です。

いろいろ設定を変えてはみたのですが、なかなか改善せず、ずっと悩んでいましたが…
今回ようやく解決方法を見つけました!

Rloginのサーバー設定の左ペインにあるサーバー->プロトコル をクリック。

下記のような画面が出てくるかと思いますので、

赤枠部分にチェックを入れ、KeepAliveの間隔を数十秒ほどにしておきます。
実際に適した設定値は各SSHサーバーの無通信でいつまで接続を維持するかの設定によって異なってきます。切断される前にKeepAiveの信号が送られるように秒数を変更してください。

ここを変更しただけで、いままで1分ほどで切られていたコネクションが、10分以上放置しておいても維持されるようになりました。

お困りの方は是非試してみてください。

  • この記事いいね! (0)
takahashi 著者:takahashi

IBMがRedHatを買収 気になるRedHat系OSへの影響

昨日、衝撃のニュースが発表されました。

IBMがRedHat買収合意を発表。買収額約3.8兆円、クラウド分野でアマゾン・マイクロソフト追撃 – Engadget 日本版

なんとオープンソース界隈で非常に大きな影響力をもつRedHat社がIBMに買収されてしまいました。
しかもその買収額は3兆8000億というとんでもない額。これには世界中のIT界隈の人々が驚いたことだと思います。

RedHat社は商用(有料)Linuxディストリビューションの中でも非常に人気の高いRedHat Enterprise Linux (RHEL)を開発、販売している会社です。
また、Linuxディストリビューションのfedoraや、RHELのオープンソース部分を使用して作られたCentOSなどともかかわりが深く、開発に協力していたり、これらのディストリの成果をRHELにも取り込んでいたりと、かなり密接な関係をもつ、オープンソース界隈でもかなり影響力の高い企業でした。

今回の買収でRedHatが完全にIBM傘下に収められたわけですが、個人的に懸念していることがあります。
RedHatは完全にオープンソースへの協力を積極的に行っている企業なのは目に見えてわかりますが、一方IBMについては、個人的に「…?」という印象でした。
もしかすると実際はいろいろなプロジェクトを支援しているのかもしれませんが、少なくとも最近になってオープンソース支援へとシフトしつつあるMicrosoftよりも地味な印象でした。

買収後もRedHatの動きについては現状のままにしたいとIBMは言っているようですが、IBMのオープンソースへのスタンスがいまいちわからないので、個人的にはちょっと不安です。

CentOSは、もともとRHELのオープンソース部分を利用して、有志のメンバーがRHELと同等の機能を持つことを目指して開発されている、RedHat Linuxから派生したRedHat系のLinuxディストリビュージョンです。CentOS自体はもともとRedHatとは関係がありませんでしたが、2014年にRedHatが正式に派生OSとして承認を出し、RedHatから直に開発支援を受けられる状態になりました。

今更聞けない!CentOSとRed Hatの違いとは? – エンジニアの入り口

そんなわけで、現在CentOSはサーバーOSとして非常に人気が高く、LinuxをサーバーOSとして使用する企業や団体の多くで使用されている上、各IaaSクラウドサービスのほどんどで公式フレーバーが提供されているほどになっています。

今後IBMが介入してくることでこういったCentOSや同じくRedHatが支援するfedoraとの関係が変化してしまうのではないか、と個人的に心配しています。

ただ、買収されたからと言って悪い方に転ぶとは限りませんし、今よりより良くなっていく可能性もあると思います。
今後RedHatの買収によってこの辺りがどうなっていくのか…注目していきたいですね。

  • この記事いいね! (3)
takahashi 著者:takahashi

WindowsにVirtIOドライバをインストールする方法

サーバー準仮想化の仕組みの一つに、”VirtIO”というものがあります。
例えば仮想マシンでNIC(ネットワークアダプタ)やディスクドライブをソフトウェアで完全に仮想化してしまうと、物理ハードで動かした場合と比較して必要な処理が多くなり、オーバーヘッド、つまり余分な負荷が増えてしまいます。
余分な負荷が増えることで、結果として可能マシンの動作が遅くなってしまうのです。

仮想マシンの仕組み上からこのオーバーヘッドを少しでも減らす方法の一つとして、一部の処理を物理的なハードウェアに直接行わせてしまう”準仮想化”という方法が用いられます。完全な仮想化ではないので”準”仮想化です。

VirtIOも、ディスクへのアクセスやネットワークへのアクセスを”準仮想化”する仕組みの一つで、最近の主要な仮想マシンやクラウドサービスなどでよく使われています。
VirtIOを使用することで、完全仮想化されたハードウェアを使用する場合と比較してより高速に仮想マシンを動作させることができます。

Linuxディストリビューションには標準でVirtIOドライバが含まれている場合が多いのですが、Windowsの場合、初期状態ではVirtIOドライバがインストールされていないのでドライバのインストールが必要になります。

今回は、セットアップ済みのWindowsにVirtIO-NETドライバをインストールする方法をご紹介します。

VirtIOのドライバはfedoraプロジェクトのサイトで配布されています。

Creating Windows virtual machines using virtIO drivers – fedoraDOCS

この中の
Stable virtio-win iso
を選択し、isoファイルをダウンロードします。

isoファイルを入手したら、各仮想マシンに光学ドライブとしてマウントします。
マウントする方法は仮想マシンソフトによって操作方法が異なるため、各ソフトのマニュアルを参照してください。

OSからは光学ディスクドライブ(CD/DVDなど)として認識されていればOKです。
マウントが完了したら、デバイスマネージャーを開いてください。

デバイスマネージャーはコントロールパネル(コントロール パネル\システムとセキュリティ\システム)、またはWindowsロゴ(スタートメニュー)を右クリック->デバイスマネージャーから開くことができます。

デバイスマネージャーを開くと、いくつかの黄色い”!”が表示されているかと思います。

“!”マークが表示されているデバイスを右クリックし、”ドライバーソフトウェアの更新”をクリックします。


するとこちらのダイアログが表示されるので
“コンピュータを参照してドライバーソフトウェアを検索します”
をクリック。

下記画面が出てくるので…


先程VirtIOのISOイメージをマウントしたドライブを選択します。
すぐ下の”サブフォルダーも検索する”もかならずチェックを入れてください。


適合するドライバの検索が始まります。

途中、許可を求められた場合は”インストール”をクリックしてください。

下記の画面になればインストールは成功です。

デバイスマネージャーで”Red Hat VirtIO Ethernet Adapter”が追加されていれば、正常に動作しています。

なお、ディスク側のVirtIOのインストールは、先にOSがインストールされたディスクをVirtIOに切り替えてしまうと正常に起動しなくなる可能性があります。
ストレージを完全仮想化状態のままにしてOSを起動し、外付けのVirtIOディスクを追加したうえでドライバーをインストール、作業が終わったらシステムディスクをVirtIOに変更すればOKのようです。

詳細はこちらの方の記事を参照してください。

KVM上のWindowsでVirtIOを利用する – 出力を入力へ

VirtIOはセットアップはめんどくさいですが、動作速度の改善が測れますし、やっておいて損はないかと思います。
仮想マシンを利用されている方は是非試してみてはいかがでしょうか。

  • この記事いいね! (0)
takahashi 著者:takahashi

[nginx小ネタ]failed (24: Too many open files)が出た時にまず確認したいこと

今回は、先日のちょっとしたやらかし談をご紹介します。

先日新しくサーバーを構築していて、nginxでバックエンドのApacheへのリバースプロキシを構築していたのですが、途中でこんなエラーに遭遇し、サイトが表示されなくなってしまいました。
logを確認するとこんなメッセージが。

accept4() failed (24: Too many open files)

いろいろ調べたところ、OSファイルディスクリプタ数上限の設定やnginxの制限の設定などを変えると解決するという情報を発見て、sysctl.confやらnginxのコンフィグやらを色々変えたのですが、何度試しても同じエラーが出続けて動作せず。

おかしいなーと思いながらもう一度設定ファイルを見返したところ、あることに気づきました。

バックエンドのApacheでは3003番ポートでListenしていて、nginxの3001番ポート経由でバックエンドのサーバーにつなげさせたかったのですが、設定ファイルには

server {
    listen       3001;
    server_name  node.example.com;

   client_max_body_size 1g;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-Proto \$scheme;


    location / {
        proxy_pass http://localhost:3001; #←!?
    }

}

となっていました。
そう、つまりlocalhostの3003番ポートで動作しているApacheへリバースプロキシさせるはずが、あろうことかnginxが待ち受ける3001番ポート自身をまたリバースプロキシするような設定になってしまっていました。
当然、nginxの待ち受けポートをnginx自身がリバースプロキシしてしまっているので接続が無限にループしてしまい、それが原因でOSの上限を超えてしまっていたというのが今回の原因でした。

すぐに

proxy_pass http://localhost:3003;

に修正したところ、正常にページが表示されるようになりました。

見慣れないエラーが出ると慌ててついいろいろ試してしまいますが、まずは自分の凡ミスを疑ってみることも大事なんだなと思いました(;´∀`)

  • この記事いいね! (0)
takahashi 著者:takahashi

普通のメールサーバーでもキャリアメールのようなプッシュ通知を可能にするIMAP IDLEとは

携帯電話やスマートフォンでキャリアメールを使用していると、何もしなくてもリアルタイムでメールを受信することができます。
一方、通常のメールサーバーからメールを受信する際、元々リアルタイム受信は一般的ではなく、ユーザーがメールサーバーに定期的に確認しに行くしかありませんでした。
ところがIMAPというメール受信のプロトコルができてから、こういった従来のメールシステムでも定期的にサーバーに確認することなくメールをリアルタイムで受信することが可能になりました。

具体的には、メールソフトがIMAPサーバーへ接続した際、特定のコマンドをクライアントが発行することで受信操作完了後もIMAPサーバーとの接続を維持し続け、新着メールがあるたびにメールサーバーからクライアントにリアルタイムで通知する仕組みになっています。

この仕組み、およびコマンドををIMAP IDLEといいます。
IMAP IDLEコマンドを使用するには、使用しているメールサーバーがIMAPに対応しており、かつIMAP IDLEコマンドにも対応している必要があります。

自分でフルコントロールできるメールサーバーがあれば、受信サーバーにdovecotなどのIMAP IDLE対応IMAPサーバーを使用することで、自分のメールサーバーに到着したメールをリアルタイムにプッシュ通知させることができます。

DovecotでIMAP IDLE を使った Pushメールを体験してみる – レンタルサーバー・自宅サーバー設定・構築のヒント

しかし、使用しているメールサーバーの管理権限を持っていない場合(通常はこの場合が多いと思います。)、IMAP IDLEに対応していないとこのプッシュ通知を利用することができません。

有名どころでは、現時点で下記のメールサービスはIMAP IDLEに対応しているようです。

・Gmail
・Yahoo!メール

そのほかのメールサービスでもIMAP IDLEが利用できるものがあるようです。各メールサービスのFAQやドキュメントを確認したり、サポートに問い合わせたり等して確認してみてください。

また、IMAP IDLEが利用できないサーバーを利用されていて、それでもIMAP IDLEをつかってプッシュ受信を実現したいということであれば、一旦他のメールサービスを受信させて、そこからIMAP IDLEを使ってプッシュさせる方法があります。

例えば、自分の場合は会社のメールサーバーはPOP3にしか対応していないため、直接IMAP接続することができません。
そこで、フリーのメールサービスであるGmailを使い、一度会社のメールサーバーのメールをPOPでGmailへ受信させ、GmailがPOPで受信した時点でIMAP IDLE経由で各端末へ通知させるような使い方をしています。

Gmailサーバーと会社のメールサーバーはPOPでやり取りしているため、実際には完全なリアルタイムではありませんが、Gmailは比較的リアルタイムに近い時間間隔でPOP受信をかけてくれるため、ほぼ数分程度の誤差でメールを受信することができます。

GmailでPOP受信設定する方法 – heteml BLOG

ただし、Gmailの場合は受信容量に上限(Google Dirveなどのサービスと共用で、1無料アカウントにつき15GB)があるので、無限にメールをため続けることができない点には注意してください。

  • この記事いいね! (0)
takahashi 著者:takahashi

nginxやAmazon ALBなどのロードバランサー経由でLaravelにアクセスさせたときにHTTP/HTTPSを振り分ける方法

nginxやロードバランサーなどを使ってWebサーバーにアクセスさせた際に困るのが、一部の情報が本体のWebサーバーまで到達しない点。
特に、クライアントがHTTPでアクセスしているのか、HTTPSでアクセスしているのか、などの情報はそのままの状態で取得するのは困難です。

こういった環境と、HTTPかHTTPSどちらで接続されているのかを判定したうえでDOMのURLを書き換えるタイプの機能を持つフレームワークやプログラムとの相性は特に最悪で、Webサーバーに対してHTTPでアクセスされた時点で”クライアントからHTTPでアクセスされている”と判定して、すべてのアセットのアドレスをhttp://から始まるURLに置き換えて返してしまい、結果jsやcssが読み込めずに表示崩れや不具合になってしまうことがあります。

最近人気のLaravelもこの機構を持っており、そのままの状態でnginxやLBを間に置いてしまうと、httpsでアクセスしたときにページが正常に表示されない問題が発生してしまいます。

幸いにも、HTTPSかどうかの部分についてnginxやロードバランサーが代わりに取得し、その情報をヘッダーに含めて投げてくれる場合が多いので、今回はLaravel上でこのヘッダ情報を使って簡単にHTTP/HTTPSを判定できるようにしてみました。

Laravelプロジェクトフォルダ内の
routes/web.php
の最初あたりに、次のコードを追加します。

<?php

// 2018/10/26追記: 一部修正しました。

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

//ここから
//リバースプロキシ経由のHTTP/HTTPS判定
if(array_key_exists('HTTP_X_FOWARDED_PROTO',$_SERVER) === true){ //"HTTP_X_FOWARDED_PROTO"ヘッダーが存在していたら
    if(strtoupper($_SERVER["HTTP_X_FOWARDED_PROTO"]) == "HTTP"){ //strtoupper("HTTP_X_FOWARDED_PROTO")の中身が"HTTP"だったら
        URL::forceScheme('http'); //すべてのURLをhttpに書き換える
    } else {
        URL::forceScheme('https'); //すべてのURLをhttpsに書き換える
    }
}
//ここまで

$_SERVERはPHPにおいて、サーバー情報および実行時の環境情報がすべて格納されるスーパーグローバル変数です。

$_SERVER – php.net

この中に、リクエストヘッダの中身もすべて格納されるので、その中からnginxやAmazon ALBやClassic Load BalancerがHTTP/HTTPSの情報を格納する”X_FOWARDED_PROTO”ヘッダーを参照して、どちらでアクセスされたかを判定しています。

ifを敢えてHTTPかどうかで判定している理由は万が一、”$_SERVER[“HTTP_X_FOWARDED_PROTO”]”にhttpでもhttpsでもない不正な値が入っていた場合も、とりあえずhttps://で吐き出すようにするためです。

こんな形で処理を加えてやれば、Laravelでもnginxやロードバランサーを使用していても正常にHTTPとHTTPSの切り替えが行えるようになると思います。

少しでも参考になりましたらしたら幸いです。

  • この記事いいね! (0)
takahashi 著者:takahashi

Certbotでnginxプラグインを使用した際に”UnicodeDecodeError”が出てしまった場合の対処法

CentOS 6.10でCertbotのインストールとSSL証明書の取得をnginxプラグインで行った際に、下記のようなエラーが発生。

2018-10-08 15:34:01,329:DEBUG:certbot.log:Exiting abnormally:
Traceback (most recent call last):
  File "/opt/eff.org/certbot/venv/bin/letsencrypt", line 11, in <module>
    load_entry_point('letsencrypt==0.7.0', 'console_scripts', 'letsencrypt')()
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/main.py", line 1364, in main
    return config.func(config, plugins)
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/main.py", line 1233, in certonly
    installer, auth = plug_sel.choose_configurator_plugins(config, plugins, "certonly")
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/selection.py", line 228, in choose_configurator_plugins
    installer = pick_installer(config, req_inst, plugins, installer_question)
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/selection.py", line 32, in pick_installer
    config, default, plugins, question, (interfaces.IInstaller,))
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/selection.py", line 106, in pick_plugin
    verified.prepare()
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/disco.py", line 251, in prepare
    return [plugin_ep.prepare() for plugin_ep in six.itervalues(self._plugins)]
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/disco.py", line 251, in <listcomp>
    return [plugin_ep.prepare() for plugin_ep in six.itervalues(self._plugins)]
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot/plugins/disco.py", line 132, in prepare
    self._initialized.prepare()
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/configurator.py", line 145, in prepare
    self.parser = parser.NginxParser(self.conf('server-root'))
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/parser.py", line 38, in __init__
    self.load()
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/parser.py", line 45, in load
    self._parse_recursively(self.config_root)
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/parser.py", line 66, in _parse_recursively
    self._parse_recursively(subentry[1])
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/parser.py", line 56, in _parse_recursively
    trees = self._parse_files(filepath)
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/parser.py", line 207, in _parse_files
    parsed = nginxparser.load(_file)
  File "/opt/eff.org/certbot/venv/lib64/python3.4/site-packages/certbot_nginx/nginxparser.py", line 123, in load
    return loads(_file.read())
  File "/usr/lib64/python3.4/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 1345: ordinal not in range(128)
2018-10-08 15:34:01,331:ERROR:certbot.log:An unexpected error occurred:

どうやら、Certbot内のpythonスクリプトで何かエラーが発生しており、そのせいでSSL証明書の取得ができなくなってしまっているようです。
エラー内容をよく見ていくと

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 1345: ordinal not in range(128)

とあり、どうやら文字コードの問題が発生していることは分かりました。
とりあえず調べていくと、こちらの記事を発見。

cert-bot/letsencrypt nginx `UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe3 in position 12: ordinal not in range(128)` – Qiita

どうやら、nginxの設定ファイルにコメントなどで日本語が入っていると、Let’sEncryptのnginxプラグインがその日本語部分を解釈できない(asciiコードとして解釈しようとしてしまう)のが原因のようです。

とりあえずの対策として、nginxの全設定ファイルから日本語やその他のマルチバイト文字をすべて取り除けば解決するようです。

自分の環境でもnginxからすべての日本語を取り除いたところ、正常に動作し、SSL証明書取得まで行うことができました。

ただ、Let’sEncryptを使用するから、という理由だけでnginx内のコンフィグで日本語が一切使用できないのはちょっと辛いものがあるので、改良されてほしいですね。

  • この記事いいね! (0)
takahashi 著者:takahashi

Let’s Encrypt + MyDNS でワイルドカードSSL証明書を自動更新する方法

昨日の記事で、無料DDNSサービスであるMyDNSで、手動でDNSの編集をしなくてもワイルドカード証明書を取得・更新できるようになったことをお伝えしました。

今回は実際に自動的にワイルドカード証明書を取得・更新為の設定方法をご紹介したいと思います。

まず前提として、まだMyDNSに登録をしていない方は、先に登録しておく必要があります。

また、MyDNSはDDNSサービスであり、IPアドレスを定期的に書き換えることが前提の仕組みになっています。
そのため、たとえ固定のIPアドレスを取得していたとしても、定期的に向き先のIPアドレスをMyDNSに通知する必要があります。

1週間通知しないと、ドメインIPの正引きが停止し、1か月間通知しないと、アカウントが削除されてしまいますが、IPアドレスの通知はプログラムを使って通知することができるようになっていますので、通知スクリプトをcronなどで定期的に実行することで、手動のメンテナンスなしで利用の継続が可能です。

https://www.mydns.jp/?MENU=030のSTEP4にある要件さえ満たしていればどんな言語やプログラムを使ってもOKなのですが、一から作るのはちょっと面倒なので、インターネット上で有志の方が作成したサンプルコードを利用した方が確実かつ手軽なので、活用することをお勧めします。

アカウントの作成方法とIPの自動更新設定についてはネット上に参考資料が沢山出ているため今回は割愛します。

上記の手順まで完了したら、自動更新スクリプトをサーバーに入れ込んでいきます。

ターミナルを開き、次のコマンドをroot権限で実行します

cd ~ #ホームフォルダなどの作業スペースへ移動
wget 'https://github.com/disco-v8/DirectEdit/archive/master.zip' -O DirectEdit-master.zip #MyDNSの自動更新スクリプトをダウンロード
unzip DirectEdit-master.zip #ダウンロードしたZipを解凍
mv DirectEdit-master /opt/ #解凍したフォルダを/opt/に移動

次に、自動DNS書き換えの設定をしていきます。

vi /opt/DirectEdit-master/txtedit.conf

内容を下記のように書き換えます。

    $MYDNSJP_URL       = 'https://www.mydns.jp/directedit.html'; //そのまま
    $MYDNSJP_MASTERID  = 'mydnsXXXXXX'; //MyDNSユーザーID
    $MYDNSJP_MASTERPWD = 'yourmydnspasswd'; //MyDNSパスワード
    $MYDNSJP_DOMAIN = 'example.com'; //MyDNSに登録したドメイン名

権限を変更します。

cd /opt/DirectEdit-master
chown root:root ./
chmod 700 ./*.php //DNS自動更新プログラム
chmod 600 ./*.conf //設定ファイル

これで下準備はOKです。
それではMyDNS自動更新スクリプトを使ってdns-01認証でワイルドカード証明書を取得してみます。

certbot-auto certonly --manual \ #certbot-autoコマンドは環境によって名前が異なる場合があります。
--preferred-challenges=dns \
--manual-auth-hook /opt/DirectEdit-master/txtregist.php \
--manual-cleanup-hook /opt/DirectEdit-master/txtdelete.php \
-d example.com -d *.example.com \ #※左記以外のサブドメイン(たとえばa.example.com)はMyDNSのスクリプトではエラーになるため指定できません。サブドメインのSSLを取得する場合は別途従来のhttp-01認証で取得してください。
--server https://acme-v02.api.letsencrypt.org/directory \
--agree-tos -m hoge@example.com \ #Let'sEncryptからの通知を受け取るアドレスを指定します。
--manual-public-ip-logging-ok

これでおそらくワイルドカード証明書を取得できたかと思います。
一度上記のコマンドを実行してしまえば、次回以降の更新では

certbot-auto renew #環境によってコマンドが異なります。

コマンドのみを実行すれば更新することができますのでcronなどで定期実行させればサーバーが自動でSSL証明書を更新するようになります。

ワイルドカード証明書を手軽に使ってみたい、という方は是非試してみてください。

  • この記事いいね! (0)