[wip]
parent
23c3cf530e
commit
ebddf2f031
@ -1,7 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
BINDIR=$(dirname $(realpath $0));
|
||||
BASEDIR=$(realpath "$BINDIR/../");
|
||||
cd $BASEDIR;
|
||||
|
||||
set -e;
|
||||
|
||||
BINDIR="$(dirname $(realpath "${0}"))";
|
||||
BASEDIR="$(realpath "${BINDIR}/../")";
|
||||
cd "${BASEDIR}";
|
||||
rm -rf ./storage/ca/*;
|
||||
mkdir ./storage/ca/certs;
|
||||
touch ./storage/ca/{,certs/}.gitkeep;
|
||||
touch ./storage/ca/certs/.gitkeep ./storage/ca/.gitkeep;
|
||||
|
@ -1,15 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e;
|
||||
|
||||
BASEDIR="$(dirname $(realpath $0))/../";
|
||||
cd $BASEDIR;
|
||||
STORAGE=$(realpath "$BASEDIR/storage/ca");
|
||||
cd "${BASEDIR}";
|
||||
STORAGE="$(realpath "${BASEDIR}/storage/ca")";
|
||||
|
||||
mkdir -p $STORAGE;
|
||||
mkdir -p $STORAGE/certs;
|
||||
mkdir -p "${STORAGE}/certs";
|
||||
|
||||
echo 01 > $STORAGE/serial;
|
||||
echo 01 > $STORAGE/crl_serial;
|
||||
touch $STORAGE/database;
|
||||
touch $STORAGE/database.attr;
|
||||
echo 01 > "${STORAGE}/serial";
|
||||
echo 01 > "${STORAGE}/crl_serial";
|
||||
touch "${STORAGE}/database";
|
||||
touch "${STORAGE}/database.attr";
|
||||
|
||||
$BASEDIR/bin/create-ca $1;
|
||||
$BASEDIR/bin/create-crl;
|
||||
"${BASEDIR}/bin/create-ca" $1;
|
||||
"${BASEDIR}/bin/create-crl";
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: eater
|
||||
* Date: 6/6/16
|
||||
* Time: 11:28 PM
|
||||
*/
|
||||
|
||||
namespace Eater\Glim\Handler;
|
||||
|
||||
|
||||
class CRL extends Main
|
||||
{
|
||||
function handle()
|
||||
{
|
||||
return $this->getResponse()
|
||||
->withHeader('Content-Type', 'plain/text')
|
||||
->withHeader('Content-Disposition', 'attachment; filename="crl.pem"')
|
||||
->write(file_get_contents($this->getCore()->getBaseDir() . '/storage/ca/crl.pem'));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Eater\Glim\Handler\Install;
|
||||
|
||||
use Eater\Glim\Service\User;
|
||||
|
||||
class Action extends Show
|
||||
{
|
||||
public function handle()
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->get('user');
|
||||
|
||||
$caCN = $this->post('ca-cn');
|
||||
|
||||
/* @var \Aura\Session\Session $session */
|
||||
$session = $this->get('session');
|
||||
$segment = $session->getSegment('main');
|
||||
|
||||
if (trim($caCN) === "") {
|
||||
$segment->setFlash('error', 'CA Common name can\'t be empty');
|
||||
return $this->redirect('/install');
|
||||
}
|
||||
|
||||
/** @var \Twig_Environment $twig */
|
||||
$twig = $this->get('twig');
|
||||
|
||||
$opensslConf = $twig->render('etc/openssl-ca.conf.twig', [
|
||||
'host' => $this->post('domainWithPort')
|
||||
]);
|
||||
|
||||
file_put_contents($this->getCore()->getBaseDir() . '/etc/openssl.conf', $opensslConf);
|
||||
|
||||
exec($this->getCore()->getBaseDir() . '/bin/clean-all');
|
||||
exec($this->getCore()->getBaseDir() . '/bin/setup ' . escapeshellarg($caCN));
|
||||
|
||||
$newUser = null;
|
||||
|
||||
try {
|
||||
$newUser = $user->createSuperuser($this->post('username'), $this->post('password'));
|
||||
} catch (\Exception $e) {
|
||||
$segment->setFlash("error", $e->getMessage());
|
||||
}
|
||||
|
||||
if ($newUser === null) {
|
||||
return $this->redirect('/install');
|
||||
}
|
||||
|
||||
$segment->set('user', $newUser);
|
||||
|
||||
return $this->redirect('/panel');
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Eater\Glim\Handler\Install;
|
||||
|
||||
use Eater\Glim\Handler\Main;
|
||||
use Eater\Glim\Model\UserQuery;
|
||||
|
||||
class Show extends Main
|
||||
{
|
||||
public function beforeHandle() {
|
||||
if (UserQuery::create()->findOne()) {
|
||||
return $this->redirect('/login');
|
||||
}
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$return = 1;
|
||||
$execEnabled = $this->isExecEnabled();
|
||||
$hasOpenSsl = false;
|
||||
if ($execEnabled) {
|
||||
exec('command -v openssl', $output, $return);
|
||||
$hasOpenSsl = $return === 0;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'hasExecEnabled' => $execEnabled,
|
||||
'hasOpenSsl' => $hasOpenSsl,
|
||||
'hasOpenSslExtension' => extension_loaded('openssl'),
|
||||
'hasZipExtension' => extension_loaded('zip'),
|
||||
'hostname' => parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST),
|
||||
'hostnameWithPort' => $_SERVER['HTTP_HOST']
|
||||
];
|
||||
|
||||
return $this->render('install.html.twig', $data);
|
||||
}
|
||||
|
||||
private function isExecEnabled() {
|
||||
if (ini_get('safe_mode')) {
|
||||
return false;
|
||||
} else {
|
||||
$d = ini_get('disable_functions');
|
||||
$s = ini_get('suhosin.executor.func.blacklist');
|
||||
if ("$d$s") {
|
||||
$array = preg_split('/,\s*/', "$d,$s");
|
||||
if (in_array('exec', $array)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: eater
|
||||
* Date: 6/12/16
|
||||
* Time: 3:26 PM
|
||||
*/
|
||||
|
||||
namespace Eater\Glim\Handler\Panel\Servers;
|
||||
|
||||
|
||||
use Eater\Glim\Handler\Session;
|
||||
use Eater\Glim\Model\Certificate;
|
||||
use Eater\Glim\Model\CertificateQuery;
|
||||
use Eater\Glim\Model\Server;
|
||||
use Eater\Glim\Model\ServerQuery;
|
||||
|
||||
class Config extends Session
|
||||
{
|
||||
public function handle()
|
||||
{
|
||||
$zipFile = tempnam(sys_get_temp_dir(), '0zip');
|
||||
$zip = new \ZipArchive();
|
||||
$zip->open($zipFile, \ZipArchive::CREATE);
|
||||
$server = ServerQuery::create()->findOneByFingerprint($this->attr('fingerprint'));
|
||||
$name = $server->getFqdn();
|
||||
|
||||
$this->fillZipWithCaAndConfig($zip, $server);
|
||||
|
||||
$cert = $this->attr('cert');
|
||||
|
||||
if ($cert !== null) {
|
||||
$certModel = CertificateQuery::create()->findOneByUserAndName($this->getUser(), $cert);
|
||||
$this->addClientCertificateData($zip, $certModel);
|
||||
|
||||
$name .= '-' . $certModel->getName() . '.' . $certModel->getSerial();
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
$zipContents = file_get_contents($zipFile);
|
||||
unlink($zipFile);
|
||||
|
||||
return $this->getResponse()
|
||||
->withHeader('Content-Type', 'application/zip')
|
||||
->withHeader('Content-Disposition', 'attachment; filename="' . $name . '.zip"')
|
||||
->write($zipContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param Server $server
|
||||
*/
|
||||
public function fillZipWithCaAndConfig($zip, $server)
|
||||
{
|
||||
$config = $this->getConfigForServerFingerprint($server);
|
||||
$zip->addFromString('server.conf', $config);
|
||||
$zip->addFromString('ca.crt', file_get_contents($this->getCore()->getBaseDir() . '/storage/ca/ca.crt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigForServerFingerprint($server)
|
||||
{
|
||||
/** @var \Twig_Environment $twig */
|
||||
$twig = $this->get('twig');
|
||||
|
||||
$config = $twig->render('etc/openvpn-client.conf.twig', [
|
||||
'server' => $server
|
||||
]);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param Certificate $cert
|
||||
*/
|
||||
public function addClientCertificateData($zip, $cert)
|
||||
{
|
||||
$zip->addFromString('client.crt', $cert->getCertificate());
|
||||
|
||||
if ($cert->hasPrivateKey()) {
|
||||
$zip->addFromString('client.key', $cert->getPrivateKey());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Eater\Glim\Handler\Panel\Servers;
|
||||
|
||||
use Eater\Glim\Handler\Session;
|
||||
use Eater\Glim\Model\ServerQuery;
|
||||
use Eater\Glim\Service\CA;
|
||||
use Eater\Glim\Service\Server;
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
|
||||
class Remove extends Session
|
||||
{
|
||||
protected $shouldHaveSuperuser = true;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$server = ServerQuery::create()->findOneByFingerprint($this->post('fingerprint'));
|
||||
$server->delete();
|
||||
|
||||
return $this->json([
|
||||
'success' => true
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
client
|
||||
|
||||
dev zerooo
|
||||
dev-type tun
|
||||
|
||||
proto {{ server.getProtocol() }}
|
||||
|
||||
remote {{ server.getExternalIp() }} {{ server.getPort() }}
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
|
||||
user nobody
|
||||
group nogroup
|
||||
|
||||
persist-key
|
||||
persist-tun
|
||||
|
||||
ca ca.crt
|
||||
cert client.crt
|
||||
key client.key
|
||||
|
||||
remote-cert-tls server
|
||||
|
||||
cipher BF-CBC
|
||||
|
||||
comp-lzo
|
||||
verb 3
|
@ -0,0 +1,32 @@
|
||||
port {{ server.getPort() }}
|
||||
proto {{ server.getProtocol() }}
|
||||
|
||||
dev ovpn0
|
||||
dev-type tun
|
||||
|
||||
ca ca.crt
|
||||
cert server.crt
|
||||
key server.key
|
||||
|
||||
dh dh2048.pem
|
||||
|
||||
server {{ server.getInternalIp() }} {{ server.getNetmaskIp() }}
|
||||
|
||||
ifconfig-pool-persist ipp.txt
|
||||
|
||||
push "redirect-gateway def1 bypass-dhcp"
|
||||
|
||||
push "dhcp-option DNS {{ server.getFirstDns() }}"
|
||||
push "dhcp-option DNS {{ server.getSecondDns() }}"
|
||||
keepalive 10 120
|
||||
cipher BF-CBC
|
||||
|
||||
crl-verify crl.pem
|
||||
|
||||
comp-lzo
|
||||
|
||||
user nobody
|
||||
group nogroup
|
||||
|
||||
persist-key
|
||||
persist-tun
|
@ -0,0 +1,80 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="col-md-offset-3 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<h2>Welcome to your Zer.ooo install</h2>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3>Checking for extensions and settings</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ hasExecEnabled ? 'Yes' : 'No' }}</td>
|
||||
<td>Is <kbd>exec</kbd> available?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ hasOpenSsl ? 'Yes' : 'No' }}</td>
|
||||
<td>Is the <kbd>openssl</kbd> binary available?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ hasOpenSslExtension ? 'Yes' : 'No' }}</td>
|
||||
<td>Is the openssl module loaded?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ hasZipExtension ? 'Yes' : 'No' }}</td>
|
||||
<td>Is the zip module loaded?</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if not (hasExecEnabled and hasOpenSslExtension and hasOpenSsl and hasZipExtension) %}
|
||||
<div class="row">
|
||||
Those functions are essential for the functionality of Zer.ooo, please enable them<br>
|
||||
<br>
|
||||
<a href="/install" class="btn btn-primary">Refresh</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="row">
|
||||
<h3>Create your superuser</h3>
|
||||
</div>
|
||||
<form method="post" action="/install">
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input id="username" class="form-control" type="text" name="username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input id="password" class="form-control" type="password" name="password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3>Server details</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<label for="ca-cn">CA Common Name</label>
|
||||
<input type="text" id="ca-cn" name="ca-cn" class="form-control" value="{{ hostname }}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="domainWithPort">HTTP Host (NOT HTTPS! needed for CRL)</label>
|
||||
<input type="text" id="domainWithPort" name="domainWithPort" class="form-control" value="{{ hostnameWithPort }}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary pull-right">Finish install</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue