githubixx.harden_linux

ansible-role-harden-linux

このAnsibleロールは、私のブログシリーズ「Kubernetesを簡単にAnsibleで運用する - インスタンスを強化する」のために主に作成されました。しかしもちろん、Linuxを強化するために単独でも使用できます。以下の機能を持っています(いくつかはオプションです):

  • 管理用の通常/デプロイユーザーを追加(例:Ansible用やSSHでのログイン用)
  • APTの更新間隔を調整
  • UFWファイアウォールを設定し、デフォルトでSSHアクセスのみを許可(必要に応じて他のルール/許可されているネットワークを追加)
  • セキュリティ関連のsysctl設定を調整
  • sshdの設定を調整(例:sshdパスワード認証を無効にする、sshdのルートログインを無効にする、sshd PermitTunnelを無効にする)
  • sshguardをインストールし、ホワイトリストを調整
  • ルートパスワードを変更
  • 「ネットワーク時刻同期」(NTP)をインストール/設定(例:openntpd/ntp/systemd-timesyncd
  • systemd-resolvedの設定を変更

バージョン

すべてのリリースにタグを付け、セマンティックバージョニングを守るようにしています。このロールを使用したい場合は、最新のタグをチェックアウトすることをお勧めします。マスターブランチは基本的に開発用で、タグは安定したリリースを示します。ただし、一般的にマスターも良好な状態を保つことを心がけています。

変更履歴

変更履歴:

完全な CHANGELOG.md を参照してください。

最近の変更:

v8.2.0

  • 機能
    • Ubuntu 24.04のサポートを追加

v8.1.0

  • その他

    • 暗号化されたパスワードを作成するためにansibleではなくmkpasswdを使用することについてのコメントを更新
    • Ubuntu: 自動削除タスクを追加
    • GitHubワークフローを更新
  • MOLECULE

    • generic Vagrantボックスの代わりにalvistackを使用
    • 異なるIPアドレスを使用

v8.0.0

  • 破壊的変更/機能

    • harden_linux_deploy_groupおよびharden_linux_deploy_group_gid変数を導入。どちらもオプションですが、harden_linux_deploy_userが設定されている場合は少なくともharden_linux_deploy_groupを指定する必要があります。harden_linux_deploy_grouprootに設定すると、何も変更されません。
    • harden_linux_deploy_userrootに設定すると、何も変更されません。
    • harden_linux_deploy_userはオプションになりました。設定しない場合、ユーザーは設定されません。また、harden_linux_deploy_user_で始まるすべての変数は、harden_linux_deploy_userが指定された場合にのみ使用されます。さらに、harden_linux_deploy_user_home変数が追加されました。harden_linux_deploy_user_shellharden_linux_deploy_user_homeharden_linux_deploy_user_uid、およびharden_linux_deploy_user_passwordはオプションになりました。harden_linux_deploy_userの$HOMEディレクトリは、harden_linux_deploy_user_homeが設定されている場合にのみ作成されます。
  • MOLECULE

    • デプロイユーザー/グループの変更を反映するためにテストシナリオを更新

インストール

  • GitHubから直接ダウンロード(クローン前にAnsibleロールディレクトリに移動してください。ロールパスはansible-config dump | grep DEFAULT_ROLES_PATHコマンドで確認できます): git clone https://github.com/githubixx/ansible-role-harden-linux.git githubixx.harden_linux

  • ansible-galaxyコマンドを使ってAnsible Galaxyから直接ダウンロード: ansible-galaxy install role githubixx.harden_linux

  • 次の内容でrequirements.ymlファイルを作成(これによりGitHubからロールがダウンロードされ)て以下のコマンドでインストールします: ansible-galaxy role install -r requirements.yml(必要に応じてversionを変更):

---
roles:
  - name: githubixx.harden_linux
    src: https://github.com/githubixx/ansible-role-harden-linux.git
    version: v8.1.0

ロール変数

以下の変数にはデフォルトがありません。group_varsまたはhost_varsディレクトリ内のファイルで指定する必要があります。例:これらの設定を特定のホストにのみ使用したい場合、そのホストのFQDNと同じ名前のファイル(例:host_vars/your-server.example.tld)を作成し、正しい値で変数を書き込んでください。この変数をホストグループに適用したい場合、group_vars/your-group.ymlという名前のファイルを作成します。ここでyour-groupは、Ansibleのhostsファイルで作成したホストグループ名に置き換えてください(/etc/hostsと混同しないでください)。

rootユーザーのパスワードを設定または変更したい場合は、harden_linux_root_password変数を設定してください。これはオプションで、暗号化されたパスワードが必要です。Ansibleがパスワードを暗号化することはありません。暗号化されたパスワードの作成方法については、AnsibleのFAQを参照してください。Linuxでは、次のコマンドが最も信頼性が高いでしょう:

mkpasswd --method=sha-512

sudをパスワードなしで実行できるユーザーをインストールするには、次の変数を設定します:

harden_linux_deploy_user: "a_username"
harden_linux_deploy_user_password: "a_password"
harden_linux_deploy_user_home: "/home/a_user"
harden_linux_deploy_user_uid: "9999"
harden_linux_deploy_user_gid: "9999"
harden_linux_deploy_user_shell: "/bin/bash"

harden_linux_deploy_userは、リモートホストにログインするために使用するユーザーを指定します。前述のように、harden_linuxロールはSSHでのrootユーザーのログインを無効にするため、別のユーザーが必要です。このユーザーには、Ansible(およびおそらくあなた自身)に必要な"sudo"権限が与えられます。

harden_linux_deploy_user_passwordには、ユーザーの暗号化されたパスワードが保存されます。harden_linux_root_passwordに関しても同様です。

ユーザーの$HOMEディレクトリは、harden_linux_root_passwordで指定します。UIDとGIDは、harden_linux_deploy_user_uidharden_linux_deploy_user_gidで設定します。注意:ユーザーがすでに存在するが、異なるホームディレクトリ、UID、および/またはGIDを持っている場合、上記の設定に従って変更されます!これはharden_linux_deploy_user_shellにも適用され、このユーザーがログイン後に使用するシェルを指定します。

harden_linux_deploy_user_public_keysは、リモートホストのデプロイユーザーの$HOME/.ssh/authorized_keysに追加したい公開SSHキーのファイルリストを指定します。例:ここで/home/deploy/.ssh/id_rsa.pubを指定すると、そのローカルファイル(Ansibleコントローラノード上)から内容がリモートホストのデプロイユーザーの$HOME/.ssh/authorized_keysに追加されます。

harden_linux_optional_packages(このロールのバージョンv6.0.0より前はharden_linux_required_packagesと呼ばれていました)は、リモートホストにインストールする追加またはオプションパッケージを指定します。デフォルトではこの変数は指定されていません。例:

harden_linux_optional_packages:
  - vim

対照的に、harden_linux_absent_packagesは、リモートホストのOSパッケージをアンインストールします。デフォルトでは、この変数は指定されていません。例:

harden_linux_absent_packages:
  - vim

以下の変数にはデフォルトがあります。したがって、他の値が必要な場合にのみ変更する必要があります。ロールはデフォルトでいくつかのsshd設定を変更します:

harden_linux_sshd_settings:
  "^PasswordAuthentication": "PasswordAuthentication no"  # パスワード認証を無効にします
  "^PermitRootLogin": "PermitRootLogin no"                # SSHのルートログインを無効にします
  "^PermitTunnel": "PermitTunnel no"                      # tun(4)デバイス転送を無効にします
  "^Port ": "Port 22"                                     # sshdポートを設定します

個人的には、攻撃を受けやすいポートのため、デフォルトのSSHポートを変更します(ただし、ポートスキャナーはすぐにそのポートを特定できることに注意してください)。ポート設定を変更したい場合は、次のようにできます:

harden_linux_sshd_settings_user:
  "^Port ": "Port 22222"

^Portの後の空白に注意してください!)。プレイブックは、harden_linux_sshd_settingsharden_linux_sshd_settings_userを組み合わせ、harden_linux_sshd_settings_userの設定が優先され、harden_linux_sshd_settings内の^Port 設定/キーを上書きします。

