multipass で cpu/memory 割当の容量を変える。
multipass get local.sample01.cpus=4 multipass set local.sample01.memory=4GiB
ディスクも変えられるらしい。(試してない)
multipass set local.sample01.disk=10GiB
ディスクは作成時に指定するほうが楽ですからね。
multipass get local.sample01.cpus=4 multipass set local.sample01.memory=4GiB
ディスクも変えられるらしい。(試してない)
multipass set local.sample01.disk=10GiB
ディスクは作成時に指定するほうが楽ですからね。
tar をパイプ経由で、ssh 経由で行い、サーバのファイルを一気に転送する
ssh srv1 'sudo tar cpvf - /var/opt ' | cat - > var-opt.tar
こんな大胆なことをするときは、サーバーのファイルをまるっと取り出したいときなので。
p
をつけて、preserve permission する。
転送量を減らしたいときは、gzip / pigz をする。
ssh srv1 'sudo tar cpvf - /var/opt | pigz -c - ' | cat - > var-opt.tar.gz
パイプってマジで便利ですよね。 確実にやるには、p オプションがいいらしい
複数台のマシンをフルに活用するとかできそうですよね。
ssh srv1 'sudo tar cpvf - /var/opt | ssh srv2 'pigz ... ' | cat - > var-opt.tar.gz
進捗を見たいのなら pv を組み合わせるのがいい。
https://blog.securem.eu/tips%20and%20tricks/2017/10/14/pipe-tar-through-ssh-to-transfer-large-files/
lvm のUSB-HDDの取り外し・取り出し(解放)
usb 接続した、linux のシステムHDDでバックアップを取ったあと、そのまま抜いたらLVMが残るので、ちゃんとLVMをデタッチしてから、USBを取り外す
lv を取り外す
sudo lvchange -an /dev/mapper/mydisk-root
vg を取り外す
sudo vgchange -an my-vg-name
仮に、cryptsetup luksClose
しようとしても、still in use / 使用中
になってCloseできない。USB接続を解除できない。
lvm の認識
sda 8:0 0 477G 0 disk ├─sda1 8:1 0 477M 0 part ├─sda2 8:2 0 477M 0 part └─sda3 8:3 0 476G 0 part └─dm-my9 253:2 0 476G 0 crypt ├─mydisk-root 253:3 0 114.6G 0 lvm ├─mydisk-home 253:4 0 60.5G 0 lvm ├─mydisk-swap 253:5 0 9.3G 0 lvm └─mydisk-cache 253:6 0 130G 0 lvm
取り外し
sudo lvchange -an /dev/mapper/mydisk-root sudo lvchange -an /dev/mapper/mydisk-home sudo lvchange -an /dev/mapper/mydisk-swap sudo lvchange -an /dev/mapper/mydisk-cache
lvm の lv を除去できた。
sda 8:0 0 477G 0 disk ├─sda1 8:1 0 477M 0 part ├─sda2 8:2 0 477M 0 part └─sda3 8:3 0 476G 0 part └─dm-my9 253:2 0 476G 0 crypt
luks を close
sudo cryptsetup luksClose dm-my9
crypt をCloseできた
sda 8:0 0 477G 0 disk ├─sda1 8:1 0 477M 0 part ├─sda2 8:2 0 477M 0 part └─sda3 8:3 0 476G 0 part
rsyslog で リモートからのログ(リモート・ログ)をローテーションする
リモート用に作った設定はこれ
/var/log/remote/*.log { rotate 4 daily missingok notifempty compress compresscmd /usr/bin/pigz compressext .gz delaycompress sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript }
設定の細かい部分は、後半で。
sudo logrotate --debug /etc/logrotate.conf
considering log /var/log/rsyslog/pi-zero.log Creating new state Now: 2022-09-05 21:48 Last rotated at 2022-09-05 21:00 log does not need rotating (log has already been rotated) considering log /var/log/remote/pizero-otg.log
takuya@raspi-ubuntu:~$ sudo systemctl cat logrotate.timer logrotate.service
なるほど、systemd経由で、logrotate が動いていて、oneshot で定期的に実行されるわけだな。
実際の設定例を見ておく
/var/log/syslog /var/log/mail.info /var/log/mail.warn /var/log/mail.err /var/log/mail.log /var/log/daemon.log /var/log/kern.log /var/log/auth.log /var/log/user.log /var/log/lpr.log /var/log/cron.log /var/log/debug /var/log/messages { rotate 4 weekly missingok notifempty compress delaycompress sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript }
これは次のようにログが管理されていて、順番にローテーションする。
ls -l /var/log/*.log* /var/log/alternatives.log /var/log/alternatives.log.1 /var/log/alternatives.log.2.gz /var/log/alternatives.log.3.gz /var/log/alternatives.log.4.gz /var/log/apport.log /var/log/apport.log.1 /var/log/apport.log.2.gz /var/log/auth.log /var/log/auth.log.1 /var/log/auth.log.2.gz /var/log/auth.log.3.gz /var/log/auth.log.4.gz /var/log/boot.log /var/log/boot.log.1 /var/log/cloud-init-output.log /var/log/cloud-init.log /var/log/dpkg.log /var/log/dpkg.log.1 /var/log/dpkg.log.2.gz /var/log/dpkg.log.3.gz /var/log/dpkg.log.4.gz /var/log/dpkg.log.5.gz /var/log/dpkg.log.6.gz /var/log/dpkg.log.7.gz /var/log/fontconfig.log /var/log/kern.log /var/log/kern.log.1 /var/log/kern.log.2.gz /var/log/kern.log.3.gz /var/log/kern.log.4.gz /var/log/ubuntu-advantage-timer.log /var/log/ubuntu-advantage-timer.log.1 /var/log/ubuntu-advantage-timer.log.2.gz /var/log/ubuntu-advantage-timer.log.3.gz /var/log/ubuntu-advantage-timer.log.4.gz /var/log/ubuntu-advantage-timer.log.5.gz /var/log/ubuntu-advantage-timer.log.6.gz /var/log/ubuntu-advantage.log /var/log/ubuntu-advantage.log.1 /var/log/ubuntu-advantage.log.2.gz
### /etc/logrotate.d/rsyslog /var/log/syslog... /var/log/messages { rotate 4 weekly missingok notifempty compress delaycompress sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript }
全体構造
ファイル名(列挙する) ファイル名(列挙する) ファイル名(列挙する) ファイル名(または、ワイルドカード使用可能) ( 設定 )
設定の部分について
{ # 名前 値 rotate 4 }
設定項目について
{ # 世代 rotate 4 # 週次(書き換えサイクル) weekly # ログファイルがない場合は無視 missingok # ログが空なら何もしない notifempty # ローテーションは圧縮する compress # 圧縮は2世代後 delaycompress # この設定で一回だけ呼ばれる。 # 未指定の場合はファイルごとに呼ばれる、 sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript }
などとなっており、べつにログファイルじゃなくてもローテーションしたいものなら何でもローテーションできそうである。たとえば、バックアップを世代別に名前をつけて保存しておくとか。
シンタックスチェックと、動作チェック
sudo logrotate --debug /etc/logrotate.conf
実際に処理を行わず、記述内容に従って処理の予定・計画を表示する。
マニュアルを見れば書いてある。 - man logrotate.conf
ローテーションするものは何でもいい。
ええんかこれ。って思うかもしれないけど。動くんだよねぇ。
仮想マシンのHDDローテーションしてやる。
/var/lib/libvirt/images/d02.qcow2.back { rotate 4 hourly missingok notifempty compress compresscmd /usr/bin/pigz compressext .gz prerotate virsh destroy d02 while [ -n "$(sudo virsh list | grep d02 )" ] ; do sleep 1 ; done cp /var/lib/libvirt/images/d02.qcow2 /var/lib/libvirt/images/d02.qcow2.back virsh start d02 endscript }
ログ・ローテーションで仮想HDDをバックアップ・ローテーション(世代別バックアップ)してみる
sudo logrotate --verbose --force /etc/logrotate.d/xxx-takuya-vm.conf
実行結果
running prerotate script Domain 'd02' is being shutdown Domain 'd02' started renaming /var/lib/libvirt/images/d02.qcow2.back to /var/lib/libvirt/images/d02.qcow2.back.1 compressing log with: /usr/bin/pigz
ファイルが作成された。
takuya@:~$ sudo ls -alt /var/lib/libvirt/images/ 合計 5275416 -rw-r--r-- 1 libvirt-qemu libvirt-qemu 1752039424 9月 5 22:37 d02.qcow2 drwxr-x--x 2 root libvirt-qemu 194 9月 5 22:32 . -rw-r--r-- 1 root root 582343243 9月 5 22:18 d02.qcow2.back.1.gz
なるほど、できなくはない。ログ・ローテーションは本当に最高ですね。
linux にKVMで仮想マシンを突っ込んだだけのときに、定期的にバックアップとって3世代バックアップを取っておいて、ついでにqcow2のメンテナンスとかできそうですね。
logrorotate しかない極限状態でなら役に立ちそう。ふつうの仮想マシンなら、python とかでSystemd Time units を書いたほうが確実だろうね。シャットダウン待ちとかローテーションとか設定を変数にしたいとか、いろいろやりたいことを調べるより、脳死で、書いた方がいい。
https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/747logrotatecmd.html
rsyslog のパケットは、平文で流れる。平文でネットワークを漂うってのは怖い。
現代では、家庭内にGoogleHome やAmazon Alex/FireTVがあり、TP-link製品もあふれている。下手をすると中華世界とつながっていてログ・パケットを覗き見サれているかもしれない。いい気はしない。家庭内ですら機器が溢れてるのだ。暗号化なしでログを流すってのは怖い。
そこで、すぐ使えるCertbotの証明書を使って、Rsyslogの通信を暗号化できないか調べて試してみた。
暗号化通信はできたけど、、RaspberryPiのストレージがアクセスし放題だった。溜まるログがストレージ暗号化されてないので意味がない・・ね。
そのうち、何処か別の場所に、移転する。
証明書を作るのにオレオレCAとか自己署名を作ってもいいけど、管理が面倒なのでLEに任せたい。
certbot / lets encrypt でサクッと作成
export certbot=/usr/bin/certbot export domain=log.example.tld sudo $certbot certonly --dns-cloudflare\ --dns-cloudflare-credentials /etc/letsencrypt/cloudflareapi.cfg \ --cert-name $domain -d $domain
rsyslog がTLSを扱えるパッケージを入れる。
sudo apt-get install rsyslog-openssl
rsyslog-openssl に含まれるファイル
apt-file show rsyslog-openssl rsyslog-openssl: /usr/lib/aarch64-linux-gnu/rsyslog/lmnsd_ossl.so rsyslog-openssl: /usr/share/doc/rsyslog-openssl/NEWS.Debian.gz rsyslog-openssl: /usr/share/doc/rsyslog-openssl/changelog.Debian.gz rsyslog-openssl: /usr/share/doc/rsyslog-openssl/copyright
lmnsd_ossl.so
とあるので、ossl
という名前で参照できることがわかる。
必要なもの - 発行機関の証明書(RootCA) - 自分の証明書(fullchain) - 自分の秘密鍵(privkey.pem)
global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="/etc/ssl/certs/ISRG_Root_X1.pem" DefaultNetstreamDriverCertFile="/etc/letsencrypt/live/log.example.tld/fullchain.pem" DefaultNetstreamDriverKeyFile="/etc/letsencrypt/live/log.example.tld/privkey.pem" )
TCPをロードしている箇所を書き換える。
module(load="imtcp")
ロード時に、OpenSSLの設定入れる。
module( load="imtcp" ## 括弧の中に追記。読みにくいので改行 StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.Authmode="x509/fingerprint" PermittedPeer=["SHA1:31:69:6D:7E:xxxxxx"] )
StreamDriver.Authmode="x509/fingerprint"
は送信元を識別する。
PermittedPeer=["SHA1:31:69:6D:7E:xxxxxx","SHA1:..."]
で送信元の鍵フィンガープリントを使って簡易認証する。
StreamDriver.Name="ossl"
は"ossl"
(たぶんopensslのこと)を指定した。
サーバー側のビフォー・アフター
Server / Before
module(load="imtcp") input(type="imtcp" port="514" address="192.168.1.240" ruleset="remote")
Server / After
## 2022-08-29 global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="/etc/ssl/certs/ISRG_Root_X1.pem" DefaultNetstreamDriverCertFile="/etc/letsencrypt/live/log.example.com/fullchain.pem" DefaultNetstreamDriverKeyFile="/etc/letsencrypt/live/log.example.com/privkey.pem" ) module( load="imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.Authmode="x509/fingerprint" PermittedPeer=["SHA1:31:69:6D:7E:xxxxxx"] ) input(type="imtcp" port="514" address="192.168.1.240" ruleset="remote") module(load="imudp") input(type="imudp" port="514" address="192.168.1.240" ruleset="remote")
送信者の確認に、Fingerprintを使うそうだ。証明書のフィンガープリントをopenssl コマンドで抽出しておく。
PEM_File=/etc/letsencrypt/live/log.example.com/fullchain.pem openssl x509 -in $PEM_File -fingerprint | grep SHA
フィンガープリントがあればなりすましが可能とかそういうことではなく署名と証明書のチェックはもちろん行う。
だろうが、送信者の証明を「受け入れる」かどうかをフィンガープリントで決める。
もし、OSの証明書ストアにLet'sEncryptの証明書がない場合。手作業で持ってくる。
ls /etc/ssl/certs/ISRG_Root_X1.pem || ( curl -LJO https://letsencrypt.org/certs/isrgrootx1.pem mv isrgrootx1.pem /etc/ssl/certs/ISRG_Root_X1.pem )
認証局、発行元がわからないとき(そんなこと起きるはずがないと思うが)
PEM_File=/etc/letsencrypt/live/log.example.com/fullchain.pem sudo openssl x509 -in $PEM_File -text -noout | grep -i issuer Issuer: C = US, O = Let's Encrypt, CN = R3 CA Issuers - URI:http://r3.i.lencr.org/
とりあえず、動けばいいので、Certbotの証明書と秘密鍵をサーバーからクライアントへコピーした。
tar cvzh cert.tgz /etc/letsencrypt/live/log.example.com/ rsync ~/cert.tgz cliet:~/cert.tgz ssh client "tar zxvf cert.tgz" ssh client "rsync -avz ./etc/ /etc/" ssh client "chown -R syslog /etc/letsencrypt/live/log.example.com/"
クライアント側でも同じように証明書と鍵の設定を入れていく。(使いまわし)
global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="/etc/ssl/certs/ISRG_Root_X1.pem" DefaultNetstreamDriverCertFile="/etc/letsencrypt/live/log.example.com/fullchain.pem" DefaultNetstreamDriverKeyFile="/etc/letsencrypt/live/log.example.com/privkey.pem"
ログ送信先に設定を書く
*.* action( type="omfwd" (略) ## 送信先 target="192.168.1.240" Port="514" Protocol="tcp" ## 暗号化設定 StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/fingerprint" StreamDriverPermittedPeers="SHA1:31:69:6D:7E:E0:2xxxxxxxxxx" )
出来上がった設定がこちら。
global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="/etc/ssl/certs/ISRG_Root_X1.pem" DefaultNetstreamDriverCertFile="/etc/letsencrypt/live/log.example.com/fullchain.pem" DefaultNetstreamDriverKeyFile="/etc/letsencrypt/live/log.example.com/privkey.pem" preserveFQDN="off" ) *.* action( type="omfwd" queue.type="LinkedList" queue.filename="raspi-ubuntu_fwd" action.resumeInterval="30" action.resumeRetryCount="-1" queue.spoolDirectory="/var/lib/rsyslog" queue.saveonshutdown="on" target="192.168.1.240" Port="514" Protocol="tcp" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/fingerprint" StreamDriverPermittedPeers="SHA1:31:69:6D:7E:E0:2xxxxxxxxxx" ) }
サーバークライアントの双方を再起動
$ssh server sudo systemctl restart rsyslog $ssh client sudo systemctl restart rsyslog
最初に苦労したエラーがこちら。
9月 05 18:34:38 acid rsyslogd[645709]: unexpected GnuTLS error -12 in nsd_gtls.c:2173: A TLS fatal alert has been received. [v8.2102.0 try https://www.rsyslog.com/e/2078 ]
ossl
ではなく、gtls
設定した場合に出るエラー。gtls でCertbot証明書を使おうとしても無理だった。
MaxSessions="10"
MaxSessionsでTCPのセッション数を絞ってもいいかもしれない
TCPKeepAliveなども設定できる。詳しくはマニュアルに https://rsyslog.readthedocs.io/en/latest/configuration/modules/imtcp.html
暗号化した経路と、被暗号化の経路を2つ作って、見比べてみた。
logger -p syslog.info -t TEST $(printf %05d $RANDOM)." Hello from sender "
暗号化した設定のクライアントのパケットは、パケットキャプチャで読めないことがわかる。
syslog転送は基本的に平文である。
ログに、パスワードなどがうっかり混じる可能性があるので、重要なサーバーのログを転送するときは暗号化をしないとやばいのである。
パケットを暗号化しても、Syslogサーバ(ログ転送先)のストレージが暗号化されてないと、サーバーを物理的に強奪された場合、ログが誰からでも読めてしまう。ログ転送先のストレージの暗号化や侵入対策にも気配りが必要。
ログがあると、自分が何をしていたのか動かぬ証拠になってしまう。というより、どのようなソフトのどのバージョンををどのように使って、どのようなエラーが出てるのかから、侵入者に思わぬ脆弱性を発見されてしまうという危険性につながる。
過去にも、G◯hubがログ転送に平文箇所があり従業員が読める状態でパスワードが保存されてしまっていた。みたいな例があり、ログ転送の設定ミスは後を絶たない。
nginx にプロキシさせるとかですかね。
certbot は特に何もせずに自動更新が入るが、サーバー・クライアントの双方でCertbotを使うのはちょっと手間かもしれない。ローカルに認証局を作成するのもありだったか。
Amazonで購入したSSDなのだが、気づかずにマケプレ商品を買っていた。
故障したので保証申請をしようと思ったが、マケプレです。負けプレイでした。
故障したので泣いた。保証申請もできなかった。
アマゾンに「マケプレ業者に連絡がつかない、連絡先をください」「5年保証の商品タイトルを許しておいて、マケプレに連絡とってくださいとか無罪放免になるのですか」とか、煽ってみたけど、全くダメでした。
マケプレは本当に負けプレにです。
どうして、気づかずにマケプレで買ってしまったんだ、以前の私。そうあの頃はまだCrucialを信じてたんだよ。
AmazonとCrucialを無邪気に信じた私がバカだったので、悔しいのと今後の反省のために、捨てずに残していた。捨てずに残していたのでずっとストレスだった。
たまに、壊れたSSDでも、活用方法がないかと思案していた。初期化後、先頭60GBまでは書き込めるんですよ。それ以上を書き込むとフリーズするからちょっとしたバックアップに使おうかとか、悔しいやらで捨てずに教訓として入り口に飾っていた。
悔しくて飾って放置してたのですが。
ふとみたら、USA経由で交換してもらった人を発見。https://ccie-go.com/crucial-ssd/
なるほど、USAサイトに行けばいいのか。
この手の多国籍企業(Appleとか)は言語設定を変えておかないと、アクセス元リージョン(地域)や言語設定(ロケール)に応じて、該当の国に飛ばされるので、問い合わせができなくなることがあるので、言語設定を変えておいた。
USAのhttps://www.crucial.com/support/contactサポートページからダメ元でメッセージを送りました.
warranty と claim のあたりから、問い合わせフォームを見つけて、S/Nを記入して送付した。
翌日にメッセージがきたではありませんか。
英語でやり取りが続きますが、「商品のS/Nを教えてください。S/N次第でサポート対象の国が決まります」「使用状況を教えてください」「君の型番はディスコンだから、同型品になるけどいいか」「受付番号はこれだよいいかい」みたいな確認事項をやり取りしました。
メッセージに、このメッセージを受け取ってから出来る限り10日以内に送って欲しい。と書いてあったのでUSAのCrucialへEMSで送ることにした。
船便でもいいだろうとおもったけど、生まれて初めての海外への発送だったし、記念にEMSにした。
なお、いま(2022年)はコロナ禍の貨物超過により、USAで貨物が滞留しているので、EMS以外はまじでどこにロストするかわからんから、EMSにしろという郵便窓口から指摘があり、EMSにした。しかもコロナ特別料金と円安により、輸送料金がバカみたいに高かった。(4200円)
郵便窓口の担当者すら「え、嘘だろそんなに高かったけっけ?」と驚いていた。なお、カード払いが可能だったので助かった。
郵便窓口は、なんと中高時代の同級生だったので、他の客の目もあるので、お互い客と係員の役割を演じながら雑談するという高度な遊びをしていた。
郵便窓口でUSAへ荷物を配送するときは、「指定フォーマット」が必要で、WEBにアカウントを作って、そこから禁制品などでないことを明示して送ることになる。手書きや印刷は一切受け付けてくれない。
発送して、14日ほどで、USAのCrucialに到着していた。
そのあと、USAのCrucialのオンライン・ストアからメールが届いた。
Crucialの公式ストアで購入した扱いになるようだ。
まつこと、さらに10日ほど。FedEXで関空に到着し、佐川急便で自宅まで届いた。
交換品が更に壊れた場合どうなるのかなと思ったら、「箱」に「書類」が「貼付」されており、そこに購入証明が入っていた。なるほど。だからオンラインストアから届くのですね。
気づかずに、箱ごと捨てるところだった。「購入証明があるので箱をよく見る」事が大事ですね。
ぶっちゃけ、買い直したほうが安い気もするが、私の送料より、USAからのFedEX送料のほうがずっと高い気もするが、ちゃんと保証を受けられたことが嬉しい。
コロナ禍でなければ、輸送料はもう少し安く済んだだろう点が残念。
だけど、Amazonのマケプレの並行輸入品で絶望してた私に救いの手があったことが嬉しい。悔しくて捨てられなかったnvme ssd が新品になって、我慢して頑張った証として、PCの前に飾られています。(嬉しくてまだ開封してない。)
ちなみに、Crucialのは2020年に壊れました、交換に買ったADATA XPGも壊れました(2021年)、保証申請しました。そして、この夏(2022)はシリコンパワーもASPM(電源まわり)のエラーが出るようになりました。
NVMEってまじで熱に弱いんですね。夏場を超えられない。
頻繁に書き込むのならヒートシンクガン積みでファン積まないとダメかもしれない。
gitlab の初回インストール
データの書き戻し(リストア)やバックアップ(取得)の練習用・実験用に、サクッとGitlabを立ち上げる。
docker 使うより楽だと思う。
multipass 上に作ってみる。
multipass launch --name sample01 -d 20G
multipass shell sample01
sudo apt update && sudo apt upgrade -y
echo -e "APT::Install-Suggests 0;\nAPT::Install-Recommends 0;" | sudo tee /etc/apt/apt.conf.d/00-no-install-recommends
レポジトリ取得元を変える
URL=http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ sudo sed -i.back "s|http://archive.ubuntu.com/ubuntu/\?|${URL}|" /etc/apt/sources.list
プロキシを使ってローカルキャッシュ
echo 'Acquire::HTTP::Proxy "http://192.168.100.5:3142";' |sudo tee /etc/apt/apt.conf.d/01proxy
man なしにして無駄を省略
cat <<EOF > 01-nodoc # Delete locales path-exclude=/usr/share/locale/* # Delete man pages path-exclude=/usr/share/man/* # Delete docs path-exclude=/usr/share/doc/* path-include=/usr/share/doc/*/copyrigh EOF sudo mv 01-nodoc /etc/dpkg/dpkg.cfg.d/01-nodoc
sudo apt update && \ sudo apt-get install -y curl vim-nox
sudo locale-gen --purge "ja_JP.UTF-8" sudo dpkg-reconfigure --frontend noninteractive locales
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl && \ curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash && \ apt update sudo apt install gitlab-ce=15.3.0-ce.0 sudo gitlab-ctl reconfigure # 初期化
インストールが終わったらバックアップの書き戻し練習
バックアップをコピー(小さい場合)
multipass transfer backups-gitlab.tgz sample01:/home/ubuntu/backups-gitlab.tgz
バックアップをマウント(でかい場合)
mkdir backups mv 1662684239_2022_09_09_15.3.3.tar backups multipass stop sample01 multipass mount ./backups sample01:/var/opt/gitlab/backups multipass start sample01
設定をリストア
sudo rsync -av my_gitlab-etc/ /etc/gitlab/ sudo gitlab-ctl reconfigure # DB初期化
バックアップをリストア
NAME=1655916823_2022_06_23_15.0.3 sudo cp 1655916823_2022_06_23_15.0.3_gitlab_backup.tar /var/opt/gitlab/backups/ sudo gitlab-backup restore BACKUP=$NAME # 書き戻し sudo gitlab-ctl reconfigure
バックアップからリストアでうまくいかないときは、gitlab をきれいに消してあげる。
sudo apt purge gitlab ## 完全に消すので注意 sudo rm -rfi /opt/gitlab/ sudo rm -rfi /etc/gitlab/ sudo rm -rfi /var/opt/gitlab/ sudo rm -rfi /var/log/gitlab/
確認
sudo gitlab-backup create STRATEGY=copy
multipass stop sample01 multipass delete sample01 multipass purge
multipass は、lxcとコマンドがほぼ同じ。覚えることが少ない。
また、multipassが動けばあとはおなじになるので、WindowsやMacOSやLinuxでも問題なく使えるのが嬉しい。
gitlab のバックアップ・リストア+ダウングレード・失敗リカバリ
sudo gitlab-ctl backup-etc sudo gitlab-backup create
omnibus gitlab は次の場所にデータを持っている。 - /var/opt/gitlab - /var/log/gitlab - /opt/gitlab - /etc/gitlab
パス | 内容 |
---|---|
/var/opt/gitlab | gitlabのデータ |
/var/opt/gitlab/postgresql | gitlabのデータベース |
/var/opt/gitlab/git-data | gitレポジトリ |
/opt/gitlab | gitlab自体のソース |
/etc/gitlab/gitlab-secrets.json | 暗号化キー |
/etc/gitlab/gitlab.rb | 設定 |
/var/log | ログ関連 |
gitlabのデータ は、レポジトリ・PostgreSQLデータベース、redis 、バックアップ、 LFSなど、ユーザーデータが入ってる。
データベースなどgitlabのデータは暗号化されている。
バックアップも、暗号化された状態が取得されるので、読込には/etc/gitlab
にある暗号化キーが必要になる。
暗号化キーは重要
専用コマンドを使う
sudo gitlab-backup create
バックアップに名前を付ける
sudo gitlab-backup create BACKUP=dump
バックアップは自動生成されることがある。 バックアップの名前は、次のようになっていた。
# タイムスタンプ・日付・gitlabバージョン 1661923506_2022_08_31_15.3.1_gitlab_backup.tar 1661893331_2022_08_31_15.2.2_gitlab_backup.tar
バージョンアップ時など自動バックアップが取られることがある。 自動バックアップはデータベースについて取られる。
レポジトリなどの「git」に関するファイルはバージョンが取られてない。
自動バックアップはレポジトリがなかったりするので、過信は油断と同じ。
次の出力は、私のGitlabのバックアップのいちんだが、ファイルサイズが小さいものが、アップデートに取得されたものである。
ファイルサイズが小さいものをよく見ると、時刻がだいたい近く、同じバージョン名のものがない。 これは、自動アップデートでDBアップデート処理されたタイミングであることを如実に示している。
takuya@:~$ sudo ls -l /var/opt/gitlab/backups/ 合計 4644540 -rw------- 1 git git 1034240 2月 26 2022 1645825437_2022_02_26_14.8.0_gitlab_backup.tar -rw------- 1 git git 1034240 2月 28 2022 1645997098_2022_02_28_14.8.1_gitlab_backup.tar -rw------- 1 git git 1044480 4月 6 06:58 1649195886_2022_04_06_14.8.2_gitlab_backup.tar -rw------- 1 git git 1105920 4月 13 06:32 1649799169_2022_04_13_14.9.2_gitlab_backup.tar -rw------- 1 git git 1105920 4月 23 06:52 1650664328_2022_04_23_14.9.3_gitlab_backup.tar -rw------- 1 git git 1116160 5月 4 06:15 1651612499_2022_05_04_14.10.0_gitlab_backup.tar -rw------- 1 git git 1116160 5月 7 06:18 1651871897_2022_05_07_14.10.1_gitlab_backup.tar -rw------- 1 git git 1116160 5月 21 06:34 1653082489_2022_05_21_14.10.2_gitlab_backup.tar -rw------- 1 git git 1116160 5月 24 06:09 1653340166_2022_05_24_14.10.3_gitlab_backup.tar -rw------- 1 git git 1126400 6月 2 06:50 1654120235_2022_06_02_15.0.0_gitlab_backup.tar -rw------- 1 git git 1126400 6月 7 06:52 1654552318_2022_06_07_15.0.1_gitlab_backup.tar -rw------- 1 git git 1126400 6月 18 06:07 1655500031_2022_06_18_15.0.2_gitlab_backup.tar -rw------- 1 git git 2364784640 6月 23 01:59 1655916823_2022_06_23_15.0.3_gitlab_backup.tar -rw------- 1 git git 1126400 6月 23 23:33 1655994833_2022_06_23_15.0.3_gitlab_backup.tar -rw------- 1 git git 1136640 6月 24 16:38 1656056322_2022_06_24_15.1.0_gitlab_backup.tar -rw------- 1 git git 1157120 7月 2 06:09 1656709755_2022_07_02_15.1.0_gitlab_backup.tar -rw------- 1 git git 1157120 7月 7 06:12 1657141951_2022_07_07_15.1.1_gitlab_backup.tar -rw------- 1 git git 1167360 7月 20 15:55 1658300112_2022_07_20_15.1.2_gitlab_backup.tar -rw------- 1 git git 1177600 7月 23 06:39 1658525990_2022_07_23_15.1.3_gitlab_backup.tar -rw------- 1 git git 1198080 7月 30 06:55 1659131714_2022_07_30_15.2.0_gitlab_backup.tar -rw------- 1 git git 1198080 8月 2 06:50 1659390611_2022_08_02_15.2.1_gitlab_backup.tar -rw------- 1 git git 1239040 8月 24 06:34 1661290448_2022_08_24_15.2.2_gitlab_backup.tar -rw------- 1 git git 1239040 8月 31 06:02 1661893331_2022_08_31_15.2.2_gitlab_backup.tar -rw------- 1 git git 1239040 8月 31 14:25 1661923506_2022_08_31_15.3.1_gitlab_backup.tar -rw------- 1 git git 2364989440 9月 2 14:45 1662097438_2022_09_02_15.3.2_gitlab_backup.tar
バックアップを指定の位置に配置して、リストアコマンド
sudo gitlab-backup restore BACKUP=$NAME
$NAME
のところには、バックアップの名前を付ける。
バックアップは次の箇所にある。
sudo ls -l /var/opt/gitlab/backups/
バックアップの名前は、次のようになっていた。
# タイムスタンプ・日付・gitlabバージョン 1661923506_2022_08_31_15.3.1_gitlab_backup.tar 1661893331_2022_08_31_15.2.2_gitlab_backup.tar
ただし、バージョンが合わないと、だめ。 バージョンを合わせるためにため、ダウングレードが必要
15.2.2 が必要な例
1661893331_2022_08_31_15.2.2_gitlab_backup.tar
apt でやる。
sudo apt remove gitlab sudo apt install gitlab-ce=15.2.2-ce.0 sudo gitlab-ctl reconfigure
https://docs.gitlab.com/ee/update/package/downgrade.html
うっかりpurgeしてしまうと、暗号化キーやレポジトリも消えちゃうかもしれないので注意
ダウングレードの失敗リストアの失敗は、データベースが新しくなってて戻らないことが原因だと思う。
データベースを削除するのが確実
DBだけのバックアップがあれば、DBだけ戻せる。
sudo ls -l /var/opt/gitlab/postgoresql/ sudo mv /var/opt/gitlab/postgoresql{,.bak} sudo gitlab-ctl reconfigure sudo gitlab-ctl restore BACKUP=DB_BACKUP
DBバックアップは、バージョンアップ時に、自動バックアップで生成されてる。
リストアが失敗した場合
ダウングレード+リストアを行う。
データベースを削除して新規インストール、暗号化キー(/etc/gitlab
)を配置して reconfigure
gitのレポジトリ自体も暗号化されているが、データ自体は、リストアにはあまり関係がないので、そのまま。
/var/opt/gitlab/git-data
にレポジトリはある。
でも、暗号化されたデータをバックアップしても使えない。暗号化キーとセットでコマンドを使う。
gitaly-backupを設定しておけば、レポジトリをバックアップを取っておける。
データを取得して、バージョンをあわせてリストア。これでいちおうは問題なさそうですよね。実際試してみたが、それで動いたわ。 ただ、Gitlabの仕様変更で今後もこの手段で行けるとは限らない。
バックアップ
sudo rsync -av /var/log/gitlab/ my_gitlab-var-log/ sudo rsync -av /var/opt/gitlab/ my_gitlab-var-opt/ sudo rsync -av /etc/gitlab/ my_gitlab-etc/ sudo rsync -av /opt/gitlab/ my_gitlab-opt/
初回インストール / gitlab の初回インストール
multipass launch sample01 -d 20G
sudo apt update && sudo apt upgrade -y sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
sudo locale-gen --purge "ja_JP.UTF-8" sudo dpkg-reconfigure --frontend noninteractive locales
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl && \ curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash && \ sudo apt-get install gitlab-ce
書き戻し
## 同じバージョンのgitlabを入れる sudo apt install gitlab-ce=15.2.2-ce.0 ## データ戻し sudo rsync -av my_gitlab-var-log/ /var/log/gitlab/ sudo rsync -av my_gitlab-var-opt/ /var/opt/gitlab/ sudo rsync -av my_gitlab-etc/ /etc/gitlab/ sudo rsync -av my_gitlab-opt/ /opt/gitlab/ sudo gitlab-ctl reconfigure
書き戻し二失敗した場合は、いったん別ホストでRestoreを試す。
バックアップは、けっこうな量になる。
github は強すぎるので、競合はもっと頑張ってほしいと思う。
バックアップが壊れたとき、ユーザーやIssueは諦めてるとしても、ソースコードだけは、バックアップ取ってきたいと思う。暗号化されているので、その点だけには注意したいと思います。
ソースコードのバックアップのためにGitlabを使っている場合、Gitlabは多機能すぎるので、他のソフトウェア(gogs / gitea ) を使ってもいいかもしれないし、ベアレポジトリを選択してもいいと思う。そのgithub/gitlab 本当に必要ですか。バックアップのためのGitlabで、さらにバックアップが煩雑になるのはちょっと違う気がするのです。
小規模事業者なら、mattermost やOAuthプロバイダとして動作するので、Gitlabは特に優秀。ただソースコードを保管したい閲覧したい目的だとGitlabはヘビィすぎる気もする。Gogsでいいんじゃないかと思ってきた。
rsyslog で and , not , or など否定や、和集合(OR)積集合(AND)はどう書くのか
rsyslog で否定
if not ( $msg contains "moby" ) then { *.* action(type="omfwd" ... ) }
if not ( $msg contains "moby" or $msg contains "docker" ) then { *.* action(type="omfwd" ... ) }
if not ( $msg contains "moby" ) and ( not $msg contains "docker" ) then { *.* action(type="omfwd" ... ) }
not と括弧は、not () / ( not cond )
のどちらでも動いた。
docker が大量のログを吐き出す。 docker のログは強烈。mount 系のログは大量になるので、転送しないようにしたい。
docker のログがすごい数。
cat daemon.log | grep -P 'docker|moby' | wc -l 10230
半日でこれですわ。docker のログはキ◯ガイ何じゃないかと思ったり。
rsyslog で rainerscript とlegacy な書き方を混ぜる
以前からの syslog の書き方。
## legacy syntax $template RemoteHost, "/var/log/rsyslog/%hostname%.log" :fromhost-ip, !isequal, "127.0.0.1" -?RemoteHost
テンプレートは、rainerscript で、ログは以前の書き方
template( name="DailyPerHostLogs" type="string" string="/var/log/rsyslog/%hostname%/%$YEAR%-%$MONTH%-%$DAY%-messages.log" ) :fromhost-ip, !isequal, "127.0.0.1" -?DailyPerHostLogs #& ~
こんな感じにも
## hybrid template (name="DynFile" type="string" string="/var/log/system-%HOSTNAME%.log") *.* ?DynFile
DynFileは Dynamic file ( 動的ファイル)として名前をつけたテンプレートですね。
混ぜるな危険ではなく、混ぜても大丈夫っすね。
if ( $programname == "docker-compose" )
例
if ( $programname == "docker-compose" ) then { *.* action(type="omfwd" target="192.168.112.11" Port="514" Protocol="tcp" ) }
if ( msg contains "docker" ) then { ... }
rsyslog Properties — rsyslog 8.18.0.master documentationをみると、いろいととありそう。
使うのは、msg/rawmsg/programname ぐらいかな。 - msg - rawmsg - rawmsg-after-pri - hostname - source - fromhost - fromhost-ip - syslogtag - programname - pri - pri-text - iut - syslogfacility - syslogfacility-text - syslogseverity - syslogseverity-text - syslogpriority - syslogpriority-text - timegenerated - timereported - timestamp - protocol-version - structured-data - app-name - procid - msgid - inputname - $bom - $myhostname - $myhostname - $now - $year - $month - $day - $hour - $hhour - $qhour - $minute
rsyslog でログを受信する
module(load="imtcp") input(type="imtcp" port="514")
module(load="imudp") input(type="imudp" port="514")
module(load="imtcp") input(type="imtcp" port="514") module(load="imudp") input(type="imudp" port="514")
module(load="imtcp") input(type="imtcp" port="514" address="192.168.2.240")
$AllowedSender TCP ,127.0.0.1, 192.168.142.0/24 $AllowedSender UDP ,127.0.0.1, 192.168.142.0/24
module(load="imtcp") input(type="imtcp" port="514" address="192.168.1.11" ruleset="remote") ## template template ( name="RemoteHostR" type="string" string="/var/log/rsyslog/%hostname%.log" ) ## log file ruleset(name="remote") { *.* action(type="omfile" dynafile="RemoteHost" name="save_remote") }
sudo rsyslogd -N 1
特定のファイルだけ調べたいとき(あまり使わない。)
sudo rsyslogd -N 1 -f /etc/rsyslog.d/99-takuya.conf
書いたらシンタックスがOKなら、再起動する。
sudo systemctl restart rsyslog
送信元からログをテスト送信する。
ssh sender-machine sender$ logger -p syslog.info -t TEST $(printf %05d $RANDOM)." Hello from $HOST b "
ログが受信されるのを確認する。
rsyslog$ tail -f /var/log/rsyslog/sender.log Sep 2 23:35:36 acid TEST: 23680. Hello from sender Sep 2 23:35:36 acid TEST: 05423. Hello from sender Sep 2 23:35:37 acid TEST: 00688. Hello from sender Sep 2 23:35:37 acid TEST: 17254. Hello from sender Sep 2 23:35:38 acid TEST: 19391. Hello from sender Sep 2 23:35:38 acid TEST: 29833. Hello from sender Sep 2 23:35:39 acid TEST: 00841. Hello from sender Sep 2 23:35:39 acid TEST: 02411. Hello from sender Sep 2 23:35:39 acid TEST: 23659. Hello from sender
これで、無事にログが別のサーバーに転送される。
今回のような単純な例ではrulesetを使用した意味が無いように見えるが、重要な役割がrulesetにある。
それは、混線の防止である。 旧来のrsyslogでは、受信logと手元のlogが一度統合され、そこからフィルターを駆使して受信ファイルを抽出していた。 しかし、rulesetを用いるとinputにて手に入れたlogはそのrulesetで処理され、外部に漏れることは無い。そして、その逆に手元のlogが別のrulesetから見えることも無い。 https://qiita.com/forno/items/0df30fa3dc055da61c7d
受信したログが、交じるので、交じる前に仕分ける。
input(type="imudp" port="514" ruleset="remote") ruleset(name="remote"){ action(type="omfile" file="/var/log/remote.log") }
なにもしないと混じる
rsyslog -> input -> tcp -> 交じる -> filter -> /var/log/message
ルールセットにしてルール化する。
## 混じらない rsyslog -> input -> tcp -> ruleset -> filter -> /var/log/remote
ログの受信設定を書くときは、受信設定を書いた方がいい。
たとえば、次のようにローカルと他ホスト受信をif で分けたとしても、いったん全部まとめてから指定マッチだけを別ファイルに書き出しているので、/var/log/message,syslog に両方出てしまうのです。
# 略 auth,authpriv.* /var/log/auth.log *.*;auth,authpriv.none -/var/log/syslog # ←すでに混じってる。 #auth,authpriv.none -/var/log/syslog #cron.* /var/log/cron.log #daemon.* -/var/log/daemon.log ## 略 if ($fromhost-ip contains "192.168.20.") then { *.* action(type="omfile" dynafile="RemoteHostRain" name="save_remote") *.* action(type="omfile" dynafile="DailyPerHostLogs" name="save_per_days") }
ログ転送って面倒こともなく、送信元と受信先に設定するだけで掛けるのはとても楽ちんですね。
ログを監視する目的でもなければ、転送なんてって思うかもしれないけど。
nvme が突然死したときにログがなかったので何が起きたか全くわかりませんでした。
NVMEのSSDは多分今後も突然死をすると思うので、ログだけでも残そうと思います。
rsyslog で転送する設定
rsyslog で転送設定。
*.* action(type="omfwd" ... )
転送設定の例
## legacy / compatible #*.* @@192.168.1.11:514 ## TCP は @@ #*.* @192.168.1.11:514 ## UDP は @ ## RasinerScript with queue *.* action(type="omfwd" queue.type="LinkedList" queue.filename="raspi-ubuntu_fwd" action.resumeInterval="30" action.resumeRetryCount="-1" queue.spoolDirectory="/var/lib/rsyslog" queue.saveonshutdown="on" target="192.168.1.11" Port="514" Protocol="tcp" )
ログ送信テスト
logger -p syslog.info -t TEST $(printf %05d $RANDOM)." Hello from pi-zero b "
TCP は接続チェック(コネクション確立)が入る。接続エラーになりログの喪失を防げる。ただし通信量が増えるので、ラグへの不安はある。
UDPは投げっぱなし(ながすだけ)なので、受け取り側が受け取らないとログは消える。
再送信をキューに入れる。
再送信に失敗した場合はキューに入る。30秒に一回送信する。
queue.type="LinkedList" queue.filename="raspi-ubuntu_fwd" action.resumeInterval="30" action.resumeRetryCount="-1"
再送信キューは基本的にメモリにあるはず。メモリなのでシャットダウン時に消えちゃう。
queue.spoolDirectory="/var/lib/rsyslog" queue.saveonshutdown="on"
シャットダウン時に保存するように設定する。。
ただ、これでも急な電源喪失だとログは喪失しちゃうけどキューに溜まるようなとき(=受け側がしんでる)ときに、送信側もしんでしまうという2重に死んでる状態は少し考えにくいのでこれでいいとする。
ネットが落ちたときに、ログが無尽蔵にたまりまくるので、上限を付けておかないと、ログ転送エラーがログに書かれて際限なく溜まる。
queue.maxdiskspace="1g"
ログ転送待ちが起きて、ログ転送の失敗ログがたまり続けて、1週間程度で10GB越えてた・・・ ネット再接続までに復旧したら問題ない。と思ってたが、たまり続けたログの転送に時間がかかりすぎてまいったので、上限を設けることにした。
''' in object definition - is there an invalid escape sequence somewhere?
シングルクォーテーションは、文法エラーになるので注意する。
いにしえからの書き方。
## legacy / compatible *.* @@192.168.1.11:514 ## TCP *.* @192.168.1.11:514 ## UDP
この場合、キューを記入するのがめんどくさい。
キューは送信エラー時に再送する。もちろん、これはTCP挙動です。
UDP時には使えない。接続チェックにTCPを用いるため。UDPは投げっぱなしですよね。
UDP設定を忘れてキューに溜まらない。ってパニクったけど。UDPだと溜まるわけ無いですよね。
とりあえずロストしてもいいや、だいたい集まってたらいいやってときはUDPのほうが圧倒的に軽量でいいんだけどね。
別に書いた。
armbianmonitorというコマンドがarmbianに用意されていた。 これをつかうと、温度・CPU・メモリをモニタリング出来る。
armbianmonitor -m
ログ書いたりするのに便利そう。
http://www.d0wn.com/orange-pi-zero-how-to-get-the-cpu-temperature/