VirtualBoxにCentOSをインストールして基本設定をしたときの備忘録【macOS】

CentOSインストールまでは以下の記事を参考。
この記事ではスムーズにいかなかったところや、設定をする上で疑問に思ったことを書いています。

qiita記事
MacでVirtualBoxを使ってCentOS 7をインストールしてみた
https://qiita.com/nooboolean/items/de4e6bbae5df040177af

##環境
MacBook Pro (macOS Catalina バージョン10.15.6)
VirtualBox 6.1.14
CentOS 8.2

##VitrualBoxインストール

macOSは`OS x hosts`を選ぶ。
macOSの旧称は`OS X`及び`Mac OS X`だったらしい。
ちなみに呼び方はオーエステン。

ウィキペディア macOS
https://ja.wikipedia.org/wiki/MacOS

##CentOSイメージファイルのインストール

通常のCentOSの他に、CentOSストリームというものがあるが、こちらは開発者向けなので、今回は通常のCentOSをインストールする。

CentOSストリームについては以下のサイトが簡潔で分かりやすかった。

Think'IT
CentOS Project、CentOS Stream」の開始を発表
https://thinkit.co.jp/news/bn/16844

ダウンロードするISOには`x86_64`,`ARM64(aarch64)`,`IBM Power(ppc64le)`の３つがある。今回はx86_64を選択。

上記の３つはマイクロプロセッサ（CPU/MPU）を動作させるための命令語の体系である。
詳細は分からないが、個人で使う分にはどれでも支障はないと判断し、よく目にするものを選択した。

ミラーサイトは近いサイトのものを適当に選択し、dvd.isoをインストール。
なお、boot.isoやdvd.isoなどの概要は以下のとおり。

###boot.iso
CDN(*)からダウンロードしてインストールされる仕組みのため、インターネットにつながっていないとインストールできない。今回は単純そうなdvdをインストールした。

*CDN Content Delivery Network
　ファイルなどのコンテンツをスムーズに配信できるようしたネットワークのこと。ダウンロード対象となるコンテンツを大元の一つのサーバ（オリジンサーバ）だけに保管するのではなく、世界各地にオリジンサーバのコンテンツをコピーしたキャッシュサーバを配置することで、ユーザは最寄りのキャッシュサーバからコンテンツをダウンロードすることができる。
　この結果、オリジンサーバの負荷分散だけでなく、インターネット全体を流れるトラフィックを減らすことができる上、ユーザにとってもより高速にダウンロードできるようになる。

詳細は以下。
カゴヤのサーバ研究室
https://www.kagoya.jp/howto/network/cdn/

###dvd.iso
インストーラーからインストールできる全てのパッケージが含まれ、一般的に使用されている。ただし容量が大きい。
###minimal.iso
必要最低限のパッケージだけが含まれているため、容量が少ない。後から自身が必要なパッケージを揃える。
###~manifest
パッケージ内容を記述しているだけのドキュメントファイル。
###~torrent
Torrentクライアントソフトで入手できるファイル。
なお、Torrentとは、一つのファイルをインターネットからダウンロードするときに、ファイルを複数のサーバなどに分散して置くことで負荷分散を実現する技術のこと。大容量データを同時に多くの人が高速にダウンロードできるようになる。isoの容量が大きいので、高速でダウンロードできるためにあると思われる。

##VirtualBoxで仮想マシンの作成

###仮想ハードディスクの容量
8GBだとCentOSのインストールに不足したので、20GBにした。
CentOSのインストールに必要な容量は約9GBだった。

###光学ドライブ
コントローラー：IDEのセカンダリマスターにdvd.isoを割り当てる。

###起動順序
OSインストール後の起動の際は、光学よりハードディスクを優先する。または光学に割当てているisoを除去する。そうしないとインストールしたハードディスクからではなく、光学にあるisoからOSを起動してしまい、挙動がおかしくなる。

###ディスプレイ
~~見切れたり小さかったりして使いにくいので、グラフィックスコントローラーをVBoxVGAにする。~~
↑途中までは良いが、インストール完了前後に画面がカラフルにピカピカ光って進まなくなったため強制切断した。デフォのVMSVGAはインストール終了までは画面が見切れたりして不便だが、インストール完了後は見切れたりせず使用できるのでグラフィックスコントローラーは変更しなくてよい。VBoxVGAにして操作すると起動時の画面がカラフルになることがあるので推奨できない（操作自体は通常どおりできた。）。

###ホスト⇄ゲスト間でコピペ等を可能にするための設定（VirtualBox）

下記サイト参照。
己で解決！泣かぬなら己で鳴こうホトトギス
VirtualBoxでホスト⇔ゲスト間でコピペができるようにする。
https://onoredekaiketsu.com/copy-and-paste-with-virtualbox/

設定→一般→高度→「クリップボードの共有」と「ドラッグ＆ドロップ」の無効設定を変更。今回は双方向に設定。
なお、この設定はCentOS側で`Guest Additions`のインストールが必要となるので後記する「CentOSの設定」参照のこと（上記サイトはUbuntuであるがCentOSでのインストールとほとんど変わりないし、写真付きなのでわかりやすい。）。

##仮想マシンでCentOSインストール
インストール後の再起動の際、「VirtualBox VMが予期しない理由で終了しました。」と出て終了。再度開くを選択すると、注意文が表示される。
要約すると、「コマンドラインでマシンを指定して起動しなさい。」と指示している。
注意文の中のコマンドはこちら。

```
% VirtualBoxVM --startvm <name | id >
```
指示どおりに行うと、起動できた。

```
% VirtualBoxVM --startvm testCentOS
```

###CentOSインストール後の起動時のエラー表示
`ERROR Failed to send host log message`という表示が出るが、グラフィックスコントローラーをVBoxVGAにしたら表示されなくなる。
その代わり、前述のとおり画面内の文字がカラフルになったりしておかしくなる。VBoxVGAにするならCentOSインストール後に行う。エラーメッセージが表示されても支障はないのでVBoxVGAに設定するのは推奨しない。

##CentOSの設定
###ホスト⇄ゲスト間でコピペ等を可能にするための設定（CentOS側）
メニューバーのdevices→Insert Guest Additions CD Image...をクリックし、パスワード入力などの指示に従う。自動でインストールするので、正常にインストールが終了したら、アクティビティ→ファイル→Guest Additionsをクリックして取り出しを選択する。
最後にCentOSを再起動したらコピペ等が可能になるが、今回は全くスムーズにいかなかった。

インストール時に以下のエラーが発生した。
・カーネルヘッダーがない。
こちらを参考にしてインストール。

Engineer-log
VirtualBox Guest Additions エラー対処法 （CentOS）
https://engineer-log.net/index.php/2016/06/06/post-281/

```
root# yum -y update kernel
root# yum -y install kernel-devel kernel-headers 
 gcc gcc-c++
```
なお、-yは全ての問い合わせにYesで応答したものとして実行するオプション。インストール時に本当にこれでいいの？などの端末上での質問にYesで答えてインストールを進めるという意味。
インストール後、CentOSをシャットダウンしてVirtualBoxで光学にGeust Additionsをセットして起動し、アクティビティ→ファイル→Guest Additionsをクリックしてソフトウェアを実行したら、「make,perl,gccをインストールしてね。」とのエラーメッセージ。

```
root# yum install make perl gcc
gccあるからそれ以外インストールするね。
以下インストール
```

再起動して再度実行したら再びエラー。
「何が間違っていたかはログを見てね。」とのこと。

```
Look at /var/log/vboxadd-setup.log to find out what went wrong
```

ログを見ると、「３つのうちどれかをインストールしてね。」とのこと。

