とーますメモ

Ruby on Rails / Goなどの学習メモ

【cron】改めてcronの設定方法について勉強し直してみた

今までなんとなく使ってきたが
以下の4つのパターンで設定することができるらしく
何が違うのかはっきりさせたかったので、学習し直すことにした。

1)/etc/cron.(daily|weekly|monthly)/内に設定する方法
2)crontabコマンドで設定する方法
3)/etc/crontabで設定する方法
4)/etc/cron.d/内に設定する方法

先に結論

/etc/corn.d/内に拡張子なしのテキストファイルを置く。
例)/etc/cron.d/test_cron

文法は以下

*[Space]*[Tab]*[Space]*[Space]*[Tab]root[Tab]Commands   

テンプレート

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
# 分 時 日 月 曜日 ユーザー コマンド

# 1分ごと
* *    * * *  root   touch /home/ubuntu/test.txt

# 1:00〜1:59まで1分ずつ実行
* 1    * * *  root   touch /home/ubuntu/test.txt

# 毎日1:00に実行
0 1    * * *  root   touch /home/ubuntu/test.txt

# 毎月12日~20日00:00に実行
0 0    12-20 * *  root   touch /home/ubuntu/test.txt

# 毎週月曜日〜金曜日00:00に実行
0 0    * * 1-5  root   touch /home/ubuntu/test.txt

17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

前提知識

cronとは?

cronは指定日時にジョブの自動実行を行うジョブスケジューラです。UNIX系のOSであれば実装の違いこそあれ,ほぼ標準でインストールされています。

by 第25回 cron周りのベストプラクティス(1):Perl Hackers Hub|gihyo.jp … 技術評論社

cronの用途

cronの使い途は,主に次の3つが考えられます。

a.アプリケーションのジョブの実行
b.システムに関わるジョブの実行
c.監視用途
a.はアプリケーションで定期的に実行したいジョブの実行です。たとえばランキングの更新処理などの用途です。b.はログのローテートやバックアップなどの用途です。c.の用途は少し意外に感じられるかもしれませんが,毎分確実に実行されることを利用して,簡易な死活監視などに利用するといった用途があります。

by 第25回 cron周りのベストプラクティス(1):Perl Hackers Hub|gihyo.jp … 技術評論社

タイムゾーンの設定

Ubuntu 18.04のデフォルトは、UTCになっていた。

Tips:

タイムゾーンは crond の起動時にのみ実行環境に設定されている値を取得しています
起動後にはタイムゾーンの更新は行われないので crond の起動後にタイムゾーンを変更しても変更前のタイムゾーンのまま動作します

cron の意外な落とし穴! - もろず blog

このためタイムゾーンを更新したら、必ずcrondを再起動すること

$ sudo service cron restart

確認コマンド

$ timedatectl
Local time: Wed 2020-03-04 17:16:21 UTC
Universal time: Wed 2020-03-04 17:16:21 UTC
RTC time: Wed 2020-03-04 17:16:22
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
systemd-timesyncd.service active: yes
RTC in local TZ: no

なので、タイムゾーンを直す。
タイムゾーン名一覧は以下
List of tz database time zones - Wikipedia

例)Asia/Tokyo
$ timedatectl set-timezone Asia/Tokyo
$ timedatectl
Local time: Thu 2020-03-05 02:28:08 JST
Universal time: Wed 2020-03-04 17:28:08 UTC
RTC time: Wed 2020-03-04 17:28:09
Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
systemd-timesyncd.service active: yes
RTC in local TZ: no

ログ出力設定(Ubuntuの場合)

以下記事を参考
[ubuntu] cronのログが出力されない時の対処方法 | BlueBear I/O

cronのログは、将来的に問題が発生した場合などの原因究明に役に立つので有効化しておく。
ログの出力されていない場合は、以下のように変更

/etc/rsyslog.d/50-default.confを編集

$ vi /etc/rsyslog.d/50-default.conf


