示例#1
0
 /**
  * Disconnect all clients with this CN from all pools and instances
  * managed by this service.
  *
  * @param string $commonName the CN to kill
  */
 public function kill($commonName)
 {
     $clientsKilled = 0;
     // loop over all pools
     foreach (array_keys($this->instanceConfig->v('vpnPools')) as $poolNumber => $poolId) {
         $poolConfig = new PoolConfig($this->instanceConfig->v('vpnPools', $poolId));
         $managementIp = sprintf('127.42.%d.%d', 100 + $this->instanceConfig->v('instanceNumber'), 100 + $poolNumber);
         // loop over all processes
         for ($i = 0; $i < $poolConfig->v('processCount'); ++$i) {
             // add all kills from this instance to poolKills
             try {
                 // open the socket connection
                 $this->managementSocket->open(sprintf('tcp://%s:%d', $managementIp, 11940 + $i));
                 $response = $this->managementSocket->command(sprintf('kill %s', $commonName));
                 if (0 === mb_strpos($response[0], 'SUCCESS: ')) {
                     ++$clientsKilled;
                 }
                 // close the socket connection
                 $this->managementSocket->close();
             } catch (ManagementSocketException $e) {
                 // we log the error, but continue with the next instance
                 $this->logger->error(sprintf('error with socket "%s:%s", message: "%s"', $managementIp, 11940 + $i, $e->getMessage()));
             }
         }
     }
     return 0 !== $clientsKilled;
 }
示例#2
0
 public function write($instanceId, InstanceConfig $instanceConfig)
 {
     $instanceNumber = $instanceConfig->v('instanceNumber');
     foreach (array_keys($instanceConfig->v('vpnPools')) as $poolNumber => $poolId) {
         $poolConfig = new PoolConfig($instanceConfig->v('vpnPools', $poolId));
         $this->writePool($instanceNumber, $instanceId, $poolNumber, $poolId, $poolConfig);
     }
 }
示例#3
0
 private function fetchGroups($bearerToken)
 {
     $httpClient = new Client();
     try {
         return $httpClient->get($this->instanceConfig->v('groupProviders', 'VootProvider', 'apiUrl'), ['headers' => ['Authorization' => sprintf('Bearer %s', $bearerToken)]])->json();
     } catch (TransferException $e) {
         return [];
     }
 }
示例#4
0
 public function init(Service $service)
 {
     $service->get('/server_pools', function (Request $request, array $hookData) {
         Utils::requireUser($hookData, ['vpn-admin-portal', 'vpn-user-portal']);
         $responseData = [];
         foreach (array_keys($this->instanceConfig->v('vpnPools')) as $poolId) {
             $poolConfig = new PoolConfig($this->instanceConfig->v('vpnPools', $poolId));
             $responseData[$poolId] = $poolConfig->v();
         }
         return new ApiResponse('server_pools', $responseData);
     });
     $service->get('/server_pool', function (Request $request, array $hookData) {
         Utils::requireUser($hookData, ['vpn-admin-portal', 'vpn-user-portal']);
         $poolId = $request->getQueryParameter('pool_id');
         InputValidation::poolId($poolId);
         $poolConfig = new PoolConfig($this->instanceConfig->v('vpnPools', $poolId));
         return new ApiResponse('server_pool', $poolConfig->v());
     });
 }