他のタスクでも同様のパターンが見られるため、これに関して述べたことが他の場合にも当てはまります。

次に、ファイアウォール/iptablesのデフォルト設定です。ファイアウォール/iptablesのルールと設定はUFWによって管理されます:

harden_linux_ufw_defaults:
  "^IPV6": 'IPV6=yes'
  "^DEFAULT_INPUT_POLICY": 'DEFAULT_INPUT_POLICY="DROP"'
  "^DEFAULT_OUTPUT_POLICY": 'DEFAULT_OUTPUT_POLICY="ACCEPT"'
  "^DEFAULT_FORWARD_POLICY": 'DEFAULT_FORWARD_POLICY="DROP"'
  "^DEFAULT_APPLICATION_POLICY": 'DEFAULT_APPLICATION_POLICY="SKIP"'
  "^MANAGE_BUILTINS": 'MANAGE_BUILTINS=no'
  "^IPT_SYSCTL": 'IPT_SYSCTL=/etc/ufw/sysctl.conf'
  "^IPT_MODULES": 'IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"'

これらの設定は基本的に/etc/defaults/ufwの値を変更します。デフォルト設定の1つまたは複数を上書きする場合、上のように同じキー(これはregexです)を指定し、新しい値を割り当てます:

harden_linux_ufw_defaults_user:
  "^DEFAULT_FORWARD_POLICY": 'DEFAULT_FORWARD_POLICY="ACCEPT"'