cronログ設定のコメントを外す。

-#cron.* /var/log/cron.log
+cron.* /var/log/cron.log

rsyslogの再起動

$ service rsyslog restart

crondの起動及び確認方法

Ubuntuの場合は以下。

確認

$ service cron status

停止

$ service cron stop

起動

$ service cron start

[参考]
Linux Start Restart and Stop The Cron or Crond Service - nixCraft

1)/etc/cron.(hourly|daily|weekly|monthly)/内に設定する方法

実行時間は「/etc/crontab」で設定されている。
※CentOS6であれば「/etc/anacrontab」

/etc/crontabの中身例

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
# 分 時 日 月 曜日 ユーザー コマンド
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

文法は以下

*[Space]*[Tab]*[Space]*[Space]*[Tab]root[Tab]Commands   

スクリプトの実行時間に対して、厳密な時間に実行するなどのルールが
なければ、任意のディレクトリに実行ファイルを入れておけば
勝手に実行されるのでこの方法が一番簡単。

2)crontabコマンドで設定する方法

この方法でcronを設定する場合は、crontabコマンドを使用する。
主に使用するコマンドは
「crontab -l」:設定内容の確認
「crontab -e]:設定の編集

まずは「crontab -e」でcron設定を行うためのエディタを設定

$ vi ~/.bashrc

デフォルトエディタをvimに設定する例

$ export EDITOR=vim
$ source ~/.bashrc

設定を行うとユーザ毎に/var/spool/cron/crontabs/[username]というファイルが作成される。
このファイルは直接編集することは推奨されていないので
編集するときは必ず「crontab -e」を使用する。

書式は左から、[分] [時] [日] [月] [曜日] [コマンド]

5分おきにfuga.shを実行する例

*/5 * * * * /home/hoge/fuga.sh
  • 分は0~59の数字で指定
  • 時は0~23の数字で指定
  • 日は1~31の数字で指定
  • 月は1~12の数字で指定
  • 曜日に関しても数字で指定し、0と7が日曜日、1以降は順に、月、火、水、木、金、土となる
  • コマンドは、設定ファイルでパスを通していないものに関してはフルパスで指定するかカレントディレクトリからの相対パスで指定しなければならない。

※各cronのジョブが実行される際のカレントディレクトリは,ユーザのホームディレクトリ。

時間の書き方例

43 23 * * * 23:43に実行
12 05 * * *    05:12に実行
0 17 * * * 17:00に実行
0 17 * * 1 毎週月曜の 17:00に実行
0,10 17 * * 0,2,3 毎週日,火,水曜の 17:00と 17:10に実行
0-10 17 1 * * 毎月 1日の 17:00から17:10まで 1分毎に実行
0 0 1,15 * 1 毎月 1日と 15日と 月曜日の 0:00に実行
42 4 1 * *     毎月 1日の 4:42分に実行
0 21 * * 1-6   月曜日から土曜まで 21:00に実行
0,10,20,30,40,50 * * * * 10分おきに実行
*/10 * * * *        10分おきに実行
* 1 * * *         1:00から 1:59まで 1分おきに実行
0 1 * * *         1:00に実行
0 */1 * * *        毎時 0分に 1時間おきに実行
0 * * * *         毎時 0分に 1時間おきに実行
2 8-20/3 * * *      8:02,11:02,14:02,17:02,20:02に実行
30 5 1,15 * *       1日と 15日の 5:30に実行

※ちなみに全部 * だと毎分実行される。e

by クーロン(cron)をさわってみるお - Qiita

間違いやすい例としては
例えば毎朝5時ちょうどにバックアップを走らせたいというような場合。

○:間違った設定

* 5 * * * /path/to/backup.sh

○:正しい設定

0 5 * * * /path/to/backup.sh

間違った設定をしてしまうと、毎朝5時台の1分毎にバックアップ処理が走ってしまう。

3)/etc/crontabで設定する方法

基本的には2)の方法と同じ書式で設定が可能だが、
あまりこのファイルを直接編集することは推奨されていない。

4)/etc/cron.d/内に設定する方法

ちなみに、「/etc/cron.d/」は
インストールされたパッケージ専用ディレクトリらしいので、
いじる必要なさそう。

by /etc/cron.monthly/ と crontabコマンド の違い - pospomeのプログラミング日記

上記参考記事のような意見もあるが
この方法を使用すると、以降で説明する「crontab -r」で設定を吹き飛ばしてしまう心配がなくなる。

設定する場合は、crontabコマンドの書式と違い、以下のように「ユーザ」を指定する必要がある。
書式は左から、[分] [時] [日] [月] [曜日][ユーザ][コマンド]

5分おきにfuga.shを実行する例

*/5 * * * * root /home/hoge/fuga.sh

またこの方法を使用した場合、複数ファイルに分けて管理ができるため
プロジェクト毎だったり、担当者毎だったりとファイルを分けられることはありがたい。

「crontab -r」対策

詳細は以下ページから参照
crontab -e は「絶対に」使ってはいけない - ろば電子が詰まつてゐる

crontabコマンドには「crontab -r」という一発で全ての設定を消してしまうコマンドがあるため
ミスタイプしてしまうと悲惨なことになる。(eとrは隣同士なので間違えるか可能性が比較的高い)
それを避けるために、は以下のような方法がある。

crontabを使用せず/etc/cron.d/内で設定する方法を使用する

上記でも紹介しているので説明は省略

「crontab ファイル名」で、ファイル内の設定をcrontabに反映する

ところで,crontab -eでのcrontabの直接編集は実は好ましくありません。crontab -rによるcrontab全消去のオペレーションミスがたびたび話題になります。実はcrontab とファイル指定することで,その内容をcrontabに反映できます。そして,このファイルをリポジトリ管理するのがベストプラクティスです。

by 第25回 cron周りのベストプラクティス(1):Perl Hackers Hub|gihyo.jp … 技術評論社

crontab -eで設定することは禁止して、常にこの形式で行うことにすれば、-eオプションを付けることが無いわけだから-r事故も起こらない。この場合、~/etc/crontab とか作っておいて、それを読み込ませる、とすると良いだろう。

by crontab -e は「絶対に」使ってはいけない - ろば電子が詰まつてゐる

「crontab -l」後に「crontab -e」を行う

こうすることで、スクリーンログを残しておけば、
何かあったときにサルベージできる。
※ iTerm2を使用しているはデフォルトではログは残さない設定になっているので、別途設定が必要

「crontab -l > /path/file/to」でバックアップを作成後、「crontab -e」を行う。

シンプルな方法。

「crontab -e」にエイリアスを付ける

alias cronedit='crontab -e' 

またはcrontabをエイリアスにする

alias crontab='crontab -i'

「/var/spool/cron/crontabs/」内をgitで管理する

$ cd /var/spool/cron/crontab/
$ git init
$ git add root
$ git commit -m "initial commit"

誤って消してしまったら

$ git reset --hard HEAD^

間違えて消してしまったら・・・

「/var/log/cron」から復旧する方法があります。

詳しくはこちらのページより参照
crontab -r とやってしまった時の対処法

結論

長々と書いたが個人的には「cron.d」ディレクトリ内にファイル入れる方法が
一番手順が少なく、間違って消してしまうこともないので良いと思う。
パッケージ用のcronファイルと混ざるのが、少し嫌だが
うまくネーミングを付けて管理すれば、あまり気にならないだろうし。

名称付の例
ex) [プロジェクト名]_[ユーザ名]_[機能名]


