summaryrefslogtreecommitdiffstats
path: root/lass/2configs
diff options
context:
space:
mode:
Diffstat (limited to 'lass/2configs')
-rw-r--r--lass/2configs/gg23.nix105
-rw-r--r--lass/2configs/radio/container-host.nix23
-rw-r--r--lass/2configs/radio/default.nix86
-rw-r--r--lass/2configs/radio/weather.nix26
-rw-r--r--lass/2configs/radio/weather_for_ips.py45
-rw-r--r--lass/2configs/riot.nix14
-rw-r--r--lass/2configs/sync/the_playlist.nix2
7 files changed, 184 insertions, 117 deletions
diff --git a/lass/2configs/gg23.nix b/lass/2configs/gg23.nix
index 6bcbd7400..1af2fa226 100644
--- a/lass/2configs/gg23.nix
+++ b/lass/2configs/gg23.nix
@@ -2,37 +2,66 @@
with import <stockholm/lib>;
{
+ # ipv6 from vodafone is really really flaky
+ boot.kernel.sysctl."net.ipv6.conf.et0.disable_ipv6" = 1;
+ systemd.network.networks."50-et0" = {
+ matchConfig.Name = "et0";
+ DHCP = "ipv4";
+ # dhcpV4Config.UseDNS = false;
+ # dhcpV6Config.UseDNS = false;
+ linkConfig = {
+ RequiredForOnline = "routable";
+ };
+ # networkConfig = {
+ # LinkLocalAddressing = "no";
+ # };
+ # dhcpV6Config = {
+ # PrefixDelegationHint = "::/60";
+ # };
+ # networkConfig = {
+ # IPv6AcceptRA = true;
+ # };
+ # ipv6PrefixDelegationConfig = {
+ # Managed = true;
+ # };
+ };
+ boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
+ systemd.network.networks."50-int0" = {
+ name = "int0";
+ address = [
+ "10.42.0.1/24"
+ ];
+ networkConfig = {
+ # IPForward = "yes";
+ # IPMasquerade = "both";
+ ConfigureWithoutCarrier = true;
+ DHCPServer = "yes";
+ # IPv6SendRA = "yes";
+ # DHCPPrefixDelegation = "yes";
+ };
+ };
networking.networkmanager.unmanaged = [ "int0" ];
- networking.interfaces.int0.ipv4.addresses = [{
- address = "10.42.0.1";
- prefixLength = 24;
- }];
+ krebs.iptables.tables.filter.INPUT.rules = [
+ { predicate = "-i int0"; target = "ACCEPT"; }
+ ];
+ krebs.iptables.tables.filter.FORWARD.rules = [
+ { predicate = "-i int0"; target = "ACCEPT"; }
+ { predicate = "-o int0"; target = "ACCEPT"; }
+ { predicate = "-p ipv6-icmp"; target = "ACCEPT"; v4 = false; }
+ ];
+ krebs.iptables.tables.nat.PREROUTING.rules = mkBefore [
+ { v6 = false; predicate = "-s 10.42.0.0/24"; target = "ACCEPT"; }
+ ];
+ krebs.iptables.tables.nat.POSTROUTING.rules = [
+ { v6 = false; predicate = "-s 10.42.0.0/24"; target = "MASQUERADE"; }
+ ];
networking.domain = "gg23";
- services.dhcpd4 = {
- enable = true;
- interfaces = [ "int0" ];
- extraConfig = ''
- option subnet-mask 255.255.255.0;
- option routers 10.42.0.1;
- option domain-name-servers 10.42.0.1;
- subnet 10.42.0.0 netmask 255.255.255.0 {
- range 10.42.0.100 10.42.0.200;
- }
- '';
- machines = [
- { ethernetAddress = "a8:a6:48:65:ce:4c"; hostName = "tv"; ipAddress = "10.42.0.3"; }
- { ethernetAddress = "3c:2a:f4:22:28:37"; hostName = "drucker"; ipAddress = "10.42.0.4"; }
- { ethernetAddress = "80:7d:3a:67:b7:01"; hostName = "s20-tv"; ipAddress = "10.42.0.10"; }
- { ethernetAddress = "80:7d:3a:68:04:f0"; hostName = "s20-drucker"; ipAddress = "10.42.0.11"; }
- { ethernetAddress = "80:7d:3a:68:11:a5"; hostName = "s20-wasch"; ipAddress = "10.42.0.12"; }
- { ethernetAddress = "80:7d:3a:67:bb:69"; hostName = "s20-stereo"; ipAddress = "10.42.0.13"; }
- { ethernetAddress = "ec:b5:fa:07:78:16"; hostName = "hue-bridge"; ipAddress = "10.42.0.21"; }
- { ethernetAddress = "80:8d:b7:c5:80:dc"; hostName = "arubaAP"; ipAddress = "10.42.0.99"; }
- ];
- };
-
+ networking.useHostResolvConf = false;
+ services.resolved.extraConfig = ''
+ DNSStubListener=no
+ '';
services.dnsmasq = {
enable = true;
resolveLocalQueries = false;
@@ -46,21 +75,11 @@ with import <stockholm/lib>;
'';
};
- boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
- krebs.iptables.tables.filter.INPUT.rules = [
- { predicate = "-i int0 -p udp --dport 53"; target = "ACCEPT"; } # dns
- ];
- krebs.iptables.tables.filter.FORWARD.rules = [
- { v6 = false; predicate = "-d 10.42.0.0/24 -o int0 -m conntrack --ctstate RELATED,ESTABLISHED"; target = "ACCEPT"; }
- { v6 = false; predicate = "-s 10.42.0.0/24 -i int0"; target = "ACCEPT"; }
- { v6 = false; predicate = "-o int0"; target = "REJECT --reject-with icmp-port-unreachable"; }
- { v6 = false; predicate = "-i int0"; target = "REJECT --reject-with icmp-port-unreachable"; }
- ];
- krebs.iptables.tables.nat.PREROUTING.rules = mkBefore [
- { v6 = false; predicate = "-s 10.42.0.0/24"; target = "ACCEPT"; }
- ];
- krebs.iptables.tables.nat.POSTROUTING.rules = [
- { v6 = false; predicate = "-s 10.42.0.0/24 ! -d 10.42.0.0/24"; target = "MASQUERADE"; }
+ environment.systemPackages = [
+ (pkgs.writers.writeDashBin "restart_router" ''
+ ${pkgs.mosquitto}/bin/mosquitto_pub -h localhost -t 'cmnd/router/POWER' -u gg23 -P gg23-mqtt -m OFF
+ sleep 2
+ ${pkgs.mosquitto}/bin/mosquitto_pub -h localhost -t 'cmnd/router/POWER' -u gg23 -P gg23-mqtt -m ON
+ '')
];
}
-
diff --git a/lass/2configs/radio/container-host.nix b/lass/2configs/radio/container-host.nix
new file mode 100644
index 000000000..e32095ffa
--- /dev/null
+++ b/lass/2configs/radio/container-host.nix
@@ -0,0 +1,23 @@
+{ config, pkgs, ... }:
+{
+ lass.sync-containers3.containers.radio = {
+ sshKey = "${toString <secrets>}/radio.sync.key";
+ };
+ containers.radio = {
+ bindMounts."/var/music" = {
+ hostPath = "/var/music";
+ isReadOnly = false;
+ };
+ };
+ krebs.iptables.tables.filter.INPUT.rules = [
+ { predicate = "-p tcp --dport 8000"; target = "ACCEPT"; }
+ ];
+ krebs.htgen.radio-redirect = {
+ port = 8000;
+ scriptFile = pkgs.writers.writeDash "redir" ''
+ printf 'HTTP/1.1 301 Moved Permanently\r\n'
+ printf "Location: http://radio.lassul.us''${Request_URI}\r\n"
+ printf '\r\n'
+ '';
+ };
+}
diff --git a/lass/2configs/radio/default.nix b/lass/2configs/radio/default.nix
index 46540969b..a511196fd 100644
--- a/lass/2configs/radio/default.nix
+++ b/lass/2configs/radio/default.nix
@@ -113,7 +113,7 @@ in {
LIMIT=1000 #how many tracks to keep in the history
HISTORY_FILE=/var/lib/radio/recent
- listeners=$(${pkgs.curl}/bin/curl -fSs lassul.us:8000/status-json.xsl |
+ listeners=$(${pkgs.curl}/bin/curl -fSs http://localhost:8000/status-json.xsl |
${pkgs.jq}/bin/jq '[.icestats.source[].listeners] | add' || echo 0)
echo "$(${pkgs.coreutils}/bin/date -Is)" "$filename" | ${pkgs.coreutils}/bin/tee -a "$HISTORY_FILE"
echo "$(${pkgs.coreutils}/bin/tail -$LIMIT "$HISTORY_FILE")" > "$HISTORY_FILE"
@@ -128,14 +128,33 @@ in {
serviceConfig.User = lib.mkForce "radio";
};
+ nixpkgs.config.packageOverrides = opkgs: {
+ icecast = opkgs.icecast.overrideAttrs (old: rec {
+ version = "2.5-beta3";
+
+ src = pkgs.fetchurl {
+ url = "http://downloads.xiph.org/releases/icecast/icecast-${version}.tar.gz";
+ sha256 = "sha256-4FDokoA9zBDYj8RAO/kuTHaZ6jZYBLSJZiX/IYFaCW8=";
+ };
+
+ buildInputs = old.buildInputs ++ [ pkgs.pkg-config ];
+ });
+ };
services.icecast = {
enable = true;
hostname = "radio.lassul.us";
admin.password = "hackme";
extraConf = ''
<authentication>
- <source-password>hackme</source-password>
+ <source-password>hackme</source-password>
+ <admin-user>admin</admin-user>
+ <admin-password>hackme</admin-password>
</authentication>
+ <logging>
+ <accesslog>-</accesslog>
+ <errorlog>-</errorlog>
+ <loglevel>3</loglevel>
+ </logging>
'';
};
@@ -234,18 +253,38 @@ in {
'';
};
+ networking.firewall.allowedTCPPorts = [ 80 ];
services.nginx = {
enable = true;
- virtualHosts."radio.lassul.us" = {
- forceSSL = true;
- enableACME = true;
+ virtualHosts."radio.r" = {
locations."/".extraConfig = ''
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header X-Forwarded-Server $host;
- proxy_set_header X-Real-IP $remote_addr;
+ # https://github.com/aswild/icecast-notes#core-nginx-config
proxy_pass http://localhost:8000;
+ # Disable request size limit, very important for uploading large files
+ client_max_body_size 0;
+
+ # Enable support `Transfer-Encoding: chunked`
+ chunked_transfer_encoding on;
+
+ # Disable request and response buffering, minimize latency to/from Icecast
+ proxy_buffering off;
+ proxy_request_buffering off;
+
+ # Icecast needs HTTP/1.1, not 1.0 or 2
+ proxy_http_version 1.1;
+
+ # Forward all original request headers
+ proxy_pass_request_headers on;
+
+ # Set some standard reverse proxy headers. Icecast server currently ignores these,
+ # but may support them in a future version so that access logs are more useful.
+ 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;
+
+ # get source ip for weather reports
+ proxy_set_header user-agent "$http_user_agent; client-ip=$remote_addr";
'';
locations."= /recent".extraConfig = ''
default_type "text/plain";
@@ -266,7 +305,7 @@ in {
while sleep 1; do
mpv \
--cache-secs=0 --demuxer-readahead-secs=0 --untimed --cache-pause=no \
- 'http://lassul.us:8000/radio.ogg'
+ 'http://radio.lassul.us/radio.ogg'
done
'';
locations."= /controls".extraConfig = ''
@@ -278,33 +317,10 @@ in {
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
'';
};
- virtualHosts."lassul.us".locations."= /the_playlist".extraConfig = let
- html = pkgs.writeText "index.html" ''
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>lassulus playlist</title>
- </head>
- <body>
- <div style="display:inline-block;margin:0px;padding:0px;overflow:hidden">
- <iframe src="https://kiwiirc.com/client/irc.hackint.org/?nick=kiwi_test|?&theme=cli#the_playlist" frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:95%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="95%" width="100%"></iframe>
- </div>
- <div style="position:absolute;bottom:1px;display:inline-block;background-color:red;">
- <audio controls autoplay="autoplay"><source src="http://lassul.us:8000/radio.ogg" type="audio/ogg">Your browser does not support the audio element.</audio>
- </div>
- <!-- page content -->
- </body>
- </html>
- '';
- in ''
- default_type "text/html";
- alias ${html};
- '';
};
services.syncthing.declarative.folders."the_playlist" = {
path = "/var/music/the_playlist";
- devices = [ "mors" "phone" "prism" "omo" ];
+ devices = [ "mors" "phone" "prism" "omo" "radio" ];
};
krebs.acl."/var/music/the_playlist"."u:syncthing:X".parents = true;
krebs.acl."/var/music/the_playlist"."u:syncthing:rwX" = {};
diff --git a/lass/2configs/radio/weather.nix b/lass/2configs/radio/weather.nix
index ad96d8ec0..dca8a7843 100644
--- a/lass/2configs/radio/weather.nix
+++ b/lass/2configs/radio/weather.nix
@@ -10,23 +10,25 @@ let
export PATH="${lib.makeBinPath [
pkgs.coreutils
pkgs.curl
- pkgs.iproute2
- pkgs.jc
pkgs.jq
]}"
curl -fSsz /tmp/GeoLite2-City.mmdb -o /tmp/GeoLite2-City.mmdb http://c.r/GeoLite2-City.mmdb
MAXMIND_GEOIP_DB="/tmp/GeoLite2-City.mmdb"; export MAXMIND_GEOIP_DB
OPENWEATHER_API_KEY=$(cat "$CREDENTIALS_DIRECTORY/openweather_api"); export OPENWEATHER_API_KEY
- ss -no 'sport = :8000' |
- jc --ss | jq -r '
- [
- .[] |
- select(
- .local_address != "[::ffff:127.0.0.1]"
- and .local_address != "[::1]"
- ) | .peer_address | gsub("[\\[\\]]"; "")
- ] | unique[]
- ' |
+ (
+ curl -sS 'http://admin:hackme@localhost:8000/admin/listclients.json?mount=/radio.ogg'
+ curl -sS 'http://admin:hackme@localhost:8000/admin/listclients.json?mount=/radio.mp3'
+ curl -sS 'http://admin:hackme@localhost:8000/admin/listclients.json?mount=/radio.opus'
+ ) | jq -rs '
+ [
+ .[][].source|values|to_entries[].value |
+ (.listener//[]) [] |
+ (.useragent | capture("client-ip=(?<ip>[a-f0-9.:]+)")).ip // .ip
+ ] |
+ unique[] |
+ select(. != "127.0.0.1") |
+ select(. != "::1")
+ ' |
${weather_for_ips}/bin/weather_for_ips
'';
in {
diff --git a/lass/2configs/radio/weather_for_ips.py b/lass/2configs/radio/weather_for_ips.py
index 447c6389b..62206a985 100644
--- a/lass/2configs/radio/weather_for_ips.py
+++ b/lass/2configs/radio/weather_for_ips.py
@@ -20,26 +20,29 @@ for ip in fileinput.input():
f'The probability of reincarnation is {random.randrange(0, 100)} percent.'
)
else:
- location = geoip.city(ip.strip())
- if location.city.geoname_id not in seen:
- seen[location.city.geoname_id] = True
- weather_api_key = os.environ['OPENWEATHER_API_KEY']
- url = (
- f'https://api.openweathermap.org/data/2.5/onecall'
- f'?lat={location.location.latitude}'
- f'&lon={location.location.longitude}'
- f'&appid={weather_api_key}'
- f'&units=metric'
- )
- resp = requests.get(url)
- weather = json.loads(resp.text)
- output.append(
- f'Weather report for {location.city.name}, {location.country.name}. '
- f'It is {weather["current"]["weather"][0]["description"]} outside '
- f'with a temperature of {weather["current"]["temp"]:.1f} degrees, '
- f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second '
- f'and a humidity of {weather["current"]["humidity"]} percent. '
- f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. '
- )
+ try:
+ location = geoip.city(ip.strip())
+ if location.city.geoname_id not in seen:
+ seen[location.city.geoname_id] = True
+ weather_api_key = os.environ['OPENWEATHER_API_KEY']
+ url = (
+ f'https://api.openweathermap.org/data/2.5/onecall'
+ f'?lat={location.location.latitude}'
+ f'&lon={location.location.longitude}'
+ f'&appid={weather_api_key}'
+ f'&units=metric'
+ )
+ resp = requests.get(url)
+ weather = json.loads(resp.text)
+ output.append(
+ f'Weather report for {location.city.name}, {location.country.name}. '
+ f'It is {weather["current"]["weather"][0]["description"]} outside '
+ f'with a temperature of {weather["current"]["temp"]:.1f} degrees, '
+ f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second '
+ f'and a humidity of {weather["current"]["humidity"]} percent. '
+ f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. '
+ )
+ except: # noqa E722
+ pass
print('\n'.join(output))
diff --git a/lass/2configs/riot.nix b/lass/2configs/riot.nix
index 559e7b20d..6aacec5b6 100644
--- a/lass/2configs/riot.nix
+++ b/lass/2configs/riot.nix
@@ -31,27 +31,31 @@
privateNetwork = true;
hostAddress = "10.233.1.1";
localAddress = "10.233.1.2";
- forwardPorts = [
- { hostPort = 45622; containerPort = 22; }
- ];
};
systemd.network.networks."50-ve-riot" = {
matchConfig.Name = "ve-riot";
networkConfig = {
- IPForward = "yes";
# weirdly we have to use POSTROUTING MASQUERADE here
+ # and set ip_forward manually
+ # IPForward = "yes";
# IPMasquerade = "both";
LinkLocalAddressing = "no";
KeepConfiguration = "static";
};
};
- # networking.nat can be used instead of this
+ boot.kernel.sysctl."net.ipv4.ip_forward" = lib.mkDefault 1;
+
krebs.iptables.tables.nat.POSTROUTING.rules = [
{ v6 = false; predicate = "-s ${config.containers.riot.localAddress}"; target = "MASQUERADE"; }
];
+
+ # networking.nat can be used instead of this
+ krebs.iptables.tables.nat.PREROUTING.rules = [
+ { predicate = "-p tcp --dport 45622"; target = "DNAT --to-destination ${config.containers.riot.localAddress}:22"; v6 = false; }
+ ];
krebs.iptables.tables.filter.FORWARD.rules = [
{ predicate = "-i ve-riot"; target = "ACCEPT"; }
{ predicate = "-o ve-riot"; target = "ACCEPT"; }
diff --git a/lass/2configs/sync/the_playlist.nix b/lass/2configs/sync/the_playlist.nix
index c01a11cc3..233ca8fb7 100644
--- a/lass/2configs/sync/the_playlist.nix
+++ b/lass/2configs/sync/the_playlist.nix
@@ -1,7 +1,7 @@
{
services.syncthing.folders.the_playlist = {
path = "/home/lass/tmp/the_playlist";
- devices = [ "mors" "phone" "prism" "omo" ];
+ devices = [ "mors" "phone" "prism" "omo" "radio" ];
};
krebs.acl."/home/lass/tmp/the_playlist"."u:syncthing:X".parents = true;
krebs.acl."/home/lass/tmp/the_playlist"."u:syncthing:rwX" = {};