先に説明したように、このプレイブックは、harden_linux_ufw_defaultsharden_linux_ufw_defaults_userを組み合わせます。この場合も、harden_linux_ufw_defaults_userの設定が優先されます。

次に、harden_linux_ufw_rulesを使ってファイアウォールルールを指定できます。デフォルトでは、ポート22でSSHトラフィックを許可します(プロトコルはtcp):

harden_linux_ufw_rules:
  - rule: "allow"
    to_port: "22"
    protocol: "tcp"

次のパラメータがデフォルト値(もしあれば)付きで利用可能です:

rule (デフォルトなし)
interface (デフォルト: '')
direction (デフォルト: 'in')
from_ip (デフォルト: 'any')
to_ip (デフォルト: 'any')
from_port (デフォルト: '')
to_port (デフォルト: '')
protocol (デフォルト: 'any')
log (デフォルト: 'false')
delete (デフォルト: 'false')

ルールはallowdenylimitrejectの値を持つことができます。インターフェースはそのルールに対して設定します。方向(inまたはout)はインターフェースによって値に依存します。from_ipはソースIPアドレス、from_portはソースポート、to_ipは宛先IPアドレス、to_portは宛先ポートを指定します。プロトコルはデフォルトでanyです。有効な値はtcpudpipv6espahgreigmpです。logはfalse(デフォルト)またはtrueのどちらかを取ります。新しい接続がこのルールに一致した場合、ログに記録されます。deleteはルールを削除するかどうかを指定します。以前に追加されたルールを削除する場合は重要です。単にharden_linux_ufw_rulesからルールを削除するだけでは不十分です!削除するためにはdeleteを使用する必要があります。

特定のネットワーク間でホストが通信できるようにすることもできます(ポート制限はなし):

harden_linux_ufw_allow_networks:
  - "10.3.0.0/24"
  - "10.200.0.0/16"

次に、harden_linuxロールは一部のシステム変数(sysctl.conf / procファイルシステム)も変更します。これらの設定は、Googleが自社のGoogle Compute Cloud OSイメージに使用している推奨事項です(Google Cloud - カスタムイメージを構築するための要件およびCompute Engine用にインポートしたイメージを構成するを参照)。デフォルト設定は次のとおりです(これらの設定に満足している場合は、特に何もする必要はありませんが、動作するかどうかは確認することをお勧めします):

harden_linux_sysctl_settings:
  "net.ipv4.tcp_syncookies": 1                    # SYNフラッド防止を有効にします
  "net.ipv4.conf.all.accept_source_route": 0      # ソースルーティングされたパケットを無視します
  "net.ipv6.conf.all.accept_source_route": 0      # IPv6 - ICMPリダイレクトを無視します
  "net.ipv4.conf.default.accept_source_route": 0  # ソースルーティングされたパケットを無視します
  "net.ipv6.conf.default.accept_source_route": 0  # IPv6 - ソースルーティングされたパケットを無視します
  "net.ipv4.conf.all.accept_redirects": 0         # ICMPリダイレクトを無視します
  "net.ipv6.conf.all.accept_redirects": 0         # IPv6 - ICMPリダイレクトを無視します
  "net.ipv4.conf.default.accept_redirects": 0     # ICMPリダイレクトを無視します
  "net.ipv6.conf.default.accept_redirects": 0     # IPv6 - ICMPリダイレクトを無視します
  "net.ipv4.conf.all.secure_redirects": 1         # 非GWホストからのICMPリダイレクトを無視します
  "net.ipv4.conf.default.secure_redirects": 1     # 非GWホストからのICMPリダイレクトを無視します
  "net.ipv4.ip_forward": 0                        # ネットワーク間のトラフィックを許可しない
  "net.ipv6.conf.all.forwarding": 0               # IPv6 - ネットワーク間のトラフィックを許可しない
  "net.ipv4.conf.all.send_redirects": 0           # ネットワーク間のトラフィックを許可しない
  "net.ipv4.conf.default.send_redirects": 0       # ネットワーク間のトラフィックを許可しない
  "net.ipv4.conf.all.rp_filter": 1                # リバースパスフィルタリング - IPスプーフィング防止
  "net.ipv4.conf.default.rp_filter": 1            # リバースパスフィルタリング - IPスプーフィング防止
  "net.ipv4.icmp_echo_ignore_broadcasts": 1       # Smurf攻撃に参加しないようにICMPブロードキャストを無視します
  "net.ipv4.icmp_ignore_bogus_error_responses": 1 # 無効なICMPエラーを無視します
  "net.ipv4.icmp_echo_ignore_all": 0              # 無効なICMPエラーを無視します
  "net.ipv4.conf.all.log_martians": 1             # スプーフィング、ソースルーティングされたパケット、およびリダイレクトパケットを記録します
  "net.ipv4.conf.default.log_martians": 1         # スプーフィング、ソースルーティングされたパケット、およびリダイレクトパケットを記録します
  "net.ipv4.tcp_rfc1337": 1                       # RFC 1337に対する修正を実装
  "kernel.randomize_va_space": 2                  # mmapベース、ヒープ、スタック、およびVDSOページのアドレスをランダム化
  "fs.protected_hardlinks": 1                     # ToCToUレースからの保護を提供
  "fs.protected_symlinks": 1                      # ToCToUレースからの保護を提供
  "kernel.kptr_restrict": 1                       # カーネルアドレスの特定を困難にします
  "kernel.perf_event_paranoid": 2                 # perfをrootのみで利用可能にします

