Linux」カテゴリーアーカイブ

ファイルサーバのRAIDディスクが1つ飛んだので修復してみる

この記事を書いているこのタイミングではまだRAIDアレイのリビルド中なので終了待ちです。今回はRAIDアレイの修復作業ではなくもっと違ったところで大変なことが起こっていたのでそれをメインに書いてみたいと思います。

 

RAID5のディスクの認識ができなくなった

まずはじめに出た問題がこれ。ログを見る限りでは4日前ほどに不良セクタの発生でI/Oエラーが出てアクセスができなくなったようです。その前後でHDDのコントローラが応答不能に陥り強制的にRAIDアレイから除外された、という状態だったようです。早めに気がついてよかったです。ということでRAID5なので早急にHDDを取り替えてRAIDアレイの修復を行う必要が出てきたのですが、ここでHDDに関するとある問題が発生しました。

 

スペアとなるHDDがない。同じ型番のHDDはすでに販売されていない。そして・・・

このファイルサーバを組み立てたときに8TB以上あり、GB単価で一番安かったのがSeagateのST8000AS0002というもの。これ、実はArchiveHDDと呼ばれているもので、組んだ当時は用途的にはぴったりのものだったのですが、スペアを買っていない(というか1年ほど前に1台故障して同一型番のものと取り替えている)ため、手元に存在しておらず、同じ型番のものはすでに販売終了。しかも後継となるHDDはなんと存在していません。これは困った。というのも、RAIDアレイの再構築を行うためのストレージは「必ず残りのストレージデバイスが持つ容量以上のものを使わなければならない」という条件があります。これが意外と問題。

というのも、HDD本体の容量は確かに「8TB」なのですが、同じ「8TB」のHDDだからといってセクタ単位で見たときに容量が足りているか、は必ずしも明記されていません。メーカや型番によりこのあたりは異なる可能性があり、例えばWesternDigitalの場合はこれが明記されていません。そのため、ST8000AS0002の代替としてWesternDigital製の8TBHDDを考えるときセクタ数が足りているかどうか確証が持てない、という問題が発生します。RAIDの場合これが致命傷になる可能性があり、この時点でWesternDigital製のHDDは8TBより上のものを使わないと代用できない可能性が出てきます。幸いにもSeagateの場合は「Guaranteed Sectors」(最低保障セクタ数)という概念があり、8TB系のHDDはすべてGuaranteed Sectorsが同じであったため代用できるだろう、という感じで考えることができます。なお、あくまで「最低保障」なので、個体により微妙に異なる可能性は否定できないのですが・・・。

というわけで今回の代替用途にはSeagateのST8000VN004が発売時期も最近なのでちょうどいいかな、と思っていたのですが・・・。

 

近くにあるショップはSeagate製大容量のNAS用HDDがおいていない!というか・・・

そもそも8TBより容量が大きいHDDを取り扱っているショップが見当たらない、と言う事態が発覚し大分困り果てました。8TBのHDDがあった場合もBarracudaかWesternDigital製という間の悪さ。地方のショップはこんなものなのでしょうかね・・・。なんとか急場をしのぐために「とりあえず」でHDDを購入してリビルド作業に移っています。(つまりセクタ数はなんとか足りていたわけですね)

 

RAID5はリビルド作業が怖いのでそろそろRAID6で組み立てたいが

RAID5は1台が壊れても復旧が可能ということで個人用途では悪い選択肢ではないのですが、最大の問題点はRAIDアレイの再構築中に別のHDDが壊れてしまいRAIDアレイが完全に崩壊してしまう可能性が大きいこと。特に同じ時期に同一型番のHDDを買って使うため、故障時期も近くなる可能性が大きくなるからです。それを防ぐにはRAID6が有効なのですが、こちらだとHDDが一つ余計に必要なことと、SATAの端子数が必要(例えば4+2台で組む場合はさらにシステムドライブが1台必要となるため、拡張ボードなしだとマザーボードに端子が8つ必要になってしまう)ということで、コストがかかるのが難点です。ちなみに現段階でRAID6による40TB保存マシン(HDDは10TB*(4+2))を軽く設計してみるとすべてで40万円前後となり、YouTubeの動画にでもして広告収入を稼ぎたくなるようなマシンとなってしまうな、というところです。

 

 

