From 4569278daa22e99c182f7c7f0590de8eb2e1acb4 Mon Sep 17 00:00:00 2001 From: Sharky Date: Mon, 14 Sep 2020 16:15:31 -0400 Subject: [PATCH 1/4] WebRTC-Docker enabled for SSL + CA cert/key provided using Let'sEncrypt Pebble + SSL certs generated using hostname signed and deployed to /cert + GAE SSL params: dev_appserver.py /apprtc/out/app_engine --skip_sdk_update_check --enable_host_checking=False --host=0.0.0.0 --ssl_certificate_path=/cert/cert.pem --ssl_certificate_key_path=/cert/key.pem --specified_service_ports default:442 + Collider (WS server in SSL mode): /goWorkspace/bin/collidermain -port=8089 -tls=true --room-server=0.0.0.0 + ICE NodeJS app changed to start in HTTPS mode + run.sh changed to create host cert signed with CA certs using openssl + Docker file updated --- README.md | 29 +- apprtc-server/Dockerfile | 21 +- apprtc-server/apprtc_supervisord.conf | 4 +- apprtc-server/build.sh | 3 + apprtc-server/cert-pebble.pem | 20 + apprtc-server/chain-pebble.pfx | Bin 0 -> 3309 bytes apprtc-server/constants.py | 5 +- apprtc-server/docker-run.sh | 3 + apprtc-server/ice-http.js | 40 ++ apprtc-server/ice.js | 17 +- apprtc-server/key-pebble.pem | 27 ++ apprtc-server/run.sh | 29 +- apprtc-server/wsgi_server.py | 586 ++++++++++++++++++++++++++ 13 files changed, 773 insertions(+), 11 deletions(-) create mode 100644 apprtc-server/build.sh create mode 100644 apprtc-server/cert-pebble.pem create mode 100644 apprtc-server/chain-pebble.pfx create mode 100644 apprtc-server/docker-run.sh create mode 100644 apprtc-server/ice-http.js create mode 100644 apprtc-server/key-pebble.pem create mode 100644 apprtc-server/wsgi_server.py diff --git a/README.md b/README.md index b870e95..f62210d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,19 @@ -# WebRTC-Docker +# WebRTC-Docker for SSL -Out-of-the-box docker images for AppRTC dev/test purpose. +Out-of-the-box docker images for AppRTC dev/test purposes. Updated for SSL support. + ++ Deploy the super slick https://appr.tc/ in your local docker env for personal enjoyment. ++ Note: FireFox/Chrome require valid SSL certificates to open WebRTC Audio/Video streams and thus run AppRTC + +SSL Changes: + ++ CA cert/key provided using Let'sEncrypt Pebble ++ SSL certs generated using hostname signed and deployed to /cert ++ GAE SSL params: dev_appserver.py /apprtc/out/app_engine --skip_sdk_update_check --enable_host_checking=False --host=0.0.0.0 --ssl_certificate_path=/cert/cert.pem --ssl_certificate_key_path=/cert/key.pem --specified_service_ports default:442 ++ Collider (WS server in SSL mode): /goWorkspace/bin/collidermain -port=8089 -tls=true --room-server=0.0.0.0 ++ ICE NodeJS app changed to start in HTTPS mode ++ run.sh changed to create host cert signed with CA certs using openssl ++ Docker file updated ## AppRTC-Server @@ -22,6 +35,18 @@ docker run --rm --net=host \ -it piasy/apprtc-server ``` +Manual build Linux host (must have docker installed): ++ Copy files to your Linux host ++ chmod +x *.sh ++ Run the bash commands below ++ Install the CA certificate (chain-pebble.pfx) in your FF/Chrome cert store ++ Open https://MYHOSTNAME/ + +``` bash +$ sudo ./build.sh # or docker build -t webrtc . (takes 5mins to build) +$ sudo ./docker-run.sh # create SSL certs for hostname and start servers +``` + About port publish: + TCP `8080` is used for room server; diff --git a/apprtc-server/Dockerfile b/apprtc-server/Dockerfile index 7bea002..c25cd09 100644 --- a/apprtc-server/Dockerfile +++ b/apprtc-server/Dockerfile @@ -5,7 +5,7 @@ EXPOSE 8080 8089 3478 3033 59000-65000 WORKDIR / -ENV GAE_VER 1.9.74 +ENV GAE_VER 1.9.91 ENV GOLANG_VER 1.8.3 ENV LIBEVENT_VER 2.1.8 ENV COTURN_VER 4.5.0.7 @@ -15,11 +15,24 @@ ENV PUBLIC_IP 127.0.0.1 RUN apt-get update -y # Deps -RUN apt-get install -y build-essential vim git curl wget unzip python2.7 python-pil python-webtest python-pip libssl-dev openjdk-8-jdk && \ +RUN apt-get install -y build-essential vim git curl wget unzip python2.7 python-pil python-webtest python-pip libssl-dev openjdk-8-jdk apache2 && \ rm -rf /usr/lib/python2.7/dist-packages/supervisor* && \ pip install supervisor requests && \ pip install git+https://github.com/bendikro/supervisord-dependent-startup +########### Apache2 SSL vsilva +RUN a2enmod proxy* ssl headers +RUN a2ensite *ssl + +# apache 2 proxy SSL -> 8080 +#COPY apache2-proxy.conf /etc/apache2/conf-enabled + +# WS copy CA ssl certs +RUN mkdir -p /cert +COPY cert-pebble.pem /cert +COPY key-pebble.pem /cert +########### + # NodeJS RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - RUN apt-get install -y nodejs @@ -37,6 +50,7 @@ ENV GAE_ZIP google_appengine_$GAE_VER.zip RUN wget https://storage.googleapis.com/appengine-sdks/featured/$GAE_ZIP RUN unzip $GAE_ZIP -d /usr/local ENV PATH $PATH:/usr/local/google_appengine +COPY wsgi_server.py /usr/local/google_appengine/google/appengine/tools/devappserver2/ # Coturn server RUN wget https://github.com/libevent/libevent/releases/download/release-$LIBEVENT_VER-stable/libevent-$LIBEVENT_VER-stable.tar.gz @@ -80,6 +94,9 @@ RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* COPY apprtc_supervisord.conf / +# vsilva +RUN mkdir /webrtc_avconf + COPY run.sh / RUN chmod +x /run.sh CMD /run.sh diff --git a/apprtc-server/apprtc_supervisord.conf b/apprtc-server/apprtc_supervisord.conf index 87a6cdd..107dd24 100644 --- a/apprtc-server/apprtc_supervisord.conf +++ b/apprtc-server/apprtc_supervisord.conf @@ -36,7 +36,7 @@ autostart=false dependent_startup=true [program:collider] -command = /goWorkspace/bin/collidermain -port=8089 -tls=false --room-server=0.0.0.0 +command = /goWorkspace/bin/collidermain -port=8089 -tls=true --room-server=0.0.0.0 stdout_logfile = /webrtc_avconf/collider.log stdout_logfile_maxbytes = 20MB stdout_logfile_backups = 500 @@ -48,7 +48,7 @@ autostart=false dependent_startup=true [program:apprtc_rs] -command = dev_appserver.py /apprtc/out/app_engine --skip_sdk_update_check --enable_host_checking=False --host=0.0.0.0 +command = dev_appserver.py /apprtc/out/app_engine --skip_sdk_update_check --enable_host_checking=False --host=0.0.0.0 --ssl_certificate_path=/cert/cert.pem --ssl_certificate_key_path=/cert/key.pem --specified_service_ports default:442 stdout_logfile = /webrtc_avconf/apprtc_rs.log stdout_logfile_maxbytes = 20MB stdout_logfile_backups = 500 diff --git a/apprtc-server/build.sh b/apprtc-server/build.sh new file mode 100644 index 0000000..7ea61e2 --- /dev/null +++ b/apprtc-server/build.sh @@ -0,0 +1,3 @@ +# + +docker build -t webrtc . \ No newline at end of file diff --git a/apprtc-server/cert-pebble.pem b/apprtc-server/cert-pebble.pem new file mode 100644 index 0000000..20aef59 --- /dev/null +++ b/apprtc-server/cert-pebble.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjigAwIBAgIIEgmTTjWiyQAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVUGViYmxlIFJvb3QgQ0EgMTdkODIzMCAXDTIwMDkxMzAyNTcwNVoYDzIwNTAw +OTEzMDI1NzA1WjAoMSYwJAYDVQQDEx1QZWJibGUgSW50ZXJtZWRpYXRlIENBIDc5 +ZWQ4OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/lIebn+Ti8jPUP +pseY+Du73oWhzFmBtGyfG04alMG8PpUCDa+XclCTU4cmDo7ZL7+WaPFFymlKDfUl +GgmNjDEw0JmuBdy5rdXZxUngmX4qMYBq+pfvU/qKiI9DKYMq0+C0blSSitrr17I8 +vs3WrGvh59cmD0euBZPsRCy77Q7/1PrIDAHGUvctuZzbhMtrJRIFjU48k66tiOaE +6dZBYRVjwdzwULeUBUiqMNpg0J8iYwx85VSPIMwJKdFxCqP0hSJR+ATpYNfjqbTb +DOYaswiNbFXP5Y4R1TNZi7lT7MBTKKODjjVIgjju+x/qOW75gB2BCzD+rYZ9nEzZ +NrXzedECAwEAAaOBgzCBgDAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFqpcFY3 +K7Y6BhNXt1wffAV4PgdgMB8GA1UdIwQYMBaAFP5M3plGqHBGy2U27RipmWRqZV9r +MA0GCSqGSIb3DQEBCwUAA4IBAQAkSncjMv5pOA/3GR52GQgIEhB1NdxJkGRu6AQ+ +PDLsvTK1WsUJCJhkjB6xalmoFe2oetrVS4sGnkFEO3UNAJWGe7euoyfDufr/fXZ+ +X9ZEbVLuh57zpD5LFZwiMxd18U2BmDrDd9Qyx0V+hPjhOfAY/RfTgq8PdJ9m8IF2 +TF0QGPKr9XEjkdIe9QvCKN03lqHh75Ev7CQ2wirbmDSJF7mrAozdYDItojIGZxgr +hcJIghOO4O7GLeZQfB6IRozDk6dFdaEOZSEgaPbzGEm3HeImxtQPElY5WPJTxlub +2PXtg3FkFoir4UYjJeGtuDoF755uCFbSkVRzvlkJjq7WKP0Q +-----END CERTIFICATE----- diff --git a/apprtc-server/chain-pebble.pfx b/apprtc-server/chain-pebble.pfx new file mode 100644 index 0000000000000000000000000000000000000000..1e812a0b2f8546e44fe3c40468b4cdff77fe39ad GIT binary patch literal 3309 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 literal 0 HcmV?d00001 diff --git a/apprtc-server/constants.py b/apprtc-server/constants.py index 82c74dd..24fe312 100644 --- a/apprtc-server/constants.py +++ b/apprtc-server/constants.py @@ -37,7 +37,7 @@ # } # ] -ICE_SERVER_BASE_URL = 'http://SERVER_PUBLIC_IP:3033' +ICE_SERVER_BASE_URL = 'https://SERVER_PUBLIC_IP:3033' ICE_SERVER_URL_TEMPLATE = '%s/iceconfig?key=%s' ICE_SERVER_API_KEY = os.environ.get('ICE_SERVER_API_KEY') @@ -81,3 +81,6 @@ # BigQuery table within the dataset. BIGQUERY_TABLE = 'analytics' + +# vsilva +HEADER_MESSAGE = 'Web RTC' diff --git a/apprtc-server/docker-run.sh b/apprtc-server/docker-run.sh new file mode 100644 index 0000000..f52b76c --- /dev/null +++ b/apprtc-server/docker-run.sh @@ -0,0 +1,3 @@ +ip=`hostname -i` + +docker run --rm --net=host -e PUBLIC_IP=`hostname -i` -it webrtc \ No newline at end of file diff --git a/apprtc-server/ice-http.js b/apprtc-server/ice-http.js new file mode 100644 index 0000000..d469df3 --- /dev/null +++ b/apprtc-server/ice-http.js @@ -0,0 +1,40 @@ +var express = require('express') +var crypto = require('crypto') +var app = express() + +var hmac = function (key, content) { + var method = crypto.createHmac('sha1', key) + method.setEncoding('base64') + method.write(content) + method.end() + return method.read() +} + +function handleIceRequest(req, resp) { + var query = req.query + var key = '4080218913' + var time_to_live = 600 + var timestamp = Math.floor(Date.now() / 1000) + time_to_live + var turn_username = timestamp + ':ninefingers' + var password = hmac(key, turn_username) + + return resp.send({ + iceServers: [ + { + urls: [ + 'stun:SERVER_PUBLIC_IP:3478', + 'turn:SERVER_PUBLIC_IP:3478' + ], + username: turn_username, + credential: password + } + ] + }) +} + +app.get('/iceconfig', handleIceRequest) +app.post('/iceconfig', handleIceRequest) + +app.listen('3033', function () { + console.log('server started') +}) diff --git a/apprtc-server/ice.js b/apprtc-server/ice.js index d469df3..f90e424 100644 --- a/apprtc-server/ice.js +++ b/apprtc-server/ice.js @@ -1,6 +1,12 @@ var express = require('express') var crypto = require('crypto') var app = express() +const https = require("https"), fs = require("fs"); + +const options = { + key: fs.readFileSync("/cert/key.pem"), + cert: fs.readFileSync("/cert/cert.pem") +}; var hmac = function (key, content) { var method = crypto.createHmac('sha1', key) @@ -18,6 +24,13 @@ function handleIceRequest(req, resp) { var turn_username = timestamp + ':ninefingers' var password = hmac(key, turn_username) + // http://expressjs.com/en/4x/api.html#res.set + resp.set({ + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'DELETE,GET,PATCH,POST,PUT', + 'Access-Control-Allow-Headers': 'Content-Type,Authorization' + }); + return resp.send({ iceServers: [ { @@ -35,6 +48,8 @@ function handleIceRequest(req, resp) { app.get('/iceconfig', handleIceRequest) app.post('/iceconfig', handleIceRequest) -app.listen('3033', function () { +app.listen('4033', function () { console.log('server started') }) + +https.createServer(options, app).listen(3033); \ No newline at end of file diff --git a/apprtc-server/key-pebble.pem b/apprtc-server/key-pebble.pem new file mode 100644 index 0000000..0af8139 --- /dev/null +++ b/apprtc-server/key-pebble.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAn+Uh5uf5OLyM9Q+mx5j4O7vehaHMWYG0bJ8bThqUwbw+lQIN +r5dyUJNThyYOjtkvv5Zo8UXKaUoN9SUaCY2MMTDQma4F3Lmt1dnFSeCZfioxgGr6 +l+9T+oqIj0MpgyrT4LRuVJKK2uvXsjy+zdasa+Hn1yYPR64Fk+xELLvtDv/U+sgM +AcZS9y25nNuEy2slEgWNTjyTrq2I5oTp1kFhFWPB3PBQt5QFSKow2mDQnyJjDHzl +VI8gzAkp0XEKo/SFIlH4BOlg1+OptNsM5hqzCI1sVc/ljhHVM1mLuVPswFMoo4OO +NUiCOO77H+o5bvmAHYELMP6thn2cTNk2tfN50QIDAQABAoIBAFAYWnQtjbUzFjUI +AxaG9QoPIPe1xgSsKXIj/WyReiTWJE9GOQ7VgWkFc9kGYlKCTx3cvXLm7+7wLq+3 +RySz6B8YAdaJytv3kzHFpcNNI/aEMknOzPrg4yNk0+VX0mqnQH2WRJJO2gmyDFl3 +fmjj+XkNL7KhmRPiA19HAhuag7R3/hc2ide4o6XpEKmnfc88Jhi5DzhFkeAfdVNQ +Mc76DKfiORISbxzCCT/fTjazMKQSE1bzTRxRmklT7bGusEXmhfr3PIABcmN2xYE0 +9yNZ8i07tifHocpssxcOwExtYgMlO7GJcDlbJxxO/Ou86JKARG5gEglBHKpPDQ0s +hOfUThUCgYEAwabCm3JoYy8e+Gy3znn+MPSkyK86AtDspUFrA6rNhzw6TrWO5hNz +ORMP0F8uLaZ6/YIoyDd1A8klcQ9J/iJ+r7yDJRpXD4zhwyLIp6U5C+Z4avTqz0CU +wTlveDFygteCTWulw9UkoE6jbNqIRcp7Ad2MulmulC+eX+77DRquci8CgYEA02AW +blnmc/v0mIIWWcIVWTN17qZRgPPzpI+fGHMl97MR2H5+5DnNLAwdCgphl+lnO0xo +V1obnRX+MBoOZFhrzGsb3UUnQYazIiu2PHutdvKv0NMNHBaePyPUayPFwjWtvEcS +R9bCmVf1GQPPisukKG+Qn4cp/6hFAySwRVFd0/8CgYAcFHE9lx5Z23hTL3iLoRbh +xGesjfQMen0GDXFWC8tXo70UsrDw3bskeIYfgd2xUuWcouYE+j2meeFK/puNFTVn +iB9AHwymvZfy8rVD0eputlGZuL/fo46uYgSu2gSvwk4rqcNUnTB9akm6PAnsjMq/ +X3/Lebud0zXU1VNj+A15kwKBgGwoGJIykgb6/zciKUmYU9Am0stgcwfmy96CVsft +85mBGTqLz2X8ZY2KTTmcAj/3AAmJmUJJKyP/4ua+DmsuC0q367QW9HVE9VggwcjF +CAd7OpdBxs1+jU6FiOWhkklDqjhSrXnw2/YW2aUJHCNK/B5sp7XZNZZJhbaMCV4O +ulIFAoGActtKw2pEieUkShJnYBvZHSIGhEncRt/p09XkHoUzyiKwXVAOLof/V/Z9 +nFwdW2+3aTb/H7ZmEsj6dzdJc4ZsV5mZfoL0mJ3Tn6heFBcVAGoS7U2c0rdQSkrC +34Vu8Of2sYg7Ww4Jw1kc3OIEyCGIcWUtO5623H2GLtxs3R7y0Bs= +-----END RSA PRIVATE KEY----- diff --git a/apprtc-server/run.sh b/apprtc-server/run.sh index 77d9ba3..09451a2 100644 --- a/apprtc-server/run.sh +++ b/apprtc-server/run.sh @@ -1,7 +1,30 @@ -sed -i "s/SERVER_PUBLIC_IP/${PUBLIC_IP}/g" /ice.js -sed -i 's/wss:\/\//ws:\/\//g' /apprtc/out/app_engine/apprtc.py -sed -i 's/https:\/\//http:\/\//g' /apprtc/out/app_engine/apprtc.py +PUBLIC_IP=`hostname` +sed -i "s/SERVER_PUBLIC_IP/${PUBLIC_IP}/g" /ice.js sed -i "s/SERVER_PUBLIC_IP/${PUBLIC_IP}/g" /apprtc/out/app_engine/constants.py +# vsilva +# Generate ssl certs for domain +echo "Generating SSL certs for domain $PUBLIC_IP" +domain=$PUBLIC_IP +openssl req -subj "/CN=$domain/O=C1AS/C=US" -newkey rsa:2048 -sha256 -nodes -keyout $domain-key.pem -out $domain.csr -outform PEM +openssl req -in $domain.csr -text -noout -verify +openssl x509 -req -in $domain.csr -CA /cert/cert-pebble.pem -CAkey /cert/key-pebble.pem -CAcreateserial -text -out $domain.pem -days 1024 -sha256 + +# copy to proper place (collider WS server) +mv $domain.pem /cert/cert.pem +mv $domain-key.pem /cert/key.pem + +# apache2 SSL (deprecated) +#cp /cert/key.pem /etc/ssl/private/ssl-cert-snakeoil.key +#cp /cert/cert.pem /etc/ssl/certs/ssl-cert-snakeoil.pem + +#echo Starting apache server +#service apache2 start + +echo "************ STARTUP ******************" +echo "* PUBLIC_IP=${PUBLIC_IP}" +echo "* Open https://${PUBLIC_IP}" +echo "***************************************" supervisord -c /apprtc_supervisord.conf + diff --git a/apprtc-server/wsgi_server.py b/apprtc-server/wsgi_server.py new file mode 100644 index 0000000..8eb6805 --- /dev/null +++ b/apprtc-server/wsgi_server.py @@ -0,0 +1,586 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""A WSGI server implementation using a shared thread pool.""" + + + +import collections +import errno +import httplib +import logging +import os +import re +import select +import socket +import sys +import threading +import time + +import google +import ipaddr + + + + + + + + + + + + + +from cherrypy import wsgiserver + + +from google.appengine.tools.devappserver2 import errors +from google.appengine.tools.devappserver2 import http_runtime_constants +from google.appengine.tools.devappserver2 import shutdown +from google.appengine.tools.devappserver2 import thread_executor + + +_HAS_POLL = hasattr(select, 'poll') + +# TODO: the only reason we need to timeout is to pick up added or remove +# descriptors. But AFAICT, we only add descriptors at startup and remove them at +# shutdown so for the bulk of the run, the timeout is useless and just simply +# wastes CPU. For startup, if we wait to start the thread until after all +# WSGI servers are created, we are good (although may need to be careful in the +# runtime instances depending on when servers are created relative to the +# sandbox being enabled). For shutdown, more research is needed (one idea is +# simply not remove descriptors as the process is about to exit). +_READINESS_TIMEOUT_SECONDS = 1 +_SECONDS_TO_MILLISECONDS = 1000 + +# Due to reports of failure to find a consistent port, trying a higher value +# to see if that reduces the problem sufficiently. If it doesn't we can try +# increasing it (on my circa 2010 desktop, it takes about 1/2 second per 1024 +# tries) but it would probably be better to either figure out a better +# algorithm or make it possible for code to work with inconsistent ports. + + +_PORT_0_RETRIES = 2048 + +# Per RFC2732, IPv6 addresses in URLs are enclosed in [] +_IPV6_HOST_RE = re.compile(r'^\[(.*)\]') + + +class BindError(errors.Error): + """The server failed to bind its address.""" + +_THREAD_POOL = thread_executor.ThreadExecutor() + + +class _SharedCherryPyThreadPool(object): + """A mimic of wsgiserver.ThreadPool that delegates to a shared thread pool.""" + + def __init__(self): + self._condition = threading.Condition() + self._connections = set() # Protected by self._condition. + + def stop(self, timeout=5): + timeout_time = time.time() + timeout + with self._condition: + while self._connections and time.time() < timeout_time: + self._condition.wait(timeout_time - time.time()) + for connection in self._connections: + self._shutdown_connection(connection) + + @staticmethod + def _shutdown_connection(connection): + if not connection.rfile.closed: + connection.socket.shutdown(socket.SHUT_RD) + + def put(self, obj): + with self._condition: + self._connections.add(obj) + _THREAD_POOL.submit(self._handle, obj) + + def _handle(self, obj): + try: + obj.communicate() + finally: + obj.close() + with self._condition: + self._connections.remove(obj) + self._condition.notify() + + +class SelectThread(object): + """A thread that selects on sockets and calls corresponding callbacks.""" + + def __init__(self): + self._lock = threading.Lock() + # self._file_descriptors is a frozenset and + # self._file_descriptor_to_callback is never mutated so they can be + # snapshotted by the select thread without needing to copy. + self._file_descriptors = frozenset() + self._file_descriptor_to_callback = {} + self._select_thread = threading.Thread( + target=self._loop_forever, name='WSGI select') + self._select_thread.daemon = True + + def start(self): + self._select_thread.start() + + def add_socket(self, s, callback): + """Add a new socket to watch. + + Args: + s: A socket to select on. + callback: A callable with no args to be called when s is ready for a read. + """ + with self._lock: + self._file_descriptors = self._file_descriptors.union([s.fileno()]) + new_file_descriptor_to_callback = self._file_descriptor_to_callback.copy() + new_file_descriptor_to_callback[s.fileno()] = callback + self._file_descriptor_to_callback = new_file_descriptor_to_callback + + def remove_socket(self, s): + """Remove a watched socket.""" + with self._lock: + self._file_descriptors = self._file_descriptors.difference([s.fileno()]) + new_file_descriptor_to_callback = self._file_descriptor_to_callback.copy() + del new_file_descriptor_to_callback[s.fileno()] + self._file_descriptor_to_callback = new_file_descriptor_to_callback + + def _loop_forever(self): + while shutdown and not shutdown.shutting_down(): + # Check shutdown as it may be gc-ed during shutdown. See + # http://stackoverflow.com/questions/17084260/imported-modules-become-none-when-running-a-function + try: + self._select() + except: + print "error in SSL" + + def _select(self): + with self._lock: + fds = self._file_descriptors + fd_to_callback = self._file_descriptor_to_callback + if fds: + if _HAS_POLL: + # With 100 file descriptors, it is approximately 5x slower to + # recreate and reinitialize the Poll object on every call to _select + # rather reuse one. But the absolute cost of contruction, + # initialization and calling poll(0) is ~25us so code simplicity + # wins. + poll = select.poll() + for fd in fds: + poll.register(fd, select.POLLIN) + ready_file_descriptors = [fd for fd, _ in poll.poll( + _READINESS_TIMEOUT_SECONDS * _SECONDS_TO_MILLISECONDS)] + else: + ready_file_descriptors, _, _ = select.select(fds, [], [], + _READINESS_TIMEOUT_SECONDS) + for fd in ready_file_descriptors: + fd_to_callback[fd]() + else: + # select([], [], [], 1) is not supported on Windows. + time.sleep(_READINESS_TIMEOUT_SECONDS) + +_SELECT_THREAD = SelectThread() +_SELECT_THREAD.start() + + +class _SingleAddressWsgiServer(wsgiserver.CherryPyWSGIServer): + """A WSGI server that uses a shared SelectThread and thread pool.""" + + def __init__(self, host, app): + """Constructs a _SingleAddressWsgiServer. + + Args: + host: A (hostname, port) tuple containing the hostname and port to bind. + The port can be 0 to allow any port. + app: A WSGI app to handle requests. + """ + super(_SingleAddressWsgiServer, self).__init__(host, self) + self._lock = threading.Lock() + self._app = app # Protected by _lock. + self._error = None # Protected by _lock. + self.requests = _SharedCherryPyThreadPool() + self.software = http_runtime_constants.SERVER_SOFTWARE + # Some servers, especially the API server, may receive many simultaneous + # requests so set the listen() backlog to something high to reduce the + # likelihood of refused connections. + self.request_queue_size = 100 + + def start(self): + """Starts the _SingleAddressWsgiServer. + + This is a modified version of the base class implementation. Changes: + - Removed unused functionality (Unix domain socket and SSL support). + - Raises BindError instead of socket.error. + - Uses _SharedCherryPyThreadPool instead of wsgiserver.ThreadPool. + - Calls _SELECT_THREAD.add_socket instead of looping forever. + + Raises: + BindError: The address could not be bound. + """ + # AF_INET or AF_INET6 socket + # Get the correct address family for our host (allows IPv6 addresses) + host, port = self.bind_addr + try: + info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, + socket.SOCK_STREAM, 0, socket.AI_PASSIVE) + except socket.gaierror: + if ':' in host: + info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, '', + self.bind_addr + (0, 0))] + else: + info = [(socket.AF_INET, socket.SOCK_STREAM, 0, '', self.bind_addr)] + + self.socket = None + for res in info: + af, socktype, proto, _, _ = res + try: + self.bind(af, socktype, proto) + except socket.error as socket_error: + if self.socket: + self.socket.close() + self.socket = None + continue + break + if not self.socket: + raise BindError('Unable to bind %s:%s' % self.bind_addr, socket_error) + + # Timeout so KeyboardInterrupt can be caught on Win32 + self.socket.settimeout(1) + self.socket.listen(self.request_queue_size) + + self.ready = True + self._start_time = time.time() + _SELECT_THREAD.add_socket(self.socket, self.tick) + + def quit(self): + """Quits the _SingleAddressWsgiServer.""" + _SELECT_THREAD.remove_socket(self.socket) + self.requests.stop(timeout=1) + + @property + def port(self): + """Returns the port that the server is bound to.""" + return self.socket.getsockname()[1] + + def set_app(self, app): + """Sets the PEP-333 app to use to serve requests.""" + with self._lock: + self._app = app + + def set_error(self, error): + """Sets the HTTP status code to serve for all requests.""" + with self._lock: + self._error = error + self._app = None + + def __call__(self, environ, start_response): + with self._lock: + app = self._app + error = self._error + if app: + return app(environ, start_response) + else: + start_response('%d %s' % (error, httplib.responses[error]), []) + return [] + + +class WsgiHostCheck(object): + """WSGI middleware for whitelisting incoming Host HTTP header values.""" + + def __init__(self, whitelisted_hosts, app): + self.whitelisted_hosts = set() + self.whitelisted_wildcard_hosts = set() + self.whitelisted_deep_wildcard_hosts = set() + for host in whitelisted_hosts: + if host.startswith('**.'): + self.whitelisted_deep_wildcard_hosts.add(self._get_base_host_name(host)) + elif host.startswith('*.'): + self.whitelisted_wildcard_hosts.add(self._get_base_host_name(host)) + else: + self.whitelisted_hosts.add(host) + self.app = app + + def __call__(self, environ, start_response): + http_host = environ.get('HTTP_HOST', '') + + if not http_host: + # Only allow requests without a Host header for HTTP/1.0 requests + if environ.get('SERVER_PROTOCOL', '') == 'HTTP/1.0': + return self.app(environ, start_response) + else: + logging.info('No Host header set in request') + start_response('400 Bad Request', []) + return ['No Host header set in request.'] + + canonical_host = self._get_canonical_host_name(http_host) + + if (self._is_local_host(canonical_host) or + self._is_whitelisted_host(canonical_host) or + self._is_whitelisted_wildcard_host(canonical_host) or + self._is_whitelisted_deep_wildcard_host(canonical_host)): + return self.app(environ, start_response) + else: + logging.error( + ('Request Host %s not whitelisted. Enabled hosts are %s' + + + + ), + canonical_host, self.whitelisted_hosts) + start_response('400 Bad Request', []) + return [('Request host is not whitelist enabled for this server. ' + 'Please use the --host command-line flag to whitelist a ' + 'specific host (recommended) or use --enable_host_checking to ' + 'disable host checking. See the command-line flags help ' + 'text for more information. ' + + + + )] + + def _is_local_host(self, host): + if host == 'localhost': + return True + + try: + return ipaddr.IPAddress(host).is_loopback + except ValueError: + return False + + def _is_whitelisted_host(self, host): + """Checks whether the provided host is whitelisted.""" + return host in self.whitelisted_hosts + + def _is_whitelisted_wildcard_host(self, host): + """Checks whether the provided host is whitelisted through wildcarding.""" + base_host = self._get_base_host_name(host) + return base_host in self.whitelisted_wildcard_hosts if base_host else False + + def _is_whitelisted_deep_wildcard_host(self, host): + """Checks the provided host for whitelisting through deep wildcarding.""" + return any(host.endswith('.' + deep_wildcard_host) for + deep_wildcard_host in self.whitelisted_deep_wildcard_hosts) + + def _get_canonical_host_name(self, host): + """Returns just the host name from a HTTP_HOST header value.""" + ipv6_match = _IPV6_HOST_RE.match(host) + if ipv6_match: + return ipv6_match.group(1) + else: + return host.rsplit(':', 1)[0] + + def _get_base_host_name(self, host): + """Returns the host name without the lowest level domain part.""" + return host.split('.', 1)[-1] if '.' in host else None + + +class WsgiServer(object): + + def __init__(self, host, app, ssl_certificate_paths=None, ssl_port=None): + """Constructs a WsgiServer. + + Args: + host: A (hostname, port) tuple containing the hostname and port to bind. + The port can be 0 to allow any port. + app: A WSGI app to handle requests. + ssl_certificate_paths: A ssl_utils.SSLCertificatePaths instance. This must + be specified in conjunction with ssl_port. + ssl_port: Port to bind to for https connections. This must be specified in + conjunction with ssl_certificate_paths. + + Raises: + ValueError: If only one of ssl_certificate_paths or ssl_port is specified. + """ + if ((ssl_certificate_paths and not ssl_port) or + (ssl_port and not ssl_certificate_paths)): + raise ValueError('Must specify both ssl_certificate_paths and ssl_port') + self.bind_addr = host + self._app = app + self._servers = [] + self._ssl_certificate_paths = ssl_certificate_paths + self._ssl_port = ssl_port + + def start(self): + """Starts the WsgiServer. + + This starts multiple _SingleAddressWsgiServers to bind the address in all + address families. + + Raises: + BindError: The address could not be bound. + """ + host, port = self.bind_addr + host_ports = self._get_all_host_ports(host, port) + + ssl_host_ports = self._get_all_host_ports( + host, self._ssl_port + ) if self.ssl_enabled else [] + ssl_adapter = self._create_ssl_adapter() if self.ssl_enabled else None + + if port != 0: + self._start_all_fixed_port(host_ports) + self._start_all_fixed_port(ssl_host_ports, ssl_adapter) + if not self._servers: + raise BindError('Unable to bind %s:%s' % self.bind_addr) + else: + for _ in range(_PORT_0_RETRIES): + if self._start_all_dynamic_port( + host_ports) and self._start_all_dynamic_port( + ssl_host_ports, ssl_adapter): + break + else: + raise BindError('Unable to find a consistent port for %s' % host) + + def _get_all_host_ports(self, host, port): + """Uses socket.getaddrinfo to return all address families for the host/port. + + Args: + host: str, hostname to bind to. + port: int, port to bind to. + + Returns: + An itertable of (host, port) tuples. + """ + try: + addrinfo = socket.getaddrinfo(host, port, socket.AF_UNSPEC, + socket.SOCK_STREAM, 0, socket.AI_PASSIVE) + sockaddrs = [addr[-1] for addr in addrinfo] + host_ports = [sockaddr[:2] for sockaddr in sockaddrs] + # Remove duplicate addresses caused by bad hosts file. Retain the + # order to minimize behavior change (and so we don't have to tweak + # unit tests to deal with different order). + return list(collections.OrderedDict.fromkeys(host_ports)) + except socket.gaierror: + return [(host, port)] + + def _create_ssl_adapter(self): + """Returns an ssl adapter for the wsgi server, or None if not using ssl.""" + # Use the 'builtin' adapter instead of 'pyopenssl' to use python's + # standard ssl module instead of OpenSSL + return wsgiserver.get_ssl_adapter_class('builtin')( + certificate=self._ssl_certificate_paths.ssl_certificate_path, + private_key=self._ssl_certificate_paths.ssl_certificate_key_path) + + def _start_all_fixed_port(self, host_ports, ssl_adapter=None): + """Starts a server for each specified address with a fixed port. + + Does the work of actually trying to create a _SingleAddressWsgiServer for + each specified address. + + Args: + host_ports: An iterable of host, port tuples. + ssl_adapter: An wsgiserver.SSLAdapter instance. If specified, all + _SingleAddressWsgiServers will have their ssl_adapter set to this. + + Raises: + BindError: The address could not be bound. + """ + for host, port in host_ports: + assert port != 0 + server = _SingleAddressWsgiServer((host, port), self._app) + if ssl_adapter: + server.ssl_adapter = ssl_adapter + try: + server.start() + except BindError as bind_error: + # TODO: I'm not sure about the behavior of quietly ignoring an + # EADDRINUSE as long as the bind succeeds on at least one interface. I + # think we should either: + # - Fail (just like we do now when bind fails on every interface). + # - Retry on next highest port. + logging.debug('Failed to bind "%s:%s": %s', host, port, bind_error) + continue + else: + self._servers.append(server) + + def _start_all_dynamic_port(self, host_ports, ssl_adapter=None): + """Starts a server for each specified address with a dynamic port. + + Does the work of actually trying to create a _SingleAddressWsgiServer for + each specified address. + + Args: + host_ports: An iterable of host, port tuples. + ssl_adapter: An wsgiserver.SSLAdapter instance. If specified, all + _SingleAddressWsgiServers will have their ssl_adapter set to this. + + Returns: + The list of all servers (also saved as self._servers). A non empty list + indicates success while an empty list indicates failure. + """ + port = 0 + for host, _ in host_ports: + server = _SingleAddressWsgiServer((host, port), self._app) + if ssl_adapter: + server.ssl_adapter = ssl_adapter + try: + server.start() + if port == 0: + port = server.port + except BindError as bind_error: + if bind_error[1][0] == errno.EADDRINUSE: + # The port picked at random for first interface was not available + # on one of the other interfaces. Forget them and try again. + for server in self._servers: + server.quit() + self._servers = [] + break + else: + # Ignore the interface if we get an error other than EADDRINUSE. + logging.debug('Failed to bind "%s:%s": %s', host, port, bind_error) + continue + else: + self._servers.append(server) + return self._servers + + def quit(self): + """Quits the WsgiServer.""" + for server in self._servers: + server.quit() + + @property + def host(self): + """Returns the host that the server is bound to.""" + return self._servers[0].socket.getsockname()[0] + + @property + def port(self): + """Returns the port that the server is bound to.""" + return self._servers[0].socket.getsockname()[1] + + @property + def ssl_enabled(self): + """Returns whether this server is using SSL.""" + return self._ssl_port and self._ssl_certificate_paths + + def set_app(self, app): + """Sets the PEP-333 app to use to serve requests.""" + self._app = app + + for server in self._servers: + server.set_app(app) + + def set_error(self, error): + """Sets the HTTP status code to serve for all requests.""" + self._error = error + self._app = None + for server in self._servers: + server.set_error(error) + + @property + def ready(self): + return all(server.ready for server in self._servers) From 41043c2ca4c4dca5f5a021d6dcc574e6632ebb0d Mon Sep 17 00:00:00 2001 From: Sharky Date: Tue, 15 Sep 2020 07:10:15 -0400 Subject: [PATCH 2/4] Update REAME.md Updated doc --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f62210d..61a4544 100644 --- a/README.md +++ b/README.md @@ -36,14 +36,18 @@ docker run --rm --net=host \ ``` Manual build Linux host (must have docker installed): -+ Copy files to your Linux host -+ chmod +x *.sh ++ Copy files to your Linux host: git clone https://github.com/Shark-y/WebRTC-Docker rtc ++ Navigate to: apprtc-server then chmod +x *.sh + Run the bash commands below + Install the CA certificate (chain-pebble.pfx) in your FF/Chrome cert store + Open https://MYHOSTNAME/ ``` bash -$ sudo ./build.sh # or docker build -t webrtc . (takes 5mins to build) +$ mkdir rtc +$ git clone https://github.com/Shark-y/WebRTC-Docker rtc +$ cd rtc/apprtc-server +$ chmod +x *.sh +$ sudo ./build.sh # Build the docker image - docker build -t webrtc . (takes 5mins to build) $ sudo ./docker-run.sh # create SSL certs for hostname and start servers ``` From 7731fb43d625265ed0d1fec943800125996e132b Mon Sep 17 00:00:00 2001 From: Shark-y <38670127+Shark-y@users.noreply.github.com> Date: Sun, 21 Mar 2021 07:21:07 -0400 Subject: [PATCH 3/4] Update Dockerfile Fixed build errors required by NodeJS updates. --- apprtc-server/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apprtc-server/Dockerfile b/apprtc-server/Dockerfile index c25cd09..c9a287e 100644 --- a/apprtc-server/Dockerfile +++ b/apprtc-server/Dockerfile @@ -34,7 +34,7 @@ COPY key-pebble.pem /cert ########### # NodeJS -RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - +RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get install -y nodejs # Golang @@ -83,7 +83,7 @@ RUN npm install -g grunt-cli RUN npm install RUN grunt build -WORKDIR / +#vsilva WORKDIR / RUN npm install express COPY ice.js / From 88015f2bd41a06c22ab9d0bbef1e241f201dfe6b Mon Sep 17 00:00:00 2001 From: Sharky Date: Sun, 28 Mar 2021 14:10:28 -0400 Subject: [PATCH 4/4] ICE/CORS bug fixes. ICE/CORS errors bug fixes after testing in GCP. --- apprtc-server/Dockerfile | 2 +- apprtc-server/apprtc_supervisord.conf | 2 +- apprtc-server/docker-run.sh | 8 +++++++- apprtc-server/run.sh | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apprtc-server/Dockerfile b/apprtc-server/Dockerfile index c9a287e..52d88e7 100644 --- a/apprtc-server/Dockerfile +++ b/apprtc-server/Dockerfile @@ -86,7 +86,7 @@ RUN grunt build #vsilva WORKDIR / RUN npm install express -COPY ice.js / +COPY ice.js /apprtc COPY constants.py /apprtc/out/app_engine/constants.py # Clean up APT when done. diff --git a/apprtc-server/apprtc_supervisord.conf b/apprtc-server/apprtc_supervisord.conf index 107dd24..6e695ef 100644 --- a/apprtc-server/apprtc_supervisord.conf +++ b/apprtc-server/apprtc_supervisord.conf @@ -24,7 +24,7 @@ autostart=true events=PROCESS_STATE [program:ice_server] -command = nodejs /ice.js +command = nodejs /apprtc/ice.js stdout_logfile = /webrtc_avconf/ice_server.log stdout_logfile_maxbytes = 20MB stdout_logfile_backups = 500 diff --git a/apprtc-server/docker-run.sh b/apprtc-server/docker-run.sh index f52b76c..59ff80b 100644 --- a/apprtc-server/docker-run.sh +++ b/apprtc-server/docker-run.sh @@ -1,3 +1,9 @@ +#!/bin/bash ip=`hostname -i` -docker run --rm --net=host -e PUBLIC_IP=`hostname -i` -it webrtc \ No newline at end of file +if [ "$1" != "" ] ; then + ip=$1 +fi + +#docker run --rm --net=host -e PUBLIC_IP=`hostname -i` -it webrtc +docker run --rm --net=host -e PUBLIC_IP=$ip -it webrtc \ No newline at end of file diff --git a/apprtc-server/run.sh b/apprtc-server/run.sh index 09451a2..161e327 100644 --- a/apprtc-server/run.sh +++ b/apprtc-server/run.sh @@ -1,4 +1,4 @@ -PUBLIC_IP=`hostname` +#PUBLIC_IP=`hostname` sed -i "s/SERVER_PUBLIC_IP/${PUBLIC_IP}/g" /ice.js sed -i "s/SERVER_PUBLIC_IP/${PUBLIC_IP}/g" /apprtc/out/app_engine/constants.py