すべての設定を上書きすることができます。たとえば、harden_linux_sysctl_settings_userという変数を作成することで上書きできます:

harden_linux_sysctl_settings_user:
  "net.ipv4.ip_forward": 1
  "net.ipv6.conf.default.forwarding": 1
  "net.ipv6.conf.all.forwarding": 1

プレイブックのタスクの1つが、harden_linux_sysctl_settingsharden_linux_sysctl_settings_userを組み合わせ、harden_linux_sysctl_settings_userの設定が優先されます。設定に関する詳細は、ロールのdefaults/main.ymlファイルを参照してください。

UFWのロギングを有効にしたい場合は、以下を設定します:

harden_linux_ufw_logging: 'on'

可能な値はonofflowmediumhighfullです。

次に「sshguard」の設定について。「sshguard」は、SSHに対するブルートフォース攻撃から保護します。自分自身を長時間ロックアウトしないように、IPまたはIP範囲をホワイトリストに追加できます。デフォルトでは基本的に「localhost」だけです:

harden_linux_sshguard_whitelist:
  - "127.0.0.0/8"
  - "::1/128"

NTPパッケージもインストール/設定できます。これはオプションです。デフォルトでは、systemd-timesyncdの使用をお勧めします。また、ntpパッケージも使用できます。ただし、openntpdsystemd-timesyncdは、デフォルトでポートを開放しないという利点があります。ホストの時計を同期させるだけであれば、これで十分です。すべてのホストで同じ時間を持つことは、証明書の検証、etcd、データベース、暗号化など、多くのサービスにとって重要です。

harden_linux_ntpの有効なオプションは次のとおりです:

  • openntpd
  • ntp
  • systemd-timesyncd

openntpdおよびsystemd-timesyncdはデフォルトでポートを開放しないため、ホストの時計を同期させるためにはこれらのいずれかで問題ありません。systemd-timesyncdは、systemdを使用するディストリビューションで既にインストールされています(基本的に現在のほとんどのLinux OSで真実です)。この場合、追加のパッケージは不要です。openntpdを有効にするには、次のようにharden_linux_ntpを設定します:

harden_linux_ntp: "openntpd"

openntpdntpdまたはsystemd-timesyncdの設定(次の段落を参照)。さらなるオプションについては、man 5 ntpd.confを参照してください。

ここでの「キー」は、置換したい設定の正規表現で、値は設定名と設定値です。例として、servers 0.debian.pool.ntp.orgの行をservers 1.debian.pool.ntp.orgに置き換えたい場合、正規表現(キー)は^servers 0となります。

これは「server 0で始まる行を検索し、行全体をservers 1.debian.pool.ntp.orgに置き換えます」となります。このように設定ファイル内の任意の設定を他の何かに置き換えることができます。いくつかの例:

harden_linux_ntp_settings:
  "^servers 0": "servers 0.debian.pool.ntp.org"
  "^servers 1": "servers 1.debian.pool.ntp.org"
  "^servers 2": "servers 2.debian.pool.ntp.org"
  "^servers 3": "servers 3.debian.pool.ntp.org"

注意systemd-timesyncdは合理的なコンパイル時のデフォルトを持ちます。そのため、設定を変更する必要は通常ありません(NTPサーバーさえも)。以下は単なる例であり、systemd-timesyncdに対してharden_linux_ntp_settingsを指定する必要はありません。

