本当にどうでもいいメモなどをたまに書く程度。

nginx で SSL Server Test 満点の設定 (2018/07/24)

日付:
タグ:

HiFormance の VPS をぼちぼち実運用に供してみる準備編。

ずっと Apache を (というよりは Apache の ITK MPM を) 愛用してきたのだが、

  • Apache 2.4.27 以降で mod_http2 が prefork MPM で動作しなくなる
  • Debian stretch 収録の Apache は 2.4.25 だが、mod_http2 のパッチバックポートにより 2.4.25 でも mod_http2 が prefork MPM で動作しなくなった
  • (ITK MPM は prefork MPM に依存している)

このため ITK MPM に未来がなくなってきてしまった。

というわけでまだ実運用に供していない環境で nginx を扱ってみることにした。


せっかくなので SSL Server Test で満点をとれる設定を目指してみたい。

まず nginx 自体を Debian 収録バージョンではなく、nginx 公式のリポジトリで mainline を入れる。

% sudo echo 'deb http://nginx.org/packages/mainline/debian/ stretch nginx' > /etc/apt/sources.list.d/nginx.list
% wget https://nginx.org/packages/keys/nginx_signing.key -O - | sudo apt-key add -
% sudo apt update
% sudo apt install nginx

Let's Encrypt の証明書を RSA 4096 bit で作る。

% sudo certbot certonly --agree-tos -n --rsa-key-size 4096 --webroot -w /var/www/html -w webmaster@example.com -d example.com

nginx の SSL まわりの設定。
いつも通りだが、Mozilla SSL Configuration Generator を基本にする。
nginx 1.15.1、OpenSSL 1.1.0f、Modern 設定。

結論からいくと、下記の設定で満点になる。

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	root /var/www/html;
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
	ssl_session_timeout 1d;
	ssl_session_cache shared:SSL:50m;
	ssl_session_tickets off;
	ssl_dhparam /etc/nginx/dhparam.pem;
	ssl_ecdh_curve secp384r1;
	ssl_protocols TLSv1.2;
	ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256';
	ssl_prefer_server_ciphers on;
	add_header Strict-Transport-Security max-age=15768000;
	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 127.0.0.1 valid=300s;
}

(resolver が 127.0.0.1 なのは、私はそこに Unbound を動かしているため)

変更点は次のとおり。

  • ssl_ecdh_curve secp384r1;
  • ssl_ciphers から ECDHE-RSA-AES128-GCM-SHA256、ECDHE-RSA-AES128-SHA256 を除去。

ただしこの設定では、Android 5/6、Windows Phone 8.1 の IE11 からはアクセスできなくなっている。


Mozilla SSL Configuration Generator の出力では ssl_ciphers はこうなっていた。

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

この設定だと SSL Server Test は A+ 100/100/100/90 で、Cipher Strength だけ満点が取れず90点。
Android 4.x 以降でアクセスできる、まずまずまともな対応範囲といえる。

  • ECDHE-RSA-AES128-GCM-SHA256 を削ると、Android 5.x/6.x が NG になる。
  • ECDHE-RSA-AES128-SHA256 も削ると Cipher Strength が満点になるが、Windows Phone 8.1 の IE11 が NG になる。

メモ

  • Mozilla SSL Configuration Generator で Modern 設定の ssl_ciphers はもう全部 ECDHE-* なので、DH 鍵を 4096 bit で生成して ssl_dhparam を書いても意味ないっぽい。
  • ssl_ecdh_curve を指定しないと secp256r1 や x25519 の 256 bit (RSA 3072 bit 相当) になり、Key Exchange が90点になる。
  • 欲張って ssl_ecdh_curve secp521r1; なんてやると Chrome でアクセスできなくなる (Chrome というか BoringSSL が2015年に P-521 対応を削除したため)。ssl_ecdh_curve secp521r1:secp384r1; なら OK。

結論

古い環境の切り捨てがスコアに直結するとはいえ、さすがに Android 5.x/6.x はまだ合計 20% 以上のシェアがあって切り捨てられない。
副作用を考えると、結局 ssl_ciphers は Mozilla SSL Configuration Generator の通りにして A+ 100/100/100/90 で我慢するのが落としどころという感じ。

