From 36e8cf323ab25e3a71a9d0800690ad50da92ebe1 Mon Sep 17 00:00:00 2001 From: Zachary Priddy Date: Sun, 7 Feb 2016 20:40:28 +0000 Subject: [PATCH 1/2] make cloud9 run on localhost and links to https Changed the port checker to only check localhost and make cloud9 launcher only launch to local host. The reason for this chnage is to imporove security. This allowes you to run nginx with proxy_pass allowing you to password protect c9 as well as run it with https. This is an issue because once you launch c9 from c9hub the c9 instance is open to the world on port 300X with no auth, password, or https. Yes this fix causes you to have to login again but it is much better than leaving it open to the world. I also removed livereloader from the page footer fixing 404 errors. --- config.js.example | 2 +- controllers/workspaces.js | 4 ++-- views/includes/footer.html | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/config.js.example b/config.js.example index ee9ccab..d1bedef 100644 --- a/config.js.example +++ b/config.js.example @@ -13,4 +13,4 @@ exports.PERMITTED_USERS = false; // cert: "/path/to/ssl.pem" //}; -exports.BASE_URL = 'http://localhost'; +exports.BASE_URL = 'https://localhost'; diff --git a/controllers/workspaces.js b/controllers/workspaces.js index d06f590..de01db2 100644 --- a/controllers/workspaces.js +++ b/controllers/workspaces.js @@ -115,7 +115,7 @@ exports.destroy = function(req, res) { }) .close() }) - .listen(port) + .listen(port, '127.0.0.1') }; var getNextAvailablePort = function(callback){ @@ -149,7 +149,7 @@ exports.destroy = function(req, res) { console.log("Starting " + __dirname + '/../c9/server.js for workspace ' + workspaceName + " on port " + nextFreePort); var workspaceDir = __dirname + '/../workspaces/' + req.user + '/' + workspaceName var out = fs.openSync(workspaceDir + '/.c9.log', 'a'); - var workspace = fork(__dirname + '/../c9/server.js', ['-w', workspaceDir, '--listen', '0.0.0.0', '-p', nextFreePort, '-a', ':'], {detached: true, stdio: [out, out, out]}); + var workspace = fork(__dirname + '/../c9/server.js', ['-w', workspaceDir, '--listen', '127.0.0.1', '-p', nextFreePort, '-a', ':'], {detached: true, stdio: [out, out, out]}); req.app.get('runningWorkspaces')[req.user + '/' + workspaceName] = { killTimeout: createWorkspaceKillTimeout(req, workspace, workspaceName), diff --git a/views/includes/footer.html b/views/includes/footer.html index f13d907..1931444 100644 --- a/views/includes/footer.html +++ b/views/includes/footer.html @@ -15,7 +15,3 @@ -{% if (process.env.NODE_ENV == 'development') %} - - -{% endif %} \ No newline at end of file From ecd6b600996e4ff22b0932e97bb66c0efeaac246 Mon Sep 17 00:00:00 2001 From: Zachary Priddy Date: Sun, 7 Feb 2016 21:14:13 +0000 Subject: [PATCH 2/2] Updated README to add nginx setup Updated walkthough for https using letsencrypot and nginx with password auth to the c9 IDE. Aslo added sample nginx confix file --- README.md | 65 +++++++++++-- etc.nginx.site-available.default.example | 111 +++++++++++++++++++++++ 2 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 etc.nginx.site-available.default.example diff --git a/README.md b/README.md index 2028daa..31901ea 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ -#Cloud9Hub +# Cloud9Hub -##What's this? +## What's this? It's a simple interface for the Cloud 9 open source edition to easily create, use and manage multiple workspaces. [The Cloud9 service](https://c9.io) has a shiny and awesome dashboard interface where you can manage multiple workspaces, however the [open source edition](https://github.com/ajaxorg/cloud9) is a single workspace instance of Cloud9. As I like the possibility to easily start working on different workspaces, create or delete them, I created Cloud9Hub to do so. -##What's Cloud9? +## What's Cloud9? A full-blown IDE in your browser. It has a full terminal integration, can run and deploy code of different languages (e.g. Ruby, node.js, PHP) and [lots more](http://en.wikipedia.org/wiki/Cloud9_IDE#Features). -##Status Quo of Cloud9Hub +## Status Quo of Cloud9Hub Right now it can * Create new workspaces * Launch multiple workspace instances @@ -24,7 +24,7 @@ Right now it can right now. These are the next steps for me to build (or you make a Pull Request with the features you want). -##Installation +## Installation First you will need [node.js](http://nodejs.org/), at least v0.8. Then you can try the quick install or the manual way: @@ -53,17 +53,64 @@ Now copy the ``config.js.example`` to ``config.js`` and edit the contents: - Add your Github client ID and secret - Change your BASE_URL to your server's address (do not include the port!) -##Firewall +## Firewall You will need ports 3000 and 5000 to however many connections will be taking place concurrently (each session is given a different port) -##Running as a daemon +## nginx and LetsEncrypt Setup + +### Get HTTPS cert using [LetsEncrypt](https://letsencrypt.org/) +```shell +cd ~/ +git clone https://github.com/letsencrypt/letsencrypt +cd letsencrypt +./letsencrypt-auto certonly --standalone +``` +Follow the directions and at the end it should say that it was sucessful. + +### Install nginx and apache2-utils +```shell +[sudo] apt-get install nginx apache2-utils +``` + +### Setup htaccess password +```shell +sudo htpasswd -c /etc/nginx/.htpasswd <> +``` + +It will then ask you to enter a password. This username and password will be used when loading the c9 IDE. You will still be using github to load the cloud9hub. Maybe look into [oauth2_proxy] (https://github.com/bitly/oauth2_proxy) in the future + +### Move Https Certs +```shell +sudo mkdir /etc/nginx/certs +sudo mkdir /etc/nginx/certs/ +sudo cp /etc/letsencrypt/live//fullchain.pem /etc/nginx/certs// +sudo cp /etc/letsencrypt/live//privkey.pem /etc/nginx/certs// +``` + +### Setup nginx +copy the etc.nginx.sites-available.defualt.example to /etc/nginx/sites-available/default +```shell +[sudo] cp etc.nginx.sites-available.defualt.example /etc/nginx/sites-available/default +``` +Edit the file /etc/nginx/sites-available/default and add the EXT IP, SERVER HOSTNAME, PATH TO CERT, PATH TO KEY + +PATH TO CERT should be /etc/nginx/certs//fullcahin.pem + +PATH TO KEY should be /etc/nginx/certs//privkey.pem + +Restart nginx +```shell +[sudo] service nginx restart +``` + +## Running as a daemon If you wish to, you can run it as a daemon, so that it stays alive. To do so, I recommend [forever](https://npmjs.org/package/forever). -##License +## License **This project:** [MIT License](http://opensource.org/licenses/MIT), baby. **Cloud9 itself:** [GPL](http://www.gnu.org/licenses/gpl.html) -##WARNING +## WARNING This is highly insecure, experimental and it may bite. diff --git a/etc.nginx.site-available.default.example b/etc.nginx.site-available.default.example new file mode 100644 index 0000000..cc38df0 --- /dev/null +++ b/etc.nginx.site-available.default.example @@ -0,0 +1,111 @@ +# You may add here your +# server { +# ... +# } +# statements for each of your virtual hosts to this file + +## +# You should look at the following URL's in order to grasp a solid understanding +# of Nginx configuration files in order to fully unleash the power of Nginx. +# http://wiki.nginx.org/Pitfalls +# http://wiki.nginx.org/QuickStart +# http://wiki.nginx.org/Configuration +# +# Generally, you will want to move this file somewhere, and start with a clean +# file but keep this around for reference. Or just disable in sites-enabled. +# +# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. +## + +#server { +# listen 80 default_server; +# listen [::]:80 default_server ipv6only=on; +# +# root /usr/share/nginx/html; +# index index.html index.htm; +# +# # Make site accessible from http://localhost/ +# server_name localhost; +# +# location / { +# # First attempt to serve request as file, then +# # as directory, then fall back to displaying a 404. +# try_files $uri $uri/ =404; +# # Uncomment to enable naxsi on this location +# # include /etc/nginx/naxsi.rules +# } +# +# # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests +# #location /RequestDenied { +# # proxy_pass http://127.0.0.1:8080; +# #} +# +## +# # redirect server error pages to the static page /50x.html +# # +# #error_page 500 502 503 504 /50x.html; +# #location = /50x.html { +# # root /usr/share/nginx/html; +# #} +# +# # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 +# # +# #location ~ \.php$ { +# # fastcgi_split_path_info ^(.+\.php)(/.+)$; +# # # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini +# # +# # # With php5-cgi alone: +# # fastcgi_pass 127.0.0.1:9000; +# # # With php5-fpm: +# # fastcgi_pass unix:/var/run/php5-fpm.sock; +# # fastcgi_index index.php; +# # include fastcgi_params; +# #} +# +# # deny access to .htaccess files, if Apache's document root +# # concurs with nginx's one +# # +# #location ~ /\.ht { +# # deny all; +# #} +#} + + +# HTTPS server +# +server { + listen <>:3001; + listen <>:3002; + listen <>:3003; + listen <>:3004; + listen <>:3005; + listen <>:3006; + listen <>:3007; + listen <>:3008; + listen <>:3009; + listen <>:3010; + + resolver 8.8.8.8; + server_name <>; + + root html; + index index.html index.htm; + + ssl on; + ssl_certificate <>; + ssl_certificate_key <>; + + ssl_session_timeout 5m; + + ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; + ssl_prefer_server_ciphers on; + + auth_basic "Restricted"; + auth_basic_user_file /etc/nginx/.htpasswd; + + + location / { + proxy_pass http://127.0.0.1:$server_port; + } +}