[参考]
cron の設定ガイド
第25回 cron周りのベストプラクティス(1):Perl Hackers Hub|gihyo.jp … 技術評論社
cron 設定ファイル (crontab ファイル) の置き場所と書式について - ひだまりソケットは壊れない
crontab -e は「絶対に」使ってはいけない - ろば電子が詰まつてゐる
/etc/cron.monthly/ と crontabコマンド の違い - pospomeのプログラミング日記
クーロン(cron)をさわってみるお - Qiita
[ubuntu] cronのログが出力されない時の対処方法 | BlueBear I/O
gitによるcron設定ファイルの管理と実行 - NaN NaN da
【Linux】crontabとcron.dの違い | naoのブログ

【SSH】ログイン時にSlackに通知する

下記のサイトさんのやり方を参考に作成
[Linux]SSHログイン時にメール/Slackで通知する – 備忘録の覚書

以下の"XXX.XXX.XXX.XXX"箇所は信頼できるIPを設定
半角スペースを入れることで複数指定可能。
e.g.) "XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY"

{{ slack_login_alert_webhook_url }}にはSlackのwebhook URLを設定。

#!/bin/bash

SOURCE_IP=${SSH_CLIENT%% *}
# 信頼するIPを指定
TRUST_IP_LIST="XXX.XXX.XXX.XXX"

# リストと比較して信頼していないIPからのアクセスならSlackに通知
for HOST in $TRUST_IP_LIST
do
  if [ $HOST == $SOURCE_IP ]; then
    exit 0
  fi
done

url="{{ slack_login_alert_webhook_url }}"

readonly USER=`whoami`
readonly HOST=`hostname`

ip=`who | awk '{print $6}' | cut -d '(' -f 2 | sed -e 's/)//g'`
user=`w -hsi | awk '{print $1}'`
day=`lastlog | grep -w "${USER}" | awk '{print $4}'`
month=`lastlog | grep -w "${USER}" | awk '{print $5}'`
date=`lastlog | grep -w "${USER}" | awk '{print $6}'`
time=`lastlog | grep -w "${USER}" | awk '{print $7}'`

payload="payload={
  \"attachments\": [
    {
      \"color\": \"#36a64f\",
            \"title\": \"'${USER}': SSH Connection has established.\",
      \"fallback\": \"'${USER}': SSH Connection has established.\",
      \"fields\": [
        {
          \"title\": \"HOSTNAME\",
          \"value\": \"${HOST}\",
          \"short\": true
        },
        {
          \"title\": \"Date / Time\",
          \"value\": \"${month} ${date} (${day})  ${time}\",
          \"short\": true
        },
                {
                  \"title\": \"User Name\",
                  \"value\": \"${user}\",
                  \"short\": true
                },
        {
          \"title\": \"from\",
          \"value\": \"${ip}\",
          \"short\": true
        }
      ]
    }
  ]
}"

curl -m 5 --data-urlencode "${payload}" "${url}" > /dev/null 2>&1

【Lynis】[ACCT-9622] プロセス・アカウンティングの設定をする

Enable process accounting [ACCT-9622]
https://cisofy.com/lynis/controls/ACCT-9622/

プロセス・アカウンティングを行うことで
ユーザー自身が自由に編集・削除可能な history とは別で、詳細なコマンド履歴を残すことができるようになる。

ユーザがコマンドを実行しますと、通常は、 シェルのヒストリ機能が履歴を記録してくれると思います。

システムをおかしくしてしまった可能性のあるときや、 だれかが侵入した可能性のあるときなどに、シェルのコマンド履歴をたどることで、 なにを実行して今の状態になったのかを、ある程度推測することができます。

しかし、ヒストリ機能を無効にしたりされたりしますと、 履歴が残らなくなってしまい、途方に暮れてしまうことになります。
また、シェルが記録してくれる履歴は、コマンドの内容だけで、 いつ実行したのかという、時間の情報までは記録してくれません。

また、シェルのヒストリ機能とは別に、ユーザが、 いつどんなコマンドを実行したのか、まるっとログに残しておくことができますと、 不安の種が尽きないシステム管理者にとっては、 非常にありがたい情報となるのではないでしょうか。

