DomainInfo.php 11.4 KB
<?php
/**
 * @remark :
 * @name   :DomainInfo.php
 * @author :lyh
 * @method :post
 * @time   :2023/9/11 14:37
 */

namespace App\Console\Commands\Domain;

use App\Models\Devops\ServerConfig;
use App\Models\Devops\ServersIp;
use App\Models\Project\CountryCustom;
use App\Models\Project\Project;
use Illuminate\Console\Command;
use App\Models\Domain\DomainInfo as DomainInfoModel;

class DomainInfo extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'domain_info';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '域名相关';

    /**
     * @remark :更新证书+证书有效时间
     * @name   :handle
     * @author :lyh
     * @method :post
     * @time   :2023/9/11 15:09
     */
    public function handle()
    {
        //更新主站域名有效时间
        $this->startUpdateDomain();

        //主站证书到期更新
        $this->startUpdateCert();

        //AMP站证书到期更新
        $this->startUpdateAmpCert();

        //创建的自定义小语种域名证书到期更新
        $this->startUpdateCustomCert();

        return true;
    }

    /**
     * 更新域名到期时间
     * @author Akun
     * @date 2024/02/26 10:26
     */
    public function startUpdateDomain()
    {
        $domainModel = new DomainInfoModel();
        $list = $domainModel->where('status', '=', 1)->where(function ($query) {
            $query->whereNull('domain_end_time')->orWhere('domain_end_time', '<', date('Y-m-d H:i:s'));
        })->get()->toArray();
        foreach ($list as $v) {
            $time = $this->updateDomain($v['domain']);
            $data = [
                'domain_start_time' => $time['start'],
                'domain_end_time' => $time['end']
            ];
            $domainModel->edit($data, ['id' => $v['id']]);
        }
    }

    /**
     * 主站证书到期更新
     * @author Akun
     * @date 2024/02/26 10:26
     */
    public function startUpdateCert()
    {
        $domainModel = new DomainInfoModel();
        $projectModel = new Project();
        $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
        $list = $domainModel->where('status', '=', 1)->where(function ($query) use ($end_day) {
            $query->whereNull('certificate_end_time')->orWhere('certificate_end_time', '<', $end_day);
        })->get()->toArray();
        foreach ($list as $v) {
            //更新证书到期时间
            $data = [];

            $ssl = $this->updateDomainSsl($v['domain']);
            $ssl['from'] && $data['certificate_start_time'] = $ssl['from'];
            $ssl['to'] && $data['certificate_end_time'] = $ssl['to'];

            $project_info = $projectModel->read(['id' => $v['project_id']], ['serve_id']);
            if ($v['type'] == 1 && $ssl['to'] < $end_day && $project_info) {
                $serverIpModel = new ServersIp();
                $servers_ip_info = $serverIpModel->read(['id' => $project_info['serve_id']], ['servers_id']);
                if ($servers_ip_info && $servers_ip_info['servers_id'] != ServerConfig::SELF_SITE_ID) {
                    //非自建站项目,申请免费证书
                    $this->updatePrivate($v);

                    $ssl_new = $this->updateDomainSsl($v['domain']);
                    $ssl_new['from'] && $data['certificate_start_time'] = $ssl_new['from'];
                    $ssl_new['to'] && $data['certificate_end_time'] = $ssl_new['to'];
                }

            }

            $domainModel->edit($data, ['id' => $v['id']]);
        }
    }

    /**
     * AMP站证书到期更新
     * @author Akun
     * @date 2024/02/26 10:26
     */
    public function startUpdateAmpCert()
    {
        $domainModel = new DomainInfoModel();
        $projectModel = new Project();
        $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
        $list = $domainModel->where('status', '=', 1)->where('amp_status', 1)->where(function ($query) use ($end_day) {
            $query->whereNull('amp_certificate_end_time')->orWhere('amp_certificate_end_time', '<', $end_day);
        })->get()->toArray();
        foreach ($list as $v) {
            //更新amp站点证书到期时间
            $domain_array = parse_url($v['domain']);
            $host = $domain_array['host'] ?? $domain_array['path'];
            $host_array = explode('.', $host);
            if (count($host_array) <= 2) {
                array_unshift($host_array, 'm');
            } else {
                $host_array[0] = 'm';
            }
            $amp_domain = implode('.', $host_array);

            $data = [];
            $ssl = $this->updateDomainSsl($amp_domain);
            $ssl['from'] && $data['amp_certificate_start_time'] = $ssl['from'];
            $ssl['to'] && $data['amp_certificate_end_time'] = $ssl['to'];

            $project_info = $projectModel->read(['id' => $v['project_id']], ['serve_id']);
            if ($v['amp_type'] == 1 && $ssl['to'] < $end_day && $project_info) {
                $serverIpModel = new ServersIp();
                $servers_ip_info = $serverIpModel->read(['id' => $project_info['serve_id']], ['servers_id']);
                if ($servers_ip_info && $servers_ip_info['servers_id'] != ServerConfig::SELF_SITE_ID) {
                    //非自建站项目,申请免费证书
                    $this->updateAmpPrivate($v);

                    $ssl_new = $this->updateDomainSsl($v['domain']);
                    $ssl_new['from'] && $data['certificate_start_time'] = $ssl_new['from'];
                    $ssl_new['to'] && $data['certificate_end_time'] = $ssl_new['to'];
                }
            }

            $domainModel->edit($data, ['id' => $v['id']]);
        }
    }

    /**
     * 自定义小语种站证书到期更新
     * @author Akun
     * @date 2024/03/23 10:08
     */
    public function startUpdateCustomCert()
    {
        $customModel = new CountryCustom();
        $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
        $list = $customModel->where('status', 1)->where('is_create', 1)->where(function ($query) use ($end_day) {
            $query->whereNull('certificate_end_time')->orWhere('certificate_end_time', '<', $end_day);
        })->get()->toArray();
        foreach ($list as $v) {
            //更新证书到期时间
            $data = [];
            $ssl = $this->updateDomainSsl($v['custom_domain']);
            $ssl['from'] && $data['certificate_start_time'] = $ssl['from'];
            $ssl['to'] && $data['certificate_end_time'] = $ssl['to'];

            if ($v['type'] == 1 && $ssl['to'] < $end_day) {
                //申请免费证书
                $this->updateCustomPrivate($v['custom_domain']);

                $ssl_new = $this->updateDomainSsl($v['domain']);
                $ssl_new['from'] && $data['certificate_start_time'] = $ssl_new['from'];
                $ssl_new['to'] && $data['certificate_end_time'] = $ssl_new['to'];
            }

            $customModel->edit($data, ['id' => $v['id']]);
        }
    }

    /**
     * @remark :更新主站证书
     * @name   :updatePrivate
     * @author :lyh
     * @method :post
     * @time   :2023/12/8 16:16
     */
    public function updatePrivate($param)
    {
        $url = 'https://' . $param['domain'] . '/api/applySsl/';
        $param = [
            "domain" => $param['domain'],
            "rewrite" => $param['extend_config'],
            'other_domain' => $param['other_domain'],
            'is_https' => $param['is_https'],
            'not_allow_country' => $param['not_allow_country'],
            'not_allow_ip' => $param['not_allow_ip'],
            'amp_status' => $param['amp_status']
        ];
        return $this->curlRequest($url, $param);
    }

    /**
     * 更新amp站证书
     * @param $param
     * @return array
     * @author Akun
     * @date 2024/02/26 10:25
     */
    public function updateAmpPrivate($param)
    {
        $url = 'https://' . $param['domain'] . '/api/createSiteAmp/';
        $param = [
            "domain" => $param['domain'],
            'not_allow_country' => $param['not_allow_country'],
            'not_allow_ip' => $param['not_allow_ip'],
        ];
        return $this->curlRequest($url, $param);
    }

    /**
     * 更新小语种自定义站证书
     * @param $domain
     * @return array
     * @author Akun
     * @date 2024/03/23 10:07
     */
    public function updateCustomPrivate($domain)
    {
        $url = 'http://' . $domain . '/api/applySsl';
        $param = [
            'domain' => $domain,
            'rewrite' => [],
            'other_domain' => [],
            'is_https' => 1
        ];

        return $this->curlRequest($url, $param);
    }

    public function curlRequest($url, $data, $method = 'POST', $header = [], $time_out = 60)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, $time_out);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        if ($data)
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge([
                'Expect:',
                'Content-type: application/json',
                'Accept: application/json',
            ], $header)
        );
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        $response = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return [$code, $response];
    }

    /**
     * @remark :获取域名证书有效时间
     * @name   :updateDomainSsl
     * @author :lyh
     * @method :post
     * @time   :2023/9/11 15:07
     */
    public function updateDomainSsl($domain)
    {
        $valid_from = '';
        $valid_to = '';
        try {
            $context = stream_context_create([
                'ssl' => [
                    'capture_peer_cert' => true,
                    'capture_peer_cert_chain' => false,
                    'verify_peer' => false,
                    'verify_peer_name' => false
                ],
            ]);
            $stream = stream_socket_client('ssl://' . $domain . ':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
            if ($stream) {
                $remote_cert = stream_context_get_params($stream)['options']['ssl']['peer_certificate'];
                if ($remote_cert) {
                    $valid_from = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validFrom_time_t']);
                    $valid_to = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validTo_time_t']);
                }
            }
            fclose($stream);
        } catch (\Exception $e) {
            $valid_from = '';
            $valid_to = '';
        }
        return ['from' => $valid_from, 'to' => $valid_to];
    }

    /**
     * @remark :更新域名有效时间
     * @name   :updateDomain
     * @author :lyh
     * @method :post
     * @time   :2023/9/11 15:11
     */
    public function updateDomain($domain)
    {
        $url = 'http://openai.waimaoq.com/v1/whois_api?domain=' . $domain;
        $response = http_get($url);
        $start = date('Y-m-d H:i:s');
        $end = date('Y-m-d H:i:s');
        if ($response['code'] == 200) {
            $start = $response['text']['creation_date'];
            $end = $response['text']['expiration_date'];
        }
        return ['start' => $start, 'end' => $end];
    }
}