- name: Voeg lokale host toe aan nextcloud groep hosts: localhost gather_facts: yes tasks: - name: Haal IP-adres op van huidige server debug: var: ansible_default_ipv4.address - name: Voeg IP-adres toe aan 'nextcloud' groep add_host: name: "{{ ansible_default_ipv4.address }}" groups: Nextcloud ansible_user: "{{ ansible_user }}" - name: Install and configure Go, Docker, NATS, Janus, and Signaling Server hosts: localhost connection: local become: true vars: version: 1.23.0 signaling_version: 2.0.3 domeinnaam: nextcloudtalk12.hvanextcloudpoc.src.surf-hosted.nl domein_nextcloud: https://nc06.hvanextcloudpoc.src.surf-hosted.nl/ apache_site_conf: /etc/apache2/sites-available/signaling.conf # Automatisch gegenereerde secrets turn_rest_api_key: "{{ lookup('password', '/dev/null chars=hexdigits length=32') }}" Cotrun_secret: "{{ lookup('password', '/dev/null chars=hexdigits length=32') }}" hashkey: "{{ lookup('password', '/dev/null chars=hexdigits length=32') }}" blockkey: "{{ lookup('password', '/dev/null chars=hexdigits length=32') }}" nextcloud_secret: "{{ lookup('password', '/dev/null chars=hexdigits length=32') }}" tasks: - name: Installeer python3-pip als dat nog niet aanwezig is apt: name: python3-pip state: present update_cache: yes - name: Install Docker SDK for Python pip: name: docker executable: pip3 - name: Download Go tar file get_url: url: "https://go.dev/dl/go{{ version }}.linux-amd64.tar.gz" dest: "/tmp/go{{ version }}.linux-amd64.tar.gz" - name: Delete previous Go installation file: path: /usr/local/go state: absent - name: Extract Go tar file to /usr/local unarchive: src: "/tmp/go{{ version }}.linux-amd64.tar.gz" dest: /usr/local remote_src: yes - name: Ensure Go bin path is in ~/.bashrc lineinfile: path: ~/.bashrc line: 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' create: yes state: present - name: Ensure Go bin path is in /etc/profile lineinfile: path: /etc/profile line: 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' create: yes state: present - name: Source /etc/profile with /bin/bash and check Go version shell: 'bash -c "source /etc/profile && go version"' register: go_version_output - name: Show Go version debug: msg: "{{ go_version_output.stdout }}" - name: Check current environment PATH shell: 'bash -c "echo $PATH"' register: path_output - name: Show current PATH debug: msg: "{{ path_output.stdout }}" - name: Install Docker apt: name: docker.io state: present update_cache: yes - name: Download NATS docker image docker_image: name: nats tag: latest source: pull - name: Start and configure NATS container docker_container: name: nats-server image: nats:latest state: started restart_policy: always published_ports: - "4222:4222" - name: Install Janus apt: name: janus state: present update_cache: yes - name: Start Janus service systemd: name: janus enabled: yes state: started - name: Clear existing content in /etc/janus/janus.jcfg copy: content: '' dest: /etc/janus/janus.jcfg - name: Update /etc/janus/janus.jcfg blockinfile: path: /etc/janus/janus.jcfg block: | general: { configs_folder = "/etc/janus" # Configuration files folder plugins_folder = "/usr/lib/x86_64-linux-gnu/janus/plugins" # Plugins folder transports_folder = "/usr/lib/x86_64-linux-gnu/janus/transports" # Transports folder events_folder = "/usr/lib/x86_64-linux-gnu/janus/events" # Event handlers folder loggers_folder = "/usr/lib/x86_64-linux-gnu/janus/loggers" # External loggers folder # The next settings configure logging #log_to_stdout = false # Whether the Janus output should be written # to stdout or not (default=true) #log_to_file = "/path/to/janus.log" # Whether to use a log file or not debug_level = 4 # Debug/logging level, valid values are 0-7 #debug_timestamps = true # Whether to show a timestamp for each log line #debug_colors = false # Whether colors should be disabled in the log #debug_locks = true # Whether to enable debugging of locks (very verbose!) admin_secret = "janusoverlord" # String that all Janus requests must contain protected_folders = [ "/bin", "/boot", "/dev", "/etc", "/initrd", "/lib", "/lib32", "/lib64", "/proc", "/sbin", "/sys", "/usr", "/var", "/opt/janus/bin", "/opt/janus/etc", "/opt/janus/include", "/opt/janus/lib", "/opt/janus/lib32", "/opt/janus/lib64", "/opt/janus/sbin" ] } certificates: { #cert_pem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" #cert_key = "/etc/ssl/private/ssl-cert-snakeoil.key" #cert_pwd = "secretpassphrase" #dtls_accept_selfsigned = false #dtls_ciphers = "your-desired-openssl-ciphers" #rsa_private_key = false } media: { #ipv6 = true #ipv6_linklocal = true #min_nack_queue = 500 #rtp_port_range = "20000-40000" #dtls_mtu = 1200 #no_media_timer = 1 #slowlink_threshold = 4 #twcc_period = 100 #dtls_timeout = 500 } nat: { #stun_server = "stun.voip.eutelia.it" #stun_port = 3478 nice_debug = false full_trickle = true #turn_rest_api = "http://yourbackend.com/path/to/api" turn_rest_api_key = "{{ turn_rest_api_key }}" ice_ignore_list = "vmnet" } plugins: { #disable = "libjanus_voicemail.so,libjanus_recordplay.so" } transports: { #disable = "libjanus_rabbitmq.so" } loggers: { #disable = "libjanus_jsonlog.so" } events: { #broadcast = true #combine_media_stats = true #disable = "libjanus_sampleevh.so" #stats_period = 5 } - name: Clear existing content in janus.transport.http.jcfg copy: content: '' dest: /etc/janus/janus.transport.http.jcfg - name: Update janus.transport.http.jcfg file blockinfile: path: /etc/janus/janus.transport.http.jcfg block: | general: { #events = true # Whether to notify event handlers about transport events (default=true) json = "indented" # Whether the JSON messages should be indented (default), # plain (no indentation) or compact (no indentation and no spaces) base_path = "/janus" # Base path to bind to in the web server (plain HTTP only) http = true # Whether to enable the plain HTTP interface port = 8088 # Web server HTTP port interface = "lo" # Whether we should bind this server to a specific interface only #ip = "192.168.0.1" # Whether we should bind this server to a specific IP address (v4 or v6) only https = false # Whether to enable HTTPS (default=false) #secure_port = 8089 # Web server HTTPS port, if enabled #secure_interface = "eth0" # Whether we should bind this server to a specific interface only #secure_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address (v4 or v6) only #acl = "127.,192.168.0." # Only allow requests coming from this comma separated list of addresses #mhd_connection_limit = 1020 # Open connections limit in libmicrohttpd (default=1020) #mhd_debug = false # Ask libmicrohttpd to write warning and error messages to stderr (default=false) } admin_http=true. admin: { admin_base_path = "/admin" # Base path to bind to in the admin/monitor web server (plain HTTP only) admin_http = false # Whether to enable the plain HTTP interface admin_port = 7088 # Admin/monitor web server HTTP port #admin_interface = "eth0" # Whether we should bind this server to a specific interface only #admin_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address (v4 of v6) only admin_https = false # Whether to enable HTTPS (default=false) #admin_secure_port = 7889 # Admin/monitor web server HTTPS port, if enabled #admin_secure_interface = "eth0" # Whether we should bind this server to a specific interface only #admin_secure_ip = "192.168.0.1 # Whether we should bind this server to a specific IP address (v4 of v6) only #admin_acl = "127.,192.168.0." # Only allow requests coming from this comma separated list of addresses } cors: { #allow_origin = "http://foo.example" #enforce_cors = true } certificates: { cert_pem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" cert_key = "/etc/ssl/private/ssl-cert-snakeoil.key" #cert_pwd = "secretpassphrase" #ciphers = "PFS:-VERS-TLS1.0:-VERS-TLS1.1:-3DES-CBC:-ARCFOUR-128" } - name: Clear existing content in janus.transport.websockets.jcfg copy: content: '' dest: /etc/janus/janus.transport.websockets.jcfg - name: Update janus.transport.websockets.jcfg file blockinfile: path: /etc/janus/janus.transport.websockets.jcfg block: | general: { #events = true # Whether to notify event handlers about transport events (default=true) json = "indented" # Whether the JSON messages should be indented (default), # plain (no indentation) or compact (no indentation and no spaces) #pingpong_trigger = 30 # After how many seconds of idle, a PING should be sent #pingpong_timeout = 10 # After how many seconds of not getting a PONG, a timeout should be detected ws = true # Whether to enable the WebSockets API ws_port = 8188 # WebSockets server port ws_interface = "lo" # Whether we should bind this server to a specific interface only #ws_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address only #ws_unix = "/run/ws.sock" # Use WebSocket server over UNIX socket instead of TCP wss = false # Whether to enable secure WebSockets #wss_port = 8989 # WebSockets server secure port, if enabled #wss_interface = "lo" # Whether we should bind this server to a specific interface only #wss_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address only #wss_unix = "/run/wss.sock" # Use WebSocket server over UNIX socket instead of TCP #ws_logging = "err,warn" # libwebsockets debugging level as a comma separated list of things # to debug, supported values: err, warn, notice, info, debug, parser, # header, ext, client, latency, user, count (plus 'none' and 'all') #ws_acl = "127.,192.168.0." # Only allow requests coming from this comma separated list of addresses } admin: { admin_ws = false # Whether to enable the Admin API WebSockets API admin_ws_port = 7188 # Admin API WebSockets server port, if enabled #admin_ws_interface = "eth0" # Whether we should bind this server to a specific interface only #admin_ws_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address only #admin_ws_unix = "/run/aws.sock" # Use WebSocket server over UNIX socket instead of TCP admin_wss = false # Whether to enable the Admin API secure WebSockets #admin_wss_port = 7989 # Admin API WebSockets server secure port, if enabled #admin_wss_interface = "eth0" # Whether we should bind this server to a specific interface only #admin_wss_ip = "192.168.0.1" # Whether we should bind this server to a specific IP address only #admin_wss_unix = "/run/awss.sock" # Use WebSocket server over UNIX socket instead of TCP #admin_ws_acl = "127.,192.168.0." # Only allow requests coming from this comma separated list of addresses } cors: { #allow_origin = "http://foo.example" #enforce_cors = true } certificates: { cert_pem = "/etc/ssl/certs/ssl-cert-snakeoil.pem" cert_key = "/etc/ssl/private/ssl-cert-snakeoil.key" #cert_pwd = "secretpassphrase" #ciphers = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256" } - name: Restart Janus to apply configuration systemd: name: janus state: restarted - name: Install coturn apt: name: coturn state: present update_cache: yes - name: Clear existing content of etc/turnserver.conf copy: content: '' dest: /etc/turnserver.conf - name: Update etc/turnserver.conf blockinfile: path: /etc/turnserver.conf block: | listening-port=5349 fingerprint lt-cred-mech use-auth-secret static-auth-secret={{ Cotrun_secret }} realm={{ domeinnaam }} total-quota=100 bps-capacity=0 stale-nonce no-loopback-peers no-multicast-peers - name: Enable and start coturn service systemd: name: coturn enabled: yes state: started - name: Install wget and unzip apt: name: "{{ item }}" state: present loop: - wget - unzip - make - name: Download Nextcloud Spreed Signaling Server get_url: url: "https://github.com/strukturag/nextcloud-spreed-signaling/archive/refs/tags/v{{ signaling_version }}.zip" dest: "/opt/signaling-server-v{{ signaling_version }}.zip" - name: Unzip Signaling Server unarchive: src: "/opt/signaling-server-v{{ signaling_version }}.zip" dest: "/opt/" remote_src: yes - name: Remove zip file file: path: "/opt/signaling-server-v{{ signaling_version }}.zip" state: absent - name: Build Signaling Server with correct PATH shell: 'bash -c "export PATH=$PATH:/usr/local/go/bin && make build"' args: chdir: "/opt/nextcloud-spreed-signaling-{{ signaling_version }}" - name: Create signaling configuration directory file: path: /etc/signaling state: directory mode: '0755' - name: Copy server configuration copy: src: "/opt/nextcloud-spreed-signaling-{{ signaling_version }}/server.conf.in" dest: /etc/signaling/server.conf - name: Create signaling group group: name: signaling system: yes - name: Create signaling user user: name: signaling group: signaling shell: /usr/sbin/nologin comment: "Standalone signaling server for Nextcloud Talk." system: yes - name: Clear existing content of signaling/server.conf copy: content: '' dest: /etc/signaling/server.conf - name: Update /etc/signaling/server.conf blockinfile: path: /etc/signaling/server.conf block: | [http] listen = 127.0.0.1:8080 [sessions] hashkey = {{ hashkey }} blockkey = {{ blockkey }} [clients] internalsecret = [backend] backends = backend-1 [backend-1] url = {{ domein_nextcloud }} secret = {{ nextcloud_secret }} timeout = 10 connectionsperhost = 8 [app] debug = false [nats] url = nats://localhost:4222 [mcu] type = janus url = ws://127.0.0.1:8188 [turn] apikey = {{ turn_rest_api_key }} secret = {{ Cotrun_secret }} servers = turn:127.0.0.1:3478?transport=udp,turn:127.0.0.1:3478?transport=tcp - name: Clear existing content of signaling service file copy: content: '' dest: /etc/systemd/system/signaling.service - name: Set permissions on signaling server configuration file: path: /etc/signaling/server.conf mode: '0755' owner: signaling group: signaling - name: Update signaling systemd service file blockinfile: path: /etc/systemd/system/signaling.service block: | [Unit] Description=Nextcloud Talk signaling server After=janus.service [Service] ExecStart=/opt/nextcloud-spreed-signaling-{{ signaling_version }}/bin/signaling --config /etc/signaling/server.conf User=root Restart=on-failure - name: Set permissions on signaling server configuration file: path: /etc/signaling/server.conf mode: '0644' owner: signaling group: signaling - name: Set permissions on signaling systemd service file: path: /etc/systemd/system/signaling.service mode: '0644' - name: Reload systemd to apply new service systemd: daemon_reload: yes - name: Enable and start signaling service systemd: name: signaling enabled: yes state: started - name: Installeer Apache en Certbot apt: name: - apache2 - certbot state: present update_cache: yes - name: Schakel vereiste Apache modules in apache2_module: state: present name: "{{ item }}" loop: - ssl - rewrite - headers - proxy - proxy_http - deflate - cache - proxy_wstunnel - http2 - proxy_fcgi - env - expires notify: Herstart Apache - name: Verwijder standaard indexpagina file: path: /var/www/html/index.html state: absent - name: Schakel default Apache site uit command: a2dissite 000-default.conf args: removes: /etc/apache2/sites-enabled/000-default.conf notify: Herstart Apache - name: Stop tijdelijk Apache voor Certbot service: name: apache2 state: stopped - name: Vraag Let's Encrypt certificaat aan (standalone) command: > certbot certonly --non-interactive --agree-tos --standalone -d {{ domeinnaam }} --register-unsafely-without-email args: creates: "/etc/letsencrypt/live/{{ domeinnaam }}/fullchain.pem" - name: Start Apache weer na Certbot service: name: apache2 state: started - name: Controleer of Let's Encrypt certificaat aanwezig is stat: path: "/etc/letsencrypt/live/{{ domeinnaam }}/fullchain.pem" register: cert_status - name: Stop playbook als certificaat ontbreekt fail: msg: "SSL-certificaat ontbreekt! Certbot is mogelijk mislukt." when: not cert_status.stat.exists - name: Maak signaling VirtualHost configuratie aan copy: dest: /etc/apache2/sites-available/signaling.conf content: | ServerName {{ domeinnaam }} # SSL instellingen SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!MD5 SSLHonorCipherOrder on SSLCompression off # Logbestanden ErrorLog /var/log/apache2/signaling_error.log CustomLog /var/log/apache2/signaling_access.log combined # SSL certificaten SSLEngine on SSLCertificateFile /etc/letsencrypt/live/{{ domeinnaam }}/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/{{ domeinnaam }}/privkey.pem # Proxy instellingen voor WebSocket en API ProxyPass "/standalone-signaling/" "ws://127.0.0.1:8080/" ProxyPassReverse "/standalone-signaling/" "ws://127.0.0.1:8080/" RewriteEngine On RewriteRule ^/standalone-signaling/spreed/$ - [L] RewriteRule ^/standalone-signaling/api/(.*) http://127.0.0.1:8080/api/$1 [L,P] - name: Activeer signaling VirtualHost command: a2ensite signaling.conf args: creates: /etc/apache2/sites-enabled/signaling.conf notify: Herstart Apache - name: Controleer Apache configuratie command: apachectl -t handlers: - name: Herstart Apache service: name: apache2 state: restarted