KDE neonの更新

KDE neonの更新 1

KDE neonは非常に良くできたLinuxのディストリビューション。
簡単なのでPCのド素人にもお薦めできるし見た目もショボくない。
と、思って昨年より愛用してたんだけど、昨年末頃から標準のソフトウエア管理ツールのDiscoverの更新機能が正常に機能しなくなっていた。WindowsでいえばWindows Updateが機能しないようなもの。

すぐに修正されるかなと思っていたが待てども解決されず。もちろん、公式サイトから今年に入ってリリースされた最新版のイメージファイルをダウンロードしたクリーンインストールしたものも同様。
更新するべきソフトウエアの件数だけは通知されるがGUIだけではどうにもできず。

KDE neonの更新 2
標準のソフトウエア管理アプリのDiscoverで更新の確認を行うと更新対象のパッケージがリストアップされて、上の画像の右上の赤い四角の部分が本来であれば[Update All]などの押せる状態のボタンに変わる筈だが、更新確認完了にならず、灰色表示のままで押せるボタンの状態にならない。もちろんリストアップされた更新対象のパッケージも更新できない。

KDE neonの更新 3
KDE neonのFAQページには上のように書かれている。ところが、これは書かれたまま実行しても延々といつまで経っても終わらない更新作業になる。おそらく普通の人は途中で諦めるかと。そして、昨日まではターミナルでコマンドを打って更新してもDiscoverで更新できる状態にはならなかった。

% sudo -s
[sudo] foobar のパスワード: ************************
# pkcon refresh -y
# pkcon update -y

sudo -sで管理者に昇格せずsudo pkcon 〜の方がLinuxの流儀かも。
どちらにしても -yを付けて実行する。これで自動進行する。

KDE neonの更新 4
昨日の更新でDiscoverの更新機能が一部or全部正しく機能するようになったみたい。少なくとも更新確認は完了するようになった。
手動で更新し終わったばかりなので新しい更新ファイルが無くて正常に更新が出来ることは確認できていない。

ただ、昨日の更新をしたら一部アプリ見た目との挙動が変になった気が・・・

同日追記:
と、思ったら、すぐに新しい更新が来たので早速Discoverで更新してみた。

KDE neonの更新 5
更新するべきパッケージのリストが表示されて、それを更新するためのボタンが押せるようになっている。このボタンが押せないという異常がおよそ3ヶ月ほど続いたのよねぇ。

KDE neonの更新 6
画像では判らないだろうが、正常に更新が完了した。そして右上の の更新するべきパッケージがあるか確認するボタンが押せて、その確認が正常に完了する。つまり更新周りの異常は無くなり正常になった。

WordPressのGoogle XML Sitemapsプラグインとサイトマップ

WordPressのGoogle XML Sitemaps (XML Sitemap Generator for WordPress)プラグイン。今回は何かとトラブルと誤解の多いこのプラグインについて。

この記事では2019年2月12日現在で最新のGoogle XML SitemapsプラグインのVer.4.1.0について書く。
バージョンついでで書くと、このプラグインもバージョンを重ねていろいろ変わっている。ここ数年の特に大きな変更はVer.4.0でサブサイトマップを出力するようになったこと。機能改善以外では、最近では2018年の1月(と12月)に脆弱性がが見つかって話題になった。少なくとも4.1.0(現在の最新版)以外の古いバージョンは使ってはいけない。
インターネットの情報を見ると何故か古いVer3.X.Xをにダウングレードして使うというバッドプラクティスがオススメ情報みたいな形で広まっているようだけど、ダメよ。おそらく元の情報が4系の初期のころに書かれたとかサブサイトマップの表示に必要なURLリライトの一手間を知らないまたはURLリライトができない環境向けなんだと思うけど、URLリライトが出来ない環境を除いてはv3系などは使わず最新版を使って下さい。URLリライトができない環境ならGoogle XML Sitemaps以外のURLリライト不要なプラグインを使うべき。

サイトマップはただのURLリスト