systemd-timesyncdの場合、設定ファイルは少し異なります。この場合、/etc/systemd/timesyncd.confのためのsystemdドロップインが/etc/systemd/timesyncd.conf.d/に作成され、指定された設定が追加されます。

Debianの例:

harden_linux_ntp_settings:
  "^#NTP=": "NTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org"

Ubuntuの例:

harden_linux_ntp_settings:
  "^#NTP=": "NTP=ntp.ubuntu.com"

Archlinuxの例:

harden_linux_ntp_settings:
  "^#NTP=": "NTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org"

harden_linux_files_to_deleteを使用して、ターゲットホストで存在しないべきファイルのリストを指定できます。例:

harden_linux_files_to_delete:
  - "/root/.pw"

systemd-resolvedがDNS解決に使用されている場合、その動作はharden_linux_systemd_resolved_settingsで調整できます。デフォルトでは、この変数は指定されていません。systemdドロップイン構成が/etc/systemd/resolved.conf.d/99-override.confに作成され、そこに指定された設定が追加されます。

注意/etc/systemd/resolved.conf内に設定がすでに設定されている場合(例:DNS=8.8.8.8)、以下にDNS=9.9.9.9を設定すると、最終的な設定はDNS=8.8.8.8 9.9.9.9になります。それを望まない場合は、まずその値を「解除」し、次に望む値を追加する必要があります。例:

harden_linux_systemd_resolved_settings:
  - DNS=
  - DNS=9.9.9.9

GoogleのDNSサーバー(8.8.8.88.8.4.4)は迅速なDNSルックアップを提供しますが、もちろん、Googleがあなたを監視する可能性があります。他のDNSサーバーを使用することは少なくとも考慮すべきことです。さらに、DNSリクエストを暗号化することも考えられます。systemd-resolvedがサポートしている方法の1つはDNSOverTLSです。Quad9 (9.9.9.9/149.112.112.112)およびCloudflare (1.1.1.1/1.0.0.1)DNSOverTLSをサポートしています。
以下のsystemd-resolved設定は、IPv4およびIPv6のためにQuad9とCloudflare DNSを設定します。設定DNSOverTLS=opportunisticは、DNSサーバーがサポートしている場合にDNSOverTLSを使用し、サポートされていない場合は通常の暗号化されていないDNSにフォールバックします(詳しくはresolved.conf.5を参照):

harden_linux_systemd_resolved_settings:
  - DNS=
  - DNS=9.9.9.9 1.1.1.1 2606:4700:4700::1111 2620:fe::fe
  - FallbackDNS=
  - FallbackDNS=149.112.112.112 1.0.0.1 2620:fe::9 2606:4700:4700::1001
  - DNSOverTLS=
  - DNSOverTLS=opportunistic

また、パッケージマネージャのキャッシュ動作も調整できます。たとえば、Ubuntuの場合:

# パッケージキャッシュを更新しない場合は"false"に設定
harden_linux_ubuntu_update_cache: true

# パッケージキャッシュの有効時間を設定
harden_linux_ubuntu_cache_valid_time: 3600

Archlinuxの場合:

# パッケージキャッシュを更新しない場合は"false"に設定
harden_linux_archlinux_update_cache: true

使用例プレイブック

ansible-galaxy install githubixx.harden_linuxでロールをインストールした場合、プレイブックにロールを含めることができます。以下の例をご覧ください:

- hosts: webservers
  roles:
    - githubixx.harden_linux

テスト

このロールには、Molecule、libvirt(vagrant-libvirt)、およびQEMU/KVMを使用して作成された小さなテストセットアップがあります。テストの設定方法については、私のブログ記事「Molecule、libvirt(vagrant-libvirt)、およびQEMU/KVMを使ったAnsibleロールのテスト」を参照してください。テスト設定はこちらです。

その後、以下のコマンドでMoleculeを実行できます:

molecule converge

これにより、異なるサポートされているLinuxオペレーティングシステムを持ついくつかの仮想マシン(VM)が設定され、harden_linuxロールが適用されます。小さな検証ステップも含まれています:

molecule verify

クリーンアップを実行するには、次のコマンドを使用します:

molecule destroy

ライセンス

GNU一般公衆ライセンス バージョン3

著者情報

www.tauceti.blog

プロジェクトについて

Ansible role for hardening Linux

インストール
ansible-galaxy install githubixx.harden_linux
ライセンス
gpl-3.0
ダウンロード
3.3k
所有者
Senior System Engineer - Python, Go, Cloud, Kubernetes, Commodore, Retro, 80's ;-)