```/var/log/vboxadd-setup.log
cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y,
please install libelf-dev, libelf-devel or elfutils-libelf-devel
```
`elfutils-libelf-devel`が唯一インストールできた（そのほかは一致するものがなくインストールできなかった。）。再起動せずにGuest Additionsの実行をしたら、マウスはシームレスにできるようになった。
再起動すると、コピペができるようになった。

###時刻の設定

以下のコマンドで現在のタイムゾーンを確認できる。

```
centos$ timedatectl status
```

日本に設定。

```
centos$ timedatectl set-timezone Asia/Tokyo
```

###ネットワークの設定

参考サイト。
TaroSky
VirtualBoxにCentOSを入れる時にしたことまとめ
https://tarosky.co.jp/tarog/649

####VMの設定
　設定→ネットワークのアダプター１をNATに、アダプター２をホストオンリーアダプターに設定。このとき自動でvboxnet0が選択されなければ、以下のVirtualBoxの設定をしてからアダプター２の設定をする。
　なお、NATは外部NWとの接続のためで、ホストオンリーアダプターはホスト⇄ゲストとの接続のため（sshをする予定）。
####VirtualBoxの設定
ツール→ネットワーク
vboxnet0が作成されていなければ、作成をクリックしたらvboxnet0が作成される。
####CentOSの設定
以下のコマンドでGUI操作に入る。

```
centos$ nmtui
```

・enp0s3(NAT)を編集。
IPv6を無視(ignore)に、自動接続を有効に変更。
CentOSが外部インターネットに接続できるようになる。NATはVirtualBoxをルータとみなして外部インターネットに接続できるようにする。

```
centos$ ping google.com
```
などで外部との疎通を確認する。

・enp0s8(ホストオンリーアダプター)を編集
IPv4を手動設定にしてアドレスを設定。ホストOSで`ifconfig`コマンドでvboxnet0のアドレスを確認し、そのアドレスと異なるアドレスを設定する（同じセグメント内にすること。最後の数字を変えれば大抵いいはず。）。
例）vboxnet0 192.168.56.1/24　ホスト側IPアドレス
  IPv4アドレス 192.168.56.10/24　ゲスト側IPアドレス
自動接続も有効にする。
これでゲストOSとホストOSで接続できるようになる。

```
centos$ ping 192.168.56.1
```
などで、ゲスト⇄ゲスト、ホスト⇄ゲストの疎通確認をする。
※ゲスト→ホストのpingが通らない場合、ホストのインターネットを切断した上でホストのファイアウォールをオフにしてpingしてみる。

###root権限を持つ一般ユーザの作成

以下を参考。
qiita記事
一般ユーザでもroot権限が必要なコマンドを実行できるようにする方法
https://qiita.com/hana_shin/items/fe077d8910dba449b840

ユーザ(test1)作成。

```
root# useradd test1
root# passwd test1
~パスワードを設定~
```
ユーザの確認。

```
root# su - test1
test1$ id
~test1であることが分かる~
```
パスワード入力なし。

```
root# visudo -f /etc/sudoers.d/test
test1 ALL=(ALL) NOPASSWD:ALL
```
visudoコマンドはsudo権限を変更するコマンドであり、sudo権限の設定を記述したsudoersファイルを編集する。
オプション-fはsudoersファイルを指定する。

###ホスト名の設定

```
root# nmcli general hostname ホスト名
root# cat /etc/hostname
ホスト名
```

###ファイアーウォールの設定
CentOS8にはファイアウォールとしてfirewalld,nftablesが採用されている。
「ゾーン」というフィルタ条件の組み合わせを作成して、ルールを追加している。
ここではicmp,ssh,tcpを許可し、ホストからのみssh,tcpを許可する。

RemSystem Techlog
サーバー構築の基本 CentOS Linux 8のインストール後に設定する12の項目
https://www.rem-system.com/centos8-first-settings/

まず、現在設定しているゾーンを確認する。

```
root# firewall-cmd --get-default-zone
　public
root# firewall-cmd --list-all
  public (active)
  target: default
  icmp-block-inversion: no
  interfaces: インターフェース名
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```
現在はインターフェース名に対してcockpit,dhcpv6-client,sshサービスへの接続が無条件で許可されている。
①新たにゾーンを作成した上で、②デフォルトであるpublicゾーンの設定を変更する。

```
①新ゾーンmanage作成
root# firewall-cmd --new-zone=manage --permanent
接続の許可をゾーンに与える
root# firewall-cmd --zone=manage --set-target=ACCEPT --permanent
SSH,FTPを許可
root# firewall-cmd --zone=manage --add-service=ssh --permanent
root# firewall-cmd --zone=manage --add-service=ftp --permanent
接続を許可するIPアドレスを指定
root# firewall-cmd --zone=manage --add-source=ホストのIPアドレス/プレフィックス長 --permanent
設定内容反映
root# firewall-cmd --reload
root# firewall-cmd --get-active-zones
manageがあれば反映済

②publicゾーンからssh接続許可を削除（全てのIPアドレスから接続できるから）
root# firewall-cmd --remove-service=ssh --zone=public --permanent
root# firewall-cmd --reload
root# firewall-cmd --list-all
```
permanentは恒久的な設定にするオプション。

###不要サービスの自動起動停止

適切なサービスを停止したらセキュリティ向上、CPU,メモリの負担軽減に繋がる。
以下のサイトを参考にしてサービスを停止。
停止するときは個別サービス名で調べた上で行うこと。
停止設定終了後、`systemctl reboot`でサーバを再起動して反映させる。

ぴちぬしのPicoグリル
CentOS 8のサービス取捨選択
https://w7b.jp/?2020%2Fcent81_services

さくらのナレッジ
systemd編～サーバーで不要なものは動かさない～ – Linuxセキュリティ入門(1)
https://knowledge.sakura.ad.jp/21779/

Red Hat Customer Portal
3.6. 起動時間を短縮するための SYSTEMD の最適化
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/optimizing-systemd-to-shorten-the-boot-time_managing-services-with-systemd

CentOSの部屋
【サブPC 自宅サーバ化計画 CentOS7版】サービス（デーモン）の確認と不要なもの無効化
https://centos.k-labo.work/2016/04/pc_centos7_1/

停止サービス
・atd.service
 指定した時間に一度だけ自動実行するサービス。デフォで設定はないし、使用予定もないから停止。
・import-state.service ネットワークストレージからOSを起動する。しないから停止。
・irabalance.service 複数CPUで割り込み処理を行う（通常割り込み処理を行うCPUは一つだけ。）。VMはCPU１つに設定しているので停止。

他にも停止して良いサービスはあるだろうが、多いしよく分からないので触れないでおく。

###時刻同期

サーバの時刻を自動的に合わせるchronydをviで以下のとおり設定し、`systemctl restart chronyd`で再起動。

```/etc/chrony.conf
# pool 2.centos.pool.ntp.org iburst　コメント化
pool ntp.jst.mfeed.ad.jp iburst
```
iburstはオプションで、同期先のサーバに4回連続で問い合わせを行い、時刻同期を早める。
なお、上記ntp.jst.mfeed.ad.jpサーバは、「インターネットマルチフィード時刻情報提供サービス for Public」において無償提供されているもの（https://www.mfeed.ad.jp/ntp/overview.html）。
タイムゾーンは自動で変わらない。

反映されているか確認。

```
root# chronyc tracking
Leap statusがNormalnなら同期OK。

root# chronyc sources
同期先候補を確認できる。*が同期先サーバ。
```

###sshの設定

####ssh接続を行う一般ユーザの作成
今回はすでに行っているので省略する。

####ssh接続を行うユーザの設定(rootを拒否し、特定ユーザのみ許可する）

次にCentOS側でviを使用してsshの設定変更を以下のとおり行う。

```:/etc/ssh/sshd_config
行
46　PermitRootLogin no

適宜　AllowUsers ユーザ名
```

