概要
趣味で運用しているNextcloudサーバーがある日急にアクセス不能になった(ハードウェア周りを弄ってる時にイーサネットが変わったせい?)ので、どうせOS再インストールするならと最新環境(CentOS 7のサポートが2024年に切れるので)にしようと移行した時の話です。
ざっくりとOSの移行方法と個人的にハマったポイントを備忘録として書いておきます。
目次
前提
- Nextcloudをセットアップ完了済みのサーバー(on CentOS 7)
- dataフォルダはRAID1を組んだ別のHDDを指定
- yum(dnf)、cp、cd、ls、ll、vimなどの基本的なコマンドが使える
- 基本的にrootで作業しています(コマンド実行の際は必要に応じてsudoを付けてください)
- SSL証明書はLet's encrypt(certbot)を使用
移行元環境
- CentOS 7.9
- Nextcloud 23.0.3
- nginx 1.20
- PHP 8.0
- MariaDB 10.2
移行後環境
- Rocky Linux 8.5
- Nextcloud 23.0.3
- nginx 1.21
- PHP 8.0
- MariaDB 10.7
バックアップするもの
- nginxの設定ファイル
- データベース
- PHP関連の設定ファイル
- Nextcloud関連ファイル
手順
1. Nextcloudをメンテナンスモードに
まずNextcloudのルートディレクトリに移動し、メンテナンスモードに切り替えます。
cd /var/www/nextcloud
sudo -u nginx php occ maintenance:mode --on
2. 各ファイルをバックアップ
SFTPなどを使ったネットワークアクセスすら不能な状態だった為、USBメモリ経由で行いました。
ネットワーク経由でアクセスできる場合はWinSCPとか使った方が楽だと思います。USBメモリのマウントの方法などは今更だと思うのであえて説明しません。
nginxの設定ファイル(/etc/nginx/conf.d/)
cp -p -r /etc/nginx/conf.d/ /mnt/usbmem/
データベース
ユーザー管理やフォルダの管理に使用しているようです。
Nextcloudで使用しているデータベースのバックアップを行い、バックアップ先のフォルダからファイルを持っていきます。
mysqldump -u nextcloud -p nextcloud > /var/database/nextcloudbak.sql
cp -p -r /var/database/ /mnt/usbmem/
PHP関連の設定ファイル(/etc/php.iniと/etc/php.d/)
PHPメモリやキャッシュ設定を持っていきます。
cp -p /etc/php.ini /mnt/usbmem/
cp -p -r /etc/php.d/ /mnt/usbmem/
Nextcloud関連ファイル
configやappフォルダを含めて持っていきます。
cp -p -r /var/www/nextcloud/ /mnt/usbmem/
3. Rocky Linuxをインストール
公式のダウンロードページのTorrent経由でISOをダウンロードし、Windows環境にてRufusを使ってインストールUSBを作りました。
ISOファイルは約10GBと大きめなのでTorrent経由がおすすめです(シーダーが多くて爆速でした)
ダウンロード
https://rockylinux.org/ja/download
インストール方法はCentOS 7と大きく変わっておらず、特に躓く事は無いと思うのでざっくり書きます。
触った部分は以下の通り
- 時刻と日付→タイムゾーンを東京(UTC+9)に変更
- インストール先→元々CentOSが入っていたストレージのデータを削除、フォーマット。
- rootパスワード及びユーザー作成→ユーザーには管理者権限を設定が良いと思います。
- ソフトウェアの選択→サーバー(自分はオプション選択なしで最小限にしました。必要に応じてGUIのオプションやパッケージを選択してください)
- ネットワーク設定→ここが一番大事。イーサネットを有効化し、さくっと固定IPにしておきましょう。
インストール自体は環境によりますが、20分~30分くらい(SSDだともっと早いのかな?)で終わると思います。
4. firewalldの設定
直接操作するのも面倒なので、さっさとSSH経由で操作できるようにします。
ついでにWebサーバー用のHTTPとHTTPSも空けておきましょう。
SSH、HTTP(80番)、HTTPS(443番)へのアクセスを永続的に許可
firewall-cmd --add-service=ssh --zone=public --permanent
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --add-service=https --zone=public --permanent
SSHのポートを変更
一応セキュリティ的に標準ポートは避けたい・・・という事でポート変更。
色々な方法がありますが、自分は適当な場所にバックアップを作り直接設定ファイルを編集しました。
ファイルをコピー、設定ファイルを開く
cp /usr/lib/firewalld/services/ssh.xml /usr/lib/firewalld/services/ssh.bak
vim /usr/lib/firewalld/services/ssh.xml
xmlファイルを編集
ポートの書き換えを行います。『port="22"』を任意の数字に変えましょう。
今回は仮に49152番にしていますが、49152~65535番は未割り当てポートなのでその範囲であればお好みで大丈夫です。
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="49152"/>
</service>
設定の反映とfirewalldを再起動
※ルーター側のポート開放もお忘れなく・・・!
firewall-cmd --reload
systemctl restart firewalld
sshd設定ファイルのポートを変更
データコピー前に公開鍵設定やroot無効化すると少し面倒なので、ポートだけ先に変更しておきましょう。
sshd設定ファイルの書き換え
5. nginx、MariaDB、PHPのインストール
標準リポジトリはバージョンが古い事が多いので、基本的には各ソフトウェアの公式リポジトリを設定してインストールする方法を取ります。
※ここからはSSHクライアント(Putty on Windows)からの操作を前提で話を進めているので、コピペが必要な項目が多めです。
nginx
公式の手順通り進めていきます。
今回はmainlineを指定しましたが、お好みで・・・
nginx: Linux packages
https://nginx.org/en/linux_packages.html#RHEL-CentOS
yum-utilsをインストール
yum install yum-utils
リポジトリファイルを作成
vim /etc/yum.repos.d/nginx.repo
公式からコピペ
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
リポジトリを有効化、nginxのインストール、起動、自動起動の設定
dnf-config-manager --enable nginx-mainline
dnf install -y nginx
systemctl start nginx
systemctl enable nginx
MariaDB
こちらも公式の手順通り進めます。
ディストリビューションは一応『CentOS 8』を指定、ミラーサーバーもお好みで大丈夫かと。
Download MariaDB Server
https://mariadb.org/download/?t=repo-config&d=CentOS+8+%28x86_64%29&v=10.7&r_m=yamagata-university
リポジトリファイルを作成
vim /etc/yum.repos.d/MariaDB.repo
公式からコピペ
# MariaDB 10.7 CentOS repository list - created 2022-04-02 18:36 UTC
# https://mariadb.org/download/
[mariadb]
name = MariaDB
baseurl = https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/yum/10.7/centos8-amd64
module_hotfixes=1
gpgkey=https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck=1
MariaDBのインストール、起動、自動起動の設定
dnf install MariaDB-server
systemctl start mariadb
systemctl enable mariadb
PHP
remiリポジトリ経由でPHP 8.0をインストールしていきます。
epelリポジトリとremiリポジトリを追加
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
PHPとモジュールのインストール
dnf -y install php80 php80-php php80-php-fpm php80-php-json php80-php-mbstring php80-php-pdo php80-php-xml php80-php-mysqlnd --enablerepo=remi-php80
PHP-FPMを起動、自動起動の設定
systemctl start php-fpm
systemctl enable php-fpm
6. バックアップしたデータをコピー
バックアップしたファイルを対応するディレクトリにコピーします。
セキュリティリスクは多少ありますが、公開鍵を設定する前にWinSCPなどを使ってSFTP使ってサクッとコピペしちゃうのが楽だと思います。
nginx、PHP、Nextcloudのファイルはバックアップを取った時と同じようにディレクトリに戻す感覚で良いかと思います(念のため上書きではなく、ファイル名変更しておきましょう)
データベースについては後ほどリストアするので、適当な場所(今回は/var/database/nextcloud/とします)に置いておきます。
nginxの設定ファイルをコピーすればサーバーが起動出来る状態になると思うので、HTTPSでアクセスされている方はSSL証明書の設定も合わせて行いましょう。
自分はLet's Encryptを使用しているので『certbot』を使用して再取得を行いました。
7. sshdの設定
今回はWindows環境で公開鍵を生成(Putty Key Generator)し、SSH経由で設定ファイル書き換え、公開鍵を設定という流れで行きます。異論は認めます。
公開鍵の生成(Putty Key Generator)
Puttyに同梱されているPutty Key Generator(PuTTYgen)を使用します。
Parameters(暗号化の種類)はお好みで設定してください(ある程度セキュリティが担保されている方式で)
今回はセキュリティつよつよのEdDSA(Ed25519)で設定しました。
- Key comment→任意
- Key passphrase→認証時のパスフレーズ(設定を強く推奨)
- Confirm→パスフレーズの確認
生成出来たら『Save private Key』をクリックして秘密鍵を任意の場所に保存(SSH認証時に使いますので大切に保管)
ウィンドウは公開鍵が設定出来るまで閉じずに置いておきます。
sshd設定ファイルの書き換え
行う設定は以下の通り
- ポートの変更(Portをfirewalldで設定したポートに変更)
- rootでのログインを禁止(PermitRootLoginをyes→no)
- パスワードでのログインを禁止(PasswordAuthenticationをyes→no)
念のためバックアップしておきます。
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
vim /etc/ssh/sshd_config
sshd_configを書き換え
# Package generated configuration file
# See the sshd_config(5) manpage for details
# What ports, IPs and protocols we listen for
Port 49152
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60
#Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
公開鍵の設定
上記画像で反転している部分が公開鍵になりますので、これをサーバーへと設定していきます。
SSHクライアントを使用してサーバーへアクセス
ローカル環境であれば固定したローカルアドレスとポートを指定すればとりあえず通ると思います(ドメイン指定でもOK)
authorized_keysファイルを設定
設定でrootでのログインが無効になっているので、OSインストール時に作成したユーザーに設定します。
vim /home/ユーザー名/.ssh/authorized_keys
Putty Key Generatorで生成された公開鍵を貼り付ける
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6HiWiDYp6WlBgwVJPWvbbmxAtL9/C/n91UrFpADI4b eddsa-key-20220403
パーミッションを変更
chmod 600 /home/ユーザー名/.ssh/authorized_keys
sshdを再起動
systemctl restart ssh
※ひとまず開いているPuttyのセッションを閉じず、別のセッションで公開鍵によるアクセスが出来るのか必ず確認してください(SSHから締め出されて少し面倒な事に)
8. データベースの設定とリストア
「mariadb-secure-installation」で初期設定
ひとまず「mysql_secure_installation」・・・ではなく「mariadb-secure-installation」を使ってMariaDBの初期設定を行います。
mariadb-secure-installation
MariaDB10.2以来の初期設定だったもので、慣習で「mysql_secure_installation」使おうとしたら「コマンドが見つかりません」と言われて泣きそうになりました。いつの間にか廃止されてたんですね・・・
質問形式で特に難しい部分も無いので割愛します。
参考までに公式ドキュメント(何故か「mysql_secure_installation」のまま)
mysql_secure_installation
https://mariadb.com/kb/ja/mysql_secure_installation/
データベース作成
とりあえずNextcloud用のユーザーとデータベースを作成します。
設定変更するのも面倒なので、移行前のサーバーで使っていたデータベース名、ユーザー、パスワードの組み合わせで良いでしょう。
mysql -u root -p
MariaDB [(none)]> CREATE DATABASE nextcloud;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nextcloud.* TO username@localhost IDENTIFIED BY 'password';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> quit
データベースのリストア
データベースをコピーしたディレクトリに移動し、リストアを行います。
cd /var/database/nextcloud/
mysql -u nextcloud -p nextcloud < nextcloudbak.sql;
9. dataディレクトリの設定
冗長化の為にdataディレクトリはRAIDを組んだ別HDDを指定しているため、マウントしてあげます。
CentOS 7上で組んだソフトウェアRAIDの構成がそのまま反映されていたのでひとまず安心。
Nextcloudでdataとして指定しているディレクトリ(自分の場合は/mnt/pool/nextcloud/data/)になるようにマウントポイントを作成します。
自分の場合HDD側が/nextcloud/data/という構造になっていたので、/mnt/pool/を生成
mkdir /mnt/pool/
HDDが認識されているのか&デバイス名の確認(fdiskかlsblkはお好みで)
fdisk -l
該当するHDD(今回はmd0)を指定し、先ほど生成したディレクトリでマウント
mount /dev/md0/ /mnt/pool/
起動時に自動マウントするように設定
このままだとサーバーを再起動する度にマウントする必要があるので、fstabを編集して自動的にマウントするように設定します。
UUID指定するのが確実らしいので、blkidでUUIDを確認。
該当するHDD(今回はmd0)のUUIDとファイルシステム(TYPE)を控えておきましょう。
blkid
fstabを開く。
vim /etc/fstab
blkidで取得した情報を基に以下のように追記します。
UUID、マウントポイント、ファイルシステム(今回はxfs)
UUID=○○○○-○○○○-○○○○-○○○○-○○○○ /mnt/pool xfs defaults 0 0
10. SELinuxの設定
config、appsはNextcloudのルートディレクトリを指定。
dataディレクトリは先程マウントした場所を指定しています。
chcon -R -t httpd_sys_rw_content_t /var/www/nextcloud/config
chcon -R -t httpd_sys_rw_content_t /var/www/nextcloud/apps
chcon -R -t httpd_sys_rw_content_t /mnt/pool/nextcloud/data
11. メンテナンスモード解除
cd /var/www/nextcloud
sudo -u nginx php occ maintenance:mode --off
ハマったポイント
Internal server error
この段階でとりえずアクセス出来る状態になりましたが、いきなり真っ白の画面に『Internal server error』を表示しやがりました・・・
occコマンドでrepairすると改善するとの情報を見つけ、試してみたところドンピシャでした。
sudo -u nginx php occ maintenance:repair
Nextcloudのセキュリティ&セットアップ警告
Nextcloudにログイン出来る状態にまで復旧出来ましたが、概要ページを確認すると沢山のエラーがお出迎え。。。
- データディレクトリが無効です データディレクトリ直下に".ocdata"ファイルがあるのを確認してください。
- Your data directory is not writable Webサーバーのルートディレクトリに書き込み権限パーミッションが必要です。
- 最後のバックグラウンドジョブの実行は昨日実行しました。何かがおかしいようです。
- このサーバーにはインターネット接続がありません。複数のエンドポイントに到達できませんでした。つまり、外部ストレージのマウント、アップデートに関する通知、サードパーティ製アプリのインストールなどの昨日の一部は機能しません。リモートからファイルにアクセスしたり、通知メールを送信したりすることもできません。インターネットの接続を確立できれば、すべての機能を利用することができます。
- Strict-Transport-Security "HTTP ヘッダーの秒数が少なくとも"1552000"に設定されていません。セキュリティを強化するには、セキュリティのヒントで説明されているようにHSTSを有効にすることをお勧めします。"
- Webサーバーで"./well-known/caldav"が解決されるように正しく設定されていません。
- PHPモジュールがいくつかありません。パフォーマンスの向上と互換性の向上のために、それらをインストールすることを強くお勧めします。
サクッと解決できた部分
- PHPのモジュールがいくつかありません。
- dnf(yum)からエラーを吐いてるモジュールを追加でインストールすればOK!
上のエラーの場合、以下のようにすれば消えると思います。
- dnf(yum)からエラーを吐いてるモジュールを追加でインストールすればOK!
yum -y install php80-php-bcmath php80-php-gmp php80-php-imagick
- Strict-Transport-Security” HTTPヘッダが最低でも “15552000” 秒に設定されていません。
- 移行前のサーバーでnginx.conf(/etc/nginx/の直下)にHSTS設定していた事が原因でした。
/etc/nginx/conf.d/内のnextcloud用の.confファイル側に以下を追加。
- 移行前のサーバーでnginx.conf(/etc/nginx/の直下)にHSTS設定していた事が原因でした。
server {
listen 443 ssl http2;
server_name example.com;
~中略~
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
- 最後のバックグラウンドジョブ
公式ドキュメント通り。crontabを設定してあげれば問題なし。
crontab -u nginx -e
*/5 * * * * php -f /var/www/nextcloud/cron.php
ハマりまくった部分
正しく設定しているはずなのにいつまでも解消せず、丸一日悩みました。
色々してたらいつの間にか消えてたエラー(こわい)
- ".ocdata"ファイルがあるのを確認してください。
- Your data directory is not writable Webサーバーのルートディレクトリに書き込み権限パーミッションが必要です。
とりあえず試した事は以下の通り。
- dataディレクトリのパーミッション確認、公式ドキュメント見ながらchmod、chownを使って再設定を行う。
- Nextcloudのルートディレクトリ(/var/www/nextcloud)のパーミッション確認、公式ドキュメント見ながらchmod、chownを使って再設定を行う。
- 『.codata』の再生成(rmで削除し、touchで作成、chownで所有者とグループをnginxに設定)
- systemctlで『nginx』『MariaDB』『PHP-FPM』を再起動。
- サーバー本体を再起動。
色々と試しているうちに消えていました(バックグラウンドジョブと関連していたりする?)
「このサーバーにはインターネット接続がありません」問題
ifconfigやらnmcliやらでネットワーク周り見たり繋ぎ直したりしても特に問題が起こっている様子はない。と言うかログイン出来てるのにインターネット無い訳ねーじゃん・・・
とかボヤきながら調べるも情報が全く出てこず、1日中悩んだ末に見つけたNextcloudのコミュニティの書き込みで一発解決(Nextcloudコミュニティいつも重いので開く気が起きませんでした)
This server has no working Internet connection (It does really)
https://help.nextcloud.com/t/this-server-has-no-working-internet-connection-it-does-really/67524
以下を打ち込んだところあっさり解決。どうやらSELinuxの設定だったようですね・・・
setsebool -P httpd_can_network_connect 1
「Webサーバーで"./well-known/~"が解決されるように正しく設定されていません。」問題
すみません・・・解決したと思ったら再び現れたりして再現性が無く未だに解決していません(実用上問題無さそうなので放置でも良さげ?)
※2022/04/07追記 ブラウザのキャッシュの問題だったようです。キャッシュ削除する事で解決しました!!!(長い戦いでした)
NGINX configuration
https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html
多分carddavとcaldavについては以下をnginxのconfファイルに追加するのが正解(公式のサンプルファイルを参照)
webfingerとnodeinfoについては色々と試していますが、どうも上手くいきません。。。
※webfingerとnodeinfoについては公式ドキュメントで触れられていませんが、以下の通り記述すればOKです。
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location = /.well-known/webfinger { return 301 /index.php$uri; }
location = /.well-known/nodeinfo { return 301 /index.php$uri; }
セキュリティスキャンも無事に『A+』になりました!(まんぞく・・・)
おわりに
Qiita初投稿してみました(まぁ非エンジニアなので・・・笑)
サーバーの構築や色々触る際にQiitaの記事に助けられる事が多いので、自分でも何か書ければいいな~と思った次第です。
自分用の備忘録として書きましたが、もし誰かの役に立てば嬉しいです。
あと、Markdown全然慣れて無くて使いこなせてないデス!スミマセン...
「上手く動かない」「ここ間違ってる!」「こうした方がいい」などのご意見がございましたら、コメントもしくはTwitter@BTY_11073までお願いします。。。
最後に使用しているサーバーでも晒しておきます。
丸4年ほど使っていますがピンピンしています(最近Xeonにしました)。あと2,3年くらいしたら買い替え
たいところ。
Base: PRIMERGY TX1310 M1
CPU: Pentium G3420(2C2T) → Xeon E3 1220V3(4C4T)
GPU: Quadro K2200
RAM: 標準のメモリ(DDR3 1600MHz 4GB×1) → W3U1600HQ-4G(DDR3 1600MHz 4GB×4)
HDD(system): 標準のSeagate製HDD(500GB×1)
HDD(data): WD40EZRZ-RT2×2(4TB×2,RAID1)