メモ置き場を Hugo に移行した

日付:

これまでこのメモ置き場は WordPress で運用してきたが、本体もプラグインもしょっちゅうアップデートがあって面倒になったこともあり、Hugo に移行することにした。


wordpress-to-hugo-exporter を使えば楽ができそうだと思ったが、案外そうでもなかった。

  • 動作させるのに PHP の zip extension が必要
    extension=zip.so
    これは結構動作環境を限定すると思う。
  • 出力される .md の frontmatter が YAML。TOML なら良かったのに。しかたないので全部直した。
  • 出力される markdown が汚い
  • さらに当サイトでは電力料金比較表があり、これは WordPress の固定ページとして作ったので、PHP であり静的 HTML ではない。
    しかたないのでこれは Hugo 用の .md (と言いつつ中身はほとんど HTML) を出力するように改造した。
    PHP CLI で実行すれば .md ができる。

WordPress 的な年月日別アーカイブ

WordPress では パーマリンク設定を /%year%/%monthnum%/%day%/%postname%/ にしていた。
この場合、親ディレクトリ (/2018/07/10/) に日別アーカイブ、さらに遡れば月別、年別アーカイブがあった。
この機能は Hugo にはないので、泥臭い形で実装した。

  • 記事は content/post/ 下に
  • contents/archive_yearly/ に年別アーカイブ用ダミーファイルを配置
  • contents/archive_monthly/ に月別アーカイブ用ダミーファイルを配置
  • contents/archive_daily/ に日別アーカイブ用ダミーファイルを配置

config.tomlでパーマリンク設定。
キモは post と archive_* のパーマリンク構造を合わせること。

[permalinks]
post = "/:year/:month/:day/:slug/"
archive_yearly = "/:year/"
archive_monthly = "/:year/:month/"
archive_daily = "/:year/:month/:day/"

次に各アーカイブのテンプレート。私はテーマ下に入れているが、まあ適宜よしなに。

年別
themes/example/layouts/archive_yearly/single.html

{{define "main"}}
{{$archive_year := .Date.Year}}
<h1>{{$archive_year}}年</h1>
<ul>
{{range (where .Site.Pages "Section" "post").ByDate}}
{{if eq .Date.Year $archive_year}}
<li>{{printf "%04d/%02d/%02d" .Date.Year .Date.Month .Date.Day}}<br /><a href="{{.Permalink}}">{{.Title}}</a></li>
{{end}}
{{end}}
</ul>
{{end}}

月別
themes/example/layouts/archive_monthly/single.html

{{define "main"}}
{{$archive_year := .Date.Year}}
{{$archive_month := .Date.Month}}
<h1>{{$archive_year}}年{{printf "%02d" $archive_month}}月</h1>
<ul>
{{range (where .Site.Pages "Section" "post").ByDate}}
{{if eq .Date.Year $archive_year}}{{if eq .Date.Month $archive_month}}
<li>{{printf "%04d/%02d/%02d" .Date.Year .Date.Month .Date.Day}}<br /><a href="{{.Permalink}}">{{.Title}}</a></li>
{{end}}{{end}}
{{end}}
</ul>
{{end}}

日別
themes/example/layouts/archive_daily/single.html

{{define "main"}}
{{$archive_year := .Date.Year}}
{{$archive_month := .Date.Month}}
{{$archive_day := .Date.Day}}
<h1>{{$archive_year}}年{{printf "%02d" $archive_month}}月{{$archive_day}}日</h1>
<ul>
{{range (where .Site.Pages "Section" "post").ByDate}}
{{if eq .Date.Year $archive_year}}{{if eq .Date.Month $archive_month}}{{if eq .Date.Day $archive_day}}
<li><a href="{{.Permalink}}">{{.Title}}</a></li>
{{end}}{{end}}{{end}}
{{end}}
</ul>
{{end}}