logrotateが動作しない? systemctlで制御されているlogrotateに注意

久しぶりのサーバネタです。せめて仕事になるネタでも書かないとだめなのに…と思いながら書いています。

 

Fedora30のlogrotateがなぜか動作していない?

今現在Fedoraを入れているサーバはプログラムやWebサイトなどの動作テストを行うためのサーバなのですが、それだけではもったいないのでffmpegを入れてとあるバッチスクリプトを書いておくことで動画エンコードサーバとしています。これはまあいいのですが、今日気がついてみるとサーバが応答しなくなっているという事態に。テスト用のサーバなので、電源を強制OFFにした後付け直してログによっていつ、何が起こったのか把握しようと思っていたのですが…。/var/log以下を見てびっくり。

なんとFedora30を入れてから今日までのログが一つのファイルに固まったまま巨大なログファイルとなっていました…。

まあ、外部からのアクセスもほとんどないサーバですし、セキュリティ的な問題でもないでしょうからまだましなのですが、何かあったときの追跡が非常にやりづらいこと。気がついてよかったです。で、そうなると今までログファイルを分割していたlogrotateは一体何をやっていたのか?ということで少し追跡してみました。

 

systemctlに管理された場合のlogrotateはcronで動作させた場合と少し違う

いつ切り替わったのかよく分からないのですが…。今現在使っているCentOS7ではlogrotateはcronが一定期間ごとに動かすように設定されているのですが、Fedora30ではsystemctlがlogrotateを起動するように設定されているようです。で、これの設定が今までと違うやり方になっていてびっくり。どうなっているかというと

  • systemctlに登録されているlogrotate.serviceは「systemctlのタイマで一定期間ごとに呼び出されるログ処理を一度だけ行うスクリプト」という扱い。
  • 「一定期間」を設定しているのはsystemctlが持っているタイマの機能で、これは/usr/lib/systemd/system/logrotate.timerで定義されている

というわけで、logrotateを動作させるスクリプトとlogrotateを「一定期間ごとに」動作させるスクリプトは別になっているという理屈です。このsystemctlがタイマを持ち、一定期間ごとに動作させる、というのがこれを考える肝になるようで、systemctlからlogrotate.serviceの動作を見ても状態が「inactive (dead)」となっていますが、これは「そのタイミングでは動いていない」だけで、常駐している(定期的に動作するように設定されている)かどうかは別の方法で確認しなければいけない、ということになります。

 

デフォルトでlogrotate.timerは登録されていないのか・・・?

確認するためには

$ sudo systemctl list-timers --all

を使います。これでlogrotate.timerに関する行が存在する場合(コマンド実行中は左右キーが効くので右も確認する)はlogrotateが一定期間で動くのですが、関する行がない場合はlogrotateは動かない、ということになるようです。きちんと動作させるには

$ sudo systemctl enable logrotate.timer
$ sudo systemctl start logrotate.timer

により動作を追加する必要があります。タイマが登録されればlogrotateはlogrotate.timerに記述されている一定期間で動くようになる、ということになります。

 

ほかにsystemctlのtimerで抜けているものがあるのでは…?

ちょっと気になったのがこのこと。システムのログ処理で重要な部分であるlogroateがこれなので、ほかの「一定期間ごとに動作するサービス」の部類で同じようなものがある可能性があるな~と考えたからです。見つけた段階で一つ一つ登録していく必要があるのでしょうかね。

 

cronとsystemctlのタイマ処理との棲み分けとなるのか?

ちょっと気になるところです、cronの機能をsystemctlがある程度持つのであればcronを吸収することになるのか、システムの中心と簡単なバッチ処理のように棲み分けるのか、これからの発展が少し気になるな~と思っています。