該当箇所は、viの`:set number`で行番号の付加を行なったり、`/Permit`などで検索するとすぐに見つけられる。

`PermitRootLogin`をyesからをnoに変更することで、rootでsshログインできなくなり、セキュリティが向上する（rootはユーザ名が割れているので、パスワードさえ判明すればsshログインできてしまい、rootをsshで接続できる状態＝セキュリティ的にまずい状態となる。）。
なお、最初はパスワード認証でsshを行い、接続が確認できたら公開鍵認証に切り替える。

また、`AllowUsers`にユーザ名を付記することで、そのユーザに限りsshでログインできるようになる（付記していないユーザはログインできない。）。
なお、AllowUsersは、`ユーザ名＠IPアドレス`のように、sshを許可するCentOSのユーザだけでなく、送信元IPアドレスも指定できる（正確にはホストを指定している。）。

`/etc/ssh/sshd_config`編集後は忘れずに`systemctl restart sshd.service`で再起動し、設定を反映させた後、ホストからsshログインを行う。
最初の接続だけyes/noを問われるのでyesを入力する。

```
hogehoge% ssh -l root -b 192.168.56.1(vboxnet0のIPアドレスを送信元に指定) 192.168.56.10
[root@192.168.56.10's password:
Permission denied, please try again.
```
-lはユーザの指定で、-bは送信元アドレスの指定。
この結果により、rootでssh接続できないことが分かる。
そして、許可したユーザでもsshを行い、接続を確認する。
仮にパスワード入力画面まで到達しなかったら、sshが届いていないことになるので、その時はpingが届くか確認する。
届けばNW設定は間違っていないことになるので、ファイアウォールの設定やsshの設定をもう一度確認する。
pingが届かなければIPアドレスが間違っている可能性がある。

確認事項
・ファイアーウォールでゾーンを設定した際、sshを許可する送信元IPアドレスは適切なIPアドレスを指定したか？
ホスト⇄ゲストで通信を行う際、通常使用しているホストのIPアドレスではなく、vboxnet0のIPアドレスで通信を行う。

・sshの設定ファイルなどで設定したユーザ名の大文字、小文字は本当に合っているか？
CentOSの端末でのユーザ名とGUIでのユーザ名は大文字・小文字が異なる場合がある。

####公開鍵認証の設定

以下の流れで公開鍵認証を行う。

①ホストで公開鍵と秘密鍵を作成
②公開鍵をゲストの指定ディレクトリに移す
③`sshd_config`の設定を行う
④ssh接続確認
⑤ssh接続の際のパスフレーズ入力を省略する

#####ホスト側の設定

参考にしたサイト。

自省録
「macOSからVirtualBoxのCentOSに公開鍵認証でssh接続できるようにする」
https://taeisheauton4programming.blogspot.com/2018/07/macosvirtualboxcentosssh_13.html

公開鍵と秘密鍵を作成する。

```
hogehoge% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/hogehoge/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/hogehoge/.ssh/id_rsa.
Your public key has been saved in /Users/hogehoge/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:honyarara
hogehoge@MacBook-Pro.hoge
The key's randomart image is:
+---[RSA 3072]----+
|       省略       |

+----[SHA256]-----+

```

本当に作成されているか確認。

```
hogehoge% ls .ssh/
id_rsa
id_rsa.pub
```
この中の公開鍵である`id_rsa.pub`をゲストのCentOSに移す。
色々と方法はあるが、今回は個人的に理解しやすかったscpで転送する方式で行う。

```
hogehoge% scp ~/.ssh/id_rsa.pub test1@192.168.56.10:~/
```

転送先のユーザは、ssh接続する予定のユーザを指定する。
転送したユーザのみが公開鍵認証でssh接続できる。
ssh同様パスワードが聞かれるので、入力したらゲストのホームディレクトリに転送される。

####ゲスト側（CentOS）の設定

