如何在 Debian 9 服务器上使用 Nginx 安装并保护 phpMyAdmin

介绍

虽然许多用户需要像MySQL这样的数据库系统的功能,但仅从MySQL命令行客户端与系统进行交互需要熟悉SQL语言,因此它可能不是某些人喜欢的界面。

phpMyAdmin是为了让用户能够通过直观的 Web 界面与 MySQL 互动,并与 PHP 开发环境一起运行,在本指南中,我们将讨论如何在 Nginx 服务器上安装 phpMyAdmin,以及如何配置服务器以增加安全性。

<$>[note] 注: 在使用软件如phpMyAdmin时,有重要的安全考虑,因为它运行在数据库服务器上,它处理数据库凭据,并允许用户轻松执行任意的SQL查询到您的数据库中。因为phpMyAdmin是一个广泛部署的PHP应用程序,它经常针对攻击。

前提条件

在您开始使用本指南之前,您需要以下内容:

由于 phpMyAdmin 使用 MySQL 身份验证来处理身份验证,所以强烈建议安装 SSL/TLS 证书,以便在服务器和客户端之间实现加密流量。

<$>[警告] 警告: 如果您没有SSL/TLS证书安装在服务器上,但仍然想要继续,请考虑通过SSH隧道执行访问,如本指南第5步所解释。

一旦你满足了这些前提条件,你可以继续与其余的指南。

第1步:安装phpMyAdmin

我们需要做的第一件事是在LEMP服务器上安装phpMyAdmin,我们将使用默认的Debian存储库来实现这一目标。

让我们先更新服务器的包索引:

1sudo apt update

现在你可以安装 phpMyAdmin:

1sudo apt install phpmyadmin

在安装过程中,您将被要求选择 Web 服务器(或 ApacheLighthttp)来配置. 因为我们正在使用 Nginx 作为 Web 服务器,我们不应该在这里做出选择。

接下来,您将被提示是否使用「dbconfig-common」来配置应用程序数据库。 选择「Yes」。 这将为 phpMyAdmin 设置内部数据库和管理用户。 您将被要求为 phpmyadmin MySQL 用户定义一个新的密码。 您还可以将其空置,并让 phpMyAdmin 随机创建密码。

为了让 Nginx Web 服务器能够正确地找到和服务 phpMyAdmin 文件,我们需要从安装文件中创建一个符号链接到 Nginx 文档根目录:

1sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

您的 phpMyAdmin 安装已启动. 要访问接口,请前往您的服务器的域名或公共 IP 地址,然后在您的 Web 浏览器中使用 /phpmyadmin:

1https://server_domain_or_IP/phpmyadmin

phpMyAdmin login screen

如前所述,phpMyAdmin使用MySQL身份验证来处理身份验证,这意味着您应该使用相同的用户名和密码,您通常会通过控制台或API连接到数据库。

<$>[注] 注: 作为 root MySQL 用户登录 phpMyAdmin 是不可鼓励的,因为它代表了重大安全风险. 我们将在本指南的下一步中看到如何禁用 root login

但是,通过安装 Web 接口,我们已经将我们的 MySQL 数据库服务器暴露在外部世界中. 由于 phpMyAdmin 的普及,以及它可能提供的大量数据,这样的安装是攻击的常见目标。 在本指南的以下部分,我们将看到一些不同的方式,我们可以使我们的 phpMyAdmin 安装更安全。

步骤 2 — 更改 phpMyAdmin 的默认位置

一个最基本的方式来保护你的phpMyAdmin安装是,使它更难找到. 机器人将扫描的常见路径,如 /phpmyadmin, /pma, /admin, /mysql 等。

通过我们的 phpMyAdmin 安装,我们创建了一个标志性链接,指向 /usr/share/phpmyadmin,实际应用程序文件所在地。

首先,让我们导航到 Nginx 文档根目录并列出其中的文件,以便更好地了解我们将进行的更改:

1cd /var/www/html/
2ls -l

您将收到以下输出:

1[secondary_label Output]
2total 8
3-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
4lrwxrwxrwx 1 root root 21 Apr 8 15:36 phpmyadmin -> /usr/share/phpmyadmin

输出显示,我们在这个目录中有一个名为phpmyadmin的符号链接,我们可以将这个链接的名称更改为我们想要的任何东西,这反过来会改变phpMyAdmin的访问URL,这可以帮助掩盖端点,从硬编码的机器人到搜索常见的端点名称。

在本指南中,我们将命名我们的端点 /nothingtosee,但你 应该选择一个替代名称

1sudo mv phpmyadmin nothingtosee
2ls -l

运行上述命令后,您将收到此输出:

1[secondary_label Output]
2total 8
3-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
4lrwxrwxrwx 1 root root 21 Apr 8 15:36 nothingtosee -> /usr/share/phpmyadmin

现在,如果你去到旧的URL,你会收到一个404错误:

1https://server_domain_or_IP/phpmyadmin

phpMyAdmin 404 error

您的phpMyAdmin接口现在将在我们刚刚配置的新URL上可用:

1https://server_domain_or_IP/nothingtosee

phpMyAdmin login screen

通过隐瞒phpMyAdmin在服务器上的真实位置,您将保护其界面免受自动扫描和手动暴力尝试。

步骤 3 – 禁用 root 登录

在 MySQL 和正常的 Linux 系统中,root 帐户是一个特殊的管理帐户,可以无限制地访问系统. 除了是一种特权帐户外,它是一种已知的登录名称,这使得它成为暴力攻击的明显目标。 为了最大限度地降低风险,我们将配置 phpMyAdmin 来拒绝来自用户 root 的任何登录尝试。

由于我们选择使用dbconfig-common来配置和存储 phpMyAdmin 设置,因此默认配置目前存储在数据库中,我们需要创建一个新的config.inc.php文件来定义我们的自定义设置。

尽管phpMyAdmin的PHP文件位于/usr/share/phpmyadmin内部,但应用程序使用位于/etc/phpmyadmin的配置文件。我们将在/etc/phpmyadmin/conf.d内部创建一个新的自定义设置文件,并将其命名为pma_secure.php:

1sudo nano /etc/phpmyadmin/conf.d/pma_secure.php

以下配置文件包含禁用无密码登录的必要设置(AllowNoPassword设置为false)和根登录(AllowRoot设置为false):

 1[label /etc/phpmyadmin/conf.d/pma_secure.php]
 2<?php
 3
 4# PhpMyAdmin Settings
 5# This should be set to a random string of at least 32 chars
 6$cfg['blowfish_secret'] = '3!#32@3sa(+=_4?),5XP_:U%%8\34sdfSdg43yH#{o';
 7
 8$i=0;
 9$i++;
10
11$cfg['Servers'][$i]['auth_type'] = 'cookie';
12$cfg['Servers'][$i]['AllowNoPassword'] = false;
13$cfg['Servers'][$i]['AllowRoot'] = false;
14
15?>

当您完成编辑时,请按CTRL +X,然后按y来确认更改和ENTER。这些更改将自动应用。如果您现在重新加载登录页面并尝试作为 root登录,您将收到一个 Access Denied 错误:

access denied

现在在您的 phpMyAdmin 安装中禁止 root 登录. 此安全措施将阻止 brute-force 脚本试图在您的服务器上猜测 root 数据库密码。

步骤4 — 创建身份验证网关

隐藏您的 phpMyAdmin 安装在一个不寻常的位置可能会阻止一些自动机器人扫描网络,但它对目标攻击是无用的。为了更好地保护受限制访问的 Web 应用程序,通常更有效地阻止攻击者在他们甚至可以到达应用程序之前。

在phpMyAdmin的具体情况下,保持登录接口锁定更为重要. 通过让它向世界开放,您正在为攻击者提供一项粗暴的平台,以便他们可以猜测您的数据库凭据。

将一个额外的身份验证层添加到您的 phpMyAdmin 安装允许您增加安全性. 用户将被要求通过 HTTP 身份验证提示,然后再看到 phpMyAdmin 登录屏幕。

要设置此设置,我们首先需要创建一个密码文件来存储身份验证凭证。 Nginx 要求使用crypt()函数加密密码。

要创建一个加密的密码,键入:

1openssl passwd

您将被要求输入并确认您想要使用的密码,该实用程序将显示密码的加密版本,它将看起来像这样:

1[secondary_label Output]
2O5az.RSPzd.HE

复制此值,因为您需要将其粘贴到我们将创建的身份验证文件中。

现在,创建一个身份验证文件,我们将这个文件称为pma_pass,并将其放入 Nginx 配置目录:

1sudo nano /etc/nginx/pma_pass

在此文件中,您将指定您想要使用的用户名,其次是密码(:),然后是您从openssl passwd实用程序获得的密码的加密版本。

我们将命名我们的用户为sammy,但您应该选择不同的用户名。

1[label /etc/nginx/pma_pass]
2sammy:O5az.RSPzd.HE

保存并关闭文件,当你完成。

现在我们已经准备好修改 Nginx 配置文件. 对于本指南,我们将使用位于 /etc/nginx/sites-available/example.com 的配置文件. 您应该使用相关的 Nginx 配置文件,用于当前托管 phpMyAdmin 的 Web 位置。

1sudo nano /etc/nginx/sites-available/example.com

我们需要在这个块中创建一个 位置部分,以匹配phpMyAdmin在服务器上的当前路径。

 1[label /etc/nginx/sites-available/default]
 2server {
 3    . . .
 4
 5        location / {
 6                try_files $uri $uri/ =404;
 7        }
 8
 9        location /nothingtosee {
10                # Settings for phpMyAdmin will go here
11        }
12
13    . . .
14}

