importing certificates into firefox trusted root CAs programmaticaly by javascript - javascript

I'm developing a webrtc application with sipml5 in firefox.
firefox does not allow unsecure connection from secure origin.
I have created a self signed certificate for my Communication server Asterisk (Secure websocket serving sipml5). But every time i want to login to to asterisk from my sipml5 page i should open a tab, write "wss://myAsteriskURL:8088" to add a security exception for my asterisk websocket connection.
Can any body show me a way to programaticaly add my my "ca.cert" to Firefox's "TRUSTED ROOT Certificate Authorities" with javaxcript code?? if actually a way exists!
Thank you

No, it's not possible to inject your ca.cert inside browsers trusted root certificate authorities with js.
But I can tell you that I had exactly the same problem: users can't be asked to accept two times the same certificate to use a web page, and I solved in another way: using mod_proxy_wstunnel in Apache/2.4.20.
Now showing a single https server to provide web pages and sip signaling the user is required to accept just a single certificate.
Here is the relevant part of the config:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
<VirtualHost *:443>
DocumentRoot ...
ServerName clic2call.demo.sociale.it:443
ErrorLog ...
TransferLog ...
SSLEngine on
...
SSLProxyCheckPeerName off
SSLProxyEngine On
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
SSLProxyVerify none
ProxyPass /ws wss://127.0.0.1:8088/ws retry=0
</VirtualHost>
I hope it can be useful to solve your problem.

Related

Creating a NodeJS based web server to take advantage of HTTP2 on windows platform

I am using windows 2012 server and want to host some static HTML/CSS/JS/image files on a nodejs based web server. I do not want to use IIS as I want to take advantages of HTTP2 & want to push files from server to client. I looked at Using node.js as a simple web server which talks about how to create a node based webserver. Another option is to use http-server node package.
My question is:
These solutions are over two year old. Do we have a better option available now?
Does any of these two options supports HTTP2?
I would prefer using a existing node module rather then reinventing the wheel.
You could try NGINX, it can support HTTP/2. http://nginx.org/en/docs/windows.html
Run your node applications by using default node, nodemon, pm2...
Then use NGINX as a static web server and you can reverse proxy your node apps.
If you want to use Node then this article seems to cover the basics: https://webapplog.com/http2-server-push-node-express/ and it seems the node-spdy module is the best option (it includes support for HTTP/2 despite the name). There is a node-http2 module but it seems much less well maintained and doesn't support Express (the most popular HTTP framework for Node).
However, as discussed in the comments, while not the question you asked, I recommend running a traditional web server (e.g. Apache, Nginx or IIS) in front of NodeJS or any other traditionally back end server. While NodeJS is very flexible and most (if not all) of the functionality of a webserver can be added to it, a traditional web server comes out of the box with a lot of functionality and requires just configuration rather than programming and/or pulling in multiple other modules to set it up properly.
For just serving static files Node seems the wrong solution to me so, for the rest of my answer I'll discuss not not using Node directly for the reasons given above but instead using a front end webserver.
I don't know IIS too well but from a quick Google it seems HTTP/2 was only introduced in IIS 10 and, as far as I know, even IIS 10 doesn't support Push except through API calls so I agree with your decision not to use that for now.
Nginx could be installed instead of IIS, as suggested, and while it supports HTTP/2 it doesn't yet support HTTP/2 (though Cloudflare have added it and run on Nginx so imagine it won't be long coming).
Apache fully supports HTTP/2 including server push. Packaged windows versions of Apache can be downloaded from Apache Lounge so is probably the easiest way of supporting HTTP/2 push on Windows Server and would be my recommendation for the scenario you've given.
While I mostly use Apache on Linux boxes I've a number of servers on Windows and have quite happily been running Apache on that as a Service (so it automatically restarts on server reboot) with no issues so not sure what "bad experience" you had previously but it really is quite stable to me.
To set up Apache on a Windows Server use the following steps:
Download the last version from Apache Lounge.
Unzip the files and save them to C:\ (or C:\Program Files\ if you prefer but update all the config to change the default C:\apache24 to C:\Program Files\)
Edit the conf\httpd.conf file to check ServerRoot, DocumentRoot and any Directory values are set to where you want it (C:\Apache24 by default).
Run a DOS->Command Prompt as Administrator
In the Administrator CD to the Apache location and the bin director.
Run httpd.exe and deal with any error messages (note port 80 must be free so stop anything else running on that report).
Check you get the default "It works!" message on http://localhost/
Install Apache as a service by killing the httpd.exe process and instead running httpd.exe -install.
Start the Apache24 service and again verify you get the "It works!" message on http://localhost/
To add HTTP/2 and HTTPS (necessary for HTTP/2 on all browsers), uncomment the following lines from httpd.conf:
LoadModule http2_module modules/mod_http2.so
...
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
...
LoadModule ssl_module modules/mod_ssl.so
...
Include conf/extra/httpd-ssl.conf
Install a cert and key to conf/server.crt and conf/server.key - note Apache 2.4 expects the cert file to include the cert plus any intermediary certs in X509 Base 64 DER format so should look something like this when opened in a text editor:
-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----
Where the first cert is the server cert and the 2nd and subsequent certs are the intermediaries.
You should make sure you're running good HTTPS config (the defaults in Apache are very poor), but the defaults will do for now. I've a blog post on that here.
Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost).
To add HTTP/2 to Apache
Edit the conf/extra/httpd-ssl.conf file to add the following near the top (e.g. after the Listen 443 line):
Protocols h2 http/1.1
Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost) and you should see h2 as the protocol in the developer tools of your web browser.
To use HTTP/2 push in Apache add the following to push a style sheet:
Header add Link "</path/to/css/styles.css>;rel=preload;as=style" env=!cssloaded
And you should see it pushed to your page in developer tools. Again, I've a blog post on that if you want more information on this.
If you do want to use Node for some (or all) of your calls you can uncomment the following line from conf/httpd.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
And then add the following config:
ProxyPass /nodecontent http://127.0.0.1:8000/
Which will send any of those requests to node service running on port 8000. Restart to pick up this config.
If your node service adds any HTTP headers like this:
link:</path/to/style/styles.css>;rel=preload;as=style
Then Apache should pick them up and push them too. For example if using Express you can use the following to set the headers:
app.get('/test/', function (req, res) {
res.header('link','</path/to/style.css>;rel=preload;as=style');
res.send('This is a test page which also uses Apache to push a CSS file!\n');
});
Finally, while on the subject of HTTP/2 push this article includes a lot of interesting food for thought: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/
I know this is a fairly old question, but I thought I would give an answer for those that come here looking for info.
Node now has a native http2 module and there are some examples on the web that show exactly how to implement a static web server.
NOTE: At the time of this answer Node 9.6.1 is current and the native module is still experimental
Example https://dexecure.com/blog/how-to-create-http2-static-file-server-nodejs-with-examples/
NOTE: I have no affiliation to the author of the example

