それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

aptで入れたcertbot にhttpd 壊されたので注意のために記事書いた

証明書の管理をcertbot にまかせていました。

lets encrypt が一般化し、ChromeHTTPSを標準化してHSTSを覚えるようになってきて、HTTPS化の流れは避けられない。

さらにあれから2年がたつ、以前はcertbot が手軽に使えるので、証明書の管理に使ってた。

certbot のインストールと証明書の取得。

インストール

sudo  apt install certbot

取得

sudo certbot  certonly  -d takuya.example.com

nginx と apache2 がダウンする事態が発生。

こうやって運用を初めて2ヶ月たった、ある日、apacheが死んでることが発覚。すぐに再起動して事なきを得た。 しかし、数時間後に再びダウンする。エラーログを調べてもわからない。

nginxに切替えてみた。しかし再び毎日ダウンする自体になり頭を抱えていた。

apt で入れたcertbot はサービスを伴う。

攻撃でも食らってるのかとDoSを疑ったり、アクセスログやサーバーのログを調べているうちに気付いた。

これ certbot が自動更新で落ちてる。。。。

disableをして事なきを得た

takuya@:~$ sudo systemctl  disable   certbot.service
takuya@:~$ sudo systemctl  disable  certbot.timer

systemd に登録された certbot のサービス

certbot を apt で入れた場合に、次の自動更新のサービスが展開される。

そう、certbotのせいだった。

この自動更新の動作が、apache/nginxを停止し、証明書の更新用に起動して失敗して放置し、そのままnginx/ apache が停止したままになるのだ。

それも数時間おきに。

takuya@:~$ sudo systemctl  status  certbot.timer
● certbot.timer - Run certbot twice daily
   Loaded: loaded (/lib/systemd/system/certbot.timer; disabled; vendor preset: enabled)
   Active: active (waiting) since Tue 2018-05-01 13:17:46 JST; 2 days ago
takuya@:~$ sudo systemctl  status  certbot.service
● certbot.service - Certbot
   Loaded: loaded (/lib/systemd/system/certbot.service; static; vendor preset: enabled)
   Active: inactive (dead) since Thu 2018-05-03 12:19:42 JST; 6h ago
     Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
           https://letsencrypt.readthedocs.io/en/latest/
  Process: 30575 ExecStart=/usr/bin/certbot -q renew (code=exited, status=0/SUCCESS)
 Main PID: 30575 (code=exited, status=0/SUCCESS)
      CPU: 545ms

 5月 03 12:19:41 myhost systemd[1]: Starting Certbot...
 5月 03 12:19:42 myhost systemd[1]: Started Certbot.

しかし、certbotは80/443 に直接アクセスが出来ない。

私はiptables でポートを変えててマッピングしてたり、リバースプロキシを挟んでいるので、certbot の自動更新は動作しない。

そのために、毎月手作業で更新していたのだが、それすらめんどくさくなってCDNHTTPSを利用している。つまりcertbot はインストールしたまま放置してたのだ。

そして、事件は起きてしまった。

certbot が証明書を自動更新しようとしてapache/nginxの設定を書き換えて死んでいく。

そのためにHTTPのアクセスはHTTPSにリダイレクトされるようにされているしもうめちゃくちゃ。。

apt の certbot は怖い。

  • http → httpsのリダイレクトを書き加えられる
  • certbot の sytemd タイマーが定期的に動作してくる
  • certbothttpd のプロセスを利用して更新を試み失敗したまま放置

割と面倒くさい。

自動更新が動作しない環境であれば、certbot を apt で入れるべきではないのかもしれない。

2018-07-23 追加

https のサービスをいったん止めて再起動させればいい感じかもしれない

/lib/systemd/system/certbot.timer  にタイマーの記述

takuya@:~$ cat  /lib/systemd/system/certbot.timer
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target

/lib/systemd/system/certbot.service にコマンドの記述

takuya@:~$ cat  /lib/systemd/system/certbot.service
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
#ExecStart=/usr/bin/certbot -q renew
ExecStart=certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"
PrivateTmp=true

systemdを再設定 .

sudo systemctl daemon-reload
sudo systemctl  status  certbot.service
sudo systemctl  status  certbot.timer

sudo systemctl  start certbot.service

sudo systemctl  status  certbot.service
sudo systemctl  status  certbot.timer

しばらく様子を見る

2018-08-07

crontab にした

* */12 * * * bash -c ' { systemctl stop apache2 nginx ; certbot -q renew; systemctl start apache2 nginx; }'

2018-08-07 systemd の記述を修正

reload の順番がおかしかったので修正

grep でシンボリック・リンクのファイルとディレクトリを無視する

grepすると終わらねぇ

遭遇した問題 。Grepでファイルを検索したら再帰的に無限ループになって検索が終わらない。

ディレクトリのリンクをたどってそれがまた次のディレクトリをたどって、永遠にループする。

シンボリック・リンクを無視する

どうすればいいか。ぐぐってみたら

grep -r を使う

これを書くことでリンクを辿らなくなる。マジカ

再帰的に検索。

man には書いてない。。。

       -R, -r, --recursive
              各ディレクトリの下にあるすべてのファイルを再帰的に読み込みます。 これは -d recurse オプションと等価です。

UbuntuLinux man-JP を読んでも書いてないんだけど.

GNU の最新版のman をんだら書いてあった

       -R, --dereference-recursive
              Read all files under each directory, recursively.  Follow all symbolic links, unlike -r.

       -r, --recursive
              Read all files under each directory, recursively, following symbolic links only if they are on
              the command line.  Note that if no file operand is given, grep searches the working directory.
              This is equivalent to the -d recurse option.

日本語man信用できない

参考資料

https://stackoverflow.com/questions/21738574/how-do-you-exclude-symlinks-in-a-grep

正規表現あと読みと grep -o の組合せで強い文字列の抜き出しができる

正規表現にはあと読みの条件付きマッチの書式がある。

(?<=:)expression

このあと読みの条件マッチを使うことで、○○のあとの△のような文字をダイレクトに抜き出すことが可能になり、コマンドと組み合わせると非常に強いクカを得ることができる。

正規表現のあと読みをgrep で使うことが出来る。

この名前付きのマッチングをgrep で使うと便利そうなので、調べてみたら 私の使ってるgrep は対応してたので、実例を残すことにした。

grep を使った文字列の抜き出し

grepをつかってマッチした文字列をダイレクトに抜き出すことが出来ます。 その際に、マッチする箇所を限定することが出来て便利です。

grep -Poで抜き出し

たとえば、A のあとに続くIPアドレスが欲しい時

$ dig t.co | \grep -Po "A\s+\d.+$"
A    104.244.42.133
A    104.244.42.5
A    104.244.42.197
A    104.244.42.69

A も含めてIPアドレスが取れてしまう。

これを条件マッチでやると

正規表現を「 lookbehind assertion」(後置参照)に変えることで、きっちりマッチする。

$ dig t.co | \grep -Po "(?<=A\s)\d.+$"
104.244.42.133
104.244.42.5
104.244.42.197
104.244.42.69

lookbehind assertionは、正規表現に〇〇に続く△でこの場合は「Aのあとにある数字から始まる文字列」を指定している。

正規表現の条件で絞っている。

そのため名前付きマッチだとか正規表現の後方参照で $0 を取り出す必要もない。

面倒なことが少し減っている。

他にもこのようなことに使える。

takuya@~$ sudo networksetup  -getairportpower en0
Wi-Fi Power (en0): On

この結果からen0のあとの ONだけを取出したい。

takuya@~$ sudo networksetup  -getairportpower en0  | env grep -Po '(?<=:)\s?\w+$'
 On

Macアドレスをコマンドの結果から取得したり。

takuya@~$ ifconfig en0 | env  grep -Po  '(?<=ether\s).+'
60:03:08:a1:82:0c

IPアドレスをしっかり抜き出したり。

takuya@~$ ifconfig en0 | env  grep -Po  '(?<=inet\s)[0-9\.]+'
172.24.49.119

慣れると便利。

慣れてくると割と便利に使うことが出来る。この文字の「ココだけが」ほしいんだけどなぁっていうときに、文字列が取れすぎるとか、絞り込めないときに知っておくと最後の一歩をすることが出来る。

今回つかった grepGNUのパッケージです。

takuya@work$ /Users/takuya/.bin/grep -V
grep (GNU grep) 3.1
Packaged by Homebrew
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

一般的なLinuxなパッケージにも含まれています。 Linuxディストーションによっては、grep はalias されている場合があります。そのためalias があると上手く動かなったりするので、alias を解除してから試す必要があります。

参考資料

今回はこの書籍から正規表現を学びました。

反復学習ソフト付き 正規表現書き方ドリル (WEB+DB PRESS plus)

反復学習ソフト付き 正規表現書き方ドリル (WEB+DB PRESS plus)