Source of file DnsHelper.php

Size: 10,063 Bytes - Last Modified: 2020-10-24T02:46:31+00:00

/home/travis/build/NextDom/nextdom-core/src/Helpers/DnsHelper.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
<?php


namespace NextDom\Helpers;


use NextDom\Exceptions\CoreException;
use NextDom\Managers\UpdateManager;
use NextDom\Model\Entity\Update;
use NextDom\Repo\RepoMarket;
use NextDom\Managers\ConfigManager;
use NextDom\Managers\EqLogicManager;
use NextDom\Managers\PluginManager;

class DnsHelper
{
    /**
     * @return openvpn|\NextDom\Model\Entity\EqLogic|\NextDom\Model\Entity\EqLogic[]|null
     * @throws CoreException
     * @throws \ReflectionException
     * @throws \Throwable
     */
    public static function dnsCreate()
    {
        if (ConfigManager::byKey('dns::token') == '') {
            return null;
        }
        try {
            $plugin = PluginManager::byId('openvpn');
            if (!is_object($plugin)) {
                $update = UpdateManager::byLogicalId('openvpn');
                if (!is_object($update)) {
                    $update = new Update();
                }
                $update->setLogicalId('openvpn');
                $update->setSource('market');
                $update->setConfiguration('version', 'stable');
                $update->save();
                $update->doUpdate();
                $plugin = PluginManager::byId('openvpn');
            }
        } catch (CoreException $e) {
            $update = UpdateManager::byLogicalId('openvpn');
            if (!is_object($update)) {
                $update = new Update();
            }
            $update->setLogicalId('openvpn');
            $update->setSource('market');
            $update->setConfiguration('version', 'stable');
            $update->save();
            $update->doUpdate();
            $plugin = PluginManager::byId('openvpn');
        }
        if (!is_object($plugin)) {
            throw new CoreException(__('Le plugin OpenVPN doit être installé'));
        }
        if (!$plugin->isActive()) {
            $plugin->setIsEnable(1);
            $plugin->dependancy_install();
        }
        if (!$plugin->isActive()) {
            throw new CoreException(__('Le plugin OpenVPN doit être actif'));
        }
        $openvpn = EqLogicManager::byLogicalId('dnsjeedom', 'openvpn');
        $direct = true;
        if (!is_object($openvpn)) {
            $direct = false;
            $openvpn = new openvpn();
            $openvpn->setName('DNS Jeedom');
        }
        $openvpn->setIsEnable(1);
        $openvpn->setLogicalId('dnsjeedom');
        $openvpn->setEqType_name('openvpn');
        $openvpn->setConfiguration('dev', 'tun');
        $openvpn->setConfiguration('proto', 'udp');
        if (ConfigManager::byKey('dns::vpnurl') != '') {
            $openvpn->setConfiguration('remote_host', ConfigManager::byKey('dns::vpnurl'));
        } else {
            $openvpn->setConfiguration('remote_host', 'vpn.dns' . ConfigManager::byKey('dns::number', 'core', 1) . '.jeedom.com');
        }
        $openvpn->setConfiguration('username', NextDomHelper::getHardwareKey());
        $openvpn->setConfiguration('password', ConfigManager::byKey('dns::token'));
        $openvpn->setConfiguration('compression', 'comp-lzo');
        $openvpn->setConfiguration('remote_port', ConfigManager::byKey('vpn::port', 'core', 1194));
        $openvpn->setConfiguration('auth_mode', 'password');
        if (ConfigManager::byKey('connection::4g') == 1) {
            $openvpn->setConfiguration('optionsAfterStart', 'sudo ip link set dev #interface# mtu ' . ConfigManager::byKey('market::dns::mtu'));
        } else {
            $openvpn->setConfiguration('optionsAfterStart', '');
        }
        $openvpn->save($direct);
        if (!file_exists(NEXTDOM_ROOT . '/plugins/openvpn/data')) {
            shell_exec('mkdir -p ' . NEXTDOM_ROOT . '/plugins/openvpn/data');
        }
        $path_ca = NEXTDOM_ROOT . '/plugins/openvpn/data/ca_' . $openvpn->getConfiguration('key') . '.crt';
        if (file_exists($path_ca)) {
            unlink($path_ca);
        }
        copy(NEXTDOM_ROOT . '/script/ca_dns.crt', $path_ca);
        if (!file_exists($path_ca)) {
            throw new CoreException(__('Impossible de créer le fichier  : ') . $path_ca);
        }
        return $openvpn;
    }

    public static function dnsStart()
    {
        if (ConfigManager::byKey('dns::token') == '') {
            return;
        }
        if (ConfigManager::byKey('market::allowDNS') != 1) {
            return;
        }
        $openvpn = self::dnsCreate();
        $cmd = $openvpn->getCmd('action', 'start');
        if (!is_object($cmd)) {
            throw new CoreException(__('La commande de démarrage du DNS est introuvable'));
        }
        $cmd->execCmd();
    }

    public static function dnsRun()
    {
        if (ConfigManager::byKey('dns::token') == '') {
            return false;
        }
        if (ConfigManager::byKey('market::allowDNS') != 1) {
            return false;
        }
        try {
            $openvpn = self::dnsCreate();
        } catch (CoreException $e) {
            return false;
        }
        $cmd = $openvpn->getCmd('info', 'state');
        if (!is_object($cmd)) {
            throw new CoreException(__('La commande de statut du DNS est introuvable'));
        }
        try {
            self::dns2Start();
        } catch (CoreException $e) {

        }
        return $cmd->execCmd();
    }

    public static function dnsStop()
    {
        if (ConfigManager::byKey('dns::token') == '') {
            return;
        }
        $openvpn = self::dnsCreate();
        $cmd = $openvpn->getCmd('action', 'stop');
        if (!is_object($cmd)) {
            throw new CoreException(__('La commande d\'arrêt du DNS est introuvable', __FILE__));
        }
        $cmd->execCmd();
    }

    public static function dns2Start()
    {
        if (ConfigManager::byKey('service::tunnel::enable') != 1) {
            return;
        }
        if (ConfigManager::byKey('market::allowDNS') != 1) {
            return;
        }
        self::dns2Stop();
        LogHelper::clear('tunnel');
        $exec = 'tunnel-linux-' . SystemHelper::getArch();
        $dir = NEXTDOM_ROOT . '/script/tunnel';
        if (!file_exists($dir . '/' . $exec)) {
            echo shell_exec('cd ' . $dir . ';wget https://images.jeedom.com/resources/tunnel/' . $exec . ' > ' . LogHelper::getPathToLog('tunnel') . ' 2>&1');
        }
        if (!file_exists($dir . '/' . $exec)) {
            throw new CoreException(__('Impossible de télécharger : ', __FILE__) . 'https://images.jeedom.com/resources/tunnel/' . $exec);
        }
        if (filesize($dir . '/' . $exec) < 7000000) {
            unlink($dir . '/' . $exec);
            throw new CoreException(__('Taille invalide pour : ', __FILE__) . $dir . '/' . $exec);
        }
        shell_exec('chmod +x ' . $dir . '/' . $exec);
        if (!file_exists($dir . '/client.crt') || !file_exists($dir . '/client.key')) {
            shell_exec('cd ' . $dir . ';openssl req -x509 -nodes -newkey rsa:2048 -sha256 -keyout client.key -out client.crt -subj "/C=EU/ST=FR/L=Paris/O=Jeedom, Inc./OU=IT/CN=jeedom.com"> ' . LogHelper::getPathToLog('tunnel') . ' 2>&1');
            if (!file_exists($dir . '/client.crt') || !file_exists($dir . '/client.key')) {
                throw new CoreException(__('Impossible de générer le certificat et la clef privé', __FILE__));
            }
        }
        $replace = array(
            '#URL#' => str_replace('https://', '', ConfigManager::byKey('service::tunnel::host')),
            '#PORT#' => 80,
            '#SERVER_ADDR#' => ConfigManager::byKey('service::tunnel::eu::backend::1')
        );
        for ($i = 1; $i < 3; $i++) {
            $infos = explode(':', ConfigManager::byKey('service::tunnel::eu::backend::' . $i));
            LogHelper::add('tunnel', 'debug', 'Test access to ' . $infos[0] . ' on port ' . $infos[1]);
            if (count($infos) < 2) {
                break;
            }
            if (NetworkHelper::checkOpenPort($infos[0], $infos[1])) {
                LogHelper::add('tunnel', 'debug', 'Access is open, used it');
                $replace['#SERVER_ADDR#'] = ConfigManager::byKey('service::tunnel::eu::backend::' . $i);
                break;
            }
            LogHelper::add('tunnel', 'debug', 'Access is close test next');
        }
        if (file_exists($dir . '/tunnel.yml')) {
            unlink($dir . '/tunnel.yml');
        }
        file_put_contents($dir . '/tunnel.yml', str_replace(array_keys($replace), $replace, file_get_contents($dir . '/tunnel.tmpl.yml')));
        $client_id = shell_exec('cd ' . $dir . ';./' . $exec . ' id');
        LogHelper::add('tunnel', 'debug', 'Client id is : ' . $client_id);
        try {
            RepoMarket::sendTunnelClientId(trim($client_id));
        } catch (CoreException $e) {
            LogHelper::add('tunnel', 'debug', 'Error on on send tunnel id to market : ' . $e->getMessage());
        }
        $replace['#URL#'] = str_replace('https://', '', ConfigManager::byKey('service::tunnel::host'));
        if (file_exists($dir . '/tunnel.yml')) {
            unlink($dir . '/tunnel.yml');
        }
        file_put_contents($dir . '/tunnel.yml', str_replace(array_keys($replace), $replace, file_get_contents($dir . '/tunnel.tmpl.yml')));
        shell_exec('cd ' . $dir . ';nohup ./' . $exec . ' start-all >> ' . LogHelper::getPathToLog('tunnel') . ' 2>&1 &');
    }

    public static function dns2Run()
    {
        if (ConfigManager::byKey('service::tunnel::enable') != 1) {
            return false;
        }
        if (ConfigManager::byKey('market::allowDNS') != 1) {
            return false;
        }
        $exec = 'tunnel-linux-' . SystemHelper::getArch();
        return (shell_exec('ps ax | grep ' . $exec . ' | grep  -c -v grep') > 0);
    }

    public static function dns2Stop()
    {
        if (ConfigManager::byKey('service::tunnel::enable') != 1) {
            return;
        }
        exec("(ps ax || ps w) | grep -ie 'tunnel-linux-" . SystemHelper::getArch() . "' | grep -v grep | awk '{print $1}' | xargs sudo kill -9 > /dev/null 2>&1");
        return;
    }

}