How do I get nodejs to run without a port number on a Apache server

I have a nodejs api application running inside a codeigniter environment. Im trying to access the nodejs api's without using a port number in the url
currently you can only hit the node api at
http://wrl.xx.com:8010/api
And I would like to have it accessible through a url like :
http://wrl.xx.com/api/
I tried to run a reverse proxy with no success
<VirtualHost *:80>
ServerName wrl.xx.com
ProxyRequests off
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass / http://localhost:8010/
ProxyPassReverse / http://localhost:8010/
ProxyPreserveHost on
</VirtualHost>
Assuming you intend to differentiate requests looking for the nodejs app from requests seeking the codigniter app by seeing /api as the root path, try:
ProxyPass /api http://localhost:8010/api
ProxyPassReverse /api http://localhost:8010/api
See ProxyPass and ProxyPassReverse for more magic.
Disclaimer: I have no experience with codeigniter, so this may be non relevant, or false.
Your node.js server listen to port 8010, which is non standard, that is why you need to indicate it in the URL.
You seems to imply codeigniter is already listening to the standard port (80).
The way I see, with no knowledge of codeigniter, to go around the issue would be to either host all the node.js url in codeigniter, and redirect them to port 8010:
Client call /node on port 80
CodeIgniter call /node on himself at port 8010
Node get the request and answer
Code igniter gove the answer to the client
Or the reverse, which would be to host any codeigniter URL in node.js, and redirect them to whatever port codeigniter will listen.
Or you will need to configure Apache to redirect the request to port whatever codeigniter on or 8010 depending of the url.

How to Marry Local apache web domain?