これで archive_daily/2018-07-10.md があれば /2018/07/10/index.html に2018年07月10日の記事一覧が出力される。

このダミーファイルも手作業でいちいち作ってたら面倒でかなわないので、自動化する。

content/post/*.md を読んで、

date = "2018-07-10T00:00:00+09:00"

みたいな行を見つけたら、

  • content/archive_yearly/2018.md
  • content/archive_monthly/2018-07.md
  • content/archive_daily/2018-07-10.md

をそれぞれ作成。というもの。

content-src/archives.php

<?php
// make archives

$dir = dirname(dirname(__FILE__)) . '/content/post/';
$archive_yearly = dirname(dirname(__FILE__)) . '/content/archive_yearly';
$archive_monthly = dirname(dirname(__FILE__)) . '/content/archive_monthly';
$archive_daily = dirname(dirname(__FILE__)) . '/content/archive_daily';

cleandir($archive_yearly);
cleandir($archive_monthly);
cleandir($archive_daily);

$dh = opendir($dir);
while(($file = readdir($dh)) != false) {
	if(preg_match('/\.md$/', $file) === 1) {
		$matches = array();
		$str = file_get_contents(sprintf('%s/%s', $dir, $file));
		$array = explode("\n", $str);
		for($i = 0; $i < count($array); $i++) {
			if(preg_match('/date\s*=\s*"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T/', $str, $matches) === 1) {
				file_put_contents(sprintf('%s/%04d.md', $archive_yearly, $matches['year']), sprintf("+++\ndate = \"%04d-01-01T00:00:00+09:00\"\ntitle = \"%04d年\"\n+++\n%04d", $matches['year'], $matches['year'], $matches['year']));
				file_put_contents(sprintf('%s/%04d-%02d.md', $archive_monthly ,$matches['year'], $matches['month']), sprintf("+++\ndate = \"%04d-%02d-01T00:00:00+09:00\"\ntitle = \"%04d年%02d月\"\n+++\n%04d-%02d", $matches['year'], $matches['month'], $matches['year'], $matches['month'], $matches['year'], $matches['month']));
				file_put_contents(sprintf('%s/%04d-%02d-%02d.md', $archive_daily , $matches['year'], $matches['month'], $matches['day']), sprintf("+++\ndate = \"%04d-%02d-%02dT00:00:00+09:00\"\ntitle = \"%04d年%02d月%02d日\"\n+++\n%04d-%02d-%02d", $matches['year'], $matches['month'], $matches['day'], $matches['year'], $matches['month'], $matches['day'], $matches['year'], $matches['month'], $matches['day']));
				break;
			}
		}
	}
}
closedir($dh);



function cleandir($d) {
	if(file_exists($d)) {
		$dh = opendir($d);
		while(($file = readdir($dh)) != false) {
			if(preg_match('/\.md$/', $file) === 1) {
				unlink($d . '/' . $file);
			}
		}
	}
	else {
		mkdir($d);
	}
}

php content-src/archives.php

すると、各アーカイブ用ダミーファイルが生成される。
ここで PHP を使っているのは、すでに電力料金比較表の生成で PHP を使っているから。どうせ1個使ってるんだから PHP に揃えてしまえと。

Hugo を使う場合ほとんどの人が CI を使うだろうし、Netlify ではビルドで PHP を使えるので、まあまあ使い物になるのではないか。

Netlify のビルドコマンド:

php content-src/archives.php; hugo

WordPress では年月日別アーカイブで本文を表示しているが、その点だけは追従していない。
日付とタイトルがあってリンクされればそれで用は済むと思うので。

当サイトは記事数が少ないので問題にならないが、記事数が多い場合は年別アーカイブぐらいにはページネーションを入れた方がいいかも知れない。


Hugo でこういうアーカイブを作る場合、普通はアーカイブ用のタクソノミーを作って list.html で出力するのが大半だと思うが、それでは WordPress 同様の /YYYY/MM/DD/ ではなく /archives/YYYY/MM/DD/ のようなパスになってしまう。
既存サイトを Hugo に移行する場合、パーマリンク構造を変化させずに移行することが重要だと思われるので、年月日別アーカイブのページを single.html で post のパーマリンク構造内に出力する形にした。

電力料金比較表を更新 (2018/06/27)

日付:

実際のページ更新は後日で、今日の時点ではまだローカルでデータを更新しただけ。

修正点:

  • 料金計算テーブルを各社の最新情報に更新。
  • 本サイトが WordPress から Hugo に移行するため、静的 HTML を出力するように変更。
  • 同じ理由で表示する契約容量の変更方法をフォームからタブに変更。
  • 当該契約容量でサービスを提供していない (または新規契約ができない) 事業者について、従来「提供なし」と表示していたが、事業者ごと表示しないことにした。

HiFormance の激安 VPS を契約してみた

日付:
タグ:

HiFormance激安 VPS に飛びついてみた。
今のところめちゃ快適。

カタログスペックはこんな感じ。

  • 11.99 USD / 年
  • vCPU 2コア
  • メモリ 4GB
  • ディスク 20GB (SSD)
  • 月間転送量 4TB
  • 場所 カリフォルニア州ロサンゼルス (ping rtt 110ms 程度)
  • OpenVZ

支払い完了後、即開通。
しかし CPU が古い。Xeon X5650。LET での宣伝投稿に書かれていたのはもっと新しい CPU なのだが。さらにカーネルが古い。2.6 系。
まあこれでもベンチマークはなかなかのもので、特にディスクアクセスがかなり高速。ConoHa 以上の数字が出てる。

LET では「PM くれたら宣伝通りの CPU 積んでるノードに移転するよ」と言っていたので PM すると、HiFormance のサイトでサポートチケット開いてくれとの返事。言われたとおりにすると「今すぐやっちゃっていい?」と来たので「やってくれ」と返すと、その7分後には新ノードの情報が到着。
なかなか対応が早い。

ベンチマーク (スクリプトはこれ) はこんな感じ。

System Info
-----------
Processor       : Intel(R) Xeon(R) CPU E3-1240 v6 @ 3.70GHz
CPU Cores       : 2
Frequency       : 3700.000 MHz
Memory          : 4096 MB
Swap            : 4096 MB
Uptime          : 0:19

OS              : Debian GNU/Linux 9
Arch            : x86_64 (64 Bit)
Kernel          : 4.9.0
Hostname        : ********


Speedtest (IPv4 only)
---------------------
Your public IPv4 is ***.***.***.***

Location                Provider        Speed
CDN                     Cachefly        95.3MB/s

Atlanta, GA, US         Coloat          28.0MB/s
Dallas, TX, US          Softlayer       43.3MB/s
Seattle, WA, US         Softlayer       48.4MB/s
San Jose, CA, US        Softlayer       82.6MB/s
Washington, DC, US      Softlayer       10.5MB/s

Tokyo, Japan            Linode          9.99MB/s
Singapore               Softlayer       8.08MB/s
Taiwan                    Hinet           10.9MB/s

Rotterdam, Netherlands  id3.net         6.17MB/s
Haarlem, Netherlands    Leaseweb        47.8MB/s


Disk Speed
----------
I/O (1st run)   : 942 MB/s
I/O (2nd run)   : 1.2 GB/s
I/O (3rd run)   : 1.0 GB/s
Average I/O     : 314.733 MB/s

(Disk Speed の Averate I/O がおかしいのはスクリプト側の問題で、MB/s だろうが GB/s だろうがとにかく前の数字を足して3で割ったものに「MB/s」をつけてるので)

かなりいい感じ。

DM&P EBOX-3310A-JSK で遊んでみた

日付:

ある意味シンクライアントのような、用途を限った極小 PC といった感じの EBOX。

  • DM&P EBOX-3310A-JSK
  • CPU Vortex86DX 1GHz
  • メモリ DDR2 512MB オンボード
  • ストレージ なし

Vortex86 というマイナー CPU 搭載機を使ってみたくてヤホオクソンで購入。
売り手は何台も所有しているようで、落札履歴を見るといくつも出てくる。

消費電力の小ささが特徴的で、ワットチェッカーで見る限り 10W。昨今のスティック PC ならもっと小さいが、発売時期を考えればかなりのものと言うべきだろう。
比例してというか処理能力はやはり低く、同じ 1GHz でも Via Nano U3500 より体感的に遅い印象がある。
CrystarlMark の数字を見ても、同クロックの VIA C3 に ALU でやや劣り FPU は半分以下といったところ。Atom 230 1.6GHz と比べると ALU は 1/4 以下、FPU は 1/8 以下というスコアなので色々しかたない。
金属筐体で天板がヒートシンクなので、ファンレスでも冷却能力は安心できそうだ。

メーカーサイトでは 600MHz と書かれているが、実際 1GHz で動いている。
メモリはオンボードで増設できない。

ストレージのインターフェイスとしては44ピン IDE ポートがあり、さらに CompactFlash、microSD のスロットがある。
IDE はメスメスケーブルが必要。筐体内のスペースが狭いので、長い方より短い方が向いている。
ヤホオクソンの出品ページでは「2.5インチストレージ内蔵可能」と書かれていたが、内蔵はあまり現実的ではないと思われる。「入った」というより「無理矢理押し込んで入れた」になりそう。mSATA-IDE 変換基板で mSATA SSD を使えることは確認した。
CF、microSD ともに挿入したカードは IDE HDD として認識されブートも可能なので、カードが余っていればその方が手っ取り早い。

Vortex86DX は i586 互換だが i686 非互換で、OS の選択肢は結構限られてくる。
たとえば Debian stretch や Alpine は i686 非互換で NG。64bit なんて当然非対応なので Arch 等も当然 NG。Debian jessie はインストール中にパッケージの展開が失敗したり、Gentoo は emerge が Segmentation fault するといった感じで、全体的に Linux は動作不安定。
またビデオが 1920x1080 に対応していないようで、GUI 使用もあまりうれしくない。
FreeBSD は安定動作したので、これを採用。

現在は事務所のインターネット接続 (J:COM) の死活確認を外からできるようにするためのミニサーバーとして運用中。
ストレージは UMAX の 8GB microSD カード。


(2018/06/29 追記)

11.2-RELEASE が出たので freebsd-update upgrade -r 11.2-RELEASE したけど時間かかりすぎてつらい。晩飯後に実行したけど全然終わらないので途中で寝た。

今更ながら GitLab と BitBucket に登録してみた

日付:

GitHub3年前に登録していたものの、GitLab BitBucket は未登録だった。
当サイトは Hugo に移行する計画があるので、これらも登録してみようと思った次第。
GitHub は Microsoft に買収されたし、他の類似サービスも確保しておけば安泰だというわけ。


どちらも普通に登録完了。

BitBucket には Academic プランがあって、内容的には Standard プラン相当が無料で提供されると考えて良い。
大学のメイルアドレスを登録することで自動的に Free プランから Academic プラン変更される。
大学以外のメイルアドレスでサインアップしていても、設定→一般→メールエイリアスで大学のメイルアドレスを追加するだけ。


静的サイトホスティングとして考えると、やはり GitHub Pages に一日の長がある。

GitLab Pages は SSL 化可能とはいえ、手動で証明書をセットする必要がある。無料で済ませようと思うと、3ヶ月ごとに Let's Encrypt の証明書を手動で調達しなくてはならないわけだ。

BitBucket はカスタムドメインが使用できない。

GitHub Pages は自動的に Let's Encrypt の証明書を調達・更新してくれる。

とはいえ結局、あくまで Git リポジトリとして使い、ホスティングは Netlify を使うのがベストであるように思われる。CI のビルドの早さも含めると。


私は GitHub の Micro プランが無料で使える立場なわけだが、これってどうせプライベートリポジトリ5個までだし、無制限の GitLab や BitBucket は良いぞ……と思っていたが、GitHub も2年前に無制限になったようだった。あんまり使わないので気づかなかった。タハー。

さらば XVM Labs

日付:
タグ:

4年前に契約した XVM Labs の激安 VPS だが、今年2月に終了のお知らせが来た。

終了と言っても突然サービス終了ではなく、契約の更新ができなくなるというもの。
激安 VPS 界隈では「今月末で閉めます」程度はよくある話で、私など業者が夜逃げという事例にも多く出くわしているが、さすがに10年以上継続しているところはしっかりしている。

この契約期間満了がついに到来してしまった。

年 2.99 USD、メモリ 512MB、IPv4 アドレス4個というスペックで、色々実験的な運用をさせてもらった。
その中の一つが Pleroma インスタンス

ありがとう、さようなら。

シンクライアント機 HP t5740 で遊んでみた

日付:

シンクライアント機をふつーの PC みたいに使ってみようシリーズ第4弾。

厳密には t5740 じゃなくて t5740wi Internet Appliance なわけだが、ぶっちゃけ中身は t5740 だし、OS イメージも t5740 のものがそのまま入るしで。

  • hp t5740wi
  • CPU Intel Atom N280 1.66GHz
  • メモリ DDR3 SO-DIMM 2GB x2
  • ストレージ IDE DOM 2GB

t5570t510 よりも幅が狭いので、たぶん2.5インチ SSD は内蔵できないと思われる。

ただ、本機はメモリスロットが2個ある。よりによって 64bit 非対応 CPU 搭載機種に!

t5570 の時と同様、soltec41 氏が mSATA SSD を t5740 の SATA ポートにマウントする変換基板「SOL313-0」を製作されているので購入。
SOL313-0 の動作確認は Transcend TS32GMSA370 で済ませて、AliExpress で一番安い mSATA 32GB SSD を注文。Hually とかいう聞いたことないブランドで、お値段1929円也。

シンクライアント機 WYSE D90D7 で遊んでみた

日付:

シンクライアント機をふつーの PC みたいに使ってみようシリーズ第3弾。

  • WYSE D90D7
  • CPU : AMD G-T48E 1.4GHz (2コア)
  • GPU : RADEON HD 6250 280MHz
  • メモリ : DDR3 SO-DIMM 2GB
  • ストレージ : SATA Half-Slim SSD 4GB
  • OS : Windows Embedded Standard 7

マザーボードには SATA 端子が、マザーボードと水平についている。
普通は垂直のところ、水平だ。しかも SSD がかなり短くないと入らない。
メモリスロットにぶつかったり、背面端子用の基板にぶつかったり。
SATA-mSATA の変換基板、それも mSATA を横向きにする Half-Slim 基板でさえ入らなかった。

SATA-M.2 2242 の変換基板 (これも横向き Half-Slim。600円ぐらい) だけはなんとか入ったので、AliExpress で一番安い M.2 2242 SSD、KingDian の 32GB をつけてみた。2254円也。

iPhone SE 使用開始

日付:

今月末で電波が止まるワイモバイル (旧イーモバイル) の携帯電話を使ってきたのだが、iPhone SE 一括1円という巻き取りで移行した。
届いた iPhone SE はバッテリーが完全に空っぽになっていて、そのため初期設定に少し手間取ることになった。
早い話、時計が盛大にずれているのでそれを直して再起動する必要があった。

それに気づくまでああでもないこうでもないと情報を探し回る羽目に。
初期設定の Apple ID ログインがまずできない。
Safari でアクセスする HTTPS サイトが片っ端から証明書エラー。
iOS 11 にアップグレードすれば直るかと思いきや、そのダウンロードさえもコケる有様。

設定項目を片っ端から見ていると、時計が半年前。諸悪の根源はこいつか!!


昨今の5インチスマートフォンよりやや細身で、片手で使うにはやはりこのサイズが使いやすい。
普段使っている SIM フリー安物 Android 端末 (MVNO) と比べると、確かに iPhone の出来は良い。
前に使ったことがある iPhone 4s の頃と違って、ちゃんとテザリングもできるし。
しかし ATOK Passport に入っているのに iOS 版 ATOK を別途購入しなくてはならないのは Apple のせいで、しかたないから買ったけれども腹立たしい。