Google XML Sitemapsの仕事は基本的にはサイトマップを出力するだけ。最近は検索エンジンに通知する機能なども追加されてるみたいだけど、メインはあくまでサイトマップ。
サイトマップというのはウェブサイトによっては人間の閲覧者向けに記事一覧とかウェブサイトの構成を表示してくれるところもあるようだけど、今回のは主に検索エンジン向けのサイトマップで、XML(他形式もあり)で書かれたウェブサイト内のページのURL一覧のようなもの。XML形式ではそれぞれのページの最終更新時間や更新頻度や重要度も合わせて記載されるが、ぶっちゃけただのURLリスト。特にXML以外の例えばテキスト形式のサイトマップではURLしか書かない超単純リストだし。それがサイトマップ。全く謎技術じゃない。

そんな単純なリストを出力するだけ(ちょっと付加機能あり)のプラグインがGoogle XML Sitemaps。
それが正しく動かないという場合は、よくあるのは他のSEO系のプラグインにサイトマップ出力機能があってコンフリクトしてるとか、WordPressが最低限動く程度しかメモリが割り当てられてないのに他のたくさんのプラグインと共に動かしてメモリ不足だったりとか。他にもいろいろありそうなので「Google XML Sitemapsではトラブルは起きません」とは言わない。でも多くは利用する側の間違いか勘違いか無茶。

ページ数の膨大なウェブサイトのサイトマップを1つのリストに記載すると検索エンジンが膨大なURLの途中までしか読んでくれないかもしれないし、巨大なサイトマップの作成にはメモリが多く必要になるのでサイトマップを分割して出力することには意味がある。一応決まりとしては1つのサイトマップあたりの上限は5万URLでファイルサイズ50MBということになってるけど、大量に書かれていても何処まで読むかは検索エンジン次第。超巨大ウェブサイトでなくても基本分けろ。Google XML Sitemapsのv4系では投稿記事と固定記事(と他フォーマットも)をそれぞれ月別で分割するみたい。メインのサイトマップにはサブサイトマップの在り処を書かなくてはならないけど、他にはどのようにサイトマップを分けるかという決まりは無いので月別にしなければならないというわけではないがGoogle XML Sitemapsではそうやってるというだけ。

Google XML Sitemapsプラグインの設定

Google XML Sitemapsプラグインのインストールは省略。
Google XML Sitemapsの設定はWordPressの管理画面のメニューから[設定]→[XML Sitemap]にある。

Google XML Sitemaps 1
XML Sitemapsの画面。
XML Sitemapsv4系では上の画像の赤枠のところにURLリライト設定の追加が必要な旨が書かれている。英語と意味不明な文字が並んでるようにしか見えない人は意味が解らなくて読み飛ばすみたいだけどダメよ。
これを無視するとメインのsitemap.xmlは出力されるがサブサイトマップは(出力はしていても)表示されないことになる。 そうすると当然検索エンジンがサブサイトマップを見ることができないので、サイトマップを使ってクロールされる筈の分がインデックスされないことになる。これはGoogleのSearch Consoleを使ってたら(そのうち)警告が来るので判ると思うけど。

赤枠の部分に書かれているコードはApache用なので多くのレンタルサーバではそのまま使える筈。WordPressのトップディレクトリと同じ階層にある.htaccessファイルに追記するだけ。無ければファイルを作成。WordPressをサブディレクトリに置いてる場合は書かれていることをよく見て必要に応じて適切に変更。

Apache用の例 (プラグイン設定画面に書かれてるまま)
1
2
3
4
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^sitemap(-+([a-zA-Z0-9_-]+))?\.xml(\.gz)?$ /sitemap$1.xml$2 [L]
</IfModule>
(上のコードがそのまま使えるとは限りません。)
使っているHTTPサーバがApache以外ならそれ用に書き換える。現在は稼働中のウェブサーバに応じたコードが表示されるのでそのまま使えることが多い。Nginx用の例 (次)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.com;

    #WordPressホスト用の設定 ホゲホゲ (省略)

    #Google XML Sitemaps用設定 (4行挿入)
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;
}
(上のコードがそのまま使えるとは限りません。)

Apacheの.htaccessなら書き込めばその設定がすぐ有効だがApacheの.htaccessではない設定ファイルに書いたとか上のNginxの設定を書いたという場合はHTTPサーバの再起動か設定再読込が必要。