I bought a domain on internet, i want on that domain put my application. My application was developed on Sails.js, and i made a virtual host with apache2 using the module mod_proxy.
How do I do to on the domain i bought on internet, put my application?
My virtual host is:
NameVirtualHost 111.11.11.111
<VirtualHost *:80>
ServerName app.domain.com.ve
ServerAlias www.app.domain.com.ve
ServerAdmin 111.11.11.111:1337
RewriteEngine on
ProxyPass / http://111.11.11.111:1337/
ProxyPassReverse / http://111.11.11.111:1337/
CustomLog /home/user/app/apache2log/accessApp.log combined
ErrorLog /home/user/app/apache2log/errorApp.log
</VirtualHost>
And my /etc/hosts:
111.11.11.111 www.app.domain.com.ve
You isp will provide a administration panel to update the A Record. You need to update your DNS records to point to your server where your application is hosted.
You need to host in a datacenter. Try AWS/Azure/Google Cloud/linode that provides a small server and provides an external network interface on the internet. Publish your application on that host. You should be able to access your application by your public IP. You can then go your domain control panel and modify your A Record.

Angular + Node(Express) + SSL integration

This is my first time deploying ssl. I have express node js module running at localhost:4000. I have generated the self-signed certificate and installed in the server and it is working. Now, I have my angularjs frontend running at localhost:3000(I am using http-server to run the angular code).
To make my point more clearer, here's is the code on the server side:-
// Import node js modules
var https = require('https')
var fs = require('fs')
var express = require('express')
// Load App configuration
var config = require('./config/config')
// Database Integration Here(mongodb)
// Initialize the express app
var app = express()
// App express Configuration
// parse application/json
app.use(bodyParser.json())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true}))
app.use(cors())
app.set('serverHost', config.server.host)
app.set('serverPort', config.server.port)
app.set('serverUrl', config.server.url)
// Initializing various app modules
// Initialize the components
//Initialize the route(controller)
// Start the app with a given port no and mode
var env = process.env.NODE_ENV || 'development'
var httpsOptions = {
key: fs.readFileSync(__dirname + '/cert/server.key'),
cert: fs.readFileSync(__dirname + '/cert/server.crt')
}
https.createServer(httpsOptions, app).listen(app.get('serverPort'), function () {
// Server and mode info
console.log('The homerungurus backend running on server: '
+ app.get('serverHost')
+ ' and the port is: '
+ app.get('serverPort'))
console.log("The mode is: " + env)
})
As you can see I have installed the certs in the server.
I don't need a http-proxy because i will deploy the angular webserver on the standard port 443.
I am not able to understand few things:-
How to enable and set ssl certificate in my angular module so that
express and angular can communicate over ssl.
How will I display the cert of my backend express node to the browser?
I hope I have made my point more clearer.
Any help is appreciated?
Ok, where do we start...
You have a backend (express node js) running on port 4000, and a frontend (angularjs with http-server) running on port 3000, so you basically have two independent webservers running. When you say you "installed" the ssl certificate on the server, I assume you have it sitting in some directory but not actually installed on one of your servers.
You have several options to deploy your code, together with your SSL certificate. The best approach would be to seperate frontend from backend by urls.
That would mean that your frontend gets served from: https://frontend.example.com
and your backend gets served from https://backend.example.com (you can change the urls to whatever you want, so something like https://example.com or https://www.example.com is fine as well)
As far as I recall, if you have https:// on your frontend, you also need https:// on your backend, otherwise you will have problems with browsers security policies. You might also have to look for same origin policy, and allow on your server that https://frontend.example.com can access https://backend.example.com, but for that open a new ticket if you need it :D
The user would see the green symbol from https://frontend.example.com
I assume you know how you would change the backend url so your angular code would use https://backend.example.com instead of http://localhost:4000
To serve now your existing servers on port 443 (that is the default port for https and is always used if you say https://... but do not specify a port) you need an http proxy.
As http proxy (you can google for reverse proxy) you can take either apache or nginx, both are very common.
There are a couple of tutorials out there, how to setup nginx / apache which are OS specific, but Im sure you will manage. Dont forget to install mod_ssl and mod_http_proxy mod for apache (I dont remember if nginx needs something specifc as well)
A typical config for an apache reverse proxy would look like this:
<VirtualHost *:80>
# this part redirects all traffic from normal http to https
ServerName frontend.example.com
ServerSignature Off
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L]
</VirtualHost>
<virtualhost *:443>
# this is the actual part with some security enhancements
ServerName frontend.example.com
ServerAdmin webmaster#localhost
# be carefull with HSTS, it might break your setup if you
# do not know what you do. If you are not sure, do not
# comment the next line in
# Header always add Strict-Transport-Security "max-age=15768000"
# Enable SSL
SSLEngine on
# only strong encryption ciphers
# for reference https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# and no RC4 according to https://community.qualys.com/blogs/securitylabs/2013/03/19/rc4-in-tls-is-broken-now-what
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"
SSLCompression Off
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/privkey.pem
# this next line is not needed if you have a self signed cert
SSLCertificateChainFile /path/to/chain.pem
ServerSignature Off
RequestHeader set X-FORWARDED-PROTOCOL https
RequestHeader set X-Forwarded-Ssl on
ProxyPreserveHost On
# Ensure that encoded slashes are not decoded but left in their encoded state.
# http://doc.gitlab.com/ce/api/projects.html#get-single-project
AllowEncodedSlashes NoDecode
<Location />
# New authorization commands for apache 2.4 and up
# http://httpd.apache.org/docs/2.4/upgrading.html#access
Require all granted
ProxyPassReverse http://127.0.0.1:3000
ProxyPassReverse http://frontend.example.com/
</Location>
#apache equivalent of nginx try files
# http://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
# http://stackoverflow.com/questions/10954516/apache2-proxypass-for-rails-app-gitlab
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule .* http://127.0.0.1:3000%{REQUEST_URI} [P,QSA]
RequestHeader set X_FORWARDED_PROTO 'https'
You will need the exact same twice, for the frontend like shown above and for the backend, where you replace port 3000 with 4000 and frontend.example.com with backend.example.com.
I hope this helps you a bit. Its not as complete as it could, but it should give you a hint how to setup your two http servers behind a http proxy to server your ssl certificate.
The above comment made by #chickahoona is more than enough. My solution is as follows:-
I removed http-server and used nginx for my frontend because i wanted to have html5 mode and for that I needed to have url rewriting.
I have used nginx as a proxy server rather than apache.
That's it and everything else is same as #chickahoona has pointed out.

