diff --git a/README.md b/README.md index 2cfb21c8..f6b8aa7e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,69 @@ -# HolyUB - A website that can be used to bypass web filters; both online and firewall. +# Alloy Proxy + +A node.js proxy that features URL encoding, and amazing compatablity! + +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/titaniumnetwork-dev/alloyproxy/) + +# How to install and use: + +`git clone https://github.com/titaniumnetwork-dev/alloyproxy.git` + +`cd alloyproxy` + +`npm install` + +`npm start` + +The default place for the proxy when its started is `http://localhost:8080` but feel free to change it in config.json! + +# How the proxy works: + +The proxy works by using node-fetch (Basically Window.fetch ported to Node-js). +Basically what the app is doing is node-fetch is sending the request to the server then +the app sends the response back to the server with the modifactions made to the attributes and elements. + +When a attribute is rewritten, depending on the contents inside. It will turn: + +`href="/assets/js/main.js"` into `href="/fetch/websiteURL/assets/js/main.js"`. + +A porition of its rewriting is in client-side JS so `Element.setAttribute`, `window.fetch()`, XMLHttpRequest, and more are rewritten. + +# Extra information: + +If your gonna have an external website redirect to this proxy. Then we recommend you have the value base64 encoded and redirected to `/alloy?url=` then value. + +# Deploying to Heroku: + +If your gonna be hosting this on something like Heroku. You need to make sure SSL mode is turned off so this will work. + +# Known websites that work + +- Google Search + +- Discord + +- LittleBigSnake + +- Surviv.io + +- Youtube + +- Y8 + +- 1v1.LOL + +- Old Reddit + +and plenty more! + +# Known issues that need to be fixed + +- Better POST body parsing instead of using body-parser. + +- Cookie header rewriting + +# Updates to come in the future + +- Full URL encoding / encryption mode + +- Websocket proxing diff --git a/alloy/assets/error.html b/alloy/assets/error.html new file mode 100644 index 00000000..3577583a --- /dev/null +++ b/alloy/assets/error.html @@ -0,0 +1,88 @@ + + + + + + + + +
+

AlloyProxy

+
+

%ERROR%