示例#5
0
 private static function getForwardChain(InstanceConfig $instanceConfig, $inetFamily)
 {
     $forwardChain = [];
     foreach (array_keys($instanceConfig->v('vpnPools')) as $poolNumber => $poolId) {
         $poolConfig = new PoolConfig($instanceConfig->v('vpnPools', $poolId));
         if (6 === $inetFamily && !$poolConfig->v('forward6')) {
             // IPv6 forwarding was disabled
             continue;
         }
         if (4 === $inetFamily) {
             // get the IPv4 range
             $srcNet = $poolConfig->v('range');
         } else {
             // get the IPv6 range
             $srcNet = $poolConfig->v('range6');
         }
         $forwardChain[] = sprintf('-N vpn-%s-%s', $instanceConfig->v('instanceNumber'), $poolNumber);
         $forwardChain[] = sprintf('-A FORWARD -i tun-%s-%s+ -s %s -j vpn-%s-%s', $instanceConfig->v('instanceNumber'), $poolNumber, $srcNet, $instanceConfig->v('instanceNumber'), $poolNumber);
         // merge outgoing forwarding firewall rules to prevent certain
         // traffic
         $forwardChain = array_merge($forwardChain, self::getForwardFirewall($instanceConfig->v('instanceNumber'), $poolNumber, $poolConfig, $inetFamily));
         if ($poolConfig->v('clientToClient')) {
             // allow client-to-client
             $forwardChain[] = sprintf('-A vpn-%s-%s -o tun-%s-%s+ -d %s -j ACCEPT', $instanceConfig->v('instanceNumber'), $poolNumber, $instanceConfig->v('instanceNumber'), $poolNumber, $srcNet);
         }
         if ($poolConfig->v('defaultGateway')) {
             // allow traffic to all outgoing destinations
             $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -j ACCEPT', $instanceConfig->v('instanceNumber'), $poolNumber, $poolConfig->v('extIf'), $srcNet);
         } else {
             // only allow certain traffic to the external interface
             foreach ($poolConfig->v('routes') as $route) {
                 $routeIp = new IP($route);
                 if ($inetFamily === $routeIp->getFamily()) {
                     $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -d %s -j ACCEPT', $instanceConfig->v('instanceNumber'), $poolNumber, $poolConfig->v('extIf'), $route);
                 }
             }
         }
     }
     return $forwardChain;
 }
示例#6
0
 *
 * IPv6:
 * The IPv6 address is generated according to RFC 4193 (Global ID), it results
 * in a /60 network.
 */