apache mod_proxy, configuring ProxyPass & ProxyPassReverse for cross-domain ajax calls

I'm creating an html5 - JavaScript app (for mobile devices, using PhoneGap). I have to interact with a REST service.
The service is now running on "http://localhost:8080/backend/mvc/"
I'm developing my app on an wamp server (apache2) (http://localhost/stage/)
I'm using Chrome for browser.
when preforming an ajax call the browser responds: XMLHttpRequest cannot load http://localhost:8080/backend/mvc/event. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
So I find several ways to circumvent this cross-domain ajax call problem:
1) starting chrome chrome.exe --disable-web-security
=> no difference
2) configuring apache using mod_proxy to redirect the traffic.
I enabled in the httpd.conf:
proxy_module
proxy_connect_module
proxy_http_module
I put a .htaccess file in the www root with the following content:
# start mod_rewrite
RewriteEngine On
ProxyRequests off
<Proxy>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /EMBackend/ http://localhost:8080/backend/mvc/
ProxyPassReverse /EMBackend/ http://localhost:8080/backend/mvc/
RewriteRule ^/EMBackend/(.*)$ /backend/mvc/$1 [R]
I restarted all services (apache,php,..)
resulting in error 500
apache error log: [Tue Oct 18 14:30:11 2011] [alert] [client 127.0.0.1] C:/wamp/www/.htaccess: ProxyRequests not allowed here
Any clues on how to resolve this?
I found a working solution:
Enable:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Put this in the main section of your configuration (or desired virtual host, if using Apache virtual hosts):
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /EMBackend http://localhost:8080/backend/mvc
ProxyPassReverse /EMBackend http://localhost:8080/backend/mvc
<Location /EMBackend>
Order allow,deny
Allow from all
</Location>
So I guess I can't put it in .htaccess or I had to set ProxyPreserveHost On. I put Include conf/extra/ in the httpd.conf file and created the httpd-proxy.conf file and put the script above in it. Restarted apache and it's working!
You could simply add the given lines in the httpd.conf after enabling the proxy modules.
ProxyPreserveHost On
ProxyPass /EMBackend http://localhost:8080/backend/mvc
ProxyPassReverse /EMBackend http://localhost:8080/backend/mvc
Just restart the server and you are done.
In very modern apache, turn on proxy by:
a2enmod proxy;
a2enmod proxy_http

Categories