firewalldを使って特定の国からのアクセスを遮断する方法

Twitterにも書きましたが、ちょっととある国からのアクセスが非常にウザくなってきたのでIPフィルタを用いてアクセスを遮断することにしました。ちなみに、4月にサーバシステムを新しくしていますが、前のサーバにはiptablesに直接フィルタ情報を書き込むタイプのスクリプトを用意して処理していたのですが、サーバが新しくなったこともあり、IPフィルタ処理がfirewalldを通して行うことが通常となってしまいましたので、そちらの方法に合わせています。ほかのサイトでも紹介されていますが、半分は自分のメモ書きのようなものです。

 

というわけで作業手順

それほど難しいものではないですが、手順としては

  1. 対象の国に属するIPのリストを取得する
  2. firewalldにIPリストを登録する
  3. firewalldの処理を有効にする

これだけです。まあ、最後にcronなどで処理を行うためのスクリプトを用意しますのでそちらをそのまま使えばOKかもしれません。

 

1.対象の国に属するIPのリストを取得する

本当ならばftpなどでリストをとってくる方法が正しいと思うのですが、この処理を組み込むために検索したときにIPリストを提示してくれるサイトとしてこちら(https://ipv4.fetus.jp/)がありましたので、私の例でもこちらを使うことにします。なお、この部分にIPリストを提示する別のサイトを使っても問題はないと思います。

このサイトではそれぞれの国に割り当てられたIPのリストについて国名(もしくは国コード)をクリックするとこのサイトからダウンロードできるアドレスが取得できます。形式もhtaccess形式やiptables形式、postfix形式など主要なサービスに対してかけられるようになっていて便利です。

ただし、firewalldでは普通にIPがずらっと書いてあるだけの形式を使うので「プレインテキスト」形式で問題ありません。対象の国のプレインテキスト形式をダウンロードできるURLを確認しておきましょう。

 

2.firewalldにIPリストを登録する

正しくはfirewalldではなくipsetという別のものを使うのですが…。ない場合はパッケージをインストールしておきましょう。私の場合はCentOS系なので

$ sudo yum install ipset

でインストールしておきましょう。

これがfirewalldに複数のIPを一括で処理させるもので、これをインストールすればこんな感じのことができます。よくスパムが来るのはこのサイトの場合はロシアやウクライナなので、ウクライナを対象にした場合はこんな感じでかけます。すでにIPリストを/tmp/ua.txtに保存してあるとすると…

$ sudo firewall-cmd --permanent --new-ipset=uk --type=hash:net
$ sudo firewall-cmd --permanent --ipset=uk --add-entries-from-file=/tmp/uk.txt

とすれば登録が完了します。

 

3.firewalldの処理を有効にする

登録が完了すれば、firewall-cmdでチェックが可能になり、

$ sudo firewall-cmd --zone=drop --list-all

というコマンドで確認すると

drop (active)
  target: DROP
  …
  sources: ipset:uk
  …

のように登録が確認できると思います。あとは

$ sudo firewall-cmd --reload

で再読込をすれば完了です。

 

で、定期的に更新するスクリプトは…

IPリストは不定期に変わりますので適当な間隔で更新していかないと思った国のIPをはじけなくなってしまいます。今のところ私はこんなスクリプトを作成しています。

#!/bin/sh

# コマンドの場所の設定
CURL = /usr/bin/curl
FIREWALL_CMD = /bin/firewall-cmd

# IPリストをダウンロード
$CURL "https://ipv4.fetus.jp/ua.txt" > /tmp/ua.txt

# firewalldに状態を設定する
$FIREWALL_CMD --permanent --delete-ipset=ua
$FIREWALL_CMD --permanent --new-ipset=ua --type=hash:net
$FIREWALL_CMD --permanent --ipset=ua --add-entries-from-file=/tmp/ua.txt
$FIREWALL_CMD --reload

# 使ったファイルを片付ける
rm /tmp/ua.txt

curlやfirewall-cmdの場所は環境によって異なると思いますので環境に合わせて変更すればOKですし、国が異なる場合はreloadの前に指定したい国の数だけ処理を追加すればOKです。最後にこれをcronで定期的に動くように設定すれば完了となります。

 

個人的には特定の国からのアクセスをはじく、とかはやりたくないが…

ちょっと目に余るアクセスがありましたのでそれに対応したものです。スパムというのも面倒なものですし、対応も面倒だな~と思いながらやっています。

Fedora30をインストールしてみた

Fedora28をインストールしてから1年たっていませんが、まあそれはそれとして。すでにFedora30がリリースされ、Fedora28のサポートも終了することが決まるタイミングですのでさっさとインストールをやってみようということでやってみました。

といっても、コツさえ知っていればServer版なのでFedora28だろうがFedora30だろうがあまり変わらずにインストールできます。今回はその中でもちょっと思ったことを少しだけ書いていきたいと思います。

 

Btrfsを使おうとすると、ブートパーティションが面倒になるのでは?

まず一つ目。毎度のことながら、dnfによるバージョン更新処理は絶対にしない、というのが私のFedoraを扱う上での一種の信念ですので完全な新規インストールです。ところで、新規インストールするのであればパーティションも新しくなるのでは?というところなのですが、実際はそんなことはみじんもありませんでした。

なぜかというと、Fedoraといえば今ではBtrfsも十分な完成度になったと思うのでそちらを使おうかと思ったのですが、まずはじめにUEFIとGPTの影響で特殊ななブートパーティションが必要になるということ。もう一つは/bootの領域に対してBtrfsを使うことができないので、その領域だけ別の形式のパーティションを当てる必要がある、という点です。こうなってしまうと最低でも

  • UEFIブート用パーティション
  • /boot用データ領域
  • Btrfsの通常データ領域
  • スワップパーティション(これは任意か?)

の4つのパーティションが必要となるわけで、個人用とであれば下手をすればすべて/に統合してもよいはず、と考えると4つもあるのは逆に面倒という事態になりかねないな~というのが正直なところでした。なので今回も結局Btrfsを使わずにext4形式になっています。もう少し規模が大きいとか実験用サーバとかならそれもありなのかもしれませんが。

 

WOLの設定はフラグが立っていても起動するごとにethtoolを動かさないとだめなのね

という事実に今更ながら気がついた人でした。以前の記事にも書いたような気がしますが、まずマザーボードに実装されているLANデバイスは、特にゲーミングマザーだとWOLの機能が必要ないと見なされているらしく、WOLができない状態でした。なので、内蔵のLANを無効化した上で外付けのLANカードを使って通信するようにしています。

そしてWOLの設定でもう一つ気をつけなければならないことは、ドライバにもよるようですが、基本的にethtoolを毎回動かしてシャットダウンを行う前までにWOLを受け付けるように設定しないとだめ、ということでした。これがちょっと面倒だったですね。いくつかのサイトを回ってみるとudevを使ったパターンが紹介されていましたが、私の場合はudevを使ったパターンではうまく動かなかったです。ちょっと不思議。

というわけで別パターンとして載っていたcronを使う方法を使わせてもらいました。これはcronにはcrontabに書くときにいくつかのフラグがあり、その中の一つである@rebootというものを使うと起動が完了したタイミング(正しくは起動後cronが動かされたタイミング)で指定したコマンドを実行する、というものです。今回はこれを使って

@reboot /usr/sbin/ethtool -s [デバイス名] wol g

という命令をcrontabに書き込むことで、起動時に実行させることができるようになり、WOLの機能が回復した、ということになりました。ちなみにWOL機能設定を自動的に行うようにしているいくつかのサイトでethtoolの位置が/usr/bin/ethtoolとなっているものがいくつかあるようですので、whichコマンドでethtoolの場所を確認した上で書いておかないと正しく動いてくれませんので気をつけましょう。

 

少しネットワークの受付が遅くなった?

といっても、対象はTelnetとSambaですので、なんともいえないところです。両者ともログイン前のID入力にいくまでに妙な時間がかかっている印象です。一応IPv6の影響で何度か試しているのかな~とも思ったのですがそうでもないようで。なぜなのでしょうか…。ちなみにTelnetを使っているのはNATがあるので外部からTelnetではログインできませんし、やりとりもハブ1個分しかない内部ネットワークだけのものですので簡単な方がよいだろうということです。そこもSSHにするのが正しいのはわかっているのですが…。

VPSでCentOS7サーバを構築する まとめ編

なんとかまとめまでたどり着きました…。ということで、今回は大規模なリンクを張っておきましょう。

 

サーバー構築の手順まとめ

以下のような手順になります。なお、手順にあるリンク先のページでは設定に関するヒントがあります。

  1. VPSの契約(自宅サーバの場合はマシンセットアップ)
  2. rootログインを行い、yumで一度最新までアップデートを行う
  3. 通常のログインユーザを作成してsudoによるroot昇格を設定する
  4. (必要であれば)SELinuxを設定する
  5. SSHの設定を行い、外部からの侵入されないようにする
  6. 不必要なサービスを停止する
  7. ディスククォータを設定する
  8. 最新のパッケージを導入するために、現在入っている不必要なパッケージをすべて削除する
  9. 最新のパッケージを導入するためのリポジトリを設定する
  10. アンチウィルスを導入する
  11. httpd(Apache)の導入
  12. Let’s Encryptを使った常時SSL化対応処理
  13. php-fpmの導入
  14. MariaDBの導入
  15. nginxの導入
  16. vsftpdの導入
  17. postfix、dovecotの導入
  18. 各サービスの動作チェック

 

やっぱりそれなりの知識は必要ですね

特に設定でエラーを起こした場合、何が間違いかどうかを調べるにはプログラムを作っているときに何が間違えているかを確認するテクニックと同じような物が必要なのでは、と思っています。今回はターミナルからの設定で何回もエラーを起こしたのが、どうもキー操作ミスで設定ファイルの一番先頭に間違えたアルファベットが入ってそれを読み込もうとしてエラーを起こす、というパターンです。作業の慣れが消えてしまっているのがわかってちょっとショック。また、設定項目を自分で書いている場合で、項目名のスペルを誤って認識している場合がありました。Apacheの設定で「SetHandler」という項目が出てきたので、にたスペルの文字を見たときにそれだ、と思い込んでいると実は「SetHeader」だった、とか…。

 

経験がない人はVPSだけではなく一度自分のマシンでやってみるとよいかも

昔とは異なり、2万円以上するCPU(具体的にはCorei3以上)であったり、メーカー製でもそのレベルのCPUがあれば仮想マシンを使うための機能くらいはついていますし、仮想マシンを作るためのプログラムも無料で手に入る(VirtualBoxなど)ので、自分の手元でやってみてどうなるか?は実験した上でVPSを契約してみるのがよいと思います。プログラミングでもそうですが、設定の説明ページだけを見てそれをコピーしていても何も成長はしません。自分の環境に合うように設定してみたときに何が起こるのか、体験してみないとわからないことが多いからです。その点、仮想マシンであれば間違えたときにすべてを吹っ飛ばすことが簡単にできますので、怖がる必要はほとんどないと思いますよ。VPS以上になれば外部サーバを使った中でもできることが通常のレンタルサーバに比べて格段に増えますからね。面倒さも同じくらい増えますが。

 

プログラミング教育でこういうのはどうにかなるのかな…。

こういう「何が間違いかを考えるためにあれこれ考える」という能力は今の社会では必要ですので、その意味でもプログラミング教育の意義はあるのかもしれません。実際にやってみると人による差が大きすぎて大変ですが。そういう教材についてちょっと研究してみたりしたので、その感想も踏まえて別の機会にblogの記事にしたいと思います。