Ubuntu Serverのセキュリティ設定の一例

# はじめに
[諸事情](#諸事情)によりUbuntu Serverを導入したけど、セキュリティ設定に手間取ったので今後のためにもメモとして記事に残しっておこうという感じです。

:::note warn
注意
あくまでセキュリティ設定の一例（一部）をご紹介するレベルです。
サーバ運用する上でセキュリティを担保するためには本記事で紹介する項目以外にも使用するミドルウェアやプロダクトに対してセキュアな設定を行う必要があります。
:::


# 環境
「Ubuntu 24.04.2 LTS」です。

# 設定項目
以下の設定の仕方を本記事では記載しています。
1. Firewall(ufw)
1. SSHサーバ設定
1. TCPwrapper
1. Anti-Virus(Clamav)

次節から上記項目の内容の設定例を記載していきます。

# Firewall
今回はufwを使用しましたので、設定方法の例を記載します。
今回の環境（Ubuntu 24.04.2 LTS）には、デフォルトでufwがインストールされておりましたので設定から始めています。
まずは、ufwをアクティブ化する必要があります。
```bash:ufw起動
$ sudo ufw status
Status: inactive      '初期は非アクティブ状態のため、アクティブにする必要があります'

$ sudo ufw enable
$ sudo ufw status
Status: active      'アクティブ化されていることを確認！'
```

デフォルト設定は以下のコマンド確認可能です。

```bash:初期設定確認
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
```
:::note info
デフォルト設定内容
- 外部から内部への通信（incoming)は、拒否となっており遮断されています
- 内部から外部へ通信(outgoing）は、許可となっています
:::

このままだと、SSHを使用してリモート操作できないためSSHのポートを開放します。
```bash:SSH(22)を開放
$ sudo ufw allow 22/tcp
```
:point_up:これは、これでOKですが、外部公開サーバで行う場合は、以下の観点でセキュリティを意識すると物足りない感じがあります。
1. SSHのポートが「22」はウェルノウンポートで、外部の攻撃者からの攻撃を受けやすい
1. 通信元が絞られていないため、不特定のネットワークセグメントから通信を許可されている

1.については、次節のSSHの設定でポート番号を変更して待受ける方法を提示します。
仮にここでは、待受ポートを仮に「1022」にした場合の設定例を記載します。
```bash:SSHの許可設定
'通信元のアドレスセグメント：10.32.0.0'
'自（通信先）サーバIPアドレス：10.32.0.xx'
$ sudo ufw allow from 10.32.0.0/24 to 10.32.0.xx port 1022 proto tcp
```
自サーバに複数のネットワークインターフェース（NIC）がある場合はネットワークインターフェースを絞ることでよりセキュアに扱えると思います。
この設定は@teyama3さんが公開している[「UFWを活用して特定の通信のみ許可する」](https://qiita.com/teyama3/items/6bfe1db6328d3678fcf4)という記事がわかりやすいです。

# SSHサーバ設定
セキュアにリモート操作するためには、待受ポートや認証方法を制限する必要があります。
公開鍵認証にして、セキュリティを高めた方が良いと思います。

***:warning:ここが手間取ったところになります。***
***一昔前は設定を記載するファイルは「/etc/ssh/sshd_config」でした。***
最近のOpenSSHは設定ファイルが別にあります。
***「/etc/ssh/sshd_config.d/*.conf」です。***

「/etc/ssh/sshd_config」に以下の記載があり、「/etc/ssh/sshd_config.d/」配下にあるconfファイルを
読み込みます。
```config:「/etc/ssh/sshd_config」抜粋
Include /etc/ssh/sshd_config.d/*.conf
```
読み込んだconfファイルの内容が優先されます。
「/etc/ssh/sshd_config.d/50-cloud-init.conf」が既に存在しており以下の記載がされています。
```config:「/etc/ssh/sshd_config/50-cloud-init.conf」
PasswordAuthentication yes
```
パスワード認証を有効にする設定が記載されています。
パスワード認証を不可にしたい場合、「/etc/ssh/sshd_config.d/」の読み込まれる優先度についても考慮する必要があります。

:::note info
「/etc/ssh/sshd_config.d/」配下のconfファイルの読み込み優先度
ファイルの名前順に読み込まれ、先に読み込まれた設定が優先されます。
:::

今回は「10-custom.conf」という名前でSSHサーバの設定ファイルを記載します。
```config:「/etc/ssh/sshd_config/10-custom.conf」
#待受ポート設定
Port 1022

#プロトコルバージョン１は脆弱性があるため、バージョン２のみ受付けるようにする。
Protocol 2

#rootログインを拒否する
PermitRootLogin no

#SSHバージョン１での公開鍵認証を拒否する。Protocolで使用できるバージョンを絞っているが念のため設定
RSAAuthentication no

#SSHバージョン２で公開鍵認証を許可する
PubkeyAuthentication yes

#空パスワードを拒否する
PermitEmptyPasswords no

#パスワード認証拒否する
PasswordAuthentication no

# ログイン試行回数を制限する（3回）
MaxAuthTries 3

#ログイン試行時間を制限する（30秒）
LoginGraceTime 30

#SSHを利用するユーザを制限する
AllowUsers  User
```

## 公開鍵の作成方法
以下の手順で公開鍵を作成して、サーバに登録します。
```bash:公開鍵を作成して、サーバに登録する
$ ssh-keygen -t ed25519

$ cat publickey >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

'publickeyはもう不要なので削除する'
$ rm publickey
```

# TCPwrapper
TCPWrapperはホスト名やIPアドレスによってアクセス制御を行うことができます。
許可内容を記載する「/etc/hosts.allow」と拒否内容を記載する「/etc/hosts.deny」で設定します。

```configuration:/etc/hosts.allow
sshd: 10.32.0.
```
```configuration:/etc/hosts.deny
ALL: ALL
```

:::note info
/etc/hosts.denyで全てのアクセスを禁止した上で、/etc/hosts.allowで許可する対象を追加するのが、抜け漏れなく設定するポイントです。
:::
:::note info
/etc/hosts.allowで「10.32.0.」は書き損じではありません。
10.32.0.0/24セグメントをしています。つまり、第４オクテットのワイルドカード「10.32.0.*」を意味しています。
:::

# Anti-Virus(Clamav)
Linuxで使用できるウイルス対策ソフトはほぼ商用版であり、一般家庭向け用に導入できるものは少ないです。
そこでオープンソースのウイルス対策ソフトであるClamavを導入します。
導入方法は[公式サイト](https://docs.clamav.net/manual/Installing.html)に記載の通りコマンド実行します。

```bash:clamavインストール
$ sudo apt install clamav
$ sudo apt install clamav-daemon
$ sudo systemctl start clamav-daemon
$ sudo systemctl enable clamav-daemon
```

## ウィルス定義の更新
以下コマンドで実施するが、エラーが発生します。
```bash:ウィルス定義更新
$ sudo freshclam
ERROR: /var/log/clamav/freshclam.log is locked by another process
ERROR: Problem with internal logger (UpdateLogFile = /var/log/clamav/freshclam.log).
ERROR: initialize: libfreshclam init failed.
ERROR: Initialization error!
```

対象方法
1. ログファイルを一度削除する
1. ログローテートの設定を変更する

```bash:ログファイルを一度削除
$ sudo rm /var/log/clamav/freshclam.log
$ sudo touch /var/log/clamav/freshclam.log
$ sudo chown clamav:clamav /var/log/clamav/freshclam.log
```

```bash:ログローテート設定を変更する
$ sudo vim /etc/logrotate.d/clamav-freshclam

＜修正箇所＞
create 640 clamav adm
           ↓
create 640 clamav clamav
```

## ウィルススキャン
/homeディレクトリを再帰的に対象としてスキャンする方法は以下です。

```bash:ウィルススキャン
$ cd
$ sudo clamscan -r
```

ウィルスを検知しても自動で削除されないため、スキャン時に自動削除する場合は以下のようにします。
```bash:ウィルス自動削除
$ sudo clamscan --remove
```

# 参考資料
1. [UFWを活用して特定の通信のみ許可する](https://qiita.com/teyama3/items/6bfe1db6328d3678fcf4)
1. [SSH公開鍵認証で接続するまで](https://qiita.com/kazokmr/items/754169cfa996b24fcbf5)
1. [PasswordAuthenticationで躓いたお話](https://zenn.dev/ochanoma/articles/f354be22ecb4cb)
1. [Ubuntu22.04 sshdでPasswordAuthentication noが効かない](https://rohhie.net/ubuntu22-04-password-authentication-does-not-work/)
1. [clamAV](https://docs.clamav.net/)
1. [【徹底解説】Ubuntu22.04にClamAVをインストール・設定する方法！](https://bytes-box.com/install-clamav/)
1. [Ubuntu 20.04にClamAVというアンチウイルスソフトをインストールする](https://shimakaze-soft-tech.hatenablog.com/entry/2021/11/27/210157)
1. [【Ubuntu 20.04/18.04 LTS Server】ClamAVで定期的にウイルスチェックし、メール通知する](https://www.yokoweb.net/2017/04/15/ubuntu-server-clamav/)
1. [【2024年08月版】Ubuntu でウイルス対策【clamav】](https://qiita.com/nouernet/items/4b5a01bba7d3ceb2d42c)


# 諸事情
記事とは直接関係ないけど、Desktop版を使用したという思いもあるので解決策をお持ちの方がいらっしゃればご教授ください！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">24.04.02 LTS Desktopにアップグレードしたら、またGUI起動しなくなった。<br>ということで、最初から24.04.02 LTS Desktopを入れてやるぜということで、isoをダウンロード中。<br>↑学習能力ないだろうと突っ込まれればそれまでだけど、やります。<br>次ダメなら、Server版入れてSSHで使おう。 <a href="https://t.co/p6c8whvcrv">https://t.co/p6c8whvcrv</a></p>&mdash; LittleBear🐻 (@littlebear_6w6) <a href="https://twitter.com/littlebear_6w6/status/1898280368782164010?ref_src=twsrc%5Etfw">March 8, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">SSH設定に手こずったのでQiitaにメモを作ろう！</p>&mdash; LittleBear🐻 (@littlebear_6w6) <a href="https://twitter.com/littlebear_6w6/status/1898606102125973572?ref_src=twsrc%5Etfw">March 9, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>