

 AWS Cloud9 不再向新客户提供。 AWS Cloud9 的现有客户可以继续正常使用这项服务。[了解详情](https://aws.amazon.com/blogs/devops/how-to-migrate-from-aws-cloud9-to-aws-ide-toolkits-or-aws-cloudshell/)

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# LAMP 教程适用于 AWS Cloud9
<a name="sample-lamp"></a>

本教程允许您设置和运行 LAMP (Linux, Apache HTTP 服务器，MySQL，以及 PHP) 在 AWS Cloud9 开发环境中。

按照本教程并创建此示例可能会导致向您收取费用 AWS 账户。其中包括亚马逊弹性计算云 (Amazon EC2) AWS 服务 等可能产生的费用。有关更多信息，请参阅 [Amazon EC2 定价](https://aws.amazon.com/ec2/pricing/)。

**Topics**
+ [先决条件](#sample-lamp-prereqs)
+ [步骤 1：安装工具](#sample-lamp-install-tools)
+ [第 2 步：设置 MySQL](#sample-lamp-setup-mysql)
+ [步骤 3：设置网站](#sample-lamp-apache)
+ [步骤 4：清除](#sample-lamp-clean-up)

## 先决条件
<a name="sample-lamp-prereqs"></a>

在使用此示例之前，请确保您的设置满足以下要求：
+ **您必须拥有现有的 AWS Cloud9 EC2 开发环境。**此示例假设您的 EC2 环境已连接到运行 Amazon Linux 的亚马逊 EC2 实例，或者 Ubuntu 服务器。如果您有不同类型的环境或操作系统，可能需要按照本示例的说明来设置相关的工具。有关更多信息，请参阅 [在中创建环境 AWS Cloud9](create-environment.md)。
+ **您已经打开了现有环境的 AWS Cloud9 IDE。**打开环境时，会在 Web 浏览器中 AWS Cloud9 打开该环境的 IDE。有关更多信息，请参阅 [在中打开环境 AWS Cloud9](open-environment.md)。

## 步骤 1：安装工具
<a name="sample-lamp-install-tools"></a>

在本步骤中，您将安装以下工具：
+ Apache HTTP 服务器，一个 Web 服务器主机。
+ PHP，一种脚本语言，特别适用于 Web 开发并可嵌入到 HTML 中。
+ MySQL，数据库管理系统。

然后，您可以通过开始完成此步骤 Apache HTTP 服务器然后 MySQL.

1. 确保已在实例上安装了最新的安全更新和错误修复。为此，在 AWS Cloud9 IDE 的终端会话中，运行 for (Amazon Linux) 或 f **`apt update`**or (**`yum update`**Ubuntu 服务器）命令。（要开始新的终端会话，请在菜单栏上依次选择 **Window（窗口）**> **New Terminal（新建终端）**。） 

   对于 Amazon Linux：

   ```
   sudo yum -y update
   ```

   对于 Ubuntu 服务器：

   ```
   sudo apt -y update
   ```

1. 检查是否 Apache HTTP 服务器已经安装完毕。为此，请运行 **`httpd -v`**（适用于亚马逊 Linux）或 **`apache2 -v`**（对于 Ubuntu 服务器）命令。

   如果成功，则输出包含 Apache HTTP 服务器版本号。

   如果您看到错误，请安装 Apache 通过运行**`install`**命令获得 HTTP 服务器。

   对于 Amazon Linux：

   ```
   sudo yum install -y httpd24
   ```

   对于 Ubuntu 服务器：

   ```
   sudo apt install -y apache2
   ```

1. 确认是否 PHP 已通过运行**`php -v`**命令进行安装。

   如果成功，输出将包含 PHP 版本号。

   如果您看到错误，则通过运行 **`install`** 命令安装 PHP。

   对于 Amazon Linux：

   ```
   sudo yum install -y php56
   ```

   对于 Ubuntu 服务器：

   ```
   sudo apt install -y php libapache2-mod-php php-xml
   ```

1. 确认是否 MySQL 已通过运行**`mysql --version`**命令进行安装。

   如果成功，则输出包含 MySQL 版本号。

   如果您看到错误，请安装 MySQL 通过运行**`install`**命令。

   对于 Amazon Linux：

   ```
   sudo yum install -y mysql-server
   ```

   对于 Ubuntu 服务器：

   ```
   sudo apt install -y mysql-server
   ```

1. 在你安装之后 Apache HTTP 服务器，PHP，以及 MySQL，开始 Apache HTTP 服务器，然后通过运行以下命令确认它已启动。

   对于 Amazon Linux（可能需要运行此命令两次）：

   ```
   sudo service httpd start && sudo service httpd status
   ```

   对于 Ubuntu 服务器（要返回命令提示符，请按`q`）：

   ```
   sudo service apache2 start && sudo service apache2 status
   ```

1. 启动 MySQL，然后通过运行以下命令确认它已启动。

   对于 Amazon Linux：

   ```
   sudo service mysqld start && sudo service mysqld status
   ```

   对于 Ubuntu 服务器（要返回命令提示符，请按`q`）：

   ```
   sudo service mysql start && sudo service mysql status
   ```

## 第 2 步：设置 MySQL
<a name="sample-lamp-setup-mysql"></a>

在此步骤中，您进行设置 MySQL 要关注 MySQL 安全最佳实践。这些安全最佳实践包括为根账户设置密码和删除可从本地主机外部访问的根账户。其他需要注意的最佳实践是删除匿名用户的权限，删除测试数据库，以及删除允许任何人访问名称以 `test_` 开头的数据库的权限。

然后，你要通过练习开始然后退出来来来完成这一步 MySQL 命令行客户端。

1. 实施 MySQL 的安全最佳实践 MySQL 通过在 AWS Cloud9 IDE 的终端会话中运行以下命令进行安装。

   ```
   sudo mysql_secure_installation
   ```

1. 在提示时，按照说明回答以下问题。

   对于 Amazon Linux：

   1. **输入当前的根密码（如无密码，按 Enter）** – 按 `Enter`（如无密码）。

   1. **设置根密码** – 键入 `Y`，然后按 `Enter`。

   1. **新建密码** – 键入密码，然后按 `Enter`。

   1. **重新输入新密码** – 再次键入密码，然后按 `Enter`。（请务必将密码存储在安全位置以便以后使用。）

   1. **删除匿名用户** – 键入 `Y`，然后按 `Enter`。

   1. **禁止远程根登录** – 键入 `Y`，然后按 `Enter`。

   1. **删除测试数据库以及对它的访问** – 键入 `Y`，然后按 `Enter`。

   1. **立即重新加载权限表** – 键入 `Y`，然后按 `Enter`。

   对于 Ubuntu 服务器：

   1. **是否要设置“验证密码”插件** – 输入 `y`，然后按 `Enter`。

   1. **有三个密码验证策略级别** – 输入 `0`、`1` 或 `2`，然后按 `Enter`。

   1. **新建密码** – 输入密码，然后按 `Enter`。

   1. **重新输入新密码** – 再次输入密码，然后按 `Enter`。务必将密码存储在安全位置以便以后使用。

   1. **是否希望继续使用提供的密码** – 输入 `y`，然后按 `Enter`。

   1. **删除匿名用户** – 输入 `y`，然后按 `Enter`。

   1. **禁止远程根登录** – 输入 `y`，然后按 `Enter`。

   1. **删除测试数据库以及对它的访问** – 输入 `y`，然后按 `Enter`。

   1. **立即重新加载权限表** – 输入 `y`，然后按 `Enter`。

1. 要直接与之互动 MySQL，启动 MySQL 通过运行以下命令以 root 用户身份运行命令行客户端。在提示时，键入您之前设置的根用户的密码，然后按 `Enter`。当你进入`mysql>`时，提示会更改为 MySQL 命令行客户端。

   ```
   sudo mysql -uroot -p
   ```

1. 要退出 MySQL 命令行客户端，运行以下命令。提示符变回 `$`。

   ```
   exit;
   ```

## 步骤 3：设置网站
<a name="sample-lamp-apache"></a>

在此步骤中，您将设置默认网站根目录 Apache 具有推荐所有者和访问权限的 HTTP 服务器。然后你创建一个 PHP基于该默认网站根目录下的网页。

然后，您可以通过在亚马逊中设置安全组，在亚马逊 EC2 虚拟私有云（Amazon VPC）中设置与此 EC2 环境关联的网络访问控制列表（Amazon VPC），使传入的网络流量能够查看该网页。每个 EC2 环境都必须与 Amazon 中的安全组 EC2 和 Amazon VPC 中的网络 ACL 相关联。但是，即使 AWS 账户 中的原定设置网络 ACL 允许环境的所有传入和传出流量，原定设置安全组也仅允许端口 22 上使用 SSH 的传入流量。有关更多信息，请参阅 [AWS Cloud9 开发环境的 VPC 设置](vpc-settings.md)。

然后，在此步骤最后从 AWS Cloud9 IDE 外部成功查看网页。

1. 为设置默认网站根目录 Apache 具有推荐所有者和访问权限的 HTTP 服务器 (`/var/www/html`)。为此，请在 AWS Cloud9 IDE 的终端会话中按以下顺序逐一运行以下六个命令。要了解每个命令的作用，请阅读每个命令后面 `#` 字符后的信息。

   对于 Amazon Linux：

   ```
   sudo groupadd web-content # Create a group named web-content.
   
   sudo usermod -G web-content -a ec2-user # Add the user ec2-user (your default user for this environment) to the group web-content.
   
   sudo usermod -G web-content -a apache # Add the user apache (Apache HTTP Server) to the group web-content.
   
   sudo chown -R ec2-user:web-content /var/www/html # Change the owner of /var/www/html and its files to user ec2-user and group web-content.
   
   sudo find /var/www/html -type f -exec chmod u=rw,g=rx,o=rx {} \; # Change all file permissions within /var/www/html to user read/write, group read-only, and others read/execute. 
   
   sudo find /var/www/html -type d -exec chmod u=rwx,g=rx,o=rx {} \; # Change /var/www/html directory permissions to user read/write/execute, group read/execute, and others read/execute.
   ```

   对于 Ubuntu 服务器：

   ```
   sudo groupadd web-content # Create a group named web-content.
   
   sudo usermod -G web-content -a ubuntu # Add the user ubuntu (your default user for this environment) to the group web-content.
   
   sudo usermod -G web-content -a www-data # Add the user www-data (Apache HTTP Server) to the group web-content.
   
   sudo chown -R ubuntu:web-content /var/www/html # Change the owner of /var/www/html and its files to user ubuntu and group web-content.
   
   sudo find /var/www/html -type f -exec chmod u=rw,g=rx,o=rx {} \; # Change all file permissions within /var/www/html to user read/write, group read-only, and others read/execute. 
   
   sudo find /var/www/html -type d -exec chmod u=rwx,g=rx,o=rx {} \; # Change /var/www/html directory permissions to user read/write/execute, group read/execute, and others read/execute.
   ```

1. 创建一个 PHP基于的网页，`index.php`在默认的网站根文件夹中命名 Apache 通过运行以下命令获得 HTTP 服务器（即`/var/www/html`）。

   对于 Amazon Linux：

   ```
   sudo touch /var/www/html/index.php && sudo chown -R ec2-user:web-content /var/www/html/index.php && sudo chmod u=rw,g=rx,o=rx /var/www/html/index.php && sudo printf '%s\n%s\n%s' '<?php' '  phpinfo();' '?>' >> /var/www/html/index.php
   ```

   前面的 Amazon Linux 命令还将文件的所有者更改为`web-content`，将文件组更改read/write for the user, and read/execute为，并将该组和其他人的文件权限更改为。`ec2-user`

   对于 Ubuntu 服务器：

   ```
   sudo touch /var/www/html/index.php && sudo chown -R ubuntu:web-content /var/www/html/index.php && sudo chmod u=rw,g=rx,o=rx /var/www/html/index.php && sudo printf '%s\n%s\n%s' '<?php' '  phpinfo();' '?>' >> /var/www/html/index.php
   ```

   前面的命令为 Ubuntu 服务器还将文件的所有者更改为`ubuntu`，将文件组更改为`web-content`，并将该组和其他人的文件权限更改read/write for the user, and read/execute为。

   如果成功，上述命令将使用以下内容创建 `index.php` 文件。

   ```
   <?php
     phpinfo();
   ?>
   ```

1. 通过在 Amazon VPC 中设置网络 ACL 和与此 EC2 环境关联的 Amazon 安全组，允许通过端口 80 EC2 的传入网络流量查看新网页。要执行此操作，按照以下顺序运行下面的八个命令，一次运行一个命令。要了解每个命令的作用，请阅读每个命令的 `#` 字符后的信息。
**重要**  
运行以下命令可启用**所有** EC2 环境以及与此环境的安全组和网络 ACL 关联的 Amazon EC2 实例通过端口 80 传入的 Web 流量。这可能会导致该环境和 Amazon 实例以外的 EC2 环境和 Amazon EC2 实例意外启用通过端口 80 的传入网络流量。
**注意**  
下面的第二到第四个命令启用安全组来允许端口 80 上的传入 Web 流量。如果您有默认安全组，其仅允许端口 22 上的传入 SSH 流量，则必须在运行第二到第四个命令后运行第一个命令。但是，如果您有已经允许端口 80 上的传入 Web 流量的自定义安全组，则可以跳过运行这些命令。  
下面的第五到第八个命令会启用网络 ACL 来允许端口 80 上的传入 Web 流量。如果您有默认网络 ACL，其允许所有端口的所有传入流量，则可以安全地跳过运行这些命令。但是，假设您有一个自定义网络 ACL，它不允许通过端口 80 传入 Web 流量。然后，运行第一个命令，然后运行第五到第八个命令。

   ```
   MY_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) # Get the ID of the instance for the environment, and store it temporarily.
              
   MY_SECURITY_GROUP_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SecurityGroups[0].GroupId' --output text) # Get the ID of the security group associated with the instance, and store it temporarily.
   
   aws ec2 authorize-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --protocol tcp --cidr 0.0.0.0/0 --port 80 # Add an inbound rule to the security group to allow all incoming IPv4-based traffic over port 80.
   
   aws ec2 authorize-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --ip-permissions IpProtocol=tcp,Ipv6Ranges='[{CidrIpv6=::/0}]',FromPort=80,ToPort=80 # Add an inbound rule to the security group to allow all incoming IPv6-based traffic over port 80.
   
   MY_SUBNET_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SubnetId' --output text) # Get the ID of the subnet associated with the instance, and store it temporarily.
   
   MY_NETWORK_ACL_ID=$(aws ec2 describe-network-acls --filters Name=association.subnet-id,Values=$MY_SUBNET_ID --query 'NetworkAcls[].Associations[0].NetworkAclId' --output text) # Get the ID of the network ACL associated with the subnet, and store it temporarily.
   
   aws ec2 create-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --protocol tcp --rule-action allow --rule-number 10000 --cidr-block 0.0.0.0/0 --port-range From=80,To=80 # Add an inbound rule to the network ACL to allow all IPv4-based traffic over port 80. Advanced users: change this suggested rule number as desired.
   
   aws ec2 create-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --protocol tcp --rule-action allow --rule-number 10100 --ipv6-cidr-block ::/0 --port-range From=80,To=80 # Add an inbound rule to the network ACL to allow all IPv6-based traffic over port 80. Advanced users: change this suggested rule number as desired.
   ```

1. 获取 Web 服务器根目录内的 `index.php` 文件的 URL。为此，请运行以下命令，然后使用新的 Web 浏览器选项卡或与 AWS Cloud9 IDE 分开的其他 Web 浏览器转到显示的 URL。如果成功，网页将显示以下信息 Apache HTTP 服务器，MySQL, PHP，以及其他相关设置。

   ```
   MY_PUBLIC_IP=$(curl http://169.254.169.254/latest/meta-data/public-ipv4) && echo http://$MY_PUBLIC_IP/index.php # Get the URL to the index.php file within the web server root.
   ```

## 步骤 4：清除
<a name="sample-lamp-clean-up"></a>

假设您希望继续使用此环境，但希望禁用端口 80 上的传入 Web 流量。那么，按照以下顺序运行下面的八个命令（一次运行一个），以删除您之前在与环境关联的安全组和网络 ACL 中设置的对应的传入流量规则。要了解每个命令的作用，请阅读每个命令的 `#` 字符后的信息。

**重要**  
运行以下命令会禁用**所有** EC2 环境以及与此环境的安全组和网络 ACL 关联的 Amazon EC2 实例通过端口 80 传入的 Web 流量。这可能会导致意外禁用除此以外的 EC2 环境和 Amazon EC2 实例通过端口 80 传入的 Web 流量。

**注意**  
下面的第五到第八个命令删除现有规则，以阻止网络 ACL 允许端口 80 上的传入 Web 流量。如果您有原定设置网络 ACL，其允许所有端口的所有传入流量，则可以跳过运行这些命令。但是，假设您有一个自定义网络 ACL，其现有规则允许通过端口 80 传入 Web 流量，而您想要删除这些规则。那么，您需要运行第一个命令，然后运行第五到第八个命令。

```
MY_INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) # Get the ID of the instance for the environment, and store it temporarily.
           
MY_SECURITY_GROUP_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SecurityGroups[0].GroupId' --output text) # Get the ID of the security group associated with the instance, and store it temporarily.

aws ec2 revoke-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --protocol tcp --cidr 0.0.0.0/0 --port 80 # Delete the existing inbound rule from the security group to block all incoming IPv4-based traffic over port 80.

aws ec2 revoke-security-group-ingress --group-id $MY_SECURITY_GROUP_ID --ip-permissions IpProtocol=tcp,Ipv6Ranges='[{CidrIpv6=::/0}]',FromPort=80,ToPort=80 # Delete the existing inbound rule from the security group to block all incoming IPv6-based traffic over port 80.

MY_SUBNET_ID=$(aws ec2 describe-instances --instance-id $MY_INSTANCE_ID --query 'Reservations[].Instances[0].SubnetId' --output text) # Get the ID of the subnet associated with the instance, and store it temporarily.

MY_NETWORK_ACL_ID=$(aws ec2 describe-network-acls --filters Name=association.subnet-id,Values=$MY_SUBNET_ID --query 'NetworkAcls[].Associations[0].NetworkAclId' --output text) # Get the ID of the network ACL associated with the subnet, and store it temporarily.

aws ec2 delete-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --rule-number 10000 # Delete the existing inbound rule from the network ACL to block all IPv4-based traffic over port 80. Advanced users: if you originally created this rule with a different number, change this suggested rule number to match.

aws ec2 delete-network-acl-entry --network-acl-id $MY_NETWORK_ACL_ID --ingress --rule-number 10100 # Delete the existing inbound rule from the network ACL to block all IPv6-based traffic over port 80. Advanced users: if you originally created this rule with a different number, change this suggested rule number to match.
```

如果您已使用完此环境，请将其删除，以免一直对您的 AWS 账户收费。有关说明，请参阅 [删除中的环境 AWS Cloud9](delete-environment.md)。