Google XML Sitemaps 2
Google XML Sitemapsの設定画面に戻り下にスクロールする。
画像中にメモを書いたが、画像に見えている部分の設定は「変更する必要無し」と言いたかった。
「基本的な設定」の部分は環境に合わせて、または自分の好みで変更。
設定を変更したなら一番下までスクロールして[設定を更新]ボタンを押す。

サイトマップを表示する

Google XML Sitemaps 3
サイトマップは基本的にはウェブサイトのトップディレクトリに置くことになっている。サブディレクトリに置いた場合はそのサイトマップには別のディレクトリのページのURLは含めてはいけないということになっている。含めてもクロールはしてくれないらしいのでインデックスに登録されないということになる。(ここまで数行は手動設置の場合)
Google XML Sitemapsではウェブサイトのトップディレクトリにsitemap.xmlが置かれて(仮想だけど)、そのメインサイトマップにサブサイトマップのURLが書かれる形となる。自動で行われるのであまり気にしない。
つまり、http://example.com/sitemap.xmlをブラウザで開けば(メインの)サイトマップが表示される。 なんか綺麗に見えるリストだが、最近のブラウザでは右クリックでそのページのソースを表示できる筈なのでソース(XML)を表示して見て欲しい。(次)

Google XML Sitemaps 4
これがXMLで書かれたサイトマップ。
で、上の画像の赤枠の部分を確認して欲しい。正しくGoogle XML Sitemapsが出力したサイトマップであれば赤枠部分のように、Google XML Sitemapsプラグインの作者のウェブサイトのURLである http://www.arnebrachhold.de と、プラグインのバージョン (上の画像では4.1.0)がある筈。さらにサイトマップの出力日時も何日も何週間も何ヶ月も前でないこと。今日プラグインを初めてインストールしたなら今日付け。
これはメインのサイトマッブなので<sitemap>〜</sitemap>という形式でサブサイトマップの在り処が書かれている。

Google XML Sitemaps 5
そのメインのサイトマップを一番下までスクロールする。上の画像の赤枠の緑字の部分(表示するブラウザによっては緑とは限らない)に出力のための処理時間や使用したメモリの量が表示されていて警告だとかエラーが発生していなければ、メインのサイトマップは正しく出力されていると思って良い。

Google XML Sitemaps 6
ソースを閉じて綺麗なリストの方から月別のサブサイトマップの1つ(1行)をクリックする。
これがサブサイトマップの例。一見メインのサイトマップとそんなに変わらない。さきほどと同様に右クリックしてソースを表示する。
ここで、サブサイトマップが表示されずにerror404になるとかWordPressの(トップ)ページ等が表示される場合はURLリライトの設定が間違っているかURLリライトが機能していない。とにかく要対応。

Google XML Sitemaps 7
サブサイトマップのXML。先程と同様にプラグインの作者のウェブサイトのURLがあってバージョンが正しいこと。さらに一番下に(スクロールして)出力処理時間などが表示されていてエラーが無いことを確認する。
このサイトマップに書かれているのは記事のURLなので<url>〜</url>という形式になっている。

ここまで問題無いようであれば、GoogleのSearch Consoleに登録する。

Google XML Sitemaps 8
Search Consoleの新しい方
左列のメニューで[サイトマップ]を選択し、右列で「新しいサイトマップの登録」を行う。基本的にはsitemap.xmlと入力して[送信]を押すだけ。
サイトマップの送信はすぐに出来ている筈だが、数日置いてから確認する。ステータスが「成功しました」になること。上の画像には表示されていないがステータス表示の右の方に検出されたURLの件数(サイトマップからGoogleに認識されたURLの数)も出る。
これだけ。