+ + \ No newline at end of file diff --git a/alloy/assets/inject.js b/alloy/assets/inject.js new file mode 100644 index 00000000..76c28bac --- /dev/null +++ b/alloy/assets/inject.js @@ -0,0 +1,209 @@ +// Ajax Rewriting + +let apData = document.getElementById('alloyData'); +let urlData = apData.getAttribute('data-alloyURL'); + + +function rewriteURL(url, encoding) { + var websiteURL + if (encoding == 'base64') { + websiteURL = btoa(url.split('/').splice(0, 3).join('/')) + } else { + websiteURL = url.split('/').splice(0, 3).join('/') + } + const path = '/' + url.split('/').splice(3).join('/') + var rewritten + if (path == '/') { + rewritten = '/fetch/' + websiteURL + } else { + rewritten = `/fetch/${websiteURL}${path}` + } + return rewritten +} +let ajaxRewrite = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) { + if (url.startsWith(`${window.location.protocol}//${window.location.hostname}`) && !url.startsWith(`${window.location.protocol}//${window.location.hostname}/fetch/`)) { + url = `/fetch/${urlData}/` + url.split('/').splice(3).join('/') + } else if (url.startsWith('http')) { + const hostname = url.split('/').slice(0, 3).join('/') + const path = url.split('/').slice(3).join('/') + const encodedHost = btoa(hostname) + const fullURL = encodedHost + '/' + path + url = '/fetch/' + fullURL + } else if (url.startsWith('//')) { + const encodedURL = btoa('http:' + url) + url = '/alloy/?url=' + encodedURL + } else if (url.startsWith('/')) { + if (url.startsWith('/fetch')) { + url = url + } else if (url.startsWith('/alloy')) { + url = url + } else { + let apData = document.getElementById('alloyData'); + let urlData = apData.getAttribute('data-alloyURL'); + url = '/fetch/' + urlData + url + } + } + + + return ajaxRewrite.apply(this, arguments); + } + + let windowFetchRewrite = window.fetch;window.fetch = function(url) { + if (url.startsWith(`https://${window.location.hostname}`)) { + url = url + } else if (url.startsWith('http')) { + const hostname = url.split('/').slice(0, 3).join('/') + const path = url.split('/').slice(3).join('/') + const encodedHost = btoa(hostname) + const fullURL = encodedHost + '/' + path + url = '/fetch/' + fullURL + } else if (url.startsWith('//')) { + const encodedURL = btoa('http:' + url) + url = '/alloy/?url=' + encodedURL + } else if (url.startsWith('/')) { + if (url.startsWith('/fetch')) { + url = url + } else if (url.startsWith('/alloy')) { + url = url + } else { + let apData = document.getElementById('alloyData'); + let urlData = apData.getAttribute('data-alloyURL'); + url = '/fetch/' + urlData + url + } + } + return windowFetchRewrite.apply(this, arguments); + } + + + + //Create Element rewriting + var original = document.createElement; + document.createElement = function (tag) { + var element = original.call(document, tag); + if (tag.toLowerCase() === 'script') { + Object.defineProperty(element.__proto__, 'src', { + set: function(newValue) { + if (newValue.startsWith('/fetch/')) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith('/alloy/')) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith(`https://${window.location.hostname}`)) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith('//')) { + const encodedURL = btoa('http:' + newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('https://')) { + const encodedURL = btoa(newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('http://')) { + const encodedURL = btoa(newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('/')) { + element.setAttribute('src', '/fetch/' + urlData + newValue) + } else { + element.setAttribute('src', newValue) + } + } + }); + } else if (tag.toLowerCase() === 'iframe') { + Object.defineProperty(element.__proto__, 'src', { + set: function(newValue) { + if (newValue.startsWith('/fetch/')) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith('/alloy/')) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith(`https://${window.location.hostname}`)) { + element.setAttribute('src', newValue) + } else if (newValue.startsWith('//')) { + const encodedURL = btoa('http:' + newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('https://')) { + const encodedURL = btoa(newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('http://')) { + const encodedURL = btoa(newValue) + element.setAttribute('src', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('/')) { + element.setAttribute('src', '/fetch/' + urlData + newValue) + + } else { + element.setAttribute('src', newValue) + } + } + }); + } + else if (tag.toLowerCase() === 'link') { + Object.defineProperty(element.__proto__, 'href', { + set: function(newValue) { + if (newValue.startsWith('/fetch/')) { + element.setAttribute('href', newValue) + } else if (newValue.startsWith('/alloy/')) { + element.setAttribute('href', newValue) + } else if (newValue.startsWith(`https://${window.location.hostname}`)) { + element.setAttribute('href', newValue) + } else if (newValue.startsWith('//')) { + const encodedURL = btoa('http:' + newValue) + element.setAttribute('href', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('https://')) { + const encodedURL = btoa(newValue) + element.setAttribute('href', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('http://')) { + const encodedURL = btoa(newValue) + element.setAttribute('href', '/alloy/?url=' + encodedURL) + } else if (newValue.startsWith('/')) { + element.setAttribute('href', '/fetch/' + urlData + newValue) + + } else { + element.setAttribute('href', newValue) + } + } + }); + } + return element; + } + + + let setAttributeRewrite = window.Element.prototype.setAttribute;window.Element.prototype.setAttribute = function(name, value) { + switch(name) { + case 'src': + if (value.startsWith('/fetch/')) { + value = value + } else if (value.startsWith('/alloy/')) { + value = value + } else if (value.startsWith('//')) { + value = rewriteURL('http:' + value, 'base64') + } else if (value.startsWith('/')) { + value = rewriteURL(urlData + value) + break; + } else if (value.startsWith('https://') || value.startsWith('http://')) { + value = rewriteURL(value, 'base64') + } else { + value = value + } + break; + case 'href': + if (value.startsWith('/fetch/')) { + value = value + } else if (value.startsWith('//')) { + value = rewriteURL('http:' + value, 'base64') + } else if (value.startsWith('/')) { + value = rewriteURL(urlData + value) + break; + } else if (value.startsWith('https://') || value.startsWith('http://')) { + value = rewriteURL(value, 'base64') + } else { + value = value + } + break; + } + + + return setAttributeRewrite.apply(this, arguments); + } + + var previousState = window.history.state; + setInterval(function() { + if (!window.location.pathname.startsWith(`/fetch/${urlData}/`)) { + history.replaceState('', '', `/fetch/${urlData}/${window.location.href.split('/').splice(3).join('/')}`); + } + }, 0.1); \ No newline at end of file diff --git a/app.js b/app.js index 3814769e..08442b89 100644 --- a/app.js +++ b/app.js @@ -1,79 +1,334 @@ -/*************** - * node-unblocker: Web Proxy for evading firewalls and content filters, - * similar to CGIProxy or PHProxy - * - * - * This project is hosted on github: https://github.com/nfriedly/nodeunblocker.com - * - * By Nathan Friedly - http://nfriedly.com - * Released under the terms of the Affero GPL v3 - */ - -var url = require('url'); -var querystring = require('querystring'); +var https = require('https'); +var http = require('http'); +var fetch = require('node-fetch'); var express = require('express'); -var unblocker = require('unblocker'); -var Transform = require('stream').Transform; - +var fs = require('fs'); var app = express(); +var cookieParser = require('cookie-parser'); +var session = require('express-session'); -var google_analytics_id = process.env.GA_ID || null; +var config = JSON.parse(fs.readFileSync('config.json', 'utf-8')), + httpsAgent = new https.Agent({ + rejectUnauthorized: false, + keepAlive: true, + }), + httpAgent = new http.Agent({ + rejectUnauthorized: false, + keepAlive: true, + }), + ssl = { key: fs.readFileSync('ssl/default.key', 'utf8'), cert: fs.readFileSync('ssl/default.crt', 'utf8') }, + server, + port = process.env.PORT || config.port, + ready = (() => { + var a = 'http://', b = config.listenip; + if (config.ssl) a = 'https://'; + if (b == '0.0.0.0' || b == '127.0.0.1') b = 'localhost'; + console.log('AlloyProxy is now running at', a + b + ':' + port); + }); -function addGa(html) { - if (google_analytics_id) { - var ga = [ - "" - ].join("\n"); - html = html.replace("", ga + "\n\n"); - } - return html; -} +http.globalAgent.maxSockets = Infinity; +https.globalAgent.maxSockets = Infinity; -function googleAnalyticsMiddleware(data) { - if (data.contentType == 'text/html') { +if (config.ssl) server = https.createServer(ssl, app).listen(port, config.listenip, ready); +else server = http.createServer(app).listen(port, config.listenip, ready); - // https://nodejs.org/api/stream.html#stream_transform - data.stream = data.stream.pipe(new Transform({ - decodeStrings: false, - transform: function(chunk, encoding, next) { - this.push(addGa(chunk.toString())); - next(); - } - })); - } -} +app.use(cookieParser()); +app.use(session({ +secret: 'alloy', +saveUninitialized: true, +resave: true +})); -var unblockerConfig = { - prefix: '/call/', - responseMiddleware: [ - googleAnalyticsMiddleware - ] -}; - - - -// this line must appear before any express.static calls (or anything else that sends responses) -app.use(unblocker(unblockerConfig)); - -// serve up static files *after* the proxy is run -app.use('/', express.static(__dirname + '/public')); - -// this is for users who's form actually submitted due to JS being disabled or whatever -app.get("/b", function(req, res) { - // grab the "url" parameter from the querystring - var site = querystring.parse(url.parse(req.url).query).url; - // and redirect the user to /proxy/url - res.redirect(unblockerConfig.prefix + site); +app.use((req, res, next)=>{ + // nice bodyparser alternative that wont cough up errors + + req.setEncoding('utf8'); + req.raw_body = '' + req.body = new Object() + + req.on('data', chunk=>{ req.raw_body += chunk }); + + req.on('end', ()=>{ + req.str_body = req.raw_body.toString('utf8'); + + try{ + var result = new Object(); + + req.str_body.split('&').forEach((pair)=>{ + pair = pair.split('='); + req.body[pair[0]] = decodeURIComponent(pair[1] || ''); + }); + }catch(err){ + req.body = {} + } + + return next(); + }); }); -// for compatibility with gatlin and other servers, export the app rather than passing it directly to http.createServer -module.exports = app; \ No newline at end of file +function base64Encode(data) { + return new Buffer.from(data).toString('base64') +} + +// How to use: base64Decode('string') will return any input base64 decoded +function base64Decode(data) { + return new Buffer.from(data, 'base64').toString('ascii') +} + +// How to use: rewritingURL('https://example.org/assets/main.js') will rewrite any external URL. Output: aHR0cHM6Ly9leGFtcGxlLm9yZw==/assets/main.js +function rewriteURL(dataURL, option) { + var websiteURL + var websitePath + if (option == 'decode') { + websiteURL = base64Decode(dataURL.split('/').splice(0, 1).join('/')) + websitePath = '/' + dataURL.split('/').splice(1).join('/') + } else { + websiteURL = base64Encode(dataURL.split('/').splice(0, 3).join('/')) + websitePath = '/' + dataURL.split('/').splice(3).join('/') + } + if (websitePath == '/') { + return `${websiteURL}` + } else return `${websiteURL}${websitePath}` +} + +// To be used with res.send() to send error. Example: res.send(error('404', 'No valid directory or file was found!')) +function error(statusCode, info) { + if (statusCode && info) { + return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error ${statusCode}: ${info}`) + } + if (info && !statusCode) { + return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error: ${info}`) + } + if (statusCode && !info) { + return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error ${statusCode}`) + } + return fs.readFileSync('public/assets/error.html', 'utf8').toString().replace('%ERROR%', `An error has occurred!`) +} + +app.post('/createSession', async (req, res) => { + if (req.body.url.startsWith('//')) { + req.body.url = 'http:' + req.body.url; + } else if (req.body.url.startsWith('https://') || req.body.url.startsWith('http://')) { + req.body.url = req.body.url; + } else { + req.body.url = 'http://' + req.body.url; + } + if (req.body.rv) { + req.session.rvURL = String(req.body.url).split('/').splice(0, 3).join('/') + return res.redirect('/fetch/rv/' + String(req.body.url).split('/').splice(3).join('/')) + } else { + return res.redirect('/fetch/' + rewriteURL(String(req.body.url))) + } +}) + +var prefix = '/fetch'; + +app.use(prefix, async (req, res, next) => { + var location = rewriteURL(req.url.slice(1), 'decode'); + if (req.url.startsWith('/rv') && !req.session.rvURL) { + res.send(error('400', 'No valid session URL for reverse proxy mode was found!')) + } + if (req.url.startsWith('/rv') && req.session.rvURL) { + location = req.session.rvURL + req.url.slice(3) + } + location = { + href: location, + hostname : location.split('/').splice(2).splice(0, 1).join('/'), + origin : location.split('/').splice(0, 3).join('/'), + origin_encoded : base64Encode(location.split('/').splice(0, 3).join('/')), + path : '/' + location.split('/').splice(3).join('/'), + protocol : location.split('\:').splice(0, 1).join(''), + } + var httpAgent = new http.Agent({ + keepAlive: true + }); + var httpsAgent = new https.Agent({ + keepAlive: true + }); + + var fetchHeaders = req.headers + fetchHeaders['referer'] = location.href + fetchHeaders['origin'] = location.origin + fetchHeaders['host'] = location.hostname + if (fetchHeaders['cookie']) { + delete fetchHeaders['cookie'] + } + var options = { + method: req.method, + headers: fetchHeaders, + redirect: 'manual', + agent: function(_parsedURL) { + if (_parsedURL.protocol == 'http:') { + return httpAgent; + } else { + return httpsAgent; + } + } + }; + + if (req.method == 'POST') { + // Have to do try catch for this POST data parser until we create our own one that won't have a syntax error sometimes. + try { + // str_body is a string containing the requests body + options['body'] = req.str_body; + }catch(err){ + return; + } + } + if (req.url.startsWith('/rv')) { + location.origin_encoded = 'rv' + } + if (!req.url.startsWith(`/${location.origin_encoded}/`)) { + try{ + return res.redirect(307,`/fetch/${location.origin_encoded}/`) + }catch(err){ + return; + } + } + if (location.href == 'https://discord.com' || location.href == 'https://discord.com/new') { + return res.redirect(307, `/fetch/${location.origin_encoded}/login`) + } + if (location.origin == 'https://www.reddit.com') { + if (req.url.startsWith('/rv') && req.session.rvURL) { + req.session.rvURL = 'https://old.reddit.com' + return res.redirect(307, '/fetch/rv' + location.path) + } + return res.redirect(307, '/fetch/' + base64Encode('https://old.reddit.com') + location.path) + } + const response = await fetch(location.href, options).catch(err => res.send(error('404', `"${location.href}" was not found!`))); + if(typeof response.buffer != 'function')return; + var resbody = await response.buffer(); + var contentType = 'text/plain' + + response.headers.forEach((e, i, a) => { + if (i == 'content-type') contentType = e; + }); + if (contentType == null || typeof contentType == 'undefined') ct = 'text/html'; + var serverHeaders = Object.fromEntries( + Object.entries(JSON.parse(JSON.stringify(response.headers.raw()))) + .map(([key, val]) => [key, val[0]]) + ); + if (serverHeaders['location']) { + if (req.url.startsWith('/rv') && req.session.rvURL) { + req.session.rvURL = String(serverHeaders['location']).split('/').splice(0, 3).join('/') + return res.redirect(307, '/fetch/rv/' + String(serverHeaders['location']).split('/').splice(3).join('/')) + } else return res.redirect(307, '/fetch/' + rewriteURL(String(serverHeaders['location']))) + } + delete serverHeaders['content-encoding'] + delete serverHeaders['x-frame-options'] + delete serverHeaders['strict-transport-security'] + delete serverHeaders['content-security-policy'] + delete serverHeaders['location'] + res.status(response.status) + res.set(serverHeaders) + res.contentType(contentType) + if (response.redirected == true) { + if (req.url.startsWith('/rv') && req.session.rvURL) { + req.session.rvURL = response.url.split('/').splice(0, 3).join('/') + return res.redirect(307, '/fetch/rv/' + response.url.split('/').splice(3).join('/')) + } else return res.redirect(307, '/fetch/' + rewriteURL(response.url)) + } + if (contentType.startsWith('text/html')) { + req.session.fetchURL = location.origin_encoded + resbody = resbody.toString() + .replace(/integrity="(.*?)"/gi, '') + .replace(/nonce="(.*?)"/gi, '') + .replace(/(href|src|poster|data|action)="\/\/(.*?)"/gi, `$1` + `="http://` + `$2` + `"`) + .replace(/(href|src|poster|data|action)='\/\/(.*?)'/gi, `$1` + `='http://` + `$2` + `'`) + .replace(/(href|src|poster|data|action)="\/(.*?)"/gi, `$1` + `="/fetch/${location.origin_encoded}/` + `$2` + `"`) + .replace(/(href|src|poster|data|action)='\/(.*?)'/gi, `$1` + `='/fetch/${location.origin_encoded}/` + `$2` + `'`) + .replace(/'(https:\/\/|http:\/\/)(.*?)'/gi, function(str) { + str = str.split(`'`).slice(1).slice(0, -1).join(``); + return `'/fetch/${rewriteURL(str)}'` + }) + .replace(/"(https:\/\/|http:\/\/)(.*?)"/gi, function(str) { + str = str.split(`"`).slice(1).slice(0, -1).join(``); + return `"/fetch/${rewriteURL(str)}"` + }) + .replace(/(window|document).location.href/gi, `"${location.href}"`) + .replace(/(window|document).location.hostname/gi, `"${location.hostname}"`) + .replace(/(window|document).location.pathname/gi, `"${location.path}"`) + .replace(/location.href/gi, `"${location.href}"`) + .replace(/location.hostname/gi, `"${location.hostname}"`) + .replace(/location.pathname/gi, `"${location.path}"`) + .replace(//gi, '') + + } else if (contentType.startsWith('text/css')) { + resbody = resbody.toString() + .replace(/url\("\/\/(.*?)"\)/gi, `url("http://` + `$1` + `")`) + .replace(/url\('\/\/(.*?)'\)/gi, `url('http://` + `$1` + `')`) + .replace(/url\(\/\/(.*?)\)/gi, `url(http://` + `$1` + `)`) + .replace(/url\("\/(.*?)"\)/gi, `url("/fetch/${location.origin_encoded}/` + `$1` + `")`) + .replace(/url\('\/(.*?)'\)/gi, `url('/fetch/${location.origin_encoded}/` + `$1` + `')`) + .replace(/url\(\/(.*?)\)/gi, `url(/fetch/${location.origin_encoded}/` + `$1` + `)`) + .replace(/"(https:\/\/|http:\/\/)(.*?)"/gi, function(str) { + str = str.split(`"`).slice(1).slice(0, -1).join(``); + return `"/fetch/${rewriteURL(str)}"` + }) + .replace(/'(https:\/\/|http:\/\/)(.*?)'/gi, function(str) { + str = str.split(`'`).slice(1).slice(0, -1).join(``); + return `'/fetch/${rewriteURL(str)}'` + }) + .replace(/\((https:\/\/|http:\/\/)(.*?)\)/gi, function(str) { + str = str.split(`(`).slice(1).join(``).split(')').slice(0, -1).join(''); + return `(/fetch/${rewriteURL(str)})` + }) + + } else if (contentType.startsWith('text/javascript') || contentType.startsWith('application/javascript')) { + resbody = resbody.toString() + .replace(/xhttp.open\("GET",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("GET",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + .replace(/xhttp.open\("POST",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("POST",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + .replace(/xhttp.open\("OPTIONS",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("OPTIONS",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + + .replace(/xhr.open\("GET",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("GET",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + .replace(/xhr.open\("POST",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("POST",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + .replace(/xhr.open\("OPTIONS",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("OPTIONS",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true') + .replace(/ajax\("http:\/\/(.*?)"\)/gi, 'ajax("/alloy/url/http://' + '$1' + '")') + .replace(/ajax\("https:\/\/(.*?)"\)/gi, 'ajax("/alloy/url/https://' + '$1' + '")') + } + res.send(resbody) +}) + +app.use('/alloy/url/',function (req, res, next) { + const mainurl = req.url.split('/').slice(1).join('/') + const host = mainurl.split('/').slice(0, 3).join('/') + const buff = new Buffer(host); + const host64 = buff.toString('base64'); + const path = mainurl.split('/').slice(3).join('/') + const fullURL = host64 + '/' + path + res.redirect(307, '/fetch/' + fullURL) +}) + + +app.use('/alloy/',function (req, res, next) { + +if (req.query.url) { +var clientInput = base64Decode(req.query.url) +var fetchURL; +if (clientInput.startsWith('//')) { + fetchURL = rewriteURL('http:' + clientInput) +} else if (clientInput.startsWith('http://') || clientInput.startsWith('https://')) { + fetchURL = rewriteURL(clientInput) +} else { + fetchURL = rewriteURL('http://' + clientInput) +} + return res.redirect(307, '/fetch/' + fetchURL) +} +res.sendFile(__dirname + '/alloy' + req.url, function (err) { + if (err) { + if (req.session.fetchURL) { + return res.redirect(307, '/fetch/' + req.session.fetchURL + req.url) + } else return res.redirect(307, '/') + } +}) + +}) + + +app.use(express.static('public')) + +app.use(function (req, res ,next) { + if (req.session.fetchURL) { + return res.redirect(307, '/fetch/' + req.session.fetchURL + req.url) + } else return res.send(error('404', 'No valid directory or file was found!')) +}) \ No newline at end of file diff --git a/app.json b/app.json index 3bf755db..7dcc9345 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,7 @@ { - "name": "Holy Unblocker", - "description": "A website that can be used to bypass web filters; both online and firewall.", - "repository": "https://github.com/QuiteAFancyEmerald/HolyUB" -} \ No newline at end of file + "name": "Alloy Proxy", + "description": "A node.js web proxy featuring URL encoding, and amazing compatablity!", + "repository": "https://github.com/titaniumnetwork-dev/alloyproxy/", + "logo": "https://avatars1.githubusercontent.com/u/47227492?s=200&v=4", + "keywords": ["node", "proxy", "unblocker"] +} diff --git a/config.json b/config.json new file mode 100644 index 00000000..ca8b4a47 --- /dev/null +++ b/config.json @@ -0,0 +1,5 @@ +{ + "listenip":"0.0.0.0", + "port":8080, + "ssl":false +} diff --git a/newrelic.js b/newrelic.js deleted file mode 100644 index 655d4250..00000000 --- a/newrelic.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * New Relic agent configuration. - * - * See lib/config.defaults.js in the agent distribution for a more complete - * description of configuration variables and their potential values. - */ -exports.config = { - /** - * Array of application names. - */ - app_name: ['Node Unblocker'], - /** - * Your New Relic license key. - */ - license_key: process.env.NEW_RELIC_LICENSE_KEY, - logging: { - /** - * Level at which to log. 'trace' is most useful to New Relic when diagnosing - * issues with the agent, 'info' and higher will impose the least overhead on - * production applications. - */ - level: 'info' - } -}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 84a02bee..d968370f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "nodeunblocker.com", + "name": "alloyproxy", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -18,11 +18,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -63,6 +58,15 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, + "cookie-parser": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz", + "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6" + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -143,6 +147,33 @@ "vary": "~1.1.2" } }, + "express-session": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", + "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.0", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + } + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -157,6 +188,11 @@ "unpipe": "~1.0.0" } }, + "follow-redirects": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", + "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -167,14 +203,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "gatling": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gatling/-/gatling-1.2.0.tgz", - "integrity": "sha1-rCDViqwTo82ntjtc0rO247MLEHw=", - "requires": { - "optimist": "~0.6.0" - } - }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -205,11 +233,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -243,11 +266,6 @@ "mime-db": "1.44.0" } }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -258,148 +276,10 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "newrelic": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/newrelic/-/newrelic-1.40.0.tgz", - "integrity": "sha1-JUjfFMRB6/ydO465idE397aaHW8=", - "requires": { - "concat-stream": "^1.5.0", - "https-proxy-agent": "^0.3.5", - "json-stringify-safe": "^5.0.0", - "readable-stream": "^1.1.13", - "semver": "^5.3.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.0", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "readable-stream": { - "version": "2.2.11", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.0.1", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true - }, - "string_decoder": { - "version": "1.0.2", - "bundled": true, - "requires": { - "safe-buffer": "~5.0.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - } - } - }, - "typedarray": { - "version": "0.0.6", - "bundled": true - } - } - }, - "https-proxy-agent": { - "version": "0.3.6", - "bundled": true, - "requires": { - "agent-base": "~1.0.1", - "debug": "2", - "extend": "3" - }, - "dependencies": { - "agent-base": { - "version": "1.0.2", - "bundled": true - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - }, - "extend": { - "version": "3.0.1", - "bundled": true - } - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - } - } - }, - "semver": { - "version": "5.3.0", - "bundled": true - } - } + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "on-finished": { "version": "2.3.0", @@ -409,14 +289,15 @@ "ee-first": "1.1.1" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "parse-raw-http": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/parse-raw-http/-/parse-raw-http-0.0.1.tgz", + "integrity": "sha512-GndQvIQXviId7eHnc+fEcmtEjkj1tQ96EhNOplPwXA8L1jgOnrlx/xLmmOEew8Yj4ZoZpmoAh0IvypAaeMbILg==" }, "parseurl": { "version": "1.3.3", @@ -442,6 +323,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -506,11 +392,6 @@ "send": "0.17.1" } }, - "set-cookie-parser": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.6.tgz", - "integrity": "sha512-mNCnTUF0OYPwYzSHbdRdCfNNHqrne+HS5tS5xNb6yJbdP9wInV0q5xPLE0EyfV/Q3tImo3y/OXpD8Jn0Jtnjrg==" - }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -521,16 +402,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tld": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/tld/-/tld-0.0.2.tgz", - "integrity": "sha1-9g442CzaB14NzHlgHOXWgpzASd4=" - }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -545,48 +416,12 @@ "mime-types": "~2.1.24" } }, - "unblocker": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/unblocker/-/unblocker-2.0.5.tgz", - "integrity": "sha512-dzt6dcfzC7W8MZ04nxsAKwF4uJBaYPLpZyab0pXdwTDVrJrxwU79PWO2ayxl9cavVAW4a7jJW7TSySDWibVmHA==", + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", "requires": { - "async": "^3.1.0", - "content-type": "^1.0.4", - "cookie": "^0.4.0", - "debug": "^4.1.1", - "iconv-lite": "^0.5.0", - "lodash": "^4.17.15", - "mime": "^2.4.4", - "set-cookie-parser": "^2.4.1", - "tld": "0.0.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "iconv-lite": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", - "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "random-bytes": "~1.0.0" } }, "unpipe": { @@ -603,11 +438,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" } } } diff --git a/package.json b/package.json index 2f9ffbed..92797b82 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,32 @@ { - "name": "nodeunblocker.com", - "description": "Web proxy for evading internet censorship", - "author": "Nathan Friedly - http://nfriedly.com", + "name": "alloyproxy", "version": "1.0.0", - "private": true, - "homepage": "https://github.com/nfriedly/nodeunblocker.com/", - "dependencies": { - "express": "^4.13.0", - "gatling": "~1.2.0", - "newrelic": "^1.20.2", - "through": "^2.3.8", - "unblocker": "*" - }, - "engines": { - "node": ">=6" - }, + "description": "A powerful web proxy!", + "main": "app.js", "scripts": { - "start": "node ./node_modules/gatling/gatling.js ./app.js" + "test": "proxy", + "start": "node app.js" }, - "license": "AGPL-3.0" + "repository": { + "type": "git", + "url": "git+https://github.com/titaniumnetwork-dev/alloyproxy.git" + }, + "keywords": [ + "web-proxy" + ], + "author": "titaniumnetwork-dev", + "license": "ISC", + "bugs": { + "url": "https://github.com/titaniumnetwork-dev/alloyproxy/issues" + }, + "homepage": "https://github.com/titaniumnetwork-dev/alloyproxy#readme", + "dependencies": { + "body-parser": "^1.19.0", + "cookie-parser": "^1.4.5", + "express": "^4.17.1", + "express-session": "^1.17.1", + "follow-redirects": "^1.13.0", + "node-fetch": "^2.6.0", + "parse-raw-http": "0.0.1" + } } diff --git a/LICENSE b/public/LICENSE similarity index 100% rename from LICENSE rename to public/LICENSE diff --git a/public/a.html b/public/a.html index 64b400df..7324509a 100644 --- a/public/a.html +++ b/public/a.html @@ -65,7 +65,7 @@ var url = $('url').value; var det = document.domain; var domain = det.replace('www.', '').split(/[/?#]/)[0]; - window.location.href = "https://a." + domain + "/alloy?url=" + url; + window.location.href = "https://" + domain + "/alloy?url=" + url; return false; }; window.onload = function() { diff --git a/ssl/default.crt b/ssl/default.crt new file mode 100644 index 00000000..46160ee6 --- /dev/null +++ b/ssl/default.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIJAJnCkScWtmL0MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRgwFgYDVQQKDA9UaXRhbml1bU5l +dHdvcmsxDjAMBgNVBAsMBWdhbWVyMR4wHAYDVQQDDBUqLnRpdGFuaXVtbmV0d29y +ay5vcmcwHhcNMjAwNjEzMTg0OTU2WhcNMjEwNjEzMTg0OTU2WjBsMQswCQYDVQQG +EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEYMBYGA1UECgwPVGl0YW5pdW1OZXR3 +b3JrMQ4wDAYDVQQLDAVnYW1lcjEeMBwGA1UEAwwVKi50aXRhbml1bW5ldHdvcmsu +b3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPL69+RE6r8RrFh4 +njzC8ZRnLB+yNtuGw14C0dvNb5JwgdLl5g9/wK/s0V5NGlqwxlQlxQ/gUSuYEcUR +6MYjcnaUmZZe/gaKVV0fkfkuigOWhLnI5AQxx7rhkzx1ujuyJ9D2pkDtZpSvv0yn +2yrvWhJMtjuxGYip8jaLuRpbXoafvR7nrlDaNcE/GwIjnCCxsRnY2bGbxYK840mN +fuMfF2nz+fXKPuQ/9PT48e3wOo9vM5s7yKhiHYwrogqzGN4cH4sSr1FE8C7flFyT +Yw101u7fUaopfeGCo9Pg6IrfzyzE5Qb7OlqlVk2IkvXx7pPqVc6lZCJEhOX/qF9o +n3mFqwIDAQABo1AwTjAdBgNVHQ4EFgQUC561ob2kGtFQ4az6y64b98+Fy+IwHwYD +VR0jBBgwFoAUC561ob2kGtFQ4az6y64b98+Fy+IwDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAQEAotvUsSLSzFyxQz329tEPyH6Tmi19FQoA5ZbLg6EqeTI9 +08qOByDGkSYJi0npaIlPO1I557NxRzdO0PxK3ybol6lnzuSlqCJP5nb1dr0z2Eax +wgKht9P+ap/yozU5ye05ah2nkpcaeDPnwnnWFmfsnYNfgu62EshOS+5FETWEKVUb +LXQhGInOdJq8KZvhoLZWJoUhyAqxBfW4oVvaqs+Ff96A2NNKrvbiAVYX30rVa+x0 +KIl0/DoVvDx2Q6TiL396cAXdKUW7edRQcSsGFcxwIrU5lePm0V05aN+oCoEBvXBG +ArPN+a5kpGjJwfcpcBVf9cJ6IsvptGS9de3eTHoTyw== +-----END CERTIFICATE----- diff --git a/ssl/default.key b/ssl/default.key new file mode 100644 index 00000000..59032b52 --- /dev/null +++ b/ssl/default.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDA8vr35ETqvxGs +WHiePMLxlGcsH7I224bDXgLR281vknCB0uXmD3/Ar+zRXk0aWrDGVCXFD+BRK5gR +xRHoxiNydpSZll7+BopVXR+R+S6KA5aEucjkBDHHuuGTPHW6O7In0PamQO1mlK+/ +TKfbKu9aEky2O7EZiKnyNou5Gltehp+9HueuUNo1wT8bAiOcILGxGdjZsZvFgrzj +SY1+4x8XafP59co+5D/09Pjx7fA6j28zmzvIqGIdjCuiCrMY3hwfixKvUUTwLt+U +XJNjDXTW7t9Rqil94YKj0+Doit/PLMTlBvs6WqVWTYiS9fHuk+pVzqVkIkSE5f+o +X2ifeYWrAgMBAAECggEAbihK8Ev6rKr5RBQeiPjXs2SuoppV/MvIXLHHmliLKS/J +29S0PGyM202VPtM/4dP1KMXR6nft8WmaIEsKtoKoqijZHfajtRO21pWb+JLy5wi1 +XoFTGBrs8MLZFl5mODTsuZ6rsq9O2kn5LJZvHsmcbSgVc9UQfytvG0HY840ArS3g +kSDtUFb1xRui6wtCBKzHVvCT+FXhSBbwkHalmbqP6BefhJ3lW2VonkOcHDrdXPfW +CEN18IJ2v8QYgXqZP6VUlAweNXLJ33ZOl+jXGdygcOG24MFqdw0VtP0XFGk0jnSS +W6dX67BZKeZ71EKaTy02jw5LpQNXA70ismPJHQ2uQQKBgQDuROawnBIW1fC3xOle +m+JmP0eMe0eIQycxRsMXsXhYAA0wV3qYZSLZrNK2eRhmSNt+ODSmZ2Vt11dwOv5u +bo8WONrRlM097SmitS2S+8o7ASem2VKQzyRE72Y9517Q+aNBdLRVtjrRNSw/hfSu +ayLuG36+yukSH7wq7mfoUX34ZwKBgQDPTrgyyw8n5XhZT/qTTRnQJ2GTvPxDzNoJ +IAGhGJGFAb6wgLoSpGx6BC122vuRxcTjkjAiMDci5N2zNW+YZVni+F0KTVvNFfU2 +pOTJUg3luRTygCra6O02PxwpbP/9KCBAKq/kYw/eBW+gxhPwP3ZrbAirvBjgBh0I +kIrFijNOHQKBgGUUAbFGZD4fwCCVflLOWnr5uUaVPcFGi6fR1w2EEgNy8iVh1vYz +YVdqg3E5aepqWgLvoRY+or64LbXEsQ70A+tvbxSdxXvR0mnd5lmGS0JAuSuE4gvg +dAhybrMwJf8NB/7KnX4G8mix3/WKxEQB2y2bqGcT+U/g+phTzuy1NXVdAoGBAIrl +jVjK4J60iswcYCEteWwT1rbr2oF60WNnxG+xTF63apJLzWAMNnoSLnwCAKgMv/xR +yFo/v9FrUnduCBUtYupFyeDLMATa/27bUEbq6VDPjw9jfFMr2TONWUsQMvvlVKZp +c2wsS0dQkRhBXr6LZsZWngCiiHAg6HcCkVgFXpapAoGBAJ/8oLGt0Ar+0MTl+gyk +xSqgHnsc5jgqhix3nIoI5oEAbfibdGmRD1S3rtWD9YsnPxMIl+6E5bOAHrmd+Zr8 +O7EP+CLvbz4JXidaaa85h9ThXSG5xk1A1UTtSFrp+KolLE1Vvmjjd+R844XsM2wZ +OAHbihzk0iPPphjEWR4lU4Av +-----END PRIVATE KEY----- diff --git a/ssl/localhost.crt b/ssl/localhost.crt new file mode 100644 index 00000000..3e747d04 --- /dev/null +++ b/ssl/localhost.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAaugAwIBAgIJAMN1fA0fbQDSMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV +BAMTCWxvY2FsaG9zdDAeFw0yMDA2MDcyMDIyMDRaFw0zMDA2MDUyMDIyMDRaMBQx +EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAPVHYq820Hi8Vy4ZAgmH/0Cl51TxWIWeoEgyQZEErgm1Vv49KuM0I1Ejk23+ ++tbKxY489dc7Gj/PqPv5F7SASNcxcKi5zbJPC6eEJBh2lHh6ldzF1aMfaYnuh25a +3uhzoLpZPRsoTBysXkQZqC/6ZP6kBcwJnMZd12Uj4JIbdJwpyUorOYOv4GO6f7SA +dUPUhSJpfUMZ4EFnkgrGJ18iqml/afhKj0g6KDxDGc1l2ioVMxiSjEfP06mbfkZ4 +zG16CmfITgyBFv8J9eF7exHCzqhbzgqWSfUNKazEKMbfCoegeZI196xtGIUbPYcf +U8a5M+/pSmojMvdqsppqro0qwa0CAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9jYWxo +b3N0MA0GCSqGSIb3DQEBBQUAA4IBAQBazEct+iiNe7/TY7c+l8wQBaCIhLtWxmfA +JLGBu5Jt+HPAMskU5+rK0nWPMIW5le+xhHXXRnmjqH1pm157hR1LvanLoHpWsPTc +eNx7utePC49t77UID1L2NHnmm9SAG/OhPJr3hh0AWG4GjJlWpK+9xeq7b9BoUsl7 +umU/X/02ZJmXWSwrqhspxtz3dSNaozAVVZs4Bokf7WiU27ACgffa7pCh9E8WTgyV +jkvG5ZbmOeje7n+Fa0PEbTrm8SBtF/Rn96VkoZGJBC4+wia/0T5Gmjk8Ds9VhjVK +bCyEsgPbkjwRdT/eRO4gEOgJI36CrheluWLnqjiidregyKYHQhwA +-----END CERTIFICATE----- diff --git a/ssl/localhost.key b/ssl/localhost.key new file mode 100644 index 00000000..729a1d4b --- /dev/null +++ b/ssl/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA9UdirzbQeLxXLhkCCYf/QKXnVPFYhZ6gSDJBkQSuCbVW/j0q +4zQjUSOTbf761srFjjz11zsaP8+o+/kXtIBI1zFwqLnNsk8Lp4QkGHaUeHqV3MXV +ox9pie6Hblre6HOgulk9GyhMHKxeRBmoL/pk/qQFzAmcxl3XZSPgkht0nCnJSis5 +g6/gY7p/tIB1Q9SFIml9QxngQWeSCsYnXyKqaX9p+EqPSDooPEMZzWXaKhUzGJKM +R8/TqZt+RnjMbXoKZ8hODIEW/wn14Xt7EcLOqFvOCpZJ9Q0prMQoxt8Kh6B5kjX3 +rG0YhRs9hx9Txrkz7+lKaiMy92qymmqujSrBrQIDAQABAoIBAQCQ6tFqlmdLvnN/ +3/StLvXn+12XeVUE9Xjbzx2gEfTF9adlZTxuqwJm0S8tISaRO5LHfEsAFIJoy0eb +QEv6MIVY53QZrFXVERDgs5kj/wOvvzXGD/kufMO9Y/oOgJANJSwEje8lmYSGuGyl +rccKOdXsAXsPV2qSZSV7M1xe1uvpyzpoUaX5aEfl44Kz1U6pURCpjqCj3OwVoaXa +vlnDSI7LArhvVTR2Xifl9/MSz1qGlnlKTJTUJi5z+XEnIEqZmhYQOUnp2Wi4KWOR +SqKnLOgfSJKb3yrdHukpLBsakF7U1urLB2wUjweZdn7zI9qbzIt9GIy1mRjYXTXL +YwPDFOfBAoGBAP5Pi3+E8HV2L+6XOl9MYtKxn2KRvHQdR13IepmF+umhOxjfc6uC +NhVeutfwuYfTXWmiEOHPKhH6NLloPbKkpfl6YxaKsAPfeEUI8PEA9J9TiNvGIP6m +MZVsp5VS4Q/O2UTT9SG5dc3zOMmys1CJMIDZkzvub9HY1EiAiqRY/y+RAoGBAPbo +e1yl/O2Z4L/ILaqo0QpIOgOdpWGZUIshUp5LEUzcYcflnCzdh1CYXWOAnPlvhh3H +k4rTBMWJ4DaFWdNhYcOLowu0pk1Cm9q0akarmCr0DhKj98qubU/0QdzJ9q80eqYA +3/pfFNs+baIGqcqOeD+da4ZrbLoefO7eBE1qJdpdAoGAFJjkt4NQ5nKYFz7wX1+U +cXQpcJZVKSJl8VaXd2++jsWcP7t5Zt64+qodf/fjTvjzi+awb1mUEritJIco2Bs1 +xir/c4fwEaA74XuD6EEnju/5GbPGYFmdknimahW4XMtoFYcFR6H5xKB6bPuoQlGa +OBVnM2dwbxKcvvKKSB1dLcECgYEAhQ4xdHMKwyv6Xr9MRLxmsijMAqjQt7C8I83Y +TO9dKlNU6jlFGTRkOD1zjix/6zd7Sc8EJnqjBqTPS/I+vteqrIsyWRuHxvjPLmOt +JdpQzUzpzIfJ/9JRnBWf7JB1vGMGeTDdgnn8rk2NHRSEKWDvUjDOAgkf9Yh6gOrp +3KIINg0CgYEA5VURroq8FtoLUeiyueKwJ8pBeWVa1IOy9OyG7MaebYVcs5XqDyMk +t/5dRHEbzjeM94qsi15BnwYtAy53RlIpA6VCsTxjgP53oj6emucoyj0eW4BRtTq1 +Er5OUU3Sl6JrILXmefjGTKha97boBWpUZQrJ/zgiqR4KvyGIBq4lqLo= +-----END RSA PRIVATE KEY-----