【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)

问题描述

在Azure上创建的数据库,单独通过SQL的连接工具是可以访问,但在Web App却无法访问,错误信息为:

{
    "timestamp": "2021-05-20T05:21:04.672+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "nested exception is org.apache.ibatis.exceptions.PersistenceException: \n### Error querying database.  
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; 
nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 0, maxActive 100, creating 0\n
### The error may exist in com/digital/dao/SumOrderMapper.java (best guess)\n
### The error may involve com.digital.dao.SumOrderMapper.selectOne\n
### The error occurred while executing a query\n
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; 
nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 0, maxActive 100, creating 0",
    "path": "/ba/getGapAndOffset"
}

问题分析&解决

一:分析从Web App到数据库的网络是否相通:使用 PsPing & PaPing 进行 TCP 端口连通性测试

PsPing 是微软 PSTools 工具套件中的其中一个命令。除了ICMP ping 测试,它主要用来测试 TCP 端口的连通性,还可以测试 TCP/UDP 网络时延和带宽。下载地址为:https://technet.microsoft.com/zh-cn/sysinternals/jj729731.aspx

PsPing 进行 TCP 连接测试时所支持的参数说明:

-t 类似于 ICMP 的长 ping 测试,直到按下 Ctrl+C 停止测试,并显示统计结果;
-n 指定测试次数。还可以指定测试的时间长度,以秒为单位,使用时在数字后加上 s,例如“10s”;
-i 每次测试的间隔,默认为 1 秒。还可以指定为 0 来进行快速 ping 测试;
-w 热身次数,默认为 1 次;
-q 测试过程中不输出结果,结束后显示统计结果;
-h 将时延结果统计为直方图打印(默认打印 20行),也可以指定结果行数,比如 -h 10,指定 10 行;另一种使用方法是统计自定义时延,比如 -h "65,70",结果将统计时延分别为 65 和 70 毫秒的次数;
-4 强制使用 IPv4;
-6 强制使用 IPv6;

如果在 Linux 中发起 TCP 端口连通性和网路时延的测试,可以使用 PaPing 。PaPing 是一个跨平台的开源工具。它的功能相对 PsPing 而言更简单,只支持 TCP 端口的相关测试,不支持 UDP 端口的测试。下载地址为:https://code.google.com/archive/p/paping/downloads

安装方式(Linux):

#cd ~
#wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/paping/paping_1.5.5_x86-64_linux.tar.gz
#tar zxvf paping_1.5.5_x86-64_linux.tar.gz

测试结果, 在App Service(Web App)上去paping数据库可以连通的,由此可见网络层面应该是可以通的。

Add alt text
image.png

二:在网络层是连通的情况下,进一步就需要查看应用的异常信息

在App Service(Web App)的应用日志中,发现了 “ ssl connection is required ” 的错误消息,这是因为数据库(PostgreSQL) 配置SSL的连接要求,而应用程序时运行在Linux环境Docker中,也是需要开启SSL的。而在Linux中为容器开启SSL,需要以下几步:

注:SSH 实现容器和客户端之间的安全通信。 为了使自定义容器支持 SSH,必须将其添加到 Docker 映像本身。

第一步:将 sshd_config 文件添加到项目文件中,示例内容如下

Port            2222
ListenAddress       0.0.0.0
LoginGraceTime      180
X11Forwarding       yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1,hmac-sha1-96
StrictModes         yes
SyslogFacility      DAEMON
PasswordAuthentication  yes
PermitEmptyPasswords    no
PermitRootLogin     yes
Subsystem sftp internal-sftp

此文件配置 OpenSSH 并且必须包括以下项:

  • Port 必须设置为 2222。
  • Ciphers 必须至少包含此列表中的一项:aes128-cbc,3des-cbc,aes256-cbc。
  • MACs 必须至少包含此列表中的一项:hmac-sha1,hmac-sha1-96。

第二步:在 Dockerfile 中,添加以下命令

# Install OpenSSH and set the password for root to "Docker!". In this example, "apk add" is the install instruction for an Alpine Linux-based image.
RUN apk add openssh \
     && echo "root:Docker!" | chpasswd 

# Copy the sshd_config file to the /etc/ssh/ directory
COPY sshd_config /etc/ssh/

# Open port 2222 for SSH access
EXPOSE 80 2222

此配置不允许从外部建立到容器的连接。 容器的端口 2222 只能在专用虚拟网络的桥网络中访问,Internet 上的攻击者无法访问该端口。

第三步:在容器的启动脚本中启动 SSH 服务器

/usr/sbin/sshd

三:App Service(Web App)如何能够解析内网中资源的Endpoint呢?

由于在App Service(Web App)中无法解析Redis的Private Endpoint IP,所以无法连接Redis,由于Redis在开启Private Endpoint时也有创建Azure Private DNS Zone,所以需要在App Service配置使用Azure Private DNS Zone用于解析Redis Private E你的point。

在App Service的配置中添加两项应用程序设置:

WEBSITE_DNS_SERVER= 168.63.129.16 #Azure Private DNS Server IP Address

**WEBSITE_VNET_ROUTE_ALL=1 **

这些设置会将所有出站调用从应用发送到 VNet,还允许应用访问 Azure DNS 专用区域。配置使用Azure Private DNS Zone的官方文档:https://docs.azure.cn/zh-cn/app-service/web-sites-integrate-with-vnet#azure-dns-private-zones

参考资料

配置使用Azure Private DNS Zone: https://docs.azure.cn/zh-cn/app-service/web-sites-integrate-with-vnet#azure-dns-private-zones

App service启用应用程序日志: https://docs.microsoft.com/zh-cn/azure/app-service/troubleshoot-diagnostic-logs#enable-application-logging-linuxcontainer

PostgreSQL配置ssl: https://docs.azure.cn/zh-cn/postgresql/concepts-ssl-connection-security

Paping测试连通性: https://docs.azure.cn/zh-cn/articles/azure-operations-guide/virtual-network/aog-virtual-network-tcp-psping-paping-connectivity#%E4%B8%8B%E8%BD%BD%E5%92%8C%E5%AE%89%E8%A3%85-1

【完】

你可能感兴趣的:(【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下))