Google XML Sitemaps 9
Search Consoleの古い方(旧ウェブマスターツール)
すでに新しいSearch Consoleを使っているならこちらを使う必要はない。ただ、今も使えるというだけ。
左列のメニューで[クロール]、[サイトマップ]を選ぶ。
右列の[サイトマップ追加テスト]ボタンを押して sitemap.xml を入力して登録する。
登録はすぐに行われる筈だが、確認は後日。確認するのは「送信」されたURL数。ここがいつまで経ってもサイトマップに含まれるURL数に遠く及ばないなら「嫌だね」レベル。サイトマップに何か問題があれば下の方に何かの警告が出る。警告が無いならまだ全て処理されていないと思われる。
「インデックスに登録済」の数をやたら気にする人がいるが、こちらはサイトマップで通知されたURLをさらに後日に全然別処理のクローラーがページ取得に来て、それが検索のインデックスに登録されてはじめて数に入るもの。数日で全て登録されればラッキーで、(全て|殆ど)が登録されるまで数週間とかもザラ。また、サイトマップの送信数とインデックス登録数は必ずイコールになるわけではない。

Google XML Sitemaps 10
警告がある場合。
「警告数」をクリックすると上の画像のように警告の内容が表示される。
この画像の場合だと、「サイトマップエラー」で「URLにアクセスできません」となっているが、実際にはサイトマップ(サブサイトマップ)にアクセスできないというのではなく、サイトマップ(サブサイトマップ)に記載されているURLの1つまたは複数にアクセスしようとしたら失敗したというもの。この画像の例では2015年4月のサブサイトマップに書かれているURLの1つにアクセスできなかったというもの。で、このアクセス失敗は自分のサーバー側が正常であってもときどき発生する。クローラー側の問題であったり通信経路の問題であったり本当にたまたまであったり。なのでアクセス失敗の1つ2つなら全然心配する必要無し。

Search Consoleを使うならこれだけはおぼえる

Googleはすぐにやってくれない

WordPress REST APIとCORS

AMPプラグインのCORS 1
「がとらぼ」のAMPページはamp-listとWordPress標準のREST APIを使って「最近の投稿」リストを表示させるようにしていたのだが、いつのまにかGoogleのAMPキャッシュページではそのリストが表示されなくなっている。(上の画像の赤い破線の四角部分が空白になっている)
ローカルサーバのAMPページでは正しく表示されるので仕組みとしては正しい筈。また、CORSも解決済み(全許可)の筈なのに何故だ?。
(この半年ほどHTTPサーバのNginxの設定やテーマのfunctions.phpを弄り倒してるので自分でも何をどうしたかよく憶えていない。)

AMPプラグインのCORS 2
Chromeブラウザのデベロッパーツールでエラーを確認した。
HTMLヘッダのAccess-Control-Allow-Originの値を指摘されている。 https://gato-intaa-net.cdn.ampproject.orgと*の2つが指定されているのがダメよということ。
「*」 (全てのドメイン)は自分が指定したが、こんな複数指定に憶えがない。というかGoogleのAMPキャッシュのホストが何故勝手に指定されている?

「がとらぼ」のGoogle AMPキャッシュはホスト名(オリジン)が gato-intaa-net.cdn.ampproject.org なので、そのAMPキャッシュページを閲覧する状態を再現するためにそのオリジン指定を付けてREST APIで「がとらぼ」の「最近の投稿」のJSONを取得する。(下)
なお、CORSの確認ならオリジンは元ホスト以外なら正直何でも良い。

$ curl 'https://gato.intaa.net/wp-json/wp/v2/posts?__amp_source_origin=https%3A%2F%2Fgato.intaa.net' -I -H 'origin: https://gato-intaa-net.cdn.ampproject.org'
HTTP/2 200 
server: nginx
date: Tue, 12 Feb 2019 01:32:48 GMT
content-type: application/json; charset=UTF-8
amp-access-control-allow-source-origin: https://gato.intaa.net
x-robots-tag: noindex
x-content-type-options: nosniff
access-control-expose-headers: X-WP-Total, X-WP-TotalPages
access-control-allow-headers: Authorization, Content-Type
x-wp-total: 573
x-wp-totalpages: 58
link: <https://gato.intaa.net/wp-json/wp/v2/posts?page=2>; rel="next"
allow: GET
access-control-allow-origin: https://gato-intaa-net.cdn.ampproject.org
access-control-allow-methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
access-control-allow-credentials: true
vary: Origin
strict-transport-security: max-age=31536000;
access-control-allow-origin: *
x-content-type-options: nosniff always
content-security-policy: default-src * 'self' data: 'unsafe-inline' 'unsafe-eval';