在这个块中,我们需要设置两个不同的指令: auth_basic,它定义了在身份验证提示中显示的消息,以及 auth_basic_user_file,指向我们刚刚创建的文件。

 1[label /etc/nginx/sites-available/default]
 2server {
 3    . . .
 4
 5        location /nothingtosee {
 6                auth_basic "Admin Login";
 7                auth_basic_user_file /etc/nginx/pma_pass;
 8        }
 9
10    . . .
11}

完成保存并关闭文件. 若要检查配置文件是否有效,您可以运行:

1sudo nginx -t

预计产出如下:

1[secondary_label Output]
2nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
3nginx: configuration file /etc/nginx/nginx.conf test is successful

要激活新的身份验证端口,您必须重新加载 Web 服务器:

1sudo systemctl reload nginx

现在,如果您在 Web 浏览器中访问 phpMyAdmin URL,您应该被提示为您添加到 pma_pass 文件的用户名和密码:

1https://server_domain_or_IP/nothingtosee

Nginx authentication page

一旦您输入您的身份证,您将被带到标准的phpMyAdmin登录页面。

注意:如果更新页面不起作用,您可能需要清除缓存或使用不同的浏览器会话,如果您已经使用了phpMyAdmin。

除了提供额外的安全层外,这个网关还将有助于保持您的MySQL日志清除垃圾邮件身份验证尝试。

步骤5 — 通过加密隧道设置访问(可选)

为了提高安全性,您可以将您的 phpMyAdmin 安装锁定到授权的主机中,您可以在您的 Nginx 配置文件中将授权的主机列为 whitelist,因此任何来自 IP 地址的请求将被拒绝。

虽然这项功能本身在某些用例中可能足够,但它并不总是最好的长期解决方案,主要是因为大多数人没有从静态IP地址访问互联网。

对于一个更强大的长期解决方案,您可以使用基于IP的访问控制来创建一个设置,其中用户只会访问您的phpMyAdmin界面,如果他们从一个 授权的IP地址本地通过 SSH隧道 访问。

将基于IP的访问控制与SSH隧道相结合,大大提高了安全性,因为它完全阻止了来自公共互联网的访问(除了授权的IP),并通过使用加密隧道提供用户和服务器之间的安全通道。

在 Nginx 上设置基于 IP 的访问控制

在 Nginx 上,基于 IP 的访问控制可以在给定网站的相应位置块中定义,使用允许拒绝指令,例如,如果我们只希望允许来自给定主机的请求,我们应该包括以下两行,按照这个顺序,在我们想要保护的网站的相关位置块中:

1allow hostname_or_IP;
2deny all;

您可以允许尽可能多的主机,您只需要在您保护的网站的相应的位置块中为每个授权的主机/IP列出一个允许行,指令将按照列出的顺序进行评估,直到找到匹配或由于拒绝所有指令最终拒绝请求。

现在我们将配置 Nginx 以仅允许来自 localhost 或您当前的 IP 地址的请求。 首先,您需要知道您的本地计算机正在使用的当前公共 IP 地址来连接到互联网。 获取这些信息的方法有很多;为了简单,我们将使用由 ipinfo.io提供的服务。 您可以在浏览器中打开 URL https://ipinfo.io/ip或从您的本地计算机**运行以下命令:

1[environment local]
2curl https://ipinfo.io/ip

您应该得到一个简单的IP地址作为输出,如下:

1[environment local]
2[secondary_label Output]
3203.0.113.111

