summaryrefslogtreecommitdiff
path: root/templates/etc
diff options
context:
space:
mode:
Diffstat (limited to 'templates/etc')
-rw-r--r--templates/etc/icecast2/icecast.xml.j266
-rw-r--r--templates/etc/icecast2/ices-playlist.xml.j244
-rw-r--r--templates/etc/icecast2/mp3-to-ogg.sh.j236
-rw-r--r--templates/etc/nginx/nginx.conf.j2147
-rw-r--r--templates/etc/systemd/system/ices2.service17
-rw-r--r--templates/etc/systemd/system/liquidsoap-radio.service17
6 files changed, 327 insertions, 0 deletions
diff --git a/templates/etc/icecast2/icecast.xml.j2 b/templates/etc/icecast2/icecast.xml.j2
new file mode 100644
index 0000000..ef6e539
--- /dev/null
+++ b/templates/etc/icecast2/icecast.xml.j2
@@ -0,0 +1,66 @@
+<icecast>
+ <location>Earth</location>
+ <admin>{{ email }}</admin>
+
+ <limits>
+ <clients>1000</clients>
+ <sources>2</sources>
+ <queue-size>524288</queue-size>
+ <client-timeout>30</client-timeout>
+ <header-timeout>15</header-timeout>
+ <source-timeout>10</source-timeout>
+ <burst-on-connect>1</burst-on-connect>
+ <burst-size>65535</burst-size>
+ </limits>
+
+ <authentication>
+ <source-password>{{ random_password }}</source-password>
+ <relay-password>disabled</relay-password>
+ <admin-user>admin</admin-user>
+ <admin-password>{{ random_password }}</admin-password>
+ </authentication>
+
+ <hostname>localhost</hostname>
+ <server-id>""</server-id>
+
+ <listen-socket>
+ <port>8000</port>
+ <bind-address>127.0.0.1</bind-address>
+ </listen-socket>
+
+ <http-headers>
+ <header name="Access-Control-Allow-Origin" value="*" />
+ </http-headers>
+
+ <mount>
+ <mount-name>/stream</mount-name>
+ <max-listeners>1000</max-listeners>
+ <public>1</public>
+ <no-yp>1</no-yp>
+ </mount>
+
+ <fileserve>1</fileserve>
+
+ <paths>
+ <basedir>/usr/share/icecast2</basedir>
+ <logdir>/var/log/icecast2</logdir>
+ <webroot>/usr/share/icecast2/web</webroot>
+ <adminroot>/usr/share/icecast2/admin</adminroot>
+ <alias source="/" destination="/status.xsl"/>
+ </paths>
+
+ <logging>
+ <accesslog>access.log</accesslog>
+ <errorlog>error.log</errorlog>
+ <loglevel>2</loglevel>
+ <logsize>10000</logsize>
+ </logging>
+
+ <security>
+ <chroot>1</chroot>
+ <changeowner>
+ <user>icecast2</user>
+ <group>icecast</group>
+ </changeowner>
+ </security>
+</icecast>
diff --git a/templates/etc/icecast2/ices-playlist.xml.j2 b/templates/etc/icecast2/ices-playlist.xml.j2
new file mode 100644
index 0000000..89fc4c9
--- /dev/null
+++ b/templates/etc/icecast2/ices-playlist.xml.j2
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<ices>
+ <background>1</background>
+ <logpath>/var/log/ices</logpath>
+ <logfile>ices.log</logfile>
+ <loglevel>4</loglevel>
+ <consolelog>1</consolelog>
+
+ <!-- <pidfile>/home/ices/ices.pid</pidfile> -->
+
+ <stream>
+ <metadata>
+ <name>Example stream name</name>
+ <genre>Example genre</genre>
+ <description>A short description of your stream</description>
+ </metadata>
+
+ <input>
+ <module>playlist</module>
+ <param name="type">basic</param>
+ <param name="file">playlist.txt</param>
+ <param name="random">1</param>
+ <param name="restart-after-reread">0</param>
+ <param name="once">0</param>
+ </input>
+
+ <instance>
+ <hostname>localhost</hostname>
+ <port>8000</port>
+ <password>{{ random_password }}</password>
+ <mount>/stream</mount>
+ <yp>0</yp>
+ <reconnectdelay>60</reconnectdelay>
+ <reconnectattempts>10</reconnectattempts>
+ <maxqueuelength>80</maxqueuelength>
+
+ <!--<encode>
+ <nominal-bitrate>64000</nominal-bitrate>
+ <samplerate>44100</samplerate>
+ <channels>2</channels>
+ </encode>-->
+ </instance>
+ </stream>
+</ices>
diff --git a/templates/etc/icecast2/mp3-to-ogg.sh.j2 b/templates/etc/icecast2/mp3-to-ogg.sh.j2
new file mode 100644
index 0000000..f475d36
--- /dev/null
+++ b/templates/etc/icecast2/mp3-to-ogg.sh.j2
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+if ! command -v ffmpeg &>/dev/null; then
+ printf "%s\n" "[err] ffmpeg not found"
+ exit 1
+fi
+
+DIR="{{ radio_music_dir }}"
+
+shopt -s nullglob
+for mp3file in "${DIR}"/*.mp3; do
+ oggfile="${mp3file%.mp3}.ogg"
+ printf "%s\n" "[inf] converting ${mp3file} to ${oggfile} with ${title}"
+
+ if ffmpeg -loglevel error -y -i "${mp3file}" -acodec libvorbis -q:a 5 -metadata title="${title}" "${oggfile}"; then
+ printf "%s\n" "[inf] conversion successful, removing ${mp3file}"
+ rm -f "${mp3file}"
+ else
+ printf "%s\n" "[err] conversion failed for ${mp3file}"
+ fi
+done
+
+for oggfile in "${DIR}"/*.ogg; do
+ title="$(basename "${oggfile}" .ogg)"
+ vorbiscomment -w -t "TITLE=${title}" "${oggfile}"
+done
+
+ls "${DIR}"/*.ogg > "${DIR}/playlist.txt"
+printf "%s\n" "[inf] playlist generated at ${DIR}/playlist.txt"
+
+if id -u icecast2 >/dev/null 2>&1 && getent group icecast >/dev/null 2>&1; then
+ chown -R icecast2:icecast "$DIR"
+ printf "%s\n" "[inf] chowned ${DIR} with icecast2:icecast"
+else
+ printf "%s\n" "[err] user or group icecast2:icecast does not exist, skipping chown"
+fi
diff --git a/templates/etc/nginx/nginx.conf.j2 b/templates/etc/nginx/nginx.conf.j2
new file mode 100644
index 0000000..bb0930e
--- /dev/null
+++ b/templates/etc/nginx/nginx.conf.j2
@@ -0,0 +1,147 @@
+user www-data;
+worker_processes auto;
+pid /run/nginx.pid;
+include /etc/nginx/modules-enabled/*.conf;
+
+events {
+ worker_connections 1024;
+ multi_accept on;
+}
+
+http {
+ sendfile on;
+ tcp_nopush on;
+ tcp_nodelay on;
+ sendfile_max_chunk 512k;
+ keepalive_timeout 300s;
+ keepalive_requests 1000;
+ types_hash_max_size 2048;
+ server_tokens off;
+
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log warn;
+
+ gzip on;
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_buffers 16 8k;
+ gzip_http_version 1.1;
+ gzip_min_length 256;
+ gzip_types
+ text/plain
+ text/css
+ application/json
+ application/javascript
+ text/xml
+ application/xml
+ application/xml+rss
+ text/javascript
+ image/svg+xml;
+
+ upstream icecast_backend {
+ server 127.0.0.1:8000;
+ keepalive 32;
+ }
+
+ server {
+ listen 80;
+ server_name {{ domain }};
+ return 301 https://{{ domain }}$request_uri;
+ }
+
+ server {
+ listen 443 ssl http2;
+ server_name {{ domain }};
+
+ ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
+ #ssl_trusted_certificate /etc/letsencrypt/live/{{ domain }}/chain.pem;
+
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers HIGH:!aNULL:!MD5;
+ ssl_prefer_server_ciphers off;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 1d;
+ ssl_session_tickets off;
+
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+ add_header X-Frame-Options "DENY" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+ add_header Content-Security-Policy "default-src 'self'; connect-src *; media-src * blob: data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline';" always;
+ add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
+
+ root /var/www/html;
+ index index.html index.htm;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /stream {
+ proxy_pass http://icecast_backend/stream;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_http_version 1.1;
+ proxy_buffering off;
+ proxy_request_buffering off;
+
+ gzip off;
+ proxy_read_timeout 3600s;
+ proxy_connect_timeout 300s;
+ proxy_send_timeout 3600s;
+ chunked_transfer_encoding on;
+
+ add_header Access-Control-Allow-Origin "{{ radio_url }}" always;
+ add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
+ add_header Access-Control-Allow-Headers "Range" always;
+ add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;
+
+ access_log off;
+ error_log /var/log/nginx/icecast-error.log warn;
+ }
+
+ location /info {
+ proxy_pass http://127.0.0.1:8000/status-json.xsl;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_http_version 1.1;
+ proxy_buffering off;
+ proxy_request_buffering off;
+
+ add_header Access-Control-Allow-Origin "{{ radio_url }}" always;
+ add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
+ add_header Access-Control-Allow-Headers "Content-Type" always;
+ }
+
+ location /admin {
+ deny all;
+ return 403;
+ }
+
+ location /admin/ {
+ deny all;
+ return 403;
+ }
+
+ location ~ ^/(status|statistics|server|webadmin) {
+ deny all;
+ return 403;
+ }
+
+ access_log /var/log/nginx/icecast-access.log;
+ error_log /var/log/nginx/icecast-error.log warn;
+ }
+}
diff --git a/templates/etc/systemd/system/ices2.service b/templates/etc/systemd/system/ices2.service
new file mode 100644
index 0000000..d3a4c2f
--- /dev/null
+++ b/templates/etc/systemd/system/ices2.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=ICES2 Icecast source client
+After=network.target icecast2.service
+Requires=icecast2.service
+
+[Service]
+Type=simple
+User=icecast2
+Group=icecast
+WorkingDirectory={{ radio_music_dir }}
+ExecStart=/usr/bin/ices2 /etc/icecast2/ices-playlist.xml
+Restart=on-failure
+RestartSec=5
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/templates/etc/systemd/system/liquidsoap-radio.service b/templates/etc/systemd/system/liquidsoap-radio.service
new file mode 100644
index 0000000..c10983d
--- /dev/null
+++ b/templates/etc/systemd/system/liquidsoap-radio.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Liquidsoap Radio Streaming Service
+After=network.target
+
+[Service]
+Type=simple
+User=icecast2
+#Group=icecast
+ExecStart=/usr/bin/liquidsoap /srv/radio/radio.liq
+Restart=on-failure
+RestartSec=5
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=liquidsoap-radio
+
+[Install]
+WantedBy=multi-user.target