

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 建立共用 Linux AMI 的建議
<a name="building-shared-amis"></a>

請使用下列準則來減少可能遭受攻擊的範圍，以及改善所建立 AMI 的可靠性。

**重要**  
沒有任何一份清單可詳盡列出所有的安全性準則。請小心建置您的共享 AMI，並花些時間思考那些位置可能暴露機密資料。

**Topics**
+ [停用根使用者的密碼型態遠端登入](#public-amis-disable-password-logins-for-root)
+ [停用本機根存取](#restrict-root-access)
+ [移除 SSH 主機金鑰對](#remove-ssh-host-key-pairs)
+ [安裝公有金鑰登入資料](#public-amis-install-credentials)
+ [停用 sshd DNS 檢查 (選用)](#public-amis-disable-ssh-dns-lookups)
+ [移除敏感性資料](#public-amis-protect-yourself)

如果您要為 建置 AMIs AWS Marketplace，請參閱《 *AWS Marketplace 賣方指南*》中的[建置 AMIs 的最佳實務](https://docs.aws.amazon.com/marketplace/latest/userguide/best-practices-for-building-your-amis.html)，以取得指導方針、政策和最佳實務。

## 停用根使用者的密碼型態遠端登入
<a name="public-amis-disable-password-logins-for-root"></a>

公用 AMI 使用固定的根密碼會帶來安全風險，且資訊會迅速向外散佈。即便仰賴使用者於第一次登入時變更密碼，都會留下一些可能遭到濫用的空窗。

若要解決此問題，請停用根使用者的密碼型態遠端登入。

**停用根使用者的密碼型態遠端登入**

1. 使用文字編輯器開啟 `/etc/ssh/sshd_config` 檔案，並找出下行：

   ```
   #PermitRootLogin yes
   ```

1. 將行變為：

   ```
   PermitRootLogin without-password
   ```

   此組態檔案的位置可能與您的發行版本不同，或您不是執行 OpenSSH。若是這種情況，請參閱相關文件。

## 停用本機根存取
<a name="restrict-root-access"></a>

使用共享 AMI 時，最佳實務之一就是停用直接根登入。若要停用，請登入運作中的執行個體，然後發出下列命令：

```
[ec2-user ~]$ sudo passwd -l root
```

**注意**  
此命令不會影響 `sudo` 的使用。

## 移除 SSH 主機金鑰對
<a name="remove-ssh-host-key-pairs"></a>

 如果您打算共享來自公用 AMI 的 AMI，請移除 `/etc/ssh` 中現有的 SSH 主機金鑰對。有其他人使用您的 AMI 啟動執行個體時，會強迫 SSH 產生新的唯一 SSH 金鑰對，藉此以改善安全性和減少發生「中間人」攻擊的可能性。

移除位在您系統中所有下列的金鑰檔案。
+  ssh\$1host\$1dsa\$1key 
+  ssh\$1host\$1dsa\$1key.pub 
+  ssh\$1host\$1key 
+  ssh\$1host\$1key.pub 
+  ssh\$1host\$1rsa\$1key 
+  ssh\$1host\$1rsa\$1key.pub 
+ ssh\$1host\$1ecdsa\$1key
+ ssh\$1host\$1ecdsa\$1key.pub
+ ssh\$1host\$1ed25519\$1key
+ ssh\$1host\$1ed25519\$1key.pub

您可以使用下列命令安全地移除所有這些檔案：

```
[ec2-user ~]$ sudo shred -u /etc/ssh/*_key /etc/ssh/*_key.pub
```

**警告**  
**shred** 等安全移除公用程式可能不會從儲存媒體中移除檔案的所有複本。檔案的隱藏複本可能由日誌檔案系統 (包含 Amazon Linux 預設 ext4)、快照、備份、RAID 和暫時性快取建立。若要了解詳細資訊，請參閱[銷毀文件](https://www.gnu.org/software/coreutils/manual/html_node/shred-invocation.html)。

**重要**  
如果您忘記從公用 AMI 中移除現有的 SSH 主機金鑰對，我們的定期稽核流程會通知您和執行您可能有安全風險之 AMI 執行個體的所有客戶。過一段短時間的寬限期後，我們會將 AMI 標示為私有。

## 安裝公有金鑰登入資料
<a name="public-amis-install-credentials"></a>

設定 AMI 避免使用密碼登入後，您必須確定使用者可用其他機制登入。

Amazon EC2 允許使用者在啟動執行個體時指定公私金鑰對名稱。為 `RunInstances` API 呼叫 (或透過命令列 API 工具) 提供有效的金鑰對名稱時，公有金鑰 (呼叫 `CreateKeyPair` 或 `ImportKeyPair` 後金鑰對中 Amazon EC2 保留在伺服器上的部分) 會透過執行個體中繼資料的 HTTP 查詢提供給執行個體。

若要透過 SSH 登入，您的 AMI 必須在開機時擷取金鑰值，並將其附加至 `/root/.ssh/authorized_keys` (或 AMI 上任何其他使用者帳戶的對等檔案)。使用者可用金鑰對啟動您 AMI 的執行個體並登入，無需根密碼。

包括 Amazon Linux 和 Ubuntu 等許多發行版本皆使用 `cloud-init` 套件來注入所設定使用者的公有金鑰登入資料。如果您的發行版本不支援 `cloud-init`，您可新增下列程式碼至系統啟動指令碼 (例如 `/etc/rc.local`)，以納入您在啟動時為根使用者指定的公有金鑰。

**注意**  
在下列範例中，IP 地址 http://169.254.169.254/ 是 link-local 地址且僅在執行個體中有效。

------
#### [ IMDSv2 ]

```
if [ ! -d /root/.ssh ] ; then
        mkdir -p /root/.ssh
        chmod 700 /root/.ssh
fi
# Fetch public key using HTTP
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /tmp/my-key
if [ $? -eq 0 ] ; then
        cat /tmp/my-key >> /root/.ssh/authorized_keys
        chmod 700 /root/.ssh/authorized_keys
        rm /tmp/my-key
fi
```

------
#### [ IMDSv1 ]

```
if [ ! -d /root/.ssh ] ; then
        mkdir -p /root/.ssh
        chmod 700 /root/.ssh
fi
# Fetch public key using HTTP
curl http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /tmp/my-key
if [ $? -eq 0 ] ; then
        cat /tmp/my-key >> /root/.ssh/authorized_keys
        chmod 700 /root/.ssh/authorized_keys
        rm /tmp/my-key
fi
```

------

 這會套用到任何使用者；無需將其限制到 `root` 使用者。

**注意**  
重新綁定以此 AMI 為基礎的執行個體，會加入其啟動金鑰。若要避免加入金鑰，您必須清除 (或刪除) `authorized_keys` 檔案或將此檔案排除於重新綁定之外。

## 停用 sshd DNS 檢查 (選用)
<a name="public-amis-disable-ssh-dns-lookups"></a>

停用 sshd DNS 檢查會稍微降低 sshd 的安全性。但假如 DNS 解析失敗，SSH 登入仍能如預期運作。如果您不停用 sshd 檢查，DNS 解析失敗將封鎖所有登入。

**停用 sshd DNS 檢查**

1. 使用文字編輯器開啟 `/etc/ssh/sshd_config` 檔案，並找出下行：

   ```
   #UseDNS yes
   ```

1. 將行變為：

   ```
   UseDNS no
   ```

**注意**  
此組態檔案的位置可能與您的發行版本不同，或您不是執行 OpenSSH。若是這種情況，請參閱相關文件。

## 移除敏感性資料
<a name="public-amis-protect-yourself"></a>

我們建議您不要將機密資料或軟體存放在共享的任何 AMI 上。啟動共享 AMI 的使用者可能會重新綁定，並將其註冊為自己的 AMI。請按照以下準則幫助您避免一些容易遭到忽視的安全風險：
+ 建議使用 `--exclude directory` 的 `ec2-bundle-vol` 選項跳過含有您不想加入到套件內之機密資訊的任何目錄和子目錄。尤其請在綁定映像時排除所有使用者擁有的 SSH 公有/私有金鑰對和 SSH `authorized_keys` 檔案。Amazon 公有 AMI 會將這些資訊存放在根使用者的 `/root/.ssh`，和一般使用者的 `/home/user_name/.ssh/` 內。如需詳細資訊，請參閱[ec2-bundle-vol](ami-tools-commands.md#ami-bundle-vol)。
+ 綁定前務必刪除 shell 歷程記錄。如果您在同一 AMI 嘗試一次以上的套件上傳，shell 歷程記錄會包含您的存取金鑰。以下範例應該是您在從執行個體內綁定之前執行的最後一項命令。

  ```
  [ec2-user ~]$ shred -u ~/.*history
  ```
**警告**  
上面警告中提及的 **shred** 限制同樣適用於此處。  
請注意，bash 會在退出時將目前工作階段的歷程記錄寫入到磁碟。如果您在刪除 `~/.bash_history` 後登出執行個體，然後再重新登入，您會發現 `~/.bash_history` 已重新建立，並包含在先前工作階段中執行的所有命令。  
bash 以外的其他程式也會將歷程記錄寫入到磁碟。請小心使用，並移除或排除不必要以點開頭的檔案或以點開頭的目錄。
+ 綁定執行中的執行個體需要您的私有金鑰和 X.509 憑證。因此請將這些憑證和其他登入資料放在不會加入綁定的位置 (例如執行個體儲存體)。