try {
    $p = new CliParser('Automatically generate an IP address and basic config for a pool', ['instance' => ['the instance to target, e.g. vpn.example', true, true], 'pool' => ['the pool to target, e.g. internet', true, true], 'host' => ['the hostname clients connect to', true, true], 'ext' => ['the external interface, e.g. eth0', true, true]]);
    $opt = $p->parse($argv);
    if ($opt->e('help')) {
        echo $p->help();
        exit(0);
    }
    $v4 = sprintf('10.%s.%s.0/24', hexdec(bin2hex(random_bytes(1))), hexdec(bin2hex(random_bytes(1))));
    $v6 = sprintf('fd%s:%s:%s:%s::/60', bin2hex(random_bytes(1)), bin2hex(random_bytes(2)), bin2hex(random_bytes(2)), bin2hex(random_bytes(2) & hex2bin('fff0')));
    echo sprintf('IPv4 CIDR  : %s', $v4) . PHP_EOL;
    echo sprintf('IPv6 prefix: %s', $v6) . PHP_EOL;
    $configFile = sprintf('%s/config/%s/config.yaml', dirname(__DIR__), $opt->v('instance'));
    $instanceConfig = InstanceConfig::fromFile($configFile);
    $poolConfig = new PoolConfig($instanceConfig->v('vpnPools', $opt->v('pool')));
    $instanceConfigData = $instanceConfig->v();
    $poolConfigData = $poolConfig->v();
    $poolConfigData['range'] = $v4;
    $poolConfigData['range6'] = $v6;
    $poolConfigData['hostName'] = $opt->v('host');
    $poolConfigData['extIf'] = $opt->v('ext');
    $instanceConfigData['vpnPools'][$opt->v('pool')] = $poolConfigData;
    InstanceConfig::toFile($configFile, $instanceConfigData);
} catch (Exception $e) {
    echo sprintf('ERROR: %s', $e->getMessage()) . PHP_EOL;
    exit(1);
}
示例#7
0
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
require_once sprintf('%s/vendor/autoload.php', dirname(__DIR__));
use SURFnet\VPN\Server\InstanceConfig;
use SURFnet\VPN\Common\Logger;
use SURFnet\VPN\Server\OpenVpn\ServerManager;
use SURFnet\VPN\Server\OpenVpn\ManagementSocket;
use SURFnet\VPN\Common\CliParser;
try {
    $p = new CliParser('Get the connection status of an instance', ['instance' => ['the instance', true, true]]);
    $opt = $p->parse($argv);
    if ($opt->e('help')) {
        echo $p->help();
        exit(0);
    }
    $configFile = sprintf('%s/config/%s/config.yaml', dirname(__DIR__), $opt->v('instance'));
    $config = InstanceConfig::fromFile($configFile);
    $serverManager = new ServerManager($config, new ManagementSocket(), new Logger($argv[0]));
    var_dump($serverManager->connections());
} catch (Exception $e) {
    echo sprintf('ERROR: %s', $e->getMessage()) . PHP_EOL;
    exit(1);
}
use SURFnet\VPN\Server\InstanceConfig;
use SURFnet\VPN\Common\FileIO;
use SURFnet\VPN\Common\CliParser;
try {
    $p = new CliParser('Generate firewall rules for all instances', ['install' => ['install the firewall', false, false]]);
    $opt = $p->parse($argv);
    if ($opt->e('help')) {
        echo $p->help();
        exit(0);
    }
    // detect all instances
    $configList = [];
    $configDir = sprintf('%s/config', dirname(__DIR__));
    foreach (glob(sprintf('%s/*', $configDir), GLOB_ONLYDIR | GLOB_ERR) as $instanceDir) {
        $instanceId = basename($instanceDir);
        $configList[$instanceId] = InstanceConfig::fromFile(sprintf('%s/%s/config.yaml', $configDir, $instanceId));
    }
    $firewall = Firewall::getFirewall4($configList);
    $firewall6 = Firewall::getFirewall6($configList);
    if ($opt->e('install')) {
        FileIO::writeFile('/etc/sysconfig/iptables', $firewall, 0600);
        FileIO::writeFile('/etc/sysconfig/ip6tables', $firewall6, 0600);
    } else {
        echo '##########################################' . PHP_EOL;
        echo '# IPv4' . PHP_EOL;
        echo '##########################################' . PHP_EOL;
        echo $firewall;
        echo '##########################################' . PHP_EOL;
        echo '# IPv6' . PHP_EOL;
        echo '##########################################' . PHP_EOL;
        echo $firewall6;
示例#9
0
use SURFnet\VPN\Server\Api\OpenVpnModule;
use SURFnet\VPN\Common\Http\Service;
use SURFnet\VPN\Server\Api\Users;
use SURFnet\VPN\Server\Api\UsersModule;
use SURFnet\VPN\Server\InstanceConfig;
use SURFnet\VPN\Common\Logger;
use SURFnet\VPN\Server\OpenVpn\ManagementSocket;
use SURFnet\VPN\Server\OpenVpn\ServerManager;
$logger = new Logger('vpn-server-api');
try {
    // this is provided by Apache, using CanonicalName
    $request = new Request($_SERVER, $_GET, $_POST);
    $instanceId = $request->getServerName();
    $dataDir = sprintf('%s/data/%s', dirname(__DIR__), $instanceId);
    $configDir = sprintf('%s/config/%s', dirname(__DIR__), $instanceId);
    $config = InstanceConfig::fromFile(sprintf('%s/config.yaml', $configDir));
    $service = new Service();
    $basicAuthentication = new BasicAuthenticationHook($config->v('apiConsumers'), 'vpn-server-api');
    $service->addBeforeHook('auth', $basicAuthentication);
    $service->addModule(new LogModule($dataDir));
    $service->addModule(new OpenVpnModule(new ServerManager($config, new ManagementSocket(), $logger)));
    $service->addModule(new CommonNamesModule(new CommonNames(sprintf('%s/common_names', $dataDir)), $logger));
    $service->addModule(new UsersModule(new Users(sprintf('%s/users', $dataDir)), $logger));
    $groupProviders = [];
    if ($config->e('groupProviders')) {
        foreach (array_keys($config->v('groupProviders')) as $groupProviderId) {
            $groupProviderClass = sprintf('SURFnet\\VPN\\Server\\GroupProvider\\%s', $groupProviderId);
            $groupProviders[] = new $groupProviderClass($dataDir, $config);
        }
    }
    $service->addModule(new GroupsModule($groupProviders, $logger));