何故かaccess-control-allow-originヘッダが2つ出力されている。元々Nginxの設定で出力するようにしていたのが * の行でhttps://gato-intaa-net.cdn.ampproject.orgの行は知らない。
つまり、勝手にAccess-Control-Allow-Originヘッダが出力されている。
また、オリジンは何を指定してもその値がAccess-Control-Allow-Originヘッダに入るのでNginxの指定でいえば add_header Access-Control-Allow-Origin "$http_origin";と同じ状態らしい。

調べたところ、最近のWordPressで標準装備のREST APIを使うと勝手にHTTPレスポンスヘッダが3行ほど追加されるよう。

1
2
3
access-control-allow-origin: https://REST API呼び出し元ホスト(可変)
access-control-allow-methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
access-control-allow-credentials: true

うーん、REST APIを使うときにCORSで困らないようにという親切なんだろうけど、勝手なことすんな!

ちなみにAMPプラグインのソースを見たところincludes/class-amp-http.phpにもHTTPレスポンスヘッダを付ける処理が追加されていた(v1.0から?)。こちらは何をするとそのヘッダが出力されるのかはまだ把握してないけど、いずれまた「勝手なことすんな!」と思う日が来るかも。

このAccess-Control-Allow-Originは勝手に追加出力(B)されると別に出力されている同ヘッダ(A)との組み合わせ(A且B)として判定されるので結果的に指定した値のどちらも許可されないという嫌らしいことになるみたい。

仕方がないのでNginxの設定で指定していた add_header access-control-allow-origin '*';の方を無効にしてみた。正直なところ「がとらぼ」はいろいろ掃除して外部からリソース共有(参照)されることもない筈なのでaccess-control-allow-originヘッダを付ける必要がなくなっていた。

いやいや、うちは、リソース提供するのでaccess-control-allow-originヘッダはHTTPサーバで常に出したいということであれば、WordPressのREST APIによって出力されるHTTPレスポンスヘッダの処理を上書きしてやるのが良さげ。

使用中のテーマのfunctions.phpの最後にでも追記
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//REST API HTTPレスポンスヘッダ制御上書き
add_action( 'rest_api_init', function() {
    remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );
    add_filter( 'rest_pre_serve_request', function( $value ) {
        //header( 'Access-Control-Allow-Origin: ' . $origin );
        header( 'Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE' );
        header( 'Access-Control-Allow-Credentials: true' );
        return $value;
    });
}, 15 );

5行目のコメントを外すと元と同じ動きになる筈。(そのときは上のコードは要らない筈だが。)

$ curl 'https://gato.intaa.net/wp-json/wp/v2/posts?__amp_source_origin=https%3A%2F%2Fgato.intaa.net' -I -H 'origin: https://gato-intaa-net.cdn.ampproject.org'
HTTP/2 200 
server: nginx
date: Tue, 12 Feb 2019 01:41:05 GMT
content-type: application/json; charset=UTF-8
amp-access-control-allow-source-origin: https://gato.intaa.net
x-robots-tag: noindex
x-content-type-options: nosniff
access-control-expose-headers: X-WP-Total, X-WP-TotalPages
access-control-allow-headers: Authorization, Content-Type
x-wp-total: 573
x-wp-totalpages: 58
link: <https://gato.intaa.net/wp-json/wp/v2/posts?page=2>; rel="next"
allow: GET
access-control-allow-origin: https://gato-intaa-net.cdn.ampproject.org
access-control-allow-methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
access-control-allow-credentials: true
vary: Origin
strict-transport-security: max-age=31536000;
x-content-type-options: nosniff always
content-security-policy: default-src * 'self' data: 'unsafe-inline' 'unsafe-eval';

access-control-allow-originヘッダは1行だけになった。

AMPプラグインのCORS 3
「最新の投稿」のリスト自体はAMPキャッシュではない(そのためのamp-list + REST API化)ので結果はAMPページの再キャッシュ化を待つまでもなくすぐに確認できる。無事にリストが表示できるようになった。

対処は簡単だったけど、CORSは面倒で油断できない。