From 593fe5ed259d5b118d41e2b961b462e922762700 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Wed, 17 May 2017 07:07:28 +0300 Subject: [PATCH] build(aio): enable HTTP/2 on the preview server (#16826) Fixes #16780 --- aio/aio-builds-setup/dockerbuild/Dockerfile | 50 ++++++++++--------- .../dockerbuild/nginx/aio-builds.conf | 20 +++++--- .../scripts-js/lib/upload-server/index.ts | 5 +- .../scripts-js/lib/verify-setup/helper.ts | 12 ++--- .../lib/verify-setup/upload-server.e2e.ts | 4 +- 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/aio/aio-builds-setup/dockerbuild/Dockerfile b/aio/aio-builds-setup/dockerbuild/Dockerfile index 025ad5ef91..61ffe68759 100644 --- a/aio/aio-builds-setup/dockerbuild/Dockerfile +++ b/aio/aio-builds-setup/dockerbuild/Dockerfile @@ -51,6 +51,7 @@ ENV AIO_BUILDS_DIR=$AIO_BUILDS_DIR TEST_AIO_BUILDS_DIR=$TEST AIO_UPLOAD_HOSTNAME=$AIO_UPLOAD_HOSTNAME TEST_AIO_UPLOAD_HOSTNAME=$TEST_AIO_UPLOAD_HOSTNAME \ AIO_UPLOAD_MAX_SIZE=$AIO_UPLOAD_MAX_SIZE TEST_AIO_UPLOAD_MAX_SIZE=$TEST_AIO_UPLOAD_MAX_SIZE \ AIO_UPLOAD_PORT=$AIO_UPLOAD_PORT TEST_AIO_UPLOAD_PORT=$TEST_AIO_UPLOAD_PORT \ + AIO_WWW_USER=www-data \ NODE_ENV=production @@ -63,6 +64,7 @@ RUN apt-get update -y && apt-get install -y curl RUN curl --silent --show-error --location https://deb.nodesource.com/setup_6.x | bash - RUN curl --silent --show-error https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/backports.list # Install packages @@ -71,11 +73,11 @@ RUN apt-get update -y && apt-get install -y \ cron \ dnsmasq \ nano \ - nginx \ nodejs \ openssl \ rsyslog \ yarn +RUN apt-get install -t jessie-backports -y nginx RUN yarn global add pm2@2 @@ -109,31 +111,31 @@ RUN update-ca-certificates # Set up nginx (for production and testing) -RUN rm /etc/nginx/sites-enabled/* +RUN sed -i -E "s|^user\s+\S+;|user $AIO_WWW_USER;|" /etc/nginx/nginx.conf +RUN [[ -d /etc/nginx/conf.d/ ]] && rm /etc/nginx/conf.d/* +RUN [[ -d /etc/nginx/sites-enabled/ ]] && rm /etc/nginx/sites-enabled/* -COPY nginx/aio-builds.conf /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_BUILDS_DIR}}|$AIO_BUILDS_DIR|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_DOMAIN_NAME}}|$AIO_DOMAIN_NAME|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_LOCALCERTS_DIR}}|$AIO_LOCALCERTS_DIR|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_NGINX_LOGS_DIR}}|$AIO_NGINX_LOGS_DIR|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTP}}|$AIO_NGINX_PORT_HTTP|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTPS}}|$AIO_NGINX_PORT_HTTPS|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_UPLOAD_HOSTNAME}}|$AIO_UPLOAD_HOSTNAME|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_UPLOAD_MAX_SIZE}}|$AIO_UPLOAD_MAX_SIZE|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN sed -i "s|{{\$AIO_UPLOAD_PORT}}|$AIO_UPLOAD_PORT|g" /etc/nginx/sites-available/aio-builds-prod.conf -RUN ln -s /etc/nginx/sites-available/aio-builds-prod.conf /etc/nginx/sites-enabled/aio-builds-prod.conf +COPY nginx/aio-builds.conf /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_BUILDS_DIR}}|$AIO_BUILDS_DIR|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_DOMAIN_NAME}}|$AIO_DOMAIN_NAME|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_LOCALCERTS_DIR}}|$AIO_LOCALCERTS_DIR|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_NGINX_LOGS_DIR}}|$AIO_NGINX_LOGS_DIR|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTP}}|$AIO_NGINX_PORT_HTTP|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTPS}}|$AIO_NGINX_PORT_HTTPS|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_UPLOAD_HOSTNAME}}|$AIO_UPLOAD_HOSTNAME|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_UPLOAD_MAX_SIZE}}|$AIO_UPLOAD_MAX_SIZE|g" /etc/nginx/conf.d/aio-builds-prod.conf +RUN sed -i "s|{{\$AIO_UPLOAD_PORT}}|$AIO_UPLOAD_PORT|g" /etc/nginx/conf.d/aio-builds-prod.conf -COPY nginx/aio-builds.conf /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_BUILDS_DIR}}|$TEST_AIO_BUILDS_DIR|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_DOMAIN_NAME}}|$TEST_AIO_DOMAIN_NAME|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_LOCALCERTS_DIR}}|$TEST_AIO_LOCALCERTS_DIR|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_NGINX_LOGS_DIR}}|$TEST_AIO_NGINX_LOGS_DIR|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTP}}|$TEST_AIO_NGINX_PORT_HTTP|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTPS}}|$TEST_AIO_NGINX_PORT_HTTPS|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_UPLOAD_HOSTNAME}}|$TEST_AIO_UPLOAD_HOSTNAME|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_UPLOAD_MAX_SIZE}}|$TEST_AIO_UPLOAD_MAX_SIZE|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN sed -i "s|{{\$AIO_UPLOAD_PORT}}|$TEST_AIO_UPLOAD_PORT|g" /etc/nginx/sites-available/aio-builds-test.conf -RUN ln -s /etc/nginx/sites-available/aio-builds-test.conf /etc/nginx/sites-enabled/aio-builds-test.conf +COPY nginx/aio-builds.conf /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_BUILDS_DIR}}|$TEST_AIO_BUILDS_DIR|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_DOMAIN_NAME}}|$TEST_AIO_DOMAIN_NAME|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_LOCALCERTS_DIR}}|$TEST_AIO_LOCALCERTS_DIR|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_NGINX_LOGS_DIR}}|$TEST_AIO_NGINX_LOGS_DIR|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTP}}|$TEST_AIO_NGINX_PORT_HTTP|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_NGINX_PORT_HTTPS}}|$TEST_AIO_NGINX_PORT_HTTPS|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_UPLOAD_HOSTNAME}}|$TEST_AIO_UPLOAD_HOSTNAME|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_UPLOAD_MAX_SIZE}}|$TEST_AIO_UPLOAD_MAX_SIZE|g" /etc/nginx/conf.d/aio-builds-test.conf +RUN sed -i "s|{{\$AIO_UPLOAD_PORT}}|$TEST_AIO_UPLOAD_PORT|g" /etc/nginx/conf.d/aio-builds-test.conf # Set up pm2 diff --git a/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf b/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf index a889f6dcba..ce740f144e 100644 --- a/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf +++ b/aio/aio-builds-setup/dockerbuild/nginx/aio-builds.conf @@ -17,11 +17,13 @@ server { server { server_name "~^pr(?[1-9][0-9]*)-(?[0-9a-f]{40})\."; - listen {{$AIO_NGINX_PORT_HTTPS}} ssl; - listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl; + listen {{$AIO_NGINX_PORT_HTTPS}} ssl http2; + listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl http2; - ssl_certificate {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.crt; - ssl_certificate_key {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.key; + ssl_certificate {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.crt; + ssl_certificate_key {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.key; + ssl_prefer_server_ciphers on; + ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; root {{$AIO_BUILDS_DIR}}/$pr/$sha; disable_symlinks on from=$document_root; @@ -47,11 +49,13 @@ server { server { server_name _; - listen {{$AIO_NGINX_PORT_HTTPS}} ssl default_server; - listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl; + listen {{$AIO_NGINX_PORT_HTTPS}} ssl http2 default_server; + listen [::]:{{$AIO_NGINX_PORT_HTTPS}} ssl http2; - ssl_certificate {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.crt; - ssl_certificate_key {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.key; + ssl_certificate {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.crt; + ssl_certificate_key {{$AIO_LOCALCERTS_DIR}}/{{$AIO_DOMAIN_NAME}}.key; + ssl_prefer_server_ciphers on; + ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; access_log {{$AIO_NGINX_LOGS_DIR}}/access.log; error_log {{$AIO_NGINX_LOGS_DIR}}/error.log; diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/upload-server/index.ts b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/upload-server/index.ts index b442c4c8b2..fdf523d538 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/upload-server/index.ts +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/upload-server/index.ts @@ -1,6 +1,3 @@ -// TODO(gkalpak): Find more suitable way to run as `www-data`. -process.setuid('www-data'); - // Imports import {getEnvVar} from '../common/utils'; import {uploadServerFactory} from './upload-server-factory'; @@ -15,8 +12,10 @@ const AIO_PREVIEW_DEPLOYMENT_TOKEN = getEnvVar('AIO_PREVIEW_DEPLOYMENT_TOKEN'); const AIO_REPO_SLUG = getEnvVar('AIO_REPO_SLUG'); const AIO_UPLOAD_HOSTNAME = getEnvVar('AIO_UPLOAD_HOSTNAME'); const AIO_UPLOAD_PORT = +getEnvVar('AIO_UPLOAD_PORT'); +const AIO_WWW_USER = getEnvVar('AIO_WWW_USER'); // Run +process.setuid(AIO_WWW_USER); // TODO(gkalpak): Find more suitable way to run as `www-data`. _main(); // Functions diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/helper.ts b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/helper.ts index ae119395dd..373449c0e2 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/helper.ts +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/helper.ts @@ -7,7 +7,6 @@ import * as shell from 'shelljs'; import {getEnvVar} from '../common/utils'; // Constans -const SERVER_USER = 'www-data'; const TEST_AIO_BUILDS_DIR = getEnvVar('TEST_AIO_BUILDS_DIR'); const TEST_AIO_NGINX_HOSTNAME = getEnvVar('TEST_AIO_NGINX_HOSTNAME'); const TEST_AIO_NGINX_PORT_HTTP = +getEnvVar('TEST_AIO_NGINX_PORT_HTTP'); @@ -15,6 +14,7 @@ const TEST_AIO_NGINX_PORT_HTTPS = +getEnvVar('TEST_AIO_NGINX_PORT_HTTPS'); const TEST_AIO_UPLOAD_HOSTNAME = getEnvVar('TEST_AIO_UPLOAD_HOSTNAME'); const TEST_AIO_UPLOAD_MAX_SIZE = +getEnvVar('TEST_AIO_UPLOAD_MAX_SIZE'); const TEST_AIO_UPLOAD_PORT = +getEnvVar('TEST_AIO_UPLOAD_PORT'); +const WWW_USER = getEnvVar('AIO_WWW_USER'); // Interfaces - Types export interface CmdResult { success: boolean; err: Error; stdout: string; stderr: string; } @@ -31,7 +31,7 @@ class Helper { public get nginxHostname() { return TEST_AIO_NGINX_HOSTNAME; } public get nginxPortHttp() { return TEST_AIO_NGINX_PORT_HTTP; } public get nginxPortHttps() { return TEST_AIO_NGINX_PORT_HTTPS; } - public get serverUser() { return SERVER_USER; } + public get wwwUser() { return WWW_USER; } public get uploadHostname() { return TEST_AIO_UPLOAD_HOSTNAME; } public get uploadPort() { return TEST_AIO_UPLOAD_PORT; } public get uploadMaxSize() { return TEST_AIO_UPLOAD_MAX_SIZE; } @@ -46,7 +46,7 @@ class Helper { // Constructor constructor() { shell.mkdir('-p', this.buildsDir); - shell.exec(`chown -R ${this.serverUser} ${this.buildsDir}`); + shell.exec(`chown -R ${this.wwwUser} ${this.buildsDir}`); } // Methods - Public @@ -64,7 +64,7 @@ class Helper { public createDummyArchive(pr: string, sha: string, archivePath: string): CleanUpFn { const inputDir = path.join(this.buildsDir, 'uploaded', pr, sha); const cmd1 = `tar --create --gzip --directory "${inputDir}" --file "${archivePath}" .`; - const cmd2 = `chown ${this.serverUser} ${archivePath}`; + const cmd2 = `chown ${this.wwwUser} ${archivePath}`; const cleanUpTemp = this.createDummyBuild(`uploaded/${pr}`, sha, true); shell.exec(cmd1); @@ -82,7 +82,7 @@ class Helper { this.writeFile(idxPath, {content: `PR: ${pr} | SHA: ${sha} | File: /index.html`}, force); this.writeFile(barPath, {content: `PR: ${pr} | SHA: ${sha} | File: /foo/bar.js`}, force); - shell.exec(`chown -R ${this.serverUser} ${prDir}`); + shell.exec(`chown -R ${this.wwwUser} ${prDir}`); return this.createCleanUpFn(() => shell.rm('-rf', prDir)); } @@ -166,7 +166,7 @@ class Helper { // Create a file with the specified content. fs.writeFileSync(filePath, content || ''); } - shell.exec(`chown ${this.serverUser} ${filePath}`); + shell.exec(`chown ${this.wwwUser} ${filePath}`); return this.createCleanUpFn(() => shell.rm('-rf', cleanUpTarget)); } diff --git a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/upload-server.e2e.ts b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/upload-server.e2e.ts index 198192a522..dc5adbb49d 100644 --- a/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/upload-server.e2e.ts +++ b/aio/aio-builds-setup/dockerbuild/scripts-js/lib/verify-setup/upload-server.e2e.ts @@ -159,7 +159,7 @@ describe('upload-server (on HTTP)', () => { }); - it(`should create files/directories owned by '${h.serverUser}'`, done => { + it(`should create files/directories owned by '${h.wwwUser}'`, done => { const shaDir = path.join(h.buildsDir, pr, sha9); const idxPath = path.join(shaDir, 'index.html'); const barPath = path.join(shaDir, 'foo', 'bar.js'); @@ -167,7 +167,7 @@ describe('upload-server (on HTTP)', () => { uploadPromise. then(() => Promise.all([ h.runCmd(`find ${shaDir}`), - h.runCmd(`find ${shaDir} -user ${h.serverUser}`), + h.runCmd(`find ${shaDir} -user ${h.wwwUser}`), ])). then(([{stdout: allFiles}, {stdout: userFiles}]) => { expect(userFiles).toBe(allFiles);