From fe49830515044071e4bd5574f69735df6f5c23d1 Mon Sep 17 00:00:00 2001 From: Max Erenberg Date: Sun, 14 Mar 2021 03:00:04 +0000 Subject: [PATCH] initial commit --- README.md | 66 +++++++++++ bigbluebutton.nginx | 86 ++++++++++++++ playbook.yml | 270 ++++++++++++++++++++++++++++++++++++++++++ turn-stun-servers.xml | 78 ++++++++++++ 4 files changed, 500 insertions(+) create mode 100644 README.md create mode 100644 bigbluebutton.nginx create mode 100644 playbook.yml create mode 100644 turn-stun-servers.xml diff --git a/README.md b/README.md new file mode 100644 index 0000000..265a164 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +## Creating the database +On coffee, login as the `postgres` user, run `psql`, then run the following: +```sql +CREATE USER greenlight WITH PASSWORD 'replace_this_password'; +CREATE DATABASE greenlight; +ALTER DATABASE greenlight OWNER TO greenlight; +``` + +## Running the playbook +Just the usual: +``` +ansible-playbook playbook.yml +``` +Once the playbook has finished, open `/opt/greenlight/.env` and set the +value of `DB_PASSWORD`. + +Also, place copies of `csclub-wildcard-chain.crt` and `csclub-wildcard.key` +(the wildcard CSC SSL certificate and key, respectively) in the directory +`/etc/nginx/ssl`. The key file must have permissions 0600. + +Then, restart BBB: +```sh +bbb-conf --restart +``` + +## Running as the greenlight user +Add the following lines to `/opt/greenlight/.profile`: +``` +export PATH=$HOME/.gem/ruby/2.5.0/bin:$PATH +export $(grep -v '^#' ~/.env) +export RAILS_ENV=production +export BUNDLE_APP_CONFIG=~/.bundle +``` +This will allow you to use the `bundle` command after running +`su - greenlight`, if you need to do so. + +## Running Greenlight +Enable and run the systemd service: +```sh +systemctl enable greenlight +systemctl start greenlight +``` + +## Creating an administrator account +Theoretically, there is a [bundle command](https://docs.bigbluebutton.org/greenlight/gl-admin.html#creating-an-administrator-account) +which should be able to create an administrator account. However, when +I did this, I found that I was unable to login using the new admin +credentials. Might be because of LDAP. Here's my workaround: + +1. Login once using your CSC credentials. +2. Log out. +3. On coffee, login as `postgres`, run `psql`, and run the following: +```sql +\c greenlight +UPDATE users SET role_id = 2 WHERE username = 'my_csc_username'; +``` + +When you log back in, you should now be an admin. + +## Greenlight customization +To ensure that future sysadmins automatically become Greenlight admins, +create a new role called "sysadmin" from the org settings in Greenlight. + +To set a custom logo in the top left corner, go to 'Site Settings', +and replace the branding image URL. I'm using a small CSC logo hosted +on our git server in the csc-propaganda repo. diff --git a/bigbluebutton.nginx b/bigbluebutton.nginx new file mode 100644 index 0000000..4e573ce --- /dev/null +++ b/bigbluebutton.nginx @@ -0,0 +1,86 @@ +server { + listen 80; + listen [::]:80; + server_name bbb.csclub.uwaterloo.ca; + # Redirect all HTTP requests to HTTPS + return 301 https://$server_name$request_uri; +} + +server { + server_name bbb.csclub.uwaterloo.ca; + + listen 443 ssl; + listen [::]:443 ssl; + + ssl_certificate /etc/nginx/ssl/csclub-wildcard-chain.crt; + ssl_certificate_key /etc/nginx/ssl/csclub-wildcard.key; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_protocols TLSv1.2; + ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256"; + ssl_prefer_server_ciphers on; + ssl_dhparam /etc/nginx/ssl/dhp-4096.pem; + + access_log /var/log/nginx/bigbluebutton.access.log; + + # Handle RTMPT (RTMP Tunneling). Forwards requests + # to Red5 on port 5080 + location ~ (/open/|/close/|/idle/|/send/|/fcs/) { + proxy_pass http://127.0.0.1:5080; + proxy_redirect off; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + client_max_body_size 10m; + client_body_buffer_size 128k; + + proxy_connect_timeout 90; + proxy_send_timeout 90; + proxy_read_timeout 90; + + proxy_buffering off; + keepalive_requests 1000000000; + } + + # Handle desktop sharing tunneling. Forwards + # requests to Red5 on port 5080. + location /deskshare { + proxy_pass http://127.0.0.1:5080; + proxy_redirect default; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + client_max_body_size 10m; + client_body_buffer_size 128k; + proxy_connect_timeout 90; + proxy_send_timeout 90; + proxy_read_timeout 90; + proxy_buffer_size 4k; + proxy_buffers 4 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 64k; + include fastcgi_params; + } + + # BigBlueButton landing page. + location / { + root /var/www/bigbluebutton-default; + index index.html index.htm; + expires 1m; + } + + # Include specific rules for record and playback + include /etc/bigbluebutton/nginx/*.nginx; + + #error_page 404 /404.html; + + # Redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /var/www/nginx-default; + } + + # Set Greenlight to be the default landing page + location = / { + return 307 /b; + } +} + diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..5545593 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,270 @@ +--- +- hosts: 127.0.0.1 + connection: local + vars: + bundle: /opt/greenlight/.gem/ruby/2.5.0/bin/bundle + tasks: + - name: add PPA for bigbluebutton support packages + apt_repository: + repo: ppa:bigbluebutton/support + - name: add PPA for yq + apt_repository: + repo: ppa:rmescandon/yq + - name: add PPA for libreoffice + apt_repository: + repo: ppa:libreoffice/ppa + - name: add GPG key for MongoDB + apt_key: + url: https://www.mongodb.org/static/pgp/server-3.4.asc + - name: add repo for MongoDB + apt_repository: + repo: "deb [arch=amd64] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" + filename: mongodb-org-3.4 + - name: add GPG key for Nodesource + apt_key: + url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key + - name: add repo for Nodesource + apt_repository: + repo: deb https://deb.nodesource.com/node_8.x xenial main + filename: nodesource + - name: add GPG key for bigbluebutton + apt_key: + url: https://ubuntu.bigbluebutton.org/repo/bigbluebutton.asc + - name: add repo for bigbluebutton + apt_repository: + repo: deb https://ubuntu.bigbluebutton.org/xenial-22/ bigbluebutton-xenial main + filename: bigbluebutton + - name: add GPG key for Brightbox ruby-ng + apt_key: + keyserver: keyserver.ubuntu.com + id: 80F70E11F0F0D5F10CB20E62F5DA5F09C3173AA6 + - name: add repo for Brightbox ruby-ng + apt_repository: + repo: deb http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu xenial main + filename: brightbox.ruby-ng + - name: add GPG key for CSC + apt_key: + url: http://debian.csclub.uwaterloo.ca/csclub.asc + - name: add CSC Debian repo + apt_repository: + repo: deb http://debian.csclub.uwaterloo.ca xenial main + filename: csclub + - name: update apt cache + apt: + update_cache: true + - name: install apt-transport-https + apt: + name: apt-transport-https + state: latest + - name: install curl + apt: + name: curl + state: latest + - name: install MongoDB + apt: + name: mongodb-org + state: latest + - name: install nodejs + apt: + # consider apt pinning this to version 8 + name: nodejs + state: latest + - name: install bigbluebutton + apt: + name: bigbluebutton + state: latest + - name: install bbb-html5 + apt: + name: bbb-html5 + state: latest + - name: install ruby2.5 + apt: + name: ruby2.5 + state: latest + - name: install greenlight + apt: + name: greenlight + state: latest + - name: set BBB hostname + # We should only need to do this once. Make sure to remove + # /tmp/bbb-setip-done if the FQDN changes for whatever reason. + shell: 'bbb-conf --setip {{ ansible_fqdn }} && touch /tmp/bbb-setip-done' + args: + creates: /tmp/bbb-setip-done + # Make sure to place the certificate and key in this directory, + # and run `chmod 0600` on the key + - name: create SSL directory + file: + path: /etc/nginx/ssl + state: directory + - name: create Diffie-Hellman params + command: + cmd: openssl dhparam -out /etc/nginx/ssl/dhp-4096.pem 4096 + creates: /etc/nginx/ssl/dhp-4096.pem + - name: update NGINX config + copy: + src: '{{ playbook_dir }}/bigbluebutton.nginx' + dest: /etc/nginx/sites-available/bigbluebutton + - name: update SIP config to use HTTPS + replace: + path: /etc/bigbluebutton/nginx/sip.nginx + regexp: '^(\s*)proxy_pass http://(.*):5066;$' + replace: '\1proxy_pass https://\2:7443;' + - name: configure BBB to load session via HTTPS (1) + replace: + path: /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties + regexp: 'http://' + replace: 'https://' + - name: configure BBB to load session via HTTPS (2) + replace: + path: /usr/share/red5/webapps/screenshare/WEB-INF/screenshare.properties + regexp: 'http://' + replace: 'https://' + - name: configure BBB to load session via HTTPS (3) + replace: + path: /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml + regexp: 'ws://' + replace: 'wss://' + - name: configure BBB to load session via HTTPS (4) + replace: + path: /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml + regexp: 'http://' + replace: 'https://' + - name: configure BBB to load session via HTTPS (5) + replace: + path: /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml + regexp: '^playback_protocol: http$' + replace: 'playback_protocol: https' + - name: configure BBB to support IPv6 + copy: + dest: /etc/nginx/conf.d/bigbluebutton_sip_addr_map.conf + content: | + map $remote_addr $freeswitch_addr { + "~:" [{{ ansible_default_ipv6.address }}]; + default {{ ansible_default_ipv4.address }}; + } + - name: update SIP config to support IPv6 (1) + replace: + path: /etc/bigbluebutton/nginx/sip.nginx + regexp: '^(\s*)proxy_pass https://(.*):7443;$' + replace: '\1proxy_pass https://$freeswitch_addr:7443;' + - name: update SIP config to support IPv6 (2) + replace: + path: /opt/freeswitch/etc/freeswitch/sip_profiles/external-ipv6.xml + regexp: '^(\s*)$' + replace: '\1' + - name: increase file number limit for bbb-web + replace: + path: /lib/systemd/system/bbb-web.service + regexp: '^LimitNOFILE=\d+$' + replace: 'LimitNOFILE=8192' + notify: + - reload systemd + - name: disable recording + replace: + path: /usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties + regexp: '^{{ item.key }}=.*$' + replace: '{{ item.key }}={{ item.value }}' + with_dict: + disableRecordingDefault: 'true' + allowStartStopRecording: 'false' + - name: turn off certain sound effects + replace: + path: /opt/freeswitch/etc/freeswitch/autoload_configs/conference.conf.xml + regexp: '^(\s*){{ item }}$' + replace: '\1' + loop: + - '' + - '' + - '' + - name: skip echo test + replace: + path: /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml + regexp: '^(\s*)skipCheck: false$' + replace: '\1skipCheck: true' + - name: increase maximum number of breakout rooms + replace: + path: /usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml + regexp: '^(\s*)breakoutRoomLimit: \d+$' + replace: '\1breakoutRoomLimit: 16' + - name: use custom STUN servers + copy: + src: '{{ playbook_dir }}/turn-stun-servers.xml' + dest: /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml + - name: update FreeSWITCH to listen for connections on external IP (1) + replace: + path: /opt/freeswitch/conf/vars.xml + regexp: '^(\s*)$' + replace: '\1' + loop: + - 'rtp' + - 'sip' + - name: update FreeSWITCH to listen for connections on external IP (2) + replace: + path: /opt/freeswitch/conf/sip_profiles/external.xml + regexp: '^(\s*)$' + replace: '\1' + loop: + - 'rtp' + - 'sip' + - name: install bundler for greenlight + become: yes + become_user: greenlight + command: gem install --user-install bundler + args: + creates: '{{ bundle }}' + - name: configure NGINX to route to Greenlight + copy: + src: /opt/greenlight/greenlight.nginx + dest: /etc/bigbluebutton/nginx/greenlight.nginx + - name: create secret key for Rails + become: yes + become_user: greenlight + shell: '{{ bundle }} exec rake secret | tee /opt/greenlight/rake_secret' + args: + creates: /opt/greenlight/rake_secret + - name: obtain BBB API secret + shell: "bbb-conf --secret | grep -oP 'Secret: \\K[[:alnum:]]+'" + register: api_secret + - name: create .env file for greenlight + copy: + src: /opt/greenlight/sample.env + dest: /opt/greenlight/.env + force: no + owner: greenlight + group: greenlight + - name: update .env file for greenlight + replace: + path: /opt/greenlight/.env + regexp: '^{{ item.key }}=.*$' + replace: '{{ item.key }}={{ item.value }}' + with_dict: + SECRET_KEY_BASE: "{{ lookup('file', '/opt/greenlight/rake_secret') }}" + BIGBLUEBUTTON_ENDPOINT: 'https://{{ ansible_fqdn }}/bigbluebutton/' + BIGBLUEBUTTON_SECRET: '{{ api_secret.stdout }}' + SAFE_HOSTS: '{{ ansible_fqdn }}' + LDAP_SERVER: auth1.csclub.uwaterloo.ca + LDAP_PORT: '636' + LDAP_METHOD: 'ssl' + LDAP_UID: 'uid' + LDAP_BASE: 'dc=csclub,dc=uwaterloo,dc=ca' + LDAP_AUTH: 'user' + # make sure to create a role in Greenlight called "sysadmin" + LDAP_ROLE_FIELD: 'position' + ALLOW_GREENLIGHT_ACCOUNTS: 'false' + DEFAULT_REGISTRATION: open + ROOM_FEATURES: 'mute-on-join,require-moderator-approval' + DB_ADAPTER: postgresql + DB_HOST: coffee.csclub.uwaterloo.ca + DB_PORT: 5432 + DB_NAME: greenlight + DB_USERNAME: greenlight + - name: reminder for DB credentials + debug: + msg: >- + Make sure to create a database and user for greenlight and + update /opt/greenlight/.env with the Postgres credentials. + + handlers: + - name: reload systemd + command: systemctl daemon-reload diff --git a/turn-stun-servers.xml b/turn-stun-servers.xml new file mode 100644 index 0000000..354b118 --- /dev/null +++ b/turn-stun-servers.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +