diff --git a/README.md b/README.md index 1a11933..0b473de 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ## WeTTy = Web + TTy +[ ![Codeship Status for butlerx/wetty](https://app.codeship.com/projects/caf50220-f884-0135-63bd-5231a73eac2d/status?branch=master)](https://app.codeship.com/projects/278281) + Terminal over HTTP and https. WeTTy is an alternative to ajaxterm and anyterm but much better than them because WeTTy uses xterm.js which is a full fledged implementation of terminal emulation written entirely in JavaScript. WeTTy uses @@ -91,8 +93,8 @@ SSL Put the following configuration in nginx's conf: ```nginx -location /wetty { - proxy_pass http://127.0.0.1:3000/wetty; +location ^~ /wetty { + proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; @@ -105,6 +107,9 @@ location /wetty { } ``` +For a more detailed look see the [nginx.conf](./bin/nginx.template) used for +testing + #### Apache Put the following configuration in apache's conf: diff --git a/bin/nginx.template b/bin/nginx.template new file mode 100644 index 0000000..e89cb69 --- /dev/null +++ b/bin/nginx.template @@ -0,0 +1,69 @@ +server { + listen ${NGINX_PORT}; + listen [::]:${NGINX_PORT}; + + server_name ${NGINX_DOMAIN}; + root /var/www/${NGINX_DOMAIN}/public; + + # $uri, index.html + location / { + try_files $uri $uri/ /index.html; + } + + # headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-UA-Compatible "IE=Edge" always; + add_header Cache-Control "no-transform" always; + + # . files + location ~ /\. { + deny all; + } + + # assets, media + location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ { + expires 7d; + access_log off; + } + + # svg, fonts + location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff|woff2)$ { + add_header Access-Control-Allow-Origin "*"; + expires 7d; + access_log off; + } + + location ^~ /wetty { + proxy_pass http://${WETTY_HOST}:${WETTY_PORT}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 43200000; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + } + + # gzip + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; +} + +# subdomains redirect +server { + listen ${NGINX_PORT}; + listen [::]:${NGINX_PORT}; + + server_name *.${NGINX_DOMAIN}; + + return 301 https://${NGINX_DOMAIN}$request_uri; +} + +# set ft=conf diff --git a/docker-compose.yml b/docker-compose.yml index 9218c2b..7cb1015 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,22 @@ services: image: butlerx/wetty container_name: wetty tty: true + restart: always working_dir: /app ports: - "3000:3000" environment: SSHHOST: 'localhost' SSHPORT: 22 + web: + image: nginx + volumes: + - ./bin/nginx.template:/etc/nginx/conf.d/wetty.template + ports: + - "80:80" + environment: + - NGINX_DOMAIN=wetty.com + - NGINX_PORT=80 + - WETTY_HOST=wetty + - WETTY_PORT=3000 + command: /bin/bash -c "envsubst '$${NGINX_DOMAIN},$${NGINX_PORT},$${WETTY_HOST},$${WETTY_PORT}' < /etc/nginx/conf.d/wetty.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" diff --git a/lib/logger.mjs b/lib/logger.mjs index 26ca2df..c364864 100644 --- a/lib/logger.mjs +++ b/lib/logger.mjs @@ -19,4 +19,10 @@ const logger = createLogger({ ], }); +logger.stream = { + write(message) { + logger.verbose(message); + }, +}; + export default logger; diff --git a/lib/server.mjs b/lib/server.mjs index 23cfb44..8b71a90 100644 --- a/lib/server.mjs +++ b/lib/server.mjs @@ -7,6 +7,8 @@ import https from 'https'; import path from 'path'; import socket from 'socket.io'; import { isUndefined } from 'lodash'; +import morgan from 'morgan'; +import logger from './logger.mjs'; import events from './emitter.mjs'; const pubDir = path.join(__dirname, '..', 'public'); @@ -16,6 +18,7 @@ export default function createServer(port, { key, cert }) { const app = express(); const wetty = (req, res) => res.sendFile(path.join(pubDir, 'index.html')); app + .use(morgan('combined', { stream: logger.stream })) .use(helmet()) .use(compression()) .use(favicon(path.join(pubDir, 'favicon.ico'))) @@ -23,7 +26,8 @@ export default function createServer(port, { key, cert }) { .get('/wetty/', wetty) .use('/wetty', express.static(path.join(__dirname, '..', 'dist'))) .get('/ssh/:user', wetty) - .get('/', wetty); + .get('/', wetty) + .use('/', express.static(path.join(__dirname, '..', 'dist'))); return socket( !isUndefined(key) && !isUndefined(cert) diff --git a/package.json b/package.json index 53b1775..1eb2dcc 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "helmet": "^3.9.0", "jsdoc-to-markdown": "^4.0.1", "lodash": "^4.17.4", + "morgan": "^1.9.0", "node-pty": "^0.7.4", "optimist": "^0.6", "serve-favicon": "^2.4.3", diff --git a/public/index.html b/public/index.html index 57e751a..475c0dc 100644 --- a/public/index.html +++ b/public/index.html @@ -4,7 +4,7 @@ - Wetty - The WebTTY Terminal Emulator + WeTTy - The Web Terminal Emulator diff --git a/yarn.lock b/yarn.lock index 6bb3068..c85e855 100644 --- a/yarn.lock +++ b/yarn.lock @@ -827,6 +827,12 @@ base64id@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" +basic-auth@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" + dependencies: + safe-buffer "5.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -3981,6 +3987,16 @@ mkdirp2@^1.0.3: dependencies: minimist "0.0.8" +morgan@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051" + dependencies: + basic-auth "~2.0.0" + debug "2.6.9" + depd "~1.1.1" + on-finished "~2.3.0" + on-headers "~1.0.1" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"