diff options
Diffstat (limited to 'templates/etc')
-rw-r--r-- | templates/etc/icecast2/icecast.xml.j2 | 66 | ||||
-rw-r--r-- | templates/etc/icecast2/ices-playlist.xml.j2 | 44 | ||||
-rw-r--r-- | templates/etc/icecast2/mp3-to-ogg.sh.j2 | 36 | ||||
-rw-r--r-- | templates/etc/nginx/nginx.conf.j2 | 147 | ||||
-rw-r--r-- | templates/etc/systemd/system/ices2.service | 17 | ||||
-rw-r--r-- | templates/etc/systemd/system/liquidsoap-radio.service | 17 |
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 |