这是您当前的 public IP 地址. 我们将配置 phpMyAdmin 的位置块,以便仅允许来自该 IP 的请求,除了 localhost. 我们还需要在 `/etc/nginx/sites-available/example.com 中再次编辑 phpMyAdmin 的配置块。

使用您所选择的命令行编辑器打开 Nginx 配置文件:

1sudo nano /etc/nginx/sites-available/example.com

由于我们已经在当前配置中有一个访问规则,所以我们需要将其与基于IP的访问控制相结合,使用满足所有人的指令。

这就是你完成编辑后你的phpMyAdmin Nginx配置应该是这样的:

 1[label /etc/nginx/sites-available/example.com]
 2server {
 3    . . .
 4
 5    location /nothingtosee {
 6        satisfy all; #requires both conditions
 7
 8        allow 203.0.113.111; #allow your IP
 9        allow 127.0.0.1; #allow localhost via SSH tunnels
10        deny all; #deny all other sources
11
12        auth_basic "Admin Login";
13        auth_basic_user_file /etc/nginx/pma_pass;
14    }
15
16    . . .
17}

请记住,用 phpMyAdmin 可找到的实际路径代替 nicktosee,并用当前的公共 IP 地址代替突出的 IP 地址。

完成保存并关闭文件. 若要检查配置文件是否有效,您可以运行:

1sudo nginx -t

预计产出如下:

1[secondary_label Output]
2nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
3nginx: configuration file /etc/nginx/nginx.conf test is successful

现在重新加载 Web 服务器,以便更改生效:

1sudo systemctl reload nginx

因为您的 IP 地址明确列为授权主机,所以您的访问不应该受到干扰. 任何其他试图访问您的 phpMyAdmin 安装的人现在将收到一个 403 错误(禁止):

1https://server_domain_or_IP/nothingtosee

403 error

在下一节中,我们将看到如何使用SSH隧道来通过本地请求访问Web服务器,这样你仍然可以访问phpMyAdmin的界面,即使你的IP地址发生变化。

通过加密隧道访问phpMyAdmin

SSH隧道是通过加密渠道重定向网络流量的一种方式。通过运行类似于你使用的ssh命令来登录服务器,你可以在本地机器和该服务器之间创建一个安全的隧道。现在可以通过加密隧道重定向给定本地端口的所有流量,并使用远程服务器作为代理,然后连接到互联网。这类似于你使用VPN(虚拟私人网络)时发生的事情,但SSH隧道设置更简单。

我们将使用SSH隧道来代理我们的请求到远程Web服务器运行phpMyAdmin. 通过创建您的本地机器和安装phpMyAdmin的服务器之间的隧道,您可以重定向本地请求到远程Web服务器,更重要的是,流量将被加密,请求将到达Nginx,仿佛它们来自 localhost

由于您的本地机器和远程 Web 服务器之间的流量将被加密,这对于您无法在运行 phpMyAdmin 的 Web 服务器上安装 SSL/TLS 证书的情况来说是一个安全的替代方案。

从本地计算机 运行此命令,当您需要访问phpMyAdmin时:

1[environment local]
2ssh user@server_domain_or_IP -L 8000:localhost:80 -L 8443:localhost:443 -N

让我们来看看命令的每个部分:

  • 用户 : SSH 用户连接到运行 phpMyAdmin 的服务器
  • hostname_or_IP : SSH 主机在运行 phpMyAdmin
  • -L 8000:localhost:80 重定向 HTTP 流量在端口 8000
  • -L 8443:localhost:443 重定向 HTTPS 流量在端口 8443
  • -N :不执行远程命令

<$>[注] 注: 此命令将阻止终端,直到被中断为止,在这种情况下,它将终止SSH连接并停止包重定向. 如果您希望在背景模式下运行此命令,您可以使用SSH选项 -f

现在,转到您的浏览器并将 server_domain_or_IP 替换为localhost:PORT,其中PORT为 HTTP 或 HTTPS 中的80008443:

1http://localhost:8000/nothingtosee
1https://localhost:443/nothingtosee

phpMyAdmin login screen

<$>[注] 注: 如果您通过 https 访问 phpMyAdmin,您可能会收到一个警告消息,质疑 SSL 证书的安全性。 这是因为您正在使用的域名(localhost)不匹配证书中注册的地址(phpMyAdmin实际上正在服务的域名)。

所有请求在localhost:8000 (HTTP) 和localhost:8443 (HTTPS) 现在正在通过安全隧道重定向到您的远程 phpMyAdmin 应用程序. 您不仅通过禁用公共访问您的 phpMyAdmin 来增加安全性,还通过使用加密隧道来发送和接收数据来保护本地计算机和远程服务器之间的所有流量。

如果你想强制使用SSH隧道,谁想要访问你的phpMyAdmin界面(包括你),你可以这样做,删除任何其他授权的IP从 Nginx配置文件,留下127.0.0.1作为唯一允许访问该位置的主机。

 1[label /etc/nginx/sites-available/example.com]
 2server {
 3   . . .
 4
 5   location /nothingtosee { 
 6       allow 127.0.0.1; #allow localhost only
 7       deny all; #deny all other sources
 8   }
 9
10   . . .
11}

一旦您使用sudo systemctl reload nginx重新加载 Nginx 配置,您的 phpMyAdmin 安装将被锁定,用户将被要求**使用 SSH 隧道以通过重定向请求访问 phpMyAdmin 界面。

结论

在本教程中,我们看到了如何在Ubuntu 18.04上安装phpMyAdmin运行 Nginx作为Web服务器,我们还涵盖了在Ubuntu上确保phpMyAdmin安装的先进方法,例如禁用根登录,创建额外的身份验证层,并使用SSH隧道访问phpMyAdmin安装仅通过本地请求。

完成本教程后,您应该能够从合理安全的 Web 界面管理您的 MySQL 数据库. 这个用户界面暴露了通过 MySQL 命令行可用的大部分功能。

Published At
Categories with 技术
comments powered by Disqus