転送された公開鍵を確認した上、公開鍵を格納するディレクトリを作成し、その中に公開鍵を入れる。
ディレクトリ名、ファイル名、権限、所有者等を間違えるとsshできないので注意する。

ディレクトリ名、ファイル名は`sshd_config`内の`AuthorizedKeysFile   .ssh/authorized_keys`の設定に合わせる。

権限は以下で指定したとおりに。

所有者等は、sshで接続する接続先のユーザにする。異なる場合はsshが拒否される。
以下は`test1`ユーザが公開鍵認証でssh接続するユーザである。

```
test1$ ls
id_rsa.pub

test1$ mkdir ~/.ssh
test1$ mv id_rsa.pub ~/.ssh/authorized_keys
test1$ chmod 700 ~/.ssh
test1$ chmod 600 ~/.ssh/authorized_keys

権限が反映されたか確認
test1$ ls -Al | grep ssh
drwx------.  2 test1 test1   29 10月 23 23:26 .ssh

test1$  ls -Al ~/.ssh/authorized_keys 
-rw-r--r--. 1 test1 test1 585 10月 23 23:25 /home/test1/.ssh/authorized_keys

所有者、グループが異なる場合（-Rでディレクトリ以下全てを変更する）
test1$ chown -R test1:test1 ~/.ssh

```

次に設定ファイルを編集する。
公開鍵認証を有効に。パスワード認証の無効は、公開鍵でssh接続が成功した後に行う。パスワード認証を有効にしていても、公開鍵認証が正しく設定できていれば、公開鍵でssh接続できる。

```:/etc/ssh/sshd_config
行
51 PubkeyAuthentication yes

```

編集終了後、`systemctl restart sshd.service`で再起動する。

####ホスト→ゲストのssh接続確認

設定が正しくできていれば接続できる。
私の場合は、誤って公開鍵ではなく秘密鍵をゲストに移してsshを行なったためか、公開鍵をゲストに移してsshをし直しても接続できなかった。
エラー内容は以下のとおり。

```:ホスト
hogehoge% ssh -l test1 192.168.56.10
test1@192.168.56.10: Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
```

```:ゲスト
test1$ tail /var/log/secure
Connection closed by authenticating user~
```
ググっても解決に繋がるものを見つけられなかったので、再度ホストで鍵を作り直し、その公開鍵をゲストに移して`authorized_keys`を上書きしたらssh接続ができるようになった。

```
hogehoge% ssh test1@192.168.56.10 
Enter passphrase for key '/Users/hogehoge/.ssh/id_rsa': 
```
パスフレーズを聞かれるので、鍵を作成したときに設定したパスフレーズを入力すれば、sshで接続できる。

公開鍵認証が成功したので、パスワード認証を無効にする。

```:ゲスト/etc/ssh/sshd_config
行 
71 PasswordAuthentication no
```

####パスフレーズの入力を省略

`ssh-agent`を使用してパスフレーズを省略する。
ssh-agentは、秘密鍵に設定されたパスフレーズの入力を自動で行なってくれる。

参考サイト
server-memo.net
「ssh-agentを使って公開鍵認証方式のsshパスワード入力を省略する方法」
https://www.server-memo.net/server-setting/ssh/ssh-agent.html

```
ssh-agent実行
hogehoge% eval `ssh-agent`

ssh-agentに秘密鍵とそのパスフレーズを登録
hogehoge% ssh-add ~/.ssh/id_rsa
Enter passphrase for .ssh/id_rsa: 
Identity added: .ssh/id_rsa (hogehoge@MacBook-Pro)

登録できたか確認
hogehoge% ssh-add -l

hogehoge% ssh -l test1 192.168.56.10
パスフレーズを聞かれずにログイン成功

ssh-agent終了
hogehoge% eval `ssh-agent -k`
```

一度ssh-agentを終了すると、登録した秘密鍵とパスフレーズも終了するので、再度登録し直す必要がある。