
Linuxサーバーの堅牢化のためのステップバイステップガイド。SSHセキュリティ、ファイアウォール、侵入検知、監査、システム設定を網羅し、攻撃対象領域を減らし防御を強化します。
Linuxサーバーをセキュアにするための進化するハウツーガイドです。セキュリティとその重要性について少しでも学べることを願っています。
(目次はnGitHubTOCで作成)
このガイドの目的は、Linuxサーバーをセキュアにする方法を教えることです。
Linuxサーバーをセキュアにするためには多くの方法があり、このガイドでは可能な限り多くの方法をカバーしようと試みます。私が学習したり、貢献してくださった方々の情報をもとに、トピック/資料を追加していきます。
このガイドのAnsibleプレイブックは、moltenbitによるHow To Secure A Linux Server With Ansibleで入手できます。
(目次に戻る)
このガイドを使用しているということは、おそらく、良いセキュリティがなぜ重要かをすでに理解されているものと思います。それはそれ自体が大きなトピックであり、詳細を説明することはこのガイドの範囲外です。もしその答えがわからない場合は、まず調査することをお勧めします。
高いレベルで言えば、サーバーなどのデバイスがパブリックドメイン、つまり外部から見える状態になった瞬間、それは悪意ある行為者の標的になります。セキュリティ対策がされていないデバイスは、あなたのデータにアクセスしたい、あるいはあなたのサーバーを大規模なDDoS攻撃の別のノードとして利用したい悪意ある行為者にとっての遊び場です。
さらに悪いことに、適切なセキュリティがなければ、サーバーが侵害されたことに気づかないかもしれません。悪意ある行為者があなたのサーバーに不正アクセスし、何も変更せずにデータをコピーした場合、あなたは決して気づかないでしょう。あるいは、あなたのサーバーがDDoS攻撃の一部になっても、気づかないかもしれません。ニュースで報じられる大規模なデータ漏洩の多くを見てください——企業は、悪意ある行為者が去ったずっと後になってからデータ漏洩や侵入を発見することがよくあります。
一般的な信念に反して、悪意ある行為者が常に何かを変更したり、データを人質に取って金銭を要求するとは限りません。時には、データウェアハウス(ビッグデータには大きなお金が動く)のためにあなたのサーバー上のデータを欲しがるだけ、あるいは隠密にあなたのサーバーを自分たちの邪悪な目的に利用することもあります。
(目次に戻る)
このガイドは重複/不要に見えるかもしれません。なぜなら、Linuxをセキュアにする方法については無数の記事がオンラインに存在しますが、情報は異なる記事に散らばっており、それぞれ異なる内容を異なる方法でカバーしているからです。何百もの記事をくまなく調べる時間がある人はいないでしょう。
Debianビルドのための調査を行う中で、私はメモを取り続けました。そして最後に、すでに知っていること、学んでいることと合わせて、ハウツーガイドの材料が揃っていることに気づきました。他の人が学び、時間を節約する助けになればと思い、オンラインに公開することにしました。
すべてを網羅する一つのガイドには出会ったことがありません——このガイドはその試みです。
このガイドでカバーする多くのことはかなり基本的/些細なことかもしれませんが、私たちのほとんどは毎日Linuxをインストールするわけではなく、そうした基本的なことを忘れがちです。
(目次に戻る)
専門家、業界リーダー、ディストリビューション自体が提供する多くのガイドがあります。それらのガイドからすべてを含めることは現実的でなく、著作権に反する場合もあります。このガイドを始める前に、それらを確認することをお勧めします。
(目次に戻る)
(目次に戻る)
このガイドは...
(目次に戻る)
サーバーには多くの種類と異なるユースケースがあります。このガイドをできるだけ汎用的にしたい一方で、すべての/他のユースケースに当てはまらない項目もあるでしょう。このガイドを進める際には、ご自身の判断を最善に使ってください。
このガイドでカバーされる多くのトピックに文脈を与えるために、私のユースケース/設定は以下の通りです:
(目次に戻る)
私はとても怠け者で、必要がなければ手動でファイルを編集したくありません。また、他の人も皆私と同じだと仮定しています :)
そのため、可能な限り、設定ファイルに行を追加したり変更したりするなど、必要なことを素早く行うためのコードスニペットを提供しました。
コードスニペットは、echo、cat、sed、awk、grepなどの基本的なコマンドを使用しています。スニペットがどのように動作するか(各コマンド/部分が何をするか)は、このガイドの範囲外です——manページがあなたの友達です。
注意: コードスニペットは、変更が実際に行われたか(つまり、行が実際に追加または変更されたか)を検証/確認しません。確認部分はあなたの有能な手に委ねます。このガイドの手順では、変更されるすべてのファイルのバックアップを取ることを含めています。
すべての変更をコードスニペットで自動化できるわけではありません。そうした変更は、昔ながらの手動編集が必要です。例えば、INIタイプのファイルに行を単純に追加することはできません。お気に入りのvi Linuxテキストエディタを使用してください。
(目次に戻る)
コラボレーションを容易にするために、このガイドをGitHubに置くことにしました。貢献してくれる人が増えれば増えるほど、このガイドはより良く、より完全になります。
貢献するには、フォークしてプルリクエストを送信するか、新しいIssueを提出してください。
(目次に戻る)
始める前に、あなたの原則は何かを明確にしたいでしょう。あなたの脅威モデルは何ですか?考えるべきいくつかのこと:
これらは考慮すべきほんの一部です。サーバーのセキュア化を始める前に、何に対して、なぜ防御しようとしているのかを理解し、何をする必要があるかを把握したいでしょう。
(目次に戻る)
このガイドはディストリビューションに依存しないように意図されているため、ユーザーは任意のディストリビューションを使用できます。とはいえ、留意すべきいくつかの点があります:
以下の条件を満たすディストリビューションを選びたいところです:
(目次に戻る)
Linuxのインストールはこのガイドの範囲外です。各ディストリビューションで方法が異なり、インストール手順は通常十分に文書化されているためです。助けが必要な場合は、まずディストリビューションのドキュメントを参照してください。ディストリビューションに関わらず、大まかなプロセスは通常以下の通りです:
該当する場合は、エキスパートインストールオプションを使用して、サーバー上で実行されるものを厳密に制御してください。絶対に必要なものだけをインストールしてください。 私は個人的に、SSH以外は何もインストールしません。また、ディスク暗号化オプションにチェックを入れてください。
(目次に戻る)
sudo apt update && sudo apt upgrade)。/etc/fstab でのマウントポイントの設定man など、必要なコアソフトウェアのインストール(目次に戻る)
apt コマンドを提供します。他のディストリビューションのそれぞれのコマンドを提供してくれる方がいれば、追加します。(目次に戻る)
このガイドのAnsibleプレイブックは、How To Secure A Linux Server With Ansibleで入手できます。変数は必要に応じて編集し、システムを壊さないことを確認するために、すべてのタスクを事前に読んでください。プレイブックを実行した後、すべての設定がニーズに合わせて構成されていることを確認してください!
5. すべての変数を*group_vars/variables.yml*内で必要に応じて変更してください。
6. プレイブックを実行する前にSSH rootアクセスを有効にしてください: ```
nano /etc/ssh/sshd_config
[...]
PermitRootLogin yes
[...]
サーバーインストール時に指定したrootパスワードを使用して、要件プレイブックを実行します:
ansible-playbook --inventory hosts.yml --ask-pass requirements-playbook.yml
variables.yml ファイルで指定した新しいユーザーのパスワードを使用して、メインプレイブックを実行します:
ansible-playbook --inventory hosts.yml --ask-pass main-playbook.yml
プレイブックを複数回実行する必要がある場合は、SSHキーと新しいSSHポートを使用することを忘れないでください:
ansible-playbook --inventory hosts.yml -e ansible_ssh_port=SSH_PORT --key-file /PATH/TO/SSH/KEY main-playbook.yml
(目次)
SSH設定の変更を 行って適用する前に、サーバーへの2つ目のターミナルを開いておくことを強くお勧めします。 こうすることで、1つ目のターミナルセッションからロックアウトされた場合でも、まだ接続中のセッションが残っているため、修正できます。
このアイデアを提供してくれた Sonnenbrand に感謝します。
SSH公開鍵/秘密鍵を使用することは、パスワードを使用するよりも安全です。また、パスワードを入力する必要がないため、サーバーへの接続がより簡単かつ高速になります。
詳細については以下の参考文献を確認してください。しかし、高いレベルでは、公開鍵/秘密鍵は、一対の鍵を使用して身元を確認することで機能します。
SSHの場合、クライアントで公開鍵と秘密鍵が作成されます。両方の鍵、特に秘密鍵は安全に保つ必要があります。公開鍵は公開されることを意図していますが、どちらの鍵も悪意のある者の手に渡らないようにすることが賢明です。
SSHサーバーに接続すると、SSHは接続元のクライアントに一致する公開鍵を、接続先サーバーの ~/.ssh/authorized_keys ファイル内で探します。このファイルは、接続しようとしているIDのホームフォルダにあることに注意してください。そのため、公開鍵を作成したら、それを ~/.ssh/authorized_keys に追加する必要があります。1つの方法として、USBメモリにコピーして物理的にサーバーに転送する方法があります。別の方法としては、ssh-copy-id を使用して公開鍵を転送し追加する方法があります。
鍵が作成され、公開鍵がホスト上の ~/.ssh/authorized_keys に追加された後、SSHは公開鍵と秘密鍵を使用して身元を確認し、安全な接続を確立します。身元確認の方法は複雑なプロセスですが、Digital Ocean にその仕組みの非常に良い解説があります。高いレベルでは、サーバーが公開鍵でチャレンジメッセージを暗号化し、それをクライアントに送信することで身元が確認されます。クライアントが秘密鍵でチャレンジメッセージを復号化できない場合、身元は確認されず、接続は確立されません。
PasswordAuthentication no を /etc/ssh/sshd_config に設定した場合、SSHは秘密鍵なしでは接続を許可しないため、秘密鍵が必要であるという点で、これらはより安全であると考えられています。
鍵にパスフレーズを設定することもできます。その場合、公開鍵/秘密鍵を使用して接続する際に、鍵のパスフレーズを入力する必要があります。これを行うと、スクリプト内でパスフレーズを送信する方法がないため、自動化に鍵を使用できなくなることに注意してください。ssh-agent は、多くのLinuxディストリビューションに同梱されている(通常はすでに実行されている)プログラムで、構成可能な期間、暗号化されていない秘密鍵をメモリに保持できます。単に ssh-add を実行すると、パスフレーズを求められます。構成可能な期間が経過するまで、再度パスフレーズを求められることはありません。
ここでは、https://linux-audit.com/ によると、Ed25519鍵を使用します。
楕円曲線署名スキームを使用しており、ECDSAやDSAよりも優れたセキュリティを提供します。同時に、パフォーマンスも良好です。
man ssh-keygenman ssh-copy-idman ssh-addサーバーに接続するために使用するコンピューター(クライアント。サーバー自体ではありません)から、ssh-keygen を使用して Ed25519 鍵を作成します:
ssh-keygen -t ed25519
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_ed25519. Your public key has been saved in /home/user/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client The key's randomart image is: +--[ED25519 256]--+ |xxxx x | |o.o +. . | | o o oo . | |. E oo . o . | | o o. o S o | |... .. o o | |.+....+ o | |+.=++o.B.. | |+..=**=o=. | +----[SHA256]-----+
注: パスフレーズを設定した場合、ssh-agent を使用していない限り、この鍵を使用してサーバーに接続するたびにパスフレーズを入力する必要があります。
次に、クライアントの公開鍵 ~/.ssh/id_ed25519.pub をサーバーの ~/.ssh/authorized_keys ファイルにする必要があります。まだLAN上の自宅にいると思われるため、おそらく攻撃からは安全なので、 を使用して公開鍵を転送し追加します:
ここで、セットアップ固有のタスクを実行するのに良いタイミングです。
(目次)
サーバーへのSSH接続を誰に許可するかを簡単に制御できるようにするため。グループを使用することで、グループへのアカウントの追加/削除を迅速に行い、サーバーへのSSHアクセスを迅速に許可または許可しないようにできます。
SSHの設定ファイル /etc/ssh/sshd_config 内の AllowGroupsオプション を使用して、特定のUNIXグループのメンバーであるユーザーのみSSH接続を許可するようにSSHサーバーに指示します。グループに属さないユーザーはSSH接続できません。
/etc/ssh/sshd_config で使用するUNIXグループ。サーバーへのSSH接続を制限するために使用します。/etc/ssh/sshd_config で設定される AllowGroup 設定をサポートするための前提条件の手順です。man groupaddman usermodグループを作成します:
sudo groupadd sshusers
グループにアカウントを追加します:
sudo usermod -a -G sshusers user1
sudo usermod -a -G sshusers user2
sudo usermod -a -G sshusers ...
サーバー上でSSHアクセスが必要なすべてのアカウントに対してこれを行う必要があります。
(目次)
/etc/ssh/sshd_config のセキュリティ強化SSHはサーバーへの扉です。これは、自宅のネットワーク外からサーバーにSSH接続できるようにルーターでポートを開放している場合に特に当てはまります。適切にセキュリティ保護されていない場合、悪意のある行為者がそれを使用してシステムに不正アクセスする可能性があります。
/etc/ssh/sshd_config は、SSHサーバーが使用するデフォルトの設定ファイルです。このファイルを使用して、SSHサーバーが使用するオプションを指定します。
man sshd_configOpenSSHサーバーの設定ファイル /etc/ssh/sshd_config のバックアップを作成し、コメントを削除して読みやすくします:
sudo cp --archive /etc/ssh/sshd_config /etc/ssh/sshd_config-COPY-$(date +"%Y%m%d%H%M%S")
sudo sed -i -r -e '/^#|^$/ d' /etc/ssh/sshd_config
/etc/ssh/sshd_config を編集し、構成/セットアップに関係なく適用されるべき以下の設定を見つけて編集するか追加します:
注: SSHは重複した矛盾する設定を好みません。例えば、ChallengeResponseAuthentication no と ChallengeResponseAuthentication yes の両方がある場合、SSHは最初のものを尊重し、2番目を無視します。/etc/ssh/sshd_config ファイルには、以下の設定/行の一部がすでに含まれている可能性があります。問題を回避するには、手動で /etc/ssh/sshd_config ファイルを確認し、重複した矛盾する設定に対処する必要があります。
注: OpenSSH 9.1以降を実行している場合、以下の設定で RequiredRSASize 3072 行のコメントを解除してください。これにより、最小RSA鍵サイズが3072ビットに強制され、認証時にそれより小さいRSA鍵が拒否されます。これはRSA鍵にのみ影響します。ED25519またはECDSA鍵を使用している場合、影響はありません。鍵のタイプとサイズは ssh-keygen -l -f ~/.ssh/id_rsa で確認できます。古いバージョンのOpenSSHでは、この行はコメントアウトしたままにしてください。コメントを解除するとsshdが起動しなくなります。
########################################################################################################
# start settings from https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 as of 2019-01-01
########################################################################################################
# Supported HostKey algorithms by order of preference.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
# Use kernel sandbox mechanisms where possible in unprivileged processes
# Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere.
# Note: This setting is deprecated in OpenSSH 7.5 (https://www.openssh.com/txt/release-7.5)
# UsePrivilegeSeparation sandbox
########################################################################################################
# end settings from https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 as of 2019-01-01
########################################################################################################
# don't let users set environment variables
PermitUserEnvironment no
# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO
# disable X11 forwarding as X11 is very insecure
# you really shouldn't be running X on a server anyway
X11Forwarding no
# disable port forwarding
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
# don't allow login if the account has an empty password
PermitEmptyPasswords no
# ignore .rhosts and .shosts
IgnoreRhosts yes
# verify hostname matches IP
UseDNS yes
Compression no
# TCP keepalive is spoofable (runs outside the encrypted channel)
# Use ClientAlive instead (runs inside the encrypted channel)
TCPKeepAlive no
AllowAgentForwarding no
PermitRootLogin no
# don't allow .rhosts or /etc/hosts.equiv
HostbasedAuthentication no
# OpenSSH 9.1 and later
# Enforce a minimum RSA key size of 3072 bits
# https://www.keylength.com/en/compare/
# RequiredRSASize 3072
# https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/115
HashKnownHosts yes
(目次)
MozillaのOpenSSH 6.7+向けOpenSSHガイドライン によると、「使用されるすべてのDiffie-Hellmanモジュラスは少なくとも3072ビット長であるべき」です。
Diffie-Hellmanアルゴリズムは、SSHが安全な接続を確立するために使用されます。モジュラス(鍵サイズ)が大きいほど、暗号化は強力になります。
man moduliSSHのモジュラスファイル /etc/ssh/moduli のバックアップを作成します:
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")
短いモジュラスを削除します:
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
(目次)
SSHはドアや窓のための非常に優れたセキュリティガードですが、それでも悪意のある行為者が見てブルートフォース攻撃を仕掛けようとする可能性のある目に見えるドアです。Fail2ban はこれらのブルートフォース試行を監視しますが、安全すぎるということはありません。2要素認証を要求することで、セキュリティの層が追加されます。
2要素認証(2FA)/多要素認証(MFA)を使用すると、入室するすべての人が2つの鍵を必要とします。これにより、悪意のある行為者の攻撃が難しくなります。2つの鍵は次のとおりです:
両方の鍵がなければ、彼らは入れません。
多くの人は、このエクスペリエンスを面倒または煩わしいと感じるかもしれません。また、システムへのアクセスは、コードを生成する付属の認証アプリに依存します。
Linuxでは、PAMが認証を担当します。PAMには4つのタスクがあり、詳細は https://en.wikipedia.org/wiki/Linux_PAM で読むことができます。このセクションでは、認証タスクについて説明します。
コンソールから直接であれSSH経由であれ、サーバーにログインすると、使用したドアは認証タスクのPAMにリクエストを送信し、PAMはパスワードを要求して検証します。各ドアが使用するルールをカスタマイズできます。たとえば、コンソールから直接ログインする場合とSSH経由でログインする場合で異なるルールセットを設定できます。
このセクションでは、SSH経由でログインする際の認証ルールを変更し、パスワードと6桁のコードの両方を要求するようにします。Googleのlibpam-google-authenticator PAMモジュールを使用して、TOTPキーを作成し検証します。https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/ と https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/ には、TOTPの仕組みについて非常に良い解説があります。
ここで行うことは、サーバーのSSH PAM設定に対して、ユーザーにパスワードを入力させ、次に数値トークンを入力させるように指示することです。PAMはユーザーのパスワードを検証し、正しければ、認証要求をlibpam-google-authenticatorにルーティングします。libpam-google-authenticatorは6桁のトークンを要求して検証します。全てが良好である場合にのみ認証が成功し、ユーザーはログインを許可されます。
libpam-google-authenticatorをインストールします。
Debian系システムの場合:
sudo apt install libpam-google-authenticator
2FA/MFAを有効にしたいユーザーIDでログインしていることを確認し、google-authenticatorを実行して必要なトークンデータを作成します:
google-authenticator
Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@host%3Fsecret%3DR4ZWX34FQKZROVX7AGLJ64684Y%26issuer%3Dhost ... Your new secret key is: R3NVX3FFQKZROVX7AGLJUGGESY Your verification code is 751419 Your emergency scratch codes are: 12345678 90123456 78901234 56789012 34567890 Do you want me to update your "/home/user/.google_authenticator" file (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, tokens are good for 30 seconds. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of +-1min (window size of 3) to about +-4min (window size of 17 acceptable tokens). Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
sudoを使用すると、アカウントは他のアカウント(rootを含む)としてコマンドを実行できます。sudoを使用できるアカウントを指定したものだけに制限したいと考えます。
Debianはsudoグループを作成します。このグループに属するユーザー(sudo権限を持つユーザー)を表示するには:
cat /etc/group | grep "sudo"
RedHatはwheelグループを作成します
グループを作成します:
sudo groupadd sudousers
アカウントをグループに追加します:
sudo usermod -a -G sudousers user1
sudo usermod -a -G sudousers user2
sudo usermod -a -G sudousers ...
サーバー上でsudo権限を必要とするすべてのアカウントに対してこれを行う必要があります。
sudoの設定ファイル /etc/sudoers のバックアップを作成します:
sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
sudoの設定ファイル /etc/sudoers を編集します:
sudo visudo
sudousers グループのユーザーだけがsudoを使用できるように、以下の行がまだない場合は追加します:
%sudousers ALL=(ALL:ALL) ALL
suもまた、アカウントが他のアカウント(rootを含む)としてコマンドを実行できるようにします。suを使用できるアカウントを指定したものだけに制限したいと考えます。
グループを作成します:
sudo groupadd suusers
アカウントをグループに追加します:
sudo usermod -a -G suusers user1
sudo usermod -a -G suusers user2
sudo usermod -a -G suusers ...
サーバー上でsudo権限を必要とするすべてのアカウントに対してこれを行う必要があります。
このグループのユーザーだけが /bin/su を実行できるようにします:
sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
多くのアプリケーションにとって、サンドボックス内で実行することは絶対的に良いことです。
ブラウザ(特にクローズドソースのもの)やメールクライアントは強く推奨されます。
ソフトウェアをインストールします:
sudo apt install firejail firejail-profiles
注意: Debian 10 Stableでは、公式のバックポートが推奨されます:
sudo apt install -t buster-backports firejail firejail-profiles
アプリケーション(/usr/bin または /bin にインストールされているもの)がサンドボックス内でのみ実行されるように許可します(以下にいくつかの例を示します):
sudo ln -s /usr/bin/firejail /usr/local/bin/google-chrome-stable
sudo ln -s /usr/bin/firejail /usr/local/bin/firefox
sudo ln -s /usr/bin/firejail /usr/local/bin/chromium
sudo ln -s /usr/bin/firejail /usr/local/bin/evolution
sudo ln -s /usr/bin/firejail /usr/local/bin/thunderbird
アプリケーションを通常通り(ターミナルまたはランチャーから)実行し、ジェイル内で動作しているか確認します:
firejail --list
サンドボックス化されたアプリケーションを以前のように再び実行できるようにします(例: firefox):
sudo rm /usr/local/bin/firefox
多くのセキュリティプロトコルは時刻に依存します。システム時刻が正しくない場合、サーバーに悪影響を及ぼす可能性があります。NTPクライアントは、システム時刻をグローバルNTPサーバーと同期させることでこの問題を解決します。
NTPはNetwork Time Protocolの略です。このガイドの文脈では、サーバー上のNTPクライアントを使用して、公式のNTPサーバーから取得した公式時刻でサーバー時刻を更新します。すべての公開NTPサーバーについては https://www.pool.ntp.org/en/ を確認してください。
注意: Debian 13 (Trixie) 以降では、従来の
ntpパッケージは削除されました。sudo apt install ntpを実行すると "Package ntp has no installation candidate" で失敗します。このガイドではNTPをクライアントとしてのみ使用する(サーバーの時計を同期する)ため、Debian 13+ ではsystemd-timesyncdを使用することを推奨します。これは既にプリインストールされており、追加のパッケージは必要ありません。以下のDebian 13+ の手順を参照してください。
systemd-timesyncd は軽量なSNTPクライアントで、Debianに既に含まれています。完全な ntpd デーモンとは異なり、ポートをリッスンしないため、攻撃対象領域が小さくなります。このガイドの目的(サーバーの時計を同期させる)には、これで十分です。
NTP同期を有効にします:
sudo timedatectl set-ntp true
動作を確認します:
timedatectl status
出力に NTP service: active と System clock synchronized: yes が表示されるはずです。
信頼できるNTPサーバーを設定します。設定ファイルのバックアップを作成してから編集します:
sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")
/etc/systemd/timesyncd.conf を編集し、[Time] セクションのコメントを外すか設定します:
[Time]
NTP=pool.ntp.org
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org
sudo sed -i -r -e "s/^#?NTP=.*$/NTP=pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
sudo sed -i -r -e "s/^#?FallbackNTP=.*$/FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
注意: これらの手順はDebian 12以前にのみ適用されます。Debian 13+では
ntpパッケージは利用できません。代わりに上記のsystemd-timesyncdの手順を使用してください。
ntpをインストールします。
Debian系システムの場合:
sudo apt install ntp
NTPクライアントの設定ファイル /etc/ntp.conf のバックアップを作成します:
sudo cp --archive /etc/ntp.conf /etc/ntp.conf-COPY-$(date +"%Y%m%d%H%M%S")
デフォルトの設定は、少なくともDebianでは、すでにかなり安全です。唯一確認すべきことは、pool ディレクティブを使用し、server ディレクティブを使用しないことです。pool ディレクティブを使用すると、応答がない場合や悪い時刻を提供する場合にNTPクライアントがサーバーの使用を停止できます。これを行うには、すべての server ディレクティブをコメントアウトし、以下の内容を /etc/ntp.conf に追加します。
pool pool.ntp.org iburst
sudo sed -i -r -e "s/^((server|pool).*)/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/ntp.conf
echo -e "\npool pool.ntp.org iburst # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ntp.conf
https://linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/ からの引用:
/procを見ると、多くのファイルやディレクトリが見つかります。その多くは単なる数字であり、特定のプロセスID (PID) に関する情報を表しています。デフォルトでは、Linuxシステムはすべてのローカルユーザーがこのすべての情報を閲覧できるようにデプロイされています。これには他のユーザーのプロセス情報が含まれ、共有したくない機密情報が含まれる可能性があります。ファイルシステムの設定をいくつか調整することで、この動作を変更し、システムのセキュリティを向上させることができます。
注意: 一部の systemd システムでこれが機能しない場合があります。詳細については https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37 を参照してください。情報提供をしてくれたnlgrangerに感謝します。
/proc を hidepid=2 でマウントし、ユーザーが自分のプロセスに関する情報のみを表示できるようにする/etc/fstab のバックアップを作成します:
sudo cp --archive /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")
以下の行を /etc/fstab に追加して、/proc を hidepid=2 でマウントします:
proc /proc proc defaults,hidepid=2 0 0
echo -e "\nproc /proc proc defaults,hidepid=2 0 0 # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/fstab
システムを再起動します:
sudo reboot now
注意: 再起動せずに sudo mount -o remount,hidepid=2 /proc で /proc を再マウントすることもできます。
デフォルトでは、アカウントは望む任意のパスワード(悪いものを含む)を使用できます。pwquality/pam_pwquality は、「システムパスワードのデフォルトのパスワード品質要件を設定する方法」を提供し、「システム辞書および不適切な選択を特定するための一連のルールに対して強度をチェック」することで、このセキュリティギャップに対処します。
Linuxでは、PAMが認証を担当します。PAMには4つのタスクがあり、https://en.wikipedia.org/wiki/Linux_PAM で読むことができます。このセクションではパスワードタスクについて説明します。アカウントのパスワードを設定または変更する必要がある場合、PAMのパスワードタスクが要求を処理します。このセクションでは、PAMのパスワードタスクが要求された新しいパスワードをlibpam-pwqualityに渡して、要件を満たしているか確認するよう指示します。要件を満たしている場合は使用/設定され、満たしていない場合はエラーを返してユーザーに通知します。
libpam-pwqualityをインストールします。
Debianベースのシステムの場合:
sudo apt install libpam-pwquality
PAMのパスワード設定ファイル /etc/pam.d/common-password のバックアップを作成します:
sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
ファイル /etc/pam.d/common-password を編集し、次のように始まる行を変更して、PAMがlibpam-pwqualityを使用して強力なパスワードを強制するように指示します:
現在:
password requisite pam_pwquality.so
変更後:
password requisite pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec
上記のオプションの説明:
retry=3 = エラーを返す前にユーザーに3回入力を求める。minlen=10 = 以下のクレジット(またはデビット)を考慮したパスワードの最小長:
dcredit=-1 = 少なくとも1桁の数字が必要(目次)
サーバーを最新の重要なセキュリティパッチと更新で保つことは重要です。そうしないと、悪意のある行為者がサーバーへの不正アクセスを得るために利用できる既知のセキュリティ脆弱性のリスクがあります。
毎日サーバーをチェックする予定がない限り、システムを自動的に更新したり、利用可能な更新に関するメールを受け取る方法が必要です。
すべての更新を実行したくはありません。更新のたびに何かが壊れるリスクがあるからです。重要な更新は行うことが重要ですが、それ以外は手動で行う時間ができるまで待つことができます。
自動的かつ無人での更新はシステムを壊す可能性があり、サーバーの近くにいて修正できないかもしれません。これは特にSSHアクセスが壊れた場合に問題になります。
Debianベースのシステムでは、以下を使用できます:
unattended-upgradesを使用して重要なセキュリティパッチを適用します。また、Debianコミュニティですでに十分にテストされているため、安定版更新も適用できます。
/etc/apt/apt.conf.d/50unattended-upgradesunattended-upgrades、apt-listchanges、apticronをインストールします:
sudo apt install unattended-upgrades apt-listchanges apticron
次に、unattended-upgradesが自動的に更新を適用するように設定します。これは通常、パッケージによって作成されたファイル /etc/apt/apt.conf.d/20auto-upgrades と /etc/apt/apt.conf.d/50unattended-upgrades を編集して行います。ただし、これらのファイルは将来の更新で上書きされる可能性があるため、代わりに新しいファイルを作成します。ファイル /etc/apt/apt.conf.d/51myunattended-upgrades を作成し、以下を追加します:
// 更新/アップグレードスクリプトを有効にする (0=無効)
APT::Periodic::Enable "1";
// "apt-get update" を自動的に n日ごとに実行 (0=無効)
APT::Periodic::Update-Package-Lists "1";
// "apt-get upgrade --download-only" を自動的に n日ごとに実行 (0=無効)
APT::Periodic::Download-Upgradeable-Packages "1";
// "apt-get autoclean" を自動的に n日ごとに実行 (0=無効)
APT::Periodic::AutocleanInterval "7";
// レポートメールをrootに送信
// 0: レポートなし (または空の文字列)
// 1: 進捗レポート (実際には任意の文字列)
// 2: + コマンド出力 (-qqを削除、2>/dev/nullを削除、-dを追加)
// 3: + トレースオン APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";
// これらのパッケージを自動的にアップグレード
Unattended-Upgrade::Origins-Pattern {
"o=Debian,a=stable";
"o=Debian,a=stable-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
// 自動アップグレードしたくない独自のパッケージをここで指定
Unattended-Upgrade::Package-Blacklist {
};
// dpkgの状態が不完全な場合に dpkg --force-confold --configure -a を実行する。以前の実行中にシステムが中断された場合でも更新が確実にインストールされるようにする。
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
//サーバーは頻繁にシャットダウンしないため、マシンが動作中にアップグレードを実行する
Unattended-Upgrade::InstallOnShutdown "false";
// アップグレードされたパッケージに関する情報をこのアドレスにメールで送信
Unattended-Upgrade::Mail "root";
// 常にメールを送信する
Unattended-Upgrade::MailOnlyOnError "false";
// アップグレード完了後に未使用の依存関係をすべて削除
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// アップグレード完了後に新たに未使用になった依存関係をすべて削除
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// アップグレード後に /var/run/reboot-required ファイルが見つかった場合、確認なしで自動再起動
Unattended-Upgrade::Automatic-Reboot "true";
// ユーザーがログインしていても自動再起動
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
(目次)
WIP
WIP
WIP
rng-toolsをインストールします。
Debianベースのシステムの場合:
sudo apt-get install rng-tools
次に、乱数を生成するために使用するハードウェアデバイスを設定するため、これを /etc/default/rng-tools に追加します:
HRNGDEVICE=/dev/urandom
echo "HRNGDEVICE=/dev/urandom" | sudo tee -a /etc/default/rng-tools
サービスを再起動します:
sudo systemctl stop rng-tools.service
sudo systemctl start rng-tools.service
ランダム性をテストします:
(目次)
物理的な攻撃(対面でのランサムウェア/強盗/暴行)に対する追加のパスワードセキュリティを提供する素晴らしいツールです。
pamduressはXユーザーにセカンダリパスワード(パニックパスワード)を追加します。このパスワードが一致すると、スクリプトが実行されます(このスクリプトは、ユーザーがこのパニックパスワードでログインしたときに実行したい処理を行います)。
実用的かつ実際の例: 「強盗が家に侵入し、サーバーを盗みました(重要なビジネスバックアップや人生の思い出などが含まれています)。ディスク/ブートの暗号化はありません。強盗は自分の「安全な場所」でサーバーを起動し、ブルートフォース攻撃を開始しました。sudoerユーザー 'admin' のローカルパスワードをSSHでクラックしました。成功しました。はい、ダミーのパスワードで、本当の強力なパスワードではありません。彼はそのクラックしたダミー/パニックパスワードで 'admin' sudoerとしてSSHセッション(または物理セッション)を開始しました。2分も経たないうちにサーバーが非常にビジーになってフリーズするのを感じ始めました…「なんだ!?再起動して情報を盗み続けよう」…残念ながら友よ。すべてのデータとシステムは破壊されました。」 結論: 強盗はダミー/パニック/セカンダリパスワードをクラックしましたが、このパスワードには関連付けられたスクリプトがあり、すべてのファイル、設定、システム、ブートを削除し、その後RAMとCPUに負荷をかけて強盗にシステムの再起動を強制します。
悪意のある人物がパスワードを強制的に入手した場合(暴行、銃、身代金など)にサーバー情報へのアクセスを防ぎます。もちろん、他の状況でも役立ちます。
cat > "$ScriptFile" <<-EOF #!/bin/bash sudo rm -rf /home
EOF ####################################################### } echo "Lets Config a PANIC PASSWORD ;)" && sleep 1 read -r -p "Want you REALLY configure A PANIC PASSWORD?? Write [ OK ] : " PAMDUR if [[ "$PAMDUR" = "OK" ]]; then echo "Lets Config a PANIC USER, PASSWORD and SCRIPT ;)" && sleep 1 while [ -z "$PANICUSR" ] do read -r -p "WRITE a Panic User to your pam-duress user [ root ]: " PANICUSR PANICUSR=${PANICUSR:=root} done if [ -z "$ScriptLoc" ]; then read -r -p "SET Script Directory with FULL PATH [ /root/.duress ]: " ScriptLoc ScriptLoc=${ScriptLoc:=/root/.duress} ScriptFile="$ScriptLoc/PanicScript.sh" fi else echo "NOT Use PAM DURESS aKa Panic Password!!! Bye" exit 1 fi
sudo apt install -y git build-essential libpam0g-dev libssl-dev
cd "$HOME" || exit 1 git clone https://github.com/nuvious/pam-duress.git cd pam-duress || exit 1 make sudo make install make clean #make uninstall
mkdir -p $ScriptLoc sudo mkdir -p /etc/duress.d myownscript duress_sign $ScriptFile chmod -R 500 $ScriptLoc chmod 400 $ScriptLoc/*.sha256 chown -R $PANICUSR $ScriptLoc
sudo cp --preserve /etc/pam.d/common-auth /etc/pam.d/common-auth.bck
echo " auth [success=2 default=ignore] pam_unix.so nullok_secure auth [success=1 default=ignore] pam_duress.so auth requisite pam_deny.so auth required pam_permit.so " | sudo tee /etc/pam.d/common-auth
read -r -p "Press Key to Finish PAM DURESS Script!" exit 0
([目次](#table-of-contents))
## ネットワーク
### UFW(Uncomplicated Firewall)によるファイアウォール
#### なぜ
私のことをパラノイアと言っても構いませんし、同意する必要もありませんが、私はサーバーへの入出力トラフィックのうち、明示的に許可したもの以外はすべて拒否したいと考えています。なぜサーバーが私の知らないトラフィックを外部に送信するのでしょうか?また、誰だか何だかわからない外部トラフィックがなぜ私のサーバーにアクセスしようとするのでしょうか?優れたセキュリティに関しては、デフォルトで拒否/遮断し、例外として許可するというのが私の意見です。
もちろん、異論があるならそれで全く構いません。その場合はニーズに合わせてUFWを設定してください。
いずれにせよ、明示的に許可したトラフィックのみを確実に通すことがファイアウォールの役目です。
#### 仕組み
Linuxカーネルはネットワークトラフィックを監視・制御する機能を提供しています。これらの機能はファイアウォールユーティリティを通じてエンドユーザーに公開されています。Linuxで最も一般的なファイアウォールは[iptables](https://en.wikipedia.org/wiki/Iptables)です。しかし、iptablesはかなり複雑でわかりにくい(IMHO)。そこで登場するのがUFWです。UFWをiptablesのフロントエンドと考えてください。ネットワークトラフィックをどう扱うかをLinuxカーネルに指示するiptablesルールの管理プロセスを簡素化します。
**UFW**の動作は、次のようなルールを設定できるようにすることで実現されます:
- **許可**または**拒否**
- **入力**または**出力**トラフィック
- **宛先**または**送信元**ポート
ルールはポートを明示的に指定するか、ポートを指定するアプリケーション設定を使って作成できます。
#### 目標
- 明示的に許可したものを除き、すべてのネットワークトラフィック(入力・出力)をブロック
#### 注意事項
- 他のプログラムをインストールしたら、必要なポート/アプリケーションを有効にする必要があります。
#### 参考資料
- https://launchpad.net/ufw
#### 手順
1. ufwをインストールする。
Debianベースのシステムの場合:
``` bash
sudo apt install ufw
```
1. すべての送信トラフィックを拒否する:
``` bash
sudo ufw default deny outgoing comment 'deny all outgoing traffic'
```
> ```
> Default outgoing policy changed to 'deny'
> (be sure to update your rules accordingly)
> ```
私ほど paranoid ではなく、すべての送信トラフィックを拒否したくない場合は、代わりに許可することもできます:
``` bash
sudo ufw default allow outgoing comment 'allow all outgoing traffic'
```
1. すべての受信トラフィックを拒否する:
``` bash
sudo ufw default deny incoming comment 'deny all incoming traffic'
```
1. 当然、SSH接続は許可したいものです。allowの代わりにlimitを使用すると、30秒以内に6回以上の接続を試みたIPアドレスからの接続を自動的に拒否します:
``` bash
sudo ufw limit in ssh comment 'allow SSH connections in'
```
> ```
> Rules updated
> Rules updated (v6)
> ```
1. 必要に応じて追加のトラフィックを許可します。一般的なユースケース:
``` bash
# allow traffic out to port 53 -- DNS
sudo ufw allow out 53 comment 'allow DNS calls out'
# allow traffic out to port 123 -- NTP
sudo ufw allow out 123 comment 'allow NTP out'
# allow traffic out for HTTP, HTTPS, or FTP
# apt might needs these depending on which sources you're using
sudo ufw allow out http comment 'allow HTTP traffic out'
sudo ufw allow out https comment 'allow HTTPS traffic out'
sudo ufw allow out ftp comment 'allow FTP traffic out'
# allow whois
sudo ufw allow out whois comment 'allow whois'
# allow mails for status notifications -- choose port according to your provider
sudo ufw allow out 25 comment 'allow SMTP out'
sudo ufw allow out 587 comment 'allow SMTP out'
# allow traffic out to port 68 -- the DHCP client
# you only need this if you're using DHCP
sudo ufw allow out 67 comment 'allow the DHCP client to update'
sudo ufw allow out 68 comment 'allow the DHCP client to update'
```
**注意**: パッケージのインストールやその他の多くのことには、HTTP/HTTPSを許可する必要があります。
1. ufwを起動する:
``` bash
sudo ufw enable
```
> ```
> Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
> Firewall is active and enabled on system startup
> ```
1. ステータスを確認したい場合:
``` bash
sudo ufw status
```
> ```
> Status: active
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> Mail submission ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> Mail submission (v6) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
または
``` bash
sudo ufw status verbose
```
> ```
> Status: active
> Logging: on (low)
> Default: deny (incoming), deny (outgoing), disabled (routed)
> New profiles: skip
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT IN Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT IN Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> 587/tcp (Mail submission) ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> 587/tcp (Mail submission (v6)) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
7. ルールを削除する必要がある場合
``` bash
sudo ufw status numbered
[...]
sudo ufw delete 3 #line number of the rule you want to delete
```
#### デフォルトアプリケーション
ufwにはいくつかのデフォルトアプリケーションが含まれています。次のコマンドで確認できます:``` bash
sudo ufw app list
```
> ```
> Available applications:
> AIM
> Bonjour
> CIFS
> DNS
> Deluge
> IMAP
> IMAPS
> IPP
> KTorrent
> Kerberos Admin
> Kerberos Full
> Kerberos KDC
> Kerberos Password
> LDAP
> LDAPS
> LPD
> MSN
> MSN SSL
> Mail submission
> NFS
> OpenSSH
> POP3
> POP3S
> PeopleNearby
> SMTP
> SSH
> Socks
> Telnet
> Transmission
> Transparent Proxy
> VNC
> WWW
> WWW Cache
> WWW Full
> WWW Secure
> XMPP
> Yahoo
> qBittorrent
> svnserve
> ```
アプリの詳細(含まれるポートなど)を取得するには、次のように入力します:``` bash
sudo ufw app info [app name]
```
> ``` bash
> sudo ufw app info DNS
> ```
>
> ```
> Profile: DNS
> Title: Internet Domain Name Server
> Description: Internet Domain Name Server
>
> Port:
> 53
> ```
#### カスタムアプリケーション
ポート番号を明示的に指定してルールを作成したくない場合は、独自のアプリケーション設定を作成できます。そのためには、`/etc/ufw/applications.d` にファイルを作成します。
例えば、[Plex](https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/) を使用する場合は次のようになります。``` bash
cat /etc/ufw/applications.d/plexmediaserver
```
> ```
> [PlexMediaServer]
> title=Plex Media Server
> description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
> ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp
> ```
その後、他のアプリと同様に有効にできます:```bash
sudo ufw allow plexmediaserver
```
([目次](#table-of-contents))
### PSAD による iptables 侵入検知・防止
#### なぜ必要か
たとえファイアウォールでドアを守っていても、守られたドアのいずれかからブルートフォース攻撃を試みられる可能性があります。私たちは、すべてのネットワークアクティビティを監視して、侵入の試み(繰り返しのアクセス試行など)を検出し、それらをブロックしたいと考えています。
#### 仕組み
[FINESEC](https://serverfault.com/users/143961/finesec) ユーザーの説明が最も適切です(https://serverfault.com/a/447604/289829 より)。
> Fail2BAN は、apache、ssh、ftp などのさまざまなアプリケーションのログファイルをスキャンし、自動ログイン試行などの悪意のある兆候を示す IP を自動的に禁止します。一方、PSAD は iptables と ip6tables のログメッセージ(通常は /var/log/messages)をスキャンして、DDoS や OS フィンガープリント試行などのスキャンやその他の不審なトラフィックを検出し、オプションでブロックします。両方のプログラムを同時に使用しても問題ありません。動作するレベルが異なるからです。
また、すでに [UFW](#ufw-uncomplicated-firewall) を使用しているため、[netson](https://gist.github.com/netson) による優れた手順(https://gist.github.com/netson/c45b2dc4e835761fbccc)に従って、PSAD を UFW と連携させます。
#### 参考文献
- http://www.cipherdyne.org/psad/
- http://www.cipherdyne.org/psad/docs/config.html
- https://www.thefanclub.co.za/how-to/how-install-psad-intrusion-detection-ubuntu-1204-lts-server
- https://serverfault.com/a/447604/289829
- https://serverfault.com/a/770424/289829
- https://gist.github.com/netson/c45b2dc4e835761fbccc
- `psadwatchd` に関する問題([#61](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/61))を指摘してくれた [moltenbit](https://github.com/moltenbit) に感謝します。
#### 手順
1. psad をインストールします。
Debian ベースのシステムの場合:
``` bash
sudo apt install psad
```
1. psad の設定ファイル `/etc/psad/psad.conf` のバックアップを作成します。
``` bash
sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. `/etc/psad/psad.conf` の設定オプションを確認し、更新します。特に以下の項目に注意してください。
|設定項目|設定値
|--|--|
|[`EMAIL_ADDRESSES`](http://www.cipherdyne.org/psad/docs/config.html#EMAIL_ADDRESSES)|あなたのメールアドレス|
|`HOSTNAME`|サーバーのホスト名|
|`EXPECT_TCP_OPTIONS`|`EXPECT_TCP_OPTIONS Y;`|
|`ENABLE_PSADWATCHD`|`ENABLE_PSADWATCHD Y;`|
|[`ENABLE_AUTO_IDS`](http://www.cipherdyne.org/psad/docs/config.html#ENABLE_AUTO_IDS)|`ENABLE_AUTO_IDS Y;`|
|`ENABLE_AUTO_IDS_EMAILS`|`ENABLE_AUTO_IDS_EMAILS Y;`|
詳細については、http://www.cipherdyne.org/psad/docs/config.html にある psad の設定ファイルのドキュメントを確認してください。
1. <a name="psad_step4"></a>次に、psad がすべてのトラフィックをログに記録して分析できるように、ufw に変更を加える必要があります。**2つのファイル**を編集し、**COMMIT 行の前、ファイルの末尾**に次の行を追加します。
バックアップを作成します。
``` bash
sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
```
次のファイルを編集します。
- `/etc/ufw/before.rules`
- `/etc/ufw/before6.rules`
そして、**COMMIT 行の前、ファイルの末尾**に次を追加します。
```
# psad が分析できるようにすべてのトラフィックをログに記録
-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
```
**注意**: iptables のすべてのログにログプレフィックスを追加しています。これは、[iptables ログを専用ファイルに分離する](#separate-iptables-log-file)際に必要です。
例:
> ```
> ...
>
> # psad が分析できるようにすべてのトラフィックをログに記録
> -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
> -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
>
> # 'COMMIT' 行は削除しないでください。削除するとこれらのルールが処理されません
> COMMIT
> ```
1. 次に、変更を反映するために ufw と psad をリロード/再起動します。
``` bash
sudo ufw reload
sudo psad -R
sudo psad --sig-update
sudo psad -H
```
1. iptables ルールのエラーを分析します。
``` bash
sudo psad --fw-analyze
```
> ```
> [+] Parsing INPUT chain rules.
> [+] Parsing INPUT chain rules.
> [+] Firewall config looks good.
> [+] Completed check of firewall ruleset.
> [+] Results in /var/log/psad/fw_check
> [+] Exiting.
> ```
**注意**: 問題がある場合は、エラーメールが届きます。
1. psad のステータスを確認します。
``` bash
sudo psad --Status
```
> ```
> [-] psad: pid file /var/run/psad/psadwatchd.pid does not exist for psadwatchd on vm
> [+] psad_fw_read (pid: 3444) %CPU: 0.0 %MEM: 2.2
> Running since: Sat Feb 16 01:03:09 2019
>
> [+] psad (pid: 3435) %CPU: 0.2 %MEM: 2.7
> Running since: Sat Feb 16 01:03:09 2019
> Command line arguments: [none specified]
> Alert email address(es): root@localhost
>
> [+] Version: psad v2.4.3
>
> [+] Top 50 signature matches:
> [NONE]
>
> [+] Top 25 attackers:
> [NONE]
>
> [+] Top 20 scanned ports:
> [NONE]
>
> [+] iptables log prefix counters:
> [NONE]
>
> Total protocol packet counters:
>
> [+] IP Status Detail:
> [NONE]
>
> Total scan sources: 0
> Total scan destinations: 0
>
> [+] These results are available in: /var/log/psad/status.out
> ```
([目次](#table-of-contents))
### Fail2Ban によるアプリケーション侵入検知・防止
#### なぜ必要か
UFW はサーバーのどのドアを塞いで見えなくするか、どのドアを許可ユーザーに通すかを指示します。PSAD はネットワークアクティビティを監視して、侵入の試み(繰り返しのアクセス試行)を検出・防止します。
しかし、SSH や Apache のように、ファイアウォールでアクセスを許可しているアプリケーション/サービスはどうでしょうか?アクセスが許可されているからといって、すべてのアクセス試行が有効で無害であるとは限りません。サーバー上で実行している Web アプリにブルートフォース攻撃を試みる人がいるかもしれません。ここで Fail2ban の出番です。
#### 仕組み
Fail2ban は、アプリケーション(SSH や Apache など)のログを監視して、潜在的な侵入を検出・防止します。ネットワークトラフィック/ログを監視し、不審なアクティビティ(例:短時間に複数回の連続失敗接続)をブロックすることで侵入を防止します。
#### 目標
- 不審なアクティビティに対するネットワーク監視と、該当 IP の自動禁止
#### 注意事項
- 現時点では、このサーバーで実行しているのは SSH のみなので、Fail2ban で SSH を監視し、必要に応じて禁止するようにします。
- 他のプログラムをインストールした場合は、適切な jails を作成・設定して有効にする必要があります。
#### 参考文献
- https://www.fail2ban.org/
- https://blog.vigilcode.com/2011/05/ufw-with-fail2ban-quick-secure-setup-part-ii/
- https://dodwell.us/security/ufw-fail2ban-portscan.html
- https://www.howtoforge.com/community/threads/fail2ban-and-ufw-on-debian.77261/
#### 手順
1. fail2ban をインストールします。
Debian ベースのシステムの場合:
``` bash
sudo apt install fail2ban
```
1. `/etc/fail2ban/fail2ban.conf` や `/etc/fail2ban/jail.conf` は直接編集したくありません。将来のアップデートで上書きされる可能性があるためです。代わりにローカルコピーを作成します。ファイル `/etc/fail2ban/jail.local` を作成し、`[LAN SEGMENT]` と `[your email]` を適切な値に置き換えて次の内容を追加します。
```
[DEFAULT]
# 無視する IP アドレス範囲
ignoreip = 127.0.0.1/8 [LAN SEGMENT]
# メール送信先
destemail = [your e-mail]
# メール送信元
sender = [your e-mail]
# exim4 を使用してメールを送信するため
mta = mail
# メールアラートを有効
action = %(action_mwl)s
```
**注意**: サーバーがメールを送信できる必要があります。そうすれば Fail2ban が不審なアクティビティや IP を禁止したことを知らせてくれます。
1. SSH 用の jail を作成し、fail2ban に SSH ログを監視させ、ufw を使用して必要に応じて IP を禁止/解除するように指示します。ファイル `/etc/fail2ban/jail.d/ssh.local` を作成し、次の内容を追加します。
```
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
```
[忙しい方向け](#editing-configuration-files---for-the-lazy):
``` bash
cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
EOF
```
1. 上記で、fail2ban に `banaction` として ufw を使用するように指示しています。Fail2ban には ufw 用のアクション設定ファイルが付属しており、`/etc/fail2ban/action.d/ufw.conf` で確認できます。
1. fail2ban を有効にします。
``` bash
sudo fail2ban-client start
sudo fail2ban-client reload
sudo fail2ban-client add sshd # 一部のシステムでは sshd jail がデフォルトで追加されているため、失敗する可能性があります
```
1. ステータスを確認するには:
``` bash
sudo fail2ban-client status
```
> ```
> Status
> |- Number of jail: 1
> `- Jail list: sshd
> ```
``` bash
sudo fail2ban-client status sshd
```
> ```
> Status for the jail: sshd
> |- Filter
> | |- Currently failed: 0
> | |- Total failed: 0
> | `- File list: /var/log/auth.log
> `- Actions
> |- Currently banned: 0
> |- Total banned: 0
> `- Banned IP list:
> ```
#### カスタム Jails
まだカスタム jail を作成する必要はありません。作成方法がわかったら、このガイドを更新します。または、方法をご存知でしたら、[貢献](#contributing)にご協力ください。
#### IP の禁止解除
IP を禁止解除するには、次のコマンドを使用します。``` bash
fail2ban-client set [jail] unbanip [IP]
```
`[jail]`はBANされたIPがあるjailの名前で、`[IP]`は解除したいIPアドレスです。例えば、SSHから `192.168.1.100` を解除するには、次のようにします:``` bash
fail2ban-client set sshd unbanip 192.168.1.100
```
([目次](#table-of-contents))
### CrowdSecによるアプリケーション侵入検知と防御
#### なぜ
UFWはサーバーに対して、どのドアを塞いで見えなくし、どのドアを許可されたユーザーに通すかを指示します。PSADはネットワーク活動を監視し、侵入の試みの繰り返しなど、潜在的な侵入を検出・防止します。
CrowdSecはFail2Banと似ており、SSHやApacheなどのアプリケーションのログを監視して潜在的な侵入を検出・防止します。ただし、CrowdSecは脅威情報をCrowdSecに共有するコミュニティと連携し、それを全ユーザーに配布するコミュニティブロックリストを提供します。
#### 仕組み
CrowdSecはアプリケーション(SSHやApacheなど)のログを監視して潜在的な侵入を検出・防止します。ネットワークトラフィック/ログを監視し、不審なアクティビティ(例:短時間での複数回の連続失敗接続)をブロックすることで侵入を防ぎます。悪意のあるIPが検出されると、ローカル決定リストに追加され、脅威情報がCrowdSecに共有されて悪意のあるIPアドレスに関するコミュニティブロックリストが更新されます。IPアドレスが一定の悪意アクティビティの閾値に達すると、自動的に他のすべてのCrowdSecユーザーに伝播され、事前にブロックされます。
#### 目標
- 不審なアクティビティのネットワーク監視と、問題のIPの自動禁止
#### 注意事項
- 現時点ではこのサーバーで実行しているのはSSHのみなので、CrowdSecにSSHを監視させ、必要に応じて禁止させます。
- 他のプログラムをインストールする際には、追加のコレクションをインストールし、適切な取得設定を行う必要があります。
#### 参考文献
- https://www.crowdsec.net/
- [CrowdSecがコミュニティブロックリストをキュレーションする方法を読む](https://www.crowdsec.net/our-data)
- [CrowdSecと共有される脅威インテリジェンスについて読む](https://docs.crowdsec.net/docs/next/central_api/intro#signal-meta-data)
- https://docs.crowdsec.net/
#### 手順
1. CrowdSecセキュリティエンジンをインストールする。(IDS)
任意のLinuxディストリビューション(Debianベースのシステムを含む)で
CrowdSecリポジトリをインストール:
``` bash
curl -s https://install.crowdsec.net | sudo sh
```
CrowdSecセキュリティエンジンをインストール:
``` bash
sudo apt install crowdsec
```
> [!TIP]
> `curl | sh` が好みでない場合は、追加のインストール方法を[こちら](https://docs.crowdsec.net/u/getting_started/installation/linux)で見つけることができます。
デフォルトでは、CrowdSecがセキュリティエンジンをインストールする際に、インストール済みのアプリケーションを自動検出し、それらに適したパーサーとシナリオをインストールします。ほとんどのLinuxサーバーがSSHを標準で実行しているため、CrowdSecはこれを自動的に設定します。
2. 修復コンポーネントをインストールする。(IPS)
CrowdSec自体は検出エンジンであり、最新のインフラストラクチャの多くには上流のファイアウォールやWAFがあるため、CrowdSec単独ではIPアドレスをブロックしません。CrowdSecが検出したIPアドレスをブロックするために修復コンポーネントをインストールできます。
```bash
sudo apt install crowdsec-firewall-bouncer-iptables
```
> [!TIP]
> UFWのインストールがバックエンドとして `iptables` を使用していない場合は、代わりに `crowdsec-firewall-bouncer-nftables` をインストールできます。インストールされるバイナリに違いはなく、設定ファイルのみが異なります。
デフォルトでは、修復コンポーネントのインストール中に、同じホストに展開されている場合(かつセキュリティエンジンがコンテナ環境内にない場合)、セキュリティエンジンと連携するために必要な設定が自動構成されます。
3. 検出と修復が意図したとおりに動作していることを確認する:
CrowdSecパッケージには、セキュリティエンジンと修復コンポーネントの状態を確認するためのCLIツールが含まれています。
```bash
sudo cscli metrics
```
```bash
Acquisition Metrics:
╭────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────╮
│ Source │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/var/log/auth.log │ 5 │ 4 │ 1 │ 10 │ - │
│ file:/var/log/syslog │ 30 │ - │ 30 │ - │ - │
╰────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯
Local API Decisions:
╭────────────────────────────────────────────┬────────┬────────┬───────╮
│ Reason │ Origin │ Action │ Count │
├────────────────────────────────────────────┼────────┼────────┼───────┤
│ crowdsecurity/http-backdoors-attempts │ CAPI │ ban │ 73 │
│ crowdsecurity/http-bad-user-agent │ CAPI │ ban │ 4836 │
│ crowdsecurity/http-path-traversal-probing │ CAPI │ ban │ 87 │
│ crowdsecurity/http-probing │ CAPI │ ban │ 2010 │
│ crowdsecurity/thinkphp-cve-2018-20062 │ CAPI │ ban │ 88 │
│ crowdsecurity/CVE-2019-18935 │ CAPI │ ban │ 7 │
│ crowdsecurity/CVE-2023-49103 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-admin-interface-probing │ CAPI │ ban │ 91 │
│ ltsich/http-w00tw00t │ CAPI │ ban │ 3 │
│ crowdsecurity/apache_log4j2_cve-2021-44228 │ CAPI │ ban │ 18 │
│ crowdsecurity/nginx-req-limit-exceeded │ CAPI │ ban │ 280 │
│ crowdsecurity/ssh-slow-bf │ CAPI │ ban │ 3412 │
│ crowdsecurity/spring4shell_cve-2022-22965 │ CAPI │ ban │ 1 │
│ crowdsecurity/ssh-cve-2024-6387 │ CAPI │ ban │ 24 │
│ crowdsecurity/CVE-2023-22515 │ CAPI │ ban │ 2 │
│ crowdsecurity/http-cve-2021-41773 │ CAPI │ ban │ 172 │
│ crowdsecurity/netgear_rce │ CAPI │ ban │ 14 │
│ crowdsecurity/ssh-bf │ CAPI │ ban │ 2000 │
│ crowdsecurity/CVE-2022-35914 │ CAPI │ ban │ 1 │
│ crowdsecurity/http-cve-2021-42013 │ CAPI │ ban │ 2 │
│ crowdsecurity/jira_cve-2021-26086 │ CAPI │ ban │ 9 │
│ crowdsecurity/http-sensitive-files │ CAPI │ ban │ 166 │
│ crowdsecurity/http-wordpress-scan │ CAPI │ ban │ 272 │
│ crowdsecurity/CVE-2022-26134 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-generic-bf │ CAPI │ ban │ 7 │
│ crowdsecurity/http-open-proxy │ CAPI │ ban │ 948 │
│ crowdsecurity/http-crawl-non_statics │ CAPI │ ban │ 339 │
│ crowdsecurity/http-cve-probing │ CAPI │ ban │ 5 │
│ crowdsecurity/CVE-2017-9841 │ CAPI │ ban │ 117 │
│ crowdsecurity/CVE-2022-37042 │ CAPI │ ban │ 1 │
│ crowdsecurity/fortinet-cve-2018-13379 │ CAPI │ ban │ 5 │
╰────────────────────────────────────────────┴────────┴────────┴───────╯
Local API Metrics:
╭──────────────────────┬────────┬──────╮
│ Route │ Method │ Hits │
├──────────────────────┼────────┼──────┤
│ /v1/alerts │ GET │ 2 │
│ /v1/decisions/stream │ GET │ 5 │
│ /v1/usage-metrics │ POST │ 2 │
│ /v1/watchers/login │ POST │ 4 │
╰──────────────────────┴────────┴──────╯
Local API Bouncers Metrics:
╭────────────────────────────────┬──────────────────────┬────────┬──────╮
│ Bouncer │ Route │ Method │ Hits │
├────────────────────────────────┼──────────────────────┼────────┼──────┤
│ cs-firewall-bouncer-1729025592 │ /v1/decisions/stream │ GET │ 5 │
╰────────────────────────────────┴──────────────────────┴────────┴──────╯
Local API Machines Metrics:
╭──────────────────────────────────────────────────┬────────────┬────────┬──────╮
│ Machine │ Route │ Method │ Hits │
├──────────────────────────────────────────────────┼────────────┼────────┼──────┤
│ <your_machine_id_will_be_here> │ /v1/alerts │ GET │ 2 │
╰──────────────────────────────────────────────────┴────────────┴────────┴──────╯
Parser Metrics:
╭─────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers │ Hits │ Parsed │ Unparsed │
├─────────────────────────────────┼──────┼────────┼──────────┤
│ child-crowdsecurity/sshd-logs │ 41 │ 4 │ 37 │
│ child-crowdsecurity/syslog-logs │ 35 │ 35 │ - │
│ crowdsecurity/dateparse-enrich │ 4 │ 4 │ - │
│ crowdsecurity/sshd-logs │ 5 │ 4 │ 1 │
│ crowdsecurity/syslog-logs │ 35 │ 35 │ - │
╰─────────────────────────────────┴──────┴────────┴──────────╯
Scenario Metrics:
╭─────────────────────────────────────┬───────────────┬───────────┬──────────────┬────────┬─────────╮
│ Scenario │ Current Count │ Overflows │ Instantiated │ Poured │ Expired │
├─────────────────────────────────────┼───────────────┼───────────┼──────────────┼────────┼─────────┤
│ crowdsecurity/ssh-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
│ crowdsecurity/ssh-slow-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-slow-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
╰─────────────────────────────────────┴───────────────┴───────────┴──────────────┴────────┴─────────╯
```
上記の出力は圧倒されるかもしれませんが、セキュリティエンジンがログを読み取り、修復コンポーネントがIPアドレスをブロックしていることを確認する良い方法です。各セクションの簡単な説明は以下の通りです:
- **取得メトリクス**: このセクションは、セキュリティエンジンが読み取り、解析しているログを示します。`Lines unparsed` 列にログが表示されている場合、セキュリティエンジンがログを解析できないことを意味します。これは設定の誤りやログが期待される形式でない可能性があります。
- **ローカルAPI決定**: このセクションは、セキュリティエンジンがデータベース内に持つ決定を示します。`Count` 列に数値が表示されている場合、セキュリティエンジンが悪意のあるアクティビティを検出し、IPアドレスをブロックしたことを意味します。
- 発信元: 決定がどこから来たかを示します。この場合は中央API(CAPI)からです。
- **ローカルAPIメトリクス**: このセクションは、ローカルAPIへのヒット数を示します。これはセキュリティエンジンが修復コンポーネントと通信するために使用するAPIです。
- **ローカルAPIバウンサーメトリクス**: このセクションは、修復コンポーネントによるローカルAPIへのヒット数を示します。
- **ローカルAPIマシンメトリクス**: このセクションは、セキュリティエンジンによるローカルAPIへのヒット数を示します(集中管理設定で複数のセキュリティエンジンを実行している場合、ここに複数のIDが表示されます)。
- **パーサーメトリクス**: このセクションは、セキュリティエンジンが使用しているパーサーを示します。`Unparsed` 列にログが表示されている場合、セキュリティエンジンがログを解析できないことを意味します。これは設定の誤りやログが期待される形式でない可能性があります。
- **シナリオメトリクス**: このセクションは、セキュリティエンジンが使用しているシナリオを示します。`Current Count` 列に数値が表示されている場合、セキュリティエンジンが悪意のあるアクティビティを検出し、IPアドレスを追跡していることを意味します。
#### IPの禁止解除
IPの禁止を解除するには、以下のコマンドを使用します:``` bash
cscli decisions delete --ip [IP]
```
`[IP]` は、アンバンしたいIPアドレスです。例えば、SSHから `192.168.1.100` をアンバンするには、次のようにします:``` bash
cscli decisions delete --ip 192.168.1.100
```
## 監査
### AIDEによるファイル/フォルダ整合性監視(作業中)
#### なぜ
作業中
#### 仕組み
作業中
#### 目標
作業中
#### 参考資料
- https://aide.github.io/
- https://www.hiroom2.com/2017/06/09/debian-8-file-integrity-check-with-aide/
- https://blog.rapid7.com/2017/06/30/how-to-install-and-configure-aide-on-ubuntu-linux/
- https://www.stephenrlang.com/2016/03/using-aide-for-file-integrity-monitoring-fim-on-ubuntu/
ssh-copy-idssh-copy-id user@server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub" The authenticity of host 'host (192.168.1.96)' can't be established. ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys user@host's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'user@host'" and check to make sure that only the key(s) you wanted were added.
次に、以下の設定を見つけて編集または追加し、要件に応じて値を設定します:
| 設定 | 有効な値 | 例 | 説明 | 備考 |
|---|---|---|---|---|
| AllowGroups | ローカルのUNIXグループ名 | AllowGroups sshusers | SSHアクセスを許可するグループ | |
| ClientAliveCountMax | 数値 | ClientAliveCountMax 3 | 応答なしで送信されるクライアント生存メッセージの最大数 | |
| ClientAliveInterval | 秒数 | ClientAliveInterval 15 | 応答要求前のタイムアウト(秒) | |
| ListenAddress | スペース区切りのローカルアドレスリスト |
| sshd がリッスンするローカルアドレス | 重要な詳細については Issue #1 を参照してください。 |
| LoginGraceTime | 秒数 | LoginGraceTime 30 | ログインがタイムアウトするまでの時間(秒) | |
| MaxAuthTries | 数値 | MaxAuthTries 2 | 許可される最大ログイン試行回数 | |
| MaxSessions | 数値 | MaxSessions 2 | 最大オープンセッション数 | |
| MaxStartups | 数値 | MaxStartups 2 | 最大ログインセッション数 | |
| PasswordAuthentication | yes または no | PasswordAuthentication no | パスワードによるログインを許可するかどうか | |
| Port | 任意の開いている/利用可能なポート番号 | Port 22 | sshd がリッスンするポート |
これらの設定の意味の詳細については、man sshd_config を確認してください。
互いに矛盾する重複設定がないことを確認してください。以下のコマンドで出力があってはなりません。
awk 'NF && $1!~/^(#|HostKey)/{print $1}' /etc/ssh/sshd_config | sort | uniq -c | grep -v ' 1 '
sshを再起動します:
sudo service sshd restart
sshd -T を使用して設定が機能していることを確認し、出力を確認できます:
sudo sshd -T
port 22 addressfamily any listenaddress [::]:22 listenaddress 0.0.0.0:22 usepam yes logingracetime 30 x11displayoffset 10 maxauthtries 2 maxsessions 2 clientaliveinterval 15 clientalivecountmax 3 streamlocalbindmask 0177 permitrootlogin no ignorerhosts yes ignoreuserknownhosts no hostbasedauthentication no ... subsystem sftp internal-sftp -f AUTHPRIV -l INFO maxstartups 2:30:2 permittunnel no ipqos lowdelay throughput rekeylimit 0 0 permitopen any
これはrootでは実行しないでください。
すべての質問に対してデフォルトオプション(ほとんどの場合 y)を選択し、緊急スクラッチコードを保存することを忘れないでください。
PAMのSSH設定ファイル /etc/pam.d/sshd のバックアップを作成します:
sudo cp --archive /etc/pam.d/sshd /etc/pam.d/sshd-COPY-$(date +"%Y%m%d%H%M%S")
次に、SSHの認証方法として有効にするために、以下の行を /etc/pam.d/sshd に追加します:
auth required pam_google_authenticator.so nullok
注意: nullok の意味についてはこちらを確認してください。
echo -e "\nauth required pam_google_authenticator.so nullok # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/pam.d/sshd
SSHにそれを利用させるために、/etc/ssh/sshd_config に以下の行を追加または編集します:
ChallengeResponseAuthentication yes
sudo sed -i -r -e "s/^(challengeresponseauthentication .*)$/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/I" /etc/ssh/sshd_config
echo -e "\nChallengeResponseAuthentication yes # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ssh/sshd_config
sshを再起動します:
sudo service sshd restart
サービスを再起動して変更を適用します:
sudo systemctl restart systemd-timesyncd
同期ステータスを確認します:
timedatectl timesync-status
Server: 108.61.56.35 (pool.ntp.org) Poll interval: 32s (min: 32s; max: 34min 8s) Leap: normal Version: 4 Stratum: 2 Reference: C342F10A Precision: 1us (2^0) Root distance: 24.054ms (max: 5s) Offset: +2.156ms Delay: 48.567ms Jitter: 1.452ms Packet count: 3
/etc/ntp.conf の例:
driftfile /var/lib/ntp/ntp.drift statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited restrict 127.0.0.1 restrict ::1 restrict source notrap nomodify noquery pool pool.ntp.org iburst # added by user on 2019-03-09 @ 10:23:35
ntpを再起動します:
sudo service ntp restart
ntpサービスのステータスを確認します:
sudo systemctl status ntp
● ntp.service - LSB: Start NTP daemon Loaded: loaded (/etc/init.d/ntp; generated; vendor preset: enabled) Active: active (running) since Sat 2019-03-09 15:19:46 EST; 4s ago Docs: man:systemd-sysv-generator(8) Process: 1016 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS) Process: 1028 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS) Tasks: 2 (limit: 4915) CGroup: /system.slice/ntp.service └─1038 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:113 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 0 v6wildcard [::]:123 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 1 v4wildcard 0.0.0.0:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 2 lo 127.0.0.1:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 3 enp0s3 10.10.20.96:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 4 lo [::1]:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 5 enp0s3 [fe80::a00:27ff:feb6:ed8e%2]:123 Mar 09 15:19:46 host ntpd[1038]: Listening on routing socket on fd #22 for interface updates Mar 09 15:19:47 host ntpd[1038]: Soliciting pool server 108.61.56.35 Mar 09 15:19:48 host ntpd[1038]: Soliciting pool server 69.89.207.199 Mar 09 15:19:49 host ntpd[1038]: Soliciting pool server 45.79.111.114
ntpのステータスを確認します:
sudo ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== pool.ntp.org .POOL. 16 p - 64 0 0.000 0.000 0.000 *lithium.constan 198.30.92.2 2 u - 64 1 19.900 4.894 3.951 ntp2.wiktel.com 212.215.1.157 2 u 2 64 1 48.061 -0.431 0.104
ucredit=-1 = 少なくとも1つの大文字が必要lcredit=-1 = 少なくとも1つの小文字が必要ocredit=-1 = 少なくとも1つの非英数字文字が必要difok=3 = 新しいパスワードのうち少なくとも3文字は以前のパスワードに含まれていない必要があるmaxrepeat=3 = 最大3文字までの繰り返しを許可gecoschec = アカウント名を含むパスワードを許可しないsudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
注意:
/usr/lib/apt/apt.systemd.daily で APT::Periodic オプションの詳細を確認してくださいUnattended-Upgrade オプションの詳細を確認してくださいunattended-upgradesのドライランを実行して、設定ファイルが正しいことを確認します:
sudo unattended-upgrade -d --dry-run
問題がなければ、スケジュールされたときに実行させるか、unattended-upgrade -d で強制実行できます。
apt-listchangesを好みに応じて設定します:
sudo dpkg-reconfigure apt-listchanges
apticronについては、デフォルト設定で十分ですが、変更したい場合は /etc/apticron/apticron.conf で確認できます。例えば、私の設定は次のようになっています:
EMAIL="root" NOTIFY_NO_UPDATES="1"