Added master domain SSL cert
This commit is contained in:
parent
0082e28e8e
commit
eef5125077
11
Dockerfile
11
Dockerfile
|
@ -46,12 +46,13 @@ ENV TZ=Asia/Tel_Aviv \
|
|||
DEBIAN_FRONTEND=noninteractive \
|
||||
PHP_VERSION=7.4 \
|
||||
_APP_ENV=production \
|
||||
_APP_DOMAIN=localhost \
|
||||
_APP_DOMAIN_TARGET=localhost \
|
||||
_APP_HOME=https://appwrite.io \
|
||||
_APP_EDITION=community \
|
||||
_APP_OPTIONS_ABUSE=enabled \
|
||||
_APP_OPENSSL_KEY_V1=your-secret-key \
|
||||
_APP_STORAGE_LIMIT=104857600 \
|
||||
_APP_DOMAINS_TARGET=localhost \
|
||||
_APP_REDIS_HOST=redis \
|
||||
_APP_REDIS_PORT=6379 \
|
||||
_APP_DB_HOST=mariadb \
|
||||
|
@ -100,8 +101,12 @@ RUN \
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set Upload Limit (default to 100MB)
|
||||
RUN echo "upload_max_filesize = ${_APP_STORAGE_LIMIT}" > /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
|
||||
RUN echo "post_max_size = ${_APP_STORAGE_LIMIT}" > /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
|
||||
RUN echo "upload_max_filesize = ${_APP_STORAGE_LIMIT}" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
|
||||
RUN echo "post_max_size = ${_APP_STORAGE_LIMIT}" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
|
||||
RUN echo "env[TESTME] = your-secret-key" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
|
||||
|
||||
# Add logs file
|
||||
RUN echo "" >> /var/log/appwrite.log
|
||||
|
||||
# Nginx Configuration (with self-signed ssl certificates)
|
||||
COPY ./docker/nginx.conf /etc/nginx/nginx.conf
|
||||
|
|
|
@ -1214,7 +1214,7 @@ $utopia->post('/v1/projects/:projectId/domains')
|
|||
throw new Exception('Domain already exists', 409);
|
||||
}
|
||||
|
||||
$target = new Domain($request->getServer('_APP_DOMAINS_TARGET', ''));
|
||||
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
|
||||
|
||||
if(!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
|
||||
|
@ -1321,7 +1321,7 @@ $utopia->patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
throw new Exception('Domain not found', 404);
|
||||
}
|
||||
|
||||
$target = new Domain($request->getServer('_APP_DOMAINS_TARGET', ''));
|
||||
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
|
||||
|
||||
if(!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
|
||||
|
|
|
@ -118,7 +118,7 @@ $utopia->get('/console/settings')
|
|||
->label('permission', 'public')
|
||||
->label('scope', 'console')
|
||||
->action(function () use ($request, $layout) {
|
||||
$target = new Domain($request->getServer('_APP_DOMAINS_TARGET', ''));
|
||||
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
|
||||
|
||||
$page = new View(__DIR__.'/../../views/console/settings/index.phtml');
|
||||
|
||||
|
|
29
app/tasks/init.php
Normal file
29
app/tasks/init.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/../init.php';
|
||||
|
||||
global $request;
|
||||
|
||||
use Utopia\CLI\CLI;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
$cli = new CLI();
|
||||
|
||||
$cli
|
||||
->task('ssl')
|
||||
->desc('Validate server certificates')
|
||||
->action(function () use ($request) {
|
||||
$domain = $request->getServer('_APP_DOMAIN', '');
|
||||
|
||||
Console::log('Issue a TLS certificate for master domain ('.$domain.')');
|
||||
|
||||
Resque::enqueue('v1-certificates', 'CertificatesV1', [
|
||||
'document' => [],
|
||||
'domain' => $domain,
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
});
|
||||
|
||||
$cli->run();
|
|
@ -160,7 +160,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
|
|||
|
||||
<p>To enable <?php echo APP_NAME; ?>'s custom domain feature, you have to start your server instance with a public accessable domain name.</p>
|
||||
|
||||
<p>Start your <?php echo APP_NAME; ?> server container with the <b>_APP_DOMAINS_TARGET</b> enviornment variable set with a public accessable domain name that resolves to your <?php echo APP_NAME; ?> server setup.</p>
|
||||
<p>Start your <?php echo APP_NAME; ?> server container with the <b>_APP_DOMAIN_TARGET</b> enviornment variable set with a public accessable domain name that resolves to your <?php echo APP_NAME; ?> server setup.</p>
|
||||
<p class="margin-bottom-no">The <?php echo APP_NAME; ?> server will use your target domain to validate new custom domains and will automatically generate SSL certificates for your new domains using letsencrypt certbot.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
@ -201,7 +201,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
|
|||
<span class="text-size-small text-info" data-ls-if="true === {{domain.verification}}"><i class="icon-ok-circled"></i> Verified </span>
|
||||
</td>
|
||||
<td data-title="Domain: ">
|
||||
<span data-ls-bind="{{domain.domain}}"></span>
|
||||
<span class="text-size-small" data-ls-bind="{{domain.domain}}"></span>
|
||||
</td>
|
||||
<td data-title="TLS: ">
|
||||
<span class="text-size-small text-fade" data-ls-if="!{{domain.certificateId}} && false === {{domain.verification}}"> Pending Verification </span>
|
||||
|
|
|
@ -96,9 +96,9 @@ $providers = $this->getParam('providers', []);
|
|||
<tr>
|
||||
<th width="60"></th>
|
||||
<th width="180">Name</th>
|
||||
<th width="220">Email</th>
|
||||
<th>Status</th>
|
||||
<th width="100">Joined</th>
|
||||
<th>Email</th>
|
||||
<th width="120">Status</th>
|
||||
<th width="120">Joined</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-ls-loop="project-users.users" data-ls-as="user">
|
||||
|
@ -117,15 +117,15 @@ $providers = $this->getParam('providers', []);
|
|||
</td>
|
||||
<td data-title="Status: ">
|
||||
<span data-ls-if="{{user.emailVerification}} === true">
|
||||
<span class="tag green">Verified</span>
|
||||
<span class="tag green">Verified</span>
|
||||
</span>
|
||||
|
||||
<span data-ls-if="{{user.emailVerification}} !== true">
|
||||
<span class="tag">Unverified</span>
|
||||
<span class="tag">Unverified</span>
|
||||
</span>
|
||||
|
||||
<span data-ls-if="{{user.status}} === <?php echo \Auth\Auth::USER_STATUS_BLOCKED; ?>">
|
||||
<span class="tag red">Blocked</span>
|
||||
<span class="tag red">Blocked</span>
|
||||
</span>
|
||||
</td>
|
||||
<td data-title="Created: "><small data-ls-bind="{{user.registration|date-text}}"></small></td>
|
||||
|
@ -242,8 +242,8 @@ $providers = $this->getParam('providers', []);
|
|||
<thead>
|
||||
<tr>
|
||||
<th width="60"></th>
|
||||
<th width="180">Name</th>
|
||||
<th>Members</th>
|
||||
<th>Name</th>
|
||||
<th width="150">Members</th>
|
||||
<th width="150">Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -38,31 +38,46 @@ class CertificatesV1
|
|||
|
||||
Authorization::disable();
|
||||
|
||||
$document = $this->args['document'];
|
||||
$domain = $this->args['domain'];
|
||||
$domain = new Domain((!empty($domain)) ? $domain : '');
|
||||
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days
|
||||
$safety = 60 * 60; // 1 hour
|
||||
$renew = (time() + $expiry);
|
||||
// Args
|
||||
$document = $this->args['document'];
|
||||
$domain = $this->args['domain'];
|
||||
|
||||
// Validation Args
|
||||
$validateTarget = (isset($this->args['validateTarget'])) ? $this->args['validateTarget'] : true;
|
||||
$validateCNAME = (isset($this->args['validateCNAME'])) ? $this->args['validateCNAME'] : true;
|
||||
|
||||
// Options
|
||||
$domain = new Domain((!empty($domain)) ? $domain : '');
|
||||
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days
|
||||
$safety = 60 * 60; // 1 hour
|
||||
$renew = (time() + $expiry);
|
||||
|
||||
if(empty($domain->get())) {
|
||||
echo 'Log: Missing domain';
|
||||
throw new Exception('Missing domain');
|
||||
}
|
||||
|
||||
if(!$domain->isKnown() || $domain->isTest()) {
|
||||
echo 'Log: Unkown public suffix for domain';
|
||||
throw new Exception('Unkown public suffix for domain');
|
||||
}
|
||||
|
||||
$target = new Domain($request->getServer('_APP_DOMAINS_TARGET', ''));
|
||||
|
||||
if(!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
|
||||
if($validateTarget) {
|
||||
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
|
||||
|
||||
if(!$target->isKnown() || $target->isTest()) {
|
||||
echo 'Log: Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.';
|
||||
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.');
|
||||
}
|
||||
}
|
||||
|
||||
$validator = new CNAME($target->get()); // Verify Domain with DNS records
|
||||
|
||||
if(!$validator->isValid($domain->get())) {
|
||||
throw new Exception('Failed to verify domain DNS records');
|
||||
if($validateCNAME) {
|
||||
$validator = new CNAME($target->get()); // Verify Domain with DNS records
|
||||
|
||||
if(!$validator->isValid($domain->get())) {
|
||||
echo 'Log: Failed to verify domain DNS records';
|
||||
throw new Exception('Failed to verify domain DNS records');
|
||||
}
|
||||
}
|
||||
|
||||
$certificate = $consoleDB->getCollection([
|
||||
|
@ -84,6 +99,7 @@ class CertificatesV1
|
|||
&& $certificate instanceof Document
|
||||
&& isset($certificate['issueDate'])
|
||||
&& (($certificate['issueDate'] + ($expiry)) > time())) { // Check last issue time
|
||||
echo 'Log: Renew isn\'t required. Domain issued at '.date('d.m.Y H:i', (isset($certificate['issueDate']) ? $certificate['issueDate'] : 0));
|
||||
throw new Exception('Renew isn\'t required. Domain issued at '.date('d.m.Y H:i', (isset($certificate['issueDate']) ? $certificate['issueDate'] : 0)));
|
||||
}
|
||||
|
||||
|
@ -94,6 +110,7 @@ class CertificatesV1
|
|||
-d {$domain->get()} 2>&1");
|
||||
|
||||
if(!$response) {
|
||||
echo 'Log: Failed to issue a certificate';
|
||||
throw new Exception('Failed to issue a certificate');
|
||||
}
|
||||
|
||||
|
@ -101,23 +118,28 @@ class CertificatesV1
|
|||
|
||||
if(!is_readable($path)) {
|
||||
if (!mkdir($path, 0755, true)) {
|
||||
echo 'Log: Failed to create path...';
|
||||
throw new Exception('Failed to create path...');
|
||||
}
|
||||
}
|
||||
|
||||
if(!@rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) {
|
||||
echo 'Log: Failed to create path... 1';
|
||||
throw new Exception('Failed to rename certificate cert.pem: '.json_encode($response));
|
||||
}
|
||||
|
||||
if(!@rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) {
|
||||
echo 'Log: Failed to create path... 2';
|
||||
throw new Exception('Failed to rename certificate chain.pem: '.json_encode($response));
|
||||
}
|
||||
|
||||
if(!@rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) {
|
||||
echo 'Log: Failed to create path... 3';
|
||||
throw new Exception('Failed to rename certificate fullchain.pem: '.json_encode($response));
|
||||
}
|
||||
|
||||
if(!@rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) {
|
||||
echo 'Log: Failed to create path... 4';
|
||||
throw new Exception('Failed to rename certificate privkey.pem: '.json_encode($response));
|
||||
}
|
||||
|
||||
|
@ -137,6 +159,7 @@ class CertificatesV1
|
|||
$certificate = $consoleDB->createDocument($certificate);
|
||||
|
||||
if(!$certificate) {
|
||||
echo 'Log: Failed saving certificate to DB';
|
||||
throw new Exception('Failed saving certificate to DB');
|
||||
}
|
||||
|
||||
|
@ -149,6 +172,7 @@ class CertificatesV1
|
|||
$document = $consoleDB->updateDocument($document);
|
||||
|
||||
if(!$document) {
|
||||
echo 'Log: Failed saving domain to DB';
|
||||
throw new Exception('Failed saving domain to DB');
|
||||
}
|
||||
}
|
||||
|
@ -160,6 +184,7 @@ class CertificatesV1
|
|||
keyFile: /storage/certificates/{$domain->get()}/privkey.pem";
|
||||
|
||||
if(!file_put_contents(APP_STORAGE_CONFIG.'/'.$domain->get().'.yml', $config)) {
|
||||
echo 'Log: Failed to save SSL configuration';
|
||||
throw new Exception('Failed to save SSL configuration');
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ services:
|
|||
# - _APP_ENV=development
|
||||
- _APP_OPTIONS_ABUSE=disabled
|
||||
- _APP_OPENSSL_KEY_V1=your-secret-key
|
||||
- _APP_DOMAINS_TARGET=demo.appwrite.io
|
||||
- _APP_DOMAIN=demo.appwrite.io
|
||||
- _APP_DOMAIN_TARGET=demo.appwrite.io
|
||||
- _APP_REDIS_HOST=redis
|
||||
- _APP_REDIS_PORT=6379
|
||||
- _APP_DB_HOST=mariadb
|
||||
|
|
|
@ -12,13 +12,13 @@ function setEnvironmentVariable() {
|
|||
fi
|
||||
|
||||
# Check whether variable already exists
|
||||
if grep -q $1 /etc/php/$PHP_VERSION/fpm/pool.d/www.conf; then
|
||||
# Reset variable
|
||||
sed -i "s/^env\[$1.*/env[$1] = $2/g" /etc/php/$PHP_VERSION/fpm/pool.d/www.conf
|
||||
else
|
||||
if ! grep -q "\[$1\]" /etc/php/$PHP_VERSION/fpm/pool.d/www.conf; then
|
||||
# Add variable
|
||||
echo "env[$1] = $2" >> /etc/php/$PHP_VERSION/fpm/pool.d/www.conf
|
||||
fi
|
||||
|
||||
# Reset variable
|
||||
# sed -i "s/^env\[$1.*/env[$1] = $2/g" /etc/php/$PHP_VERSION/fpm/pool.d/www.conf
|
||||
}
|
||||
|
||||
# Grep for variables that look like MySQL (APP_)
|
||||
|
@ -28,5 +28,8 @@ for _curVar in $(env | grep _APP_ | awk -F = '{print $1}');do
|
|||
setEnvironmentVariable ${_curVar} ${!_curVar}
|
||||
done
|
||||
|
||||
# Init server settings
|
||||
php /usr/share/nginx/html/app/tasks/init.php ssl
|
||||
|
||||
# Start supervisord and services
|
||||
/usr/bin/supervisord -n -c /etc/supervisord.conf
|
||||
|
|
|
@ -60,6 +60,8 @@ stopsignal=QUIT
|
|||
startretries=10
|
||||
;stdout_logfile=/dev/stdout
|
||||
;stdout_logfile_maxbytes=0
|
||||
stdout_logfile=/var/log/appwrite.log
|
||||
stdout_logfile_maxbytes=5000000
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes = 0
|
||||
|
||||
|
@ -75,6 +77,8 @@ stopsignal=QUIT
|
|||
startretries=10
|
||||
;stdout_logfile=/dev/stdout
|
||||
;stdout_logfile_maxbytes=0
|
||||
stdout_logfile=/var/log/appwrite.log
|
||||
stdout_logfile_maxbytes=5000000
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes = 0
|
||||
|
||||
|
@ -90,6 +94,8 @@ stopsignal=QUIT
|
|||
startretries=10
|
||||
;stdout_logfile=/dev/stdout
|
||||
;stdout_logfile_maxbytes=0
|
||||
stdout_logfile=/var/log/appwrite.log
|
||||
stdout_logfile_maxbytes=5000000
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes = 0
|
||||
|
||||
|
@ -105,6 +111,8 @@ stopsignal=QUIT
|
|||
startretries=10
|
||||
;stdout_logfile=/dev/stdout
|
||||
;stdout_logfile_maxbytes=0
|
||||
stdout_logfile=/var/log/appwrite.log
|
||||
stdout_logfile_maxbytes=5000000
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes = 0
|
||||
|
||||
|
@ -120,6 +128,8 @@ stopsignal=QUIT
|
|||
startretries=10
|
||||
;stdout_logfile=/dev/stdout
|
||||
;stdout_logfile_maxbytes=0
|
||||
stdout_logfile=/var/log/appwrite.log
|
||||
stdout_logfile_maxbytes=5000000
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes = 0
|
||||
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
* ― Rick Cook, The Wizardry Compiled
|
||||
*/
|
||||
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
// ini_set('display_errors', 1);
|
||||
// ini_set('display_startup_errors', 1);
|
||||
// error_reporting(E_ALL);
|
||||
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
$path = (isset($_GET['q'])) ? explode('/', $_GET['q']) : [];
|
||||
$domain = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : '';
|
||||
|
||||
|
|
Loading…
Reference in a new issue