Comprehensive Diagnosis and Resolution: When Aliyun SMS API (dysmsapi.aliyuncs.com) Is Unreachable in a PHP Environment

When integrating Alibaba Cloud’s SMS service (Aliyun SMS API) into your PHP applications, you may occasionally encounter errors such as “message not sent,” “DNS resolution failed,” or “connection timed out.” This article walks you through the environment overview, symptom analysis, rapid troubleshooting steps, detailed root-cause strategies, and full-featured detection scripts—enabling you to pinpoint and remedy any accessibility issues to dysmsapi.aliyuncs.com in a PHP runtime. Written in clear, accessible language for tertiary-educated developers, it preserves technical rigor while remaining easy to follow.


1. Environment and Context Overview

In enterprise-grade deployments, production servers often live within private networks or corporate intranets. They are typically protected by multiple layers: virtual machines, firewalls, and specialized network security appliances. In this scenario:

  • Virtualization & Security Appliances

    • Servers run on virtual machines provided by Sangfor (深信服), governed by strict firewall policies that may restrict or proxy outbound internet traffic.
  • Backend Language & Library

    • The application backend uses PHP. SMS dispatch logic relies on the community-supported overtrue/easy-sms library, which wraps Alibaba Cloud’s SMS API.
  • Target Endpoint

    • Hostname: dysmsapi.aliyuncs.com
    • Protocols & Ports: HTTP(S) over TCP 80 and TCP 443

When invoking EasySms under these constraints, you might see:


All the gateways have failed. You can get error details by \$exception->getExceptions()

And deeper in the logs:


Error 28: Resolving timed out after 5000 milliseconds
port 80 connection failed (0: php\_network\_getaddresses: getaddrinfo failed: Name or service not known)
port 443 connection failed (0: php\_network\_getaddresses: getaddrinfo failed: Name or service not known)

These messages indicate that neither DNS resolution nor TCP connectivity to dysmsapi.aliyuncs.com was successful.


2. Symptom Breakdown: Why Does SMS Dispatch Fail?

When EasySms attempts to call the Aliyun SMS API within a restricted environment, it follows these core steps:

  1. DNS Resolution

    • Resolve dysmsapi.aliyuncs.com to one or more IP addresses.
  2. HTTPS Request via cURL

    • Initiate an HTTPS request to the resolved IP(s).
  3. Fallback Logic

    • If the primary gateway fails, EasySms may try alternative endpoints or ports.
  4. Exception Aggregation

    • Any errors are collected into $exception->getExceptions(), leading to the “All the gateways have failed” summary.

If DNS fails (step 1), cURL immediately times out with “Error 28: Resolving timed out,” and getaddrinfo failed appears. If DNS succeeds but TCP port 80/443 is blocked, cURL may either hang or report connection refused. In all cases, EasySms deems the gateway unreachable and aborts.


3. Rapid Troubleshooting Strategy

To empower developers and operations personnel to quickly isolate the culprit—DNS, HTTP layer, or TCP port blockage—you can deploy a lightweight PHP-based diagnostic page. It sequentially tests each stage and reports results in a simple table.

3.1 Deploying the Basic Diagnostic Script

Save the following as check_sms.php in your webroot (e.g., /var/www/html/check_sms.php) and access it via your browser.

<?php
// check_sms.php

$host  = 'dysmsapi.aliyuncs.com';
$ports = [80, 443];

// Test HTTPS reachability via cURL HEAD request
function checkWithCurl($url, $timeout = 5) {
    if (!function_exists('curl_init')) {
        return ['ok' => false, 'msg' => 'cURL not enabled'];
    }
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_NOBODY         => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => $timeout,
        CURLOPT_CONNECTTIMEOUT => $timeout,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    curl_exec($ch);
    $errno  = curl_errno($ch);
    $errmsg = curl_error($ch);
    $code   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($errno !== 0) {
        return ['ok' => false, 'msg' => "Error {$errno}: {$errmsg}"];
    }
    return ['ok' => ($code >= 200 && $code < 400), 'msg' => "HTTP {$code}"];
}

// Test raw TCP port connectivity via fsockopen
function checkWithSocket($host, $port, $timeout = 5) {
    $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
    if (!$fp) {
        return ['ok' => false, 'msg' => "Port {$port} failed ({$errno}: {$errstr})"];
    }
    fclose($fp);
    return ['ok' => true, 'msg' => "Port {$port} reachable"];
}

$results = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 1. HTTPS cURL check
    $results[] = array_merge(['method' => 'cURL (HTTPS)'], checkWithCurl("https://{$host}/"));

    // 2. TCP port checks
    foreach ($ports as $p) {
        $results[] = array_merge(['method' => "TCP {$p}"], checkWithSocket($host, $p));
    }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Aliyun SMS API Reachability Check</title>
    <style>
        body  { font-family: Arial, sans-serif; padding: 20px; }
        table { border-collapse: collapse; width: 100%; max-width: 600px; margin-top: 20px; }
        th, td { padding: 8px; border: 1px solid #ddd; text-align: left; }
        th     { background: #f9f9f9; }
        .ok    { color: green; font-weight: bold; }
        .fail  { color: red;   font-weight: bold; }
        button { padding: 10px 20px; font-size: 14px; }
    </style>
</head>
<body>
    <h1>Aliyun SMS API Reachability Check</h1>
    <form method="post">
        <button type="submit">Run Diagnostics</button>
    </form>

    <?php if (!empty($results)): ?>
    <table>
        <thead>
            <tr><th>Test</th><th>Status</th><th>Details</th></tr>
        </thead>
        <tbody>
        <?php foreach ($results as $r): ?>
            <tr>
                <td><?= htmlspecialchars($r['method']) ?></td>
                <td class="<?= $r['ok'] ? 'ok' : 'fail' ?>">
                    <?= $r['ok'] ? '✓ Reachable' : '✗ Unreachable' ?>
                </td>
                <td><?= htmlspecialchars($r['msg']) ?></td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    <?php endif; ?>
</body>
</html>

How to Use

  1. Deploy check_sms.php to your PHP-enabled web directory.
  2. Navigate to http://<your-domain>/check_sms.php in a browser.
  3. Click Run Diagnostics to see results for cURL HTTPS reachability and raw TCP port connectivity.

This visual table quickly reveals:

  • DNS Resolution: If cURL immediately errors on name lookup.
  • HTTPS Layer: Whether an HTTP 200–399 response is returned.
  • TCP Port Access: Whether ports 80 and 443 accept connections.

4. In-Depth Analysis: Common Root Causes & Remediation

Based on diagnostic outcomes, the typical reasons for API inaccessibility fall into five categories:

4.1 DNS Configuration Issues

  • Symptom: Both cURL and socket tests fail with “getaddrinfo failed” or no IP resolved.

  • Cause: /etc/resolv.conf lists non-responsive or internal-only DNS servers; PHP-FPM’s user lacks permission to query DNS.

  • Solution:

    1. Edit /etc/resolv.conf to include public nameservers like Google DNS (8.8.8.8, 8.8.4.4) or Alibaba Cloud DNS (223.5.5.5).
    2. Restart network services or systemd-resolved.
    3. Ensure PHP-FPM or web server user can access the system’s DNS resolver sockets.

4.2 Hostname Typos or Local Hosts File Interference

  • Symptom: Diagnostic script hangs or resolves to a wrong IP.

  • Cause: Typographical errors in the API hostname; conflicting entries in /etc/hosts.

  • Solution:

    1. Double‑check code for exact spelling: dysmsapi.aliyuncs.com.
    2. Review /etc/hosts for incorrect mappings overriding public DNS; remove or comment out invalid entries.

4.3 Outbound Network Restrictions

  • Symptom: DNS resolves, but TCP port checks fail.

  • Cause: Enterprise firewall or proxy prevents direct outbound TCP 80/443 traffic.

  • Solution:

    1. Configure PHP to use company HTTP/SOCKS proxy: set environment variables (HTTP_PROXY, HTTPS_PROXY) or cURL options.
    2. Request firewall/security team to open outbound ports 80 and 443 for the server’s IP.

4.4 Blocked UDP 53

  • Symptom: DNS queries time out despite correct nameserver settings.

  • Cause: Firewall blocks UDP port 53 used for DNS lookups.

  • Solution:

    1. Open outbound UDP port 53.
    2. Alternatively, enable DNS over TCP on the system (if supported).

4.5 Insufficient Timeouts

  • Symptom: cURL errors “timed out” even though diagnostics eventually succeed with longer waits.

  • Cause: High-latency network environment; default 5‑second timeout too short.

  • Solution:

    1. Increase cURL’s CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT to 15–30 seconds, matching your network’s typical round‑trip times.

5. Verifying DNS Availability Quickly

A focused DNS test can confirm or rule out name‑resolution issues before diving deeper.

5.1 Command-Line DNS Checks

On Linux servers, run:

# Query via host
host dysmsapi.aliyuncs.com

# Query via dig
dig +short dysmsapi.aliyuncs.com

# Validate connectivity
ping -c 2 dysmsapi.aliyuncs.com

Unless you see one or more IP addresses returned, your system’s DNS configuration is not resolving the API domain.

5.2 PHP DNS Resolution Script

Save as test_dns.php and run via CLI or browser:

<?php
$host = 'dysmsapi.aliyuncs.com';
$ip   = gethostbyname($host);

if ($ip === $host) {
    echo "DNS resolution failed for {$host}\n";
} else {
    echo "Resolved {$host} to IP: {$ip}\n";
}

An output of “DNS resolution failed” confirms DNS as the blocker.


6. All‑In‑One Diagnostic Script

To consolidate DNS, HTTPS, and TCP port checks into a single page, use this enhanced script check_dysms.php:

<?php
// check_dysms.php

$host  = 'dysmsapi.aliyuncs.com';
$ports = [80, 443];

// 1. DNS resolution
function testDns($host) {
    $ip = gethostbyname($host);
    return ($ip === $host)
        ? ['ok' => false, 'msg' => "Resolution failed"]
        : ['ok' => true,  'msg' => "Resolved to {$ip}"];
}

// 2. HTTP HEAD via cURL
function testCurl($url, $timeout = 15) {
    if (!function_exists('curl_init')) {
        return ['ok' => false, 'msg' => 'cURL not installed'];
    }
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_NOBODY         => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => $timeout,
        CURLOPT_TIMEOUT        => $timeout,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);
    curl_exec($ch);
    $errno = curl_errno($ch);
    $code  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($errno !== 0) {
        return ['ok' => false, 'msg' => "Error {$errno}"];
    }
    return ['ok' => ($code >= 200 && $code < 400), 'msg' => "HTTP {$code}"];
}

// 3. TCP port test
function testSocket($host, $port, $timeout = 5) {
    $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
    if (!$fp) {
        return ['ok' => false, 'msg' => "Port {$port} error: {$errstr}"];
    }
    fclose($fp);
    return ['ok' => true, 'msg' => "Port {$port} open"];
}

// Execute tests
$dnsResult  = testDns($host);
$httpResult = $dnsResult['ok']
    ? testCurl("https://{$host}/")
    : ['ok' => false, 'msg' => 'Skipped due to DNS failure'];
$socketResults = [];
foreach ($ports as $p) {
    $socketResults[] = testSocket($host, $p);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Aliyun SMS API Full Check</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; }
        h2   { margin-top: 30px; }
        .ok  { color: green; font-weight: bold; }
        .fail{ color: red;   font-weight: bold; }
    </style>
</head>
<body>
    <h1>Aliyun SMS API Connectivity Overview</h1>

    <h2>1. DNS Resolution</h2>
    <p class="<?= $dnsResult['ok'] ? 'ok' : 'fail' ?>">
        <?= $dnsResult['ok'] ? '✓' : '✗' ?> <?= htmlspecialchars($dnsResult['msg']) ?>
    </p>

    <h2>2. HTTPS Request</h2>
    <p class="<?= $httpResult['ok'] ? 'ok' : 'fail' ?>">
        <?= $httpResult['ok'] ? '✓' : '✗' ?> <?= htmlspecialchars($httpResult['msg']) ?>
    </p>

    <h2>3. TCP Port Tests</h2>
    <ul>
        <?php foreach ($socketResults as $res): ?>
            <li class="<?= $res['ok'] ? 'ok' : 'fail' ?>">
                <?= $res['ok'] ? '✓' : '✗' ?> <?= htmlspecialchars($res['msg']) ?>
            </li>
        <?php endforeach; ?>
    </ul>
</body>
</html>

Deploying this page gives you a unified dashboard of your environment’s ability to resolve, connect over HTTPS, and reach TCP ports 80/443—all with a single click.


7. Collaboration with Service Providers & Verification

After you’ve tweaked DNS settings, hosts files, and firewall/proxy rules, it’s often necessary to loop in your network or security appliance provider (e.g., Sangfor):

  1. Share Diagnostic Tools

    • Provide them with your scripts so they can execute tests in their management consoles.
  2. Confirm Policy Changes

    • Ask for explicit confirmation that outbound UDP 53, TCP 80, and TCP 443 are permitted.
  3. Revalidate

    • Once they apply changes, rerun diagnostics to ensure the checks all return green—indicating full connectivity to the Aliyun SMS API.

With all three stages showing success, you can be confident that overtrue/easy-sms or any HTTP-based client will resume sending messages without hindrance.


8. Summary and Best Practices

  • Scripted Diagnostics

    • Implement one‑click web pages to test DNS, HTTPS, and TCP ports, saving precious debugging time.
  • Adjustable Timeouts

    • Tune cURL connect and request timeouts based on your network’s latency profile to prevent premature failures.
  • Effective Collaboration

    • Use your diagnostic outputs to have informed discussions with network/security teams, ensuring changes are applied accurately.
  • Reusable Tools

    • Maintain these scripts in your operations repository; repurpose them for other external service connectivity tests.

By following this guide and leveraging the provided scripts, you’ll be able to swiftly diagnose and resolve issues accessing dysmsapi.aliyuncs.com from your PHP environment—restoring stable, reliable SMS dispatch via Alibaba Cloud’s API.