by プロセスアカウンティングでコマンド履歴を残す - いますぐ実践! Linuxシステム管理 / Vol.139

またacctを入れることでコマンド履歴以外の履歴も参照できる。詳細は以下で説明。
※Ubuntu上での設定が前提

インストール

$ sudo apt-get install acct

自動起動設定

$ /etc/init.d/acct start
$ /etc/init.d/acct status

コマンド履歴を表示

※コマンド履歴の中身は「/var/log/account/pacct」

コマンド履歴を出力

$ lastcomm

指定したユーザのコマンド履歴を出力

$ lastcomm --user developer

指定したコマンドのコマンド履歴を出力

$ lastcomm --command su

接続時間履歴を表示

総接続時間の表示(時単位)

$ ac
total 1814.03

現在のwtmp(/var/log/wtmp)ファイルから計算している。
wtmpファイル(バイナリ)内には、ログイン及びログアウトの履歴が保存されており、whoやlastコマンドから参照される。

日毎の接続時間

$ ac -d
Sep 17  total        5.23
Sep 18  total       15.20
Sep 24  total        3.21
Sep 25  total        2.27
Sep 26  total        2.64
Sep 27  total        6.19
Oct  1  total        6.41
Oct  3  total        2.42
Oct  4  total        2.52
Oct  5  total        6.11
Oct  8  total       12.98
Oct  9  total       22.65
Oct 11  total       16.18


ユーザ日毎の総接続時間

$ ac -p
root                              1645.18
tecmint                            168.96
total     1814.14

要約情報の表示

$ sa
2       9.86re       0.00cp     2466k   sshd*
8       1.05re       0.00cp     1064k   man
2      10.08re       0.00cp     2562k   sshd
12       0.00re       0.00cp     1298k   psacct
2       0.00re       0.00cp     1575k   troff
14       0.00re       0.00cp      503k   ac
10       0.00re       0.00cp     1264k   psacct*
10       0.00re       0.00cp      466k   consoletype
9       0.00re       0.00cp      509k   sa
8       0.02re       0.00cp      769k   udisks-helper-a
6       0.00re       0.00cp     1057k   touch
6       0.00re       0.00cp      592k   gzip
6       0.00re       0.00cp      465k   accton
4       1.05re       0.00cp     1264k   sh*
4       0.00re       0.00cp     1264k   nroff*
2       1.05re       0.00cp     1264k   sh
2       1.05re       0.00cp     1120k   less
2       0.00re       0.00cp     1346k   groff
2       0.00re       0.00cp     1383k   grotty
2       0.00re       0.00cp     1053k   mktemp
2       0.00re       0.00cp     1030k   iconv
2       0.00re       0.00cp     1023k   rm
2       0.00re       0.00cp     1020k   cat
2       0.00re       0.00cp     1018k   locale
2       0.00re       0.00cp      802k   gtbl
  • 2 is a number of times the command was executed.
  • 9.86re is a “real time” as per wall clock minutes
  • 0.01cp is a sum of system/user time in cpu minutes
  • 2466k is a cpu-time averaged core usage, i.e. 1k units
  • sshd command name

個別ユーザ毎の要約情報の表示

$ sa -u
root       0.00 cpu      465k mem accton
root       0.00 cpu     1057k mem touch
root       0.00 cpu     1298k mem psacct
root       0.00 cpu      466k mem consoletype
root       0.00 cpu     1264k mem psacct           *
root       0.00 cpu     1298k mem psacct
root       0.00 cpu      466k mem consoletype
root       0.00 cpu     1264k mem psacct           *
root       0.00 cpu     1298k mem psacct
root       0.00 cpu      466k mem consoletype
root       0.00 cpu     1264k mem psacct           *
root       0.00 cpu      465k mem accton
root       0.00 cpu     1057k mem touch

コマンドの使用率が入った要約情報

$ sa -c
132  100.00%      24.16re  100.00%       0.01cp  100.00%      923k
2    1.52%       9.86re   40.83%       0.00cp   53.33%     2466k   sshd*
8    6.06%       1.05re    4.34%       0.00cp   20.00%     1064k   man
2    1.52%      10.08re   41.73%       0.00cp   13.33%     2562k   sshd
12    9.09%       0.00re    0.01%       0.00cp    6.67%     1298k   psacct
2    1.52%       0.00re    0.00%       0.00cp    6.67%     1575k   troff
18   13.64%       0.00re    0.00%       0.00cp    0.00%      509k   sa
14   10.61%       0.00re    0.00%       0.00cp    0.00%      503k   ac
10    7.58%       0.00re    0.00%       0.00cp    0.00%     1264k   psacct*
10    7.58%       0.00re    0.00%       0.00cp    0.00%      466k   consoletype
8    6.06%       0.02re    0.07%       0.00cp    0.00%      769k   udisks-helper-a
6    4.55%       0.00re    0.00%       0.00cp    0.00%     1057k   touch
6    4.55%       0.00re    0.00%       0.00cp    0.00%      592k   gzip
6    4.55%       0.00re    0.00%       0.00cp    0.00%      465k   accton
4    3.03%       1.05re    4.34%       0.00cp    0.00%     1264k   sh*
4    3.03%       0.00re    0.00%       0.00cp    0.00%     1264k   nroff*
2    1.52%       1.05re    4.34%       0.00cp    0.00%     1264k   sh
2    1.52%       1.05re    4.34%       0.00cp    0.00%     1120k   less
2    1.52%       0.00re    0.00%       0.00cp    0.00%     1346k   groff
2    1.52%       0.00re    0.00%       0.00cp    0.00%     1383k   grotty
2    1.52%       0.00re    0.00%       0.00cp    0.00%     1053k   mktemp

プロセス・アカウンティングのON/OFF

ON

$ accton on

OFF

$ accton off

ログイン成功履歴

$ last

【Lynis】Suggestionsの項目を無視する方法

以下の記事を参考
How to Perform Security Audits With Lynis on Ubuntu 16.04 | DigitalOcean

設定ファイルを編集

$ vi /etc/lynis/custom.prf

以下は設定例

# Lines starting with "#" are comments
# Skip a test (one per line)

# This will ignore separation of partitions test
skip-test=FILE-6310

# Is Nginx installed?
skip-test=HTTP-6622

# Is Apache installed?
skip-test=HTTP-6702

# Skip checking print-related services
skip-test=PRNT-2307
skip-test=PRNT-2308

# If a test id includes more than one test use this form to ignore a particular test
skip-test=SSH-7408:tcpkeepalive

【Lynis】[BOOT-5122] シングルユーザモードでもログインできなくする

自分用メモ。

以下方法を行うことでデータの損失その他あらゆる不具合、不都合が生じた場合についても、一切の責任を負いません。
あくまでも自己責任でお願いします。

Set a password on GRUB bootloader to prevent altering boot configuration (e.g. boot in single user mode without password) [BOOT-5122]
https://cisofy.com/lynis/controls/BOOT-5122/

パスワードがなくても
ログインできてしまう機能(シングルユーザモードでのログイン)にパスワードをかける。

1)パスワードのハッシュ生成

パスワードを入力し、ハッシュを生成
以下の「grub.pbkdf2.sha512.10000.xxxxxxxx.........」の箇所をコピー

$ grub-mkpasswd-pbkdf2
Enter password:
Reenter password:
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.xxxxxxxx.........

2)設定ファイルの編集

/etc/grub.d/40_customを開く

$ sudo vi /etc/grub.d/40_custom

ファイルの末尾に以下の設定を追記。
superusersの"username"は任意のユーザ名を追加。
password_pbkdf2のusernameはsuperusersのユーザ名と同じものをつける。
また1)で作成したハッシュパスワードをユーザ名の後に半角スペースを入れた後にペーストする。
設定例

set superusers="username"  
password_pbkdf2 username grub.pbkdf2.sha512.10000.xxxxxxxx.........  

3)grubのアップデート

$ sudo update-grub

4)サーバを再起動

これでサーバを再起動すると上記で作成したIDとPW(※ハッシュ文字ではない)の入力が必要になる。
VPSを借りて、SSHでログインしていた場合は、先にWEBコンソールなどでGRUBログインを先にしていないと
SSHでログインできないので注意

[参考]
grub2 - How to password protect Grub menu - Ask Ubuntu
How to Password Protect Ubuntu’s Boot Loader

ドキュメントの追加(書込)と検索(読込)

前回の記事の続き。
thoames.hatenadiary.jp

前準備

その後、プロジェクト用のディレクトリを任意の場所に作成

例)デスクトップにsampleディレクトリを作成

$ cd Desktop
$ mkdir sample

Firebase CLIの設定

$ firebase init

続く画面では、FirestoreとHosting選んで設定を続ける。(ずっとEnterで良い)

Cloud Firestoreの設定

Realtime Databaseの後継バージョンらしいが、まだベータ版。ベータ版でも問題ないならこちらを選択したほうが良いらしい。
Webの管理画面から、[Database]を選択し、データベースを作成する。
作成するには「ロックモード」か「テストモード」かを選ぶ必要があるが、ここでは「テストモード」を選択する。

index.htmlの作成

デフォルトでpublic/index.htmlが生成されているので、
中身を以下に変更。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Sample Chat</title>
</head>
<body>
  <h1>Hello world!</h1>

  <script src="https://www.gstatic.com/firebasejs/5.7.0/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.7.0/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.7.0/firebase-firestore.js"></script>
  <script>
    // Initialize Firebase
    var config = {
      apiKey: "ウェブAPIキー",
      authDomain: "プロジェクトID.firebaseapp.com",
      databaseURL: "https://プロジェクトID.firebaseio.com",
      projectId: "プロジェクトID",
      storageBucket: "プロジェクトID.appspot.com",
      messagingSenderId: "XXXXXXXXXXXXXX"
    };
    firebase.initializeApp(config);
  </script>
</body>
</html>

ちなみにデフォルトのindex.htmlで使用されている「https://www.gstatic.com/firebasejs/5.7.0/firebase.js」を使用していると
以下の警告がコンソールに表示される。

It looks like you're using the development build of the Firebase JS SDK.
When deploying Firebase apps to production, it is advisable to only import
the individual SDK components you intend to use.

For the CDN builds, these are available in the following manner
(replace with the name of a component - i.e. auth, database, etc):

https://www.gstatic.com/firebasejs/5.0.0/firebase-.js

ガイドにも説明があるが要は
プロダクション環境だと、全てが固まっているjsを読み込むのではなく、必要なものを
個別に読み込んだほうが望ましいとのこと。
詳しくはガイド参照。

Firestoreを使ってデータの追加と検索を行う。

追加

以下の記述を内に追加

<button id="add_name">Add</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$(function() {
$('#add_name').on('click', function() {
  var usersCollectionRef = db.collection("users");

  usersCollectionRef.add({
    first: "Ada",
    last: "Lovelace",
    born: 1815
  })
  .then(function(docRef) {
    console.log("Document written with ID: ", docRef.id);
  })
  .catch(function(error) {
    console.error("Error adding document: ", error);
  });
});
});
</script>

index.htmlをブラウザで表示し、「Add」ボタンをクリックすると、データがFirestoreに追加される。

ちなみに最初は以下の記述抜きでコードを書いていたが

  db.settings({
    timestampsInSnapshots: true
  });

以下のエラーが出たため、上記のコードを入れた。

The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the
following code to your app before calling any other Cloud Firestore methods:

取得

取得についての詳細は以下のqiitaを参考にすると良い。

[参考]
Firebase Cloud Firestoreの使い方 - Qiita