This commit is contained in:
Robin Appelman 2025-06-02 22:21:13 +02:00
commit e9a16ce546
5 changed files with 56 additions and 46 deletions

View file

@ -8,7 +8,8 @@ Remembering what ip addresses all of your tasmota devices is a pain.
## Setup
Ensure your tasmota devices are connected to an MQTT server with the following "Full Topic":
Ensure your tasmota devices are connected to an MQTT server with the following
"Full Topic":
%prefix%/%topic%/
@ -22,12 +23,16 @@ Run the binary with the following environment variables
- `MQTT_PASSWORD`: password to authenticate against the mqtt server
- `PORT`: port this binary MQTT listen on, defaults to 80
You can also configure the proxy to send HTTP Basic authentication to the tasmota devices by setting the `TASMOTA_USERNAME` and `TASMOTA_PASSWORD` environment variables.
You can also configure the proxy to send HTTP Basic authentication to the
tasmota devices by setting the `TASMOTA_USERNAME` and `TASMOTA_PASSWORD`
environment variables.
Setup dns/hosts/etc to point `*.example.com` to the server running this binary
## Usage
The proxy server will use MQTT to discover and gather the ip addresses of your tasmota devices.
The proxy server will use MQTT to discover and gather the ip addresses of your
tasmota devices.
Any request made to `%hostname%.example.com` will be proxied to the tasmota device with the corresponding topic.
Any request made to `%hostname%.example.com` will be proxied to the tasmota
device with the corresponding topic.

View file

@ -1,5 +1,6 @@
{ dockerTools
, tasproxy
{
dockerTools,
tasproxy,
}:
dockerTools.buildLayeredImage {
name = "icewind1991/tasproxy";
@ -10,9 +11,9 @@ dockerTools.buildLayeredImage {
dockerTools.caCertificates
];
config = {
Cmd = [ "tasproxy" ];
Cmd = ["tasproxy"];
ExposedPorts = {
"80/tcp" = { };
"80/tcp" = {};
};
};
}

View file

@ -1,30 +1,32 @@
{ config
, lib
, pkgs
, ...
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.tasproxy;
format = pkgs.formats.toml { };
format = pkgs.formats.toml {};
configFile = format.generate "tasproxy-config.toml" {
listen = {
inherit (cfg) socket;
};
mqtt = {
inherit (cfg.mqtt) hostname port;
} // (
optionalAttrs (cfg.mqtt.passwordFile != null) {
inherit (cfg.mqtt) username;
password_file = "$CREDENTIALS_DIRECTORY/mqtt_password";
mqtt =
{
inherit (cfg.mqtt) hostname port;
}
);
// (
optionalAttrs (cfg.mqtt.passwordFile != null) {
inherit (cfg.mqtt) username;
password_file = "$CREDENTIALS_DIRECTORY/mqtt_password";
}
);
tasmota = optionalAttrs (cfg.tasmota.username != null) {
inherit (cfg.tasmota) username;
password_file = "$CREDENTIALS_DIRECTORY/tasmota_password";
};
};
in
{
in {
options.services.tasproxy = {
enable = mkEnableOption "Log archiver";
@ -81,7 +83,7 @@ in
};
};
};
default = { };
default = {};
};
enableUnixSocket = mkOption {
@ -99,14 +101,16 @@ in
config = mkIf cfg.enable {
systemd.services."tasproxy" = {
wantedBy = [ "multi-user.target" ];
wantedBy = ["multi-user.target"];
serviceConfig = {
LoadCredential = (optional (cfg.mqtt.passwordFile != null) [
"mqtt_password:${cfg.mqtt.passwordFile}"
]) ++ (optional (cfg.tasmota.passwordFile != null) [
"tasmota_password:${cfg.tasmota.passwordFile}"
]);
LoadCredential =
(optional (cfg.mqtt.passwordFile != null) [
"mqtt_password:${cfg.mqtt.passwordFile}"
])
++ (optional (cfg.tasmota.passwordFile != null) [
"tasmota_password:${cfg.tasmota.passwordFile}"
]);
ExecStart = "${cfg.package}/bin/tasproxy ${configFile}";
@ -128,10 +132,10 @@ in
ProtectHostname = true;
LockPersonality = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ] ++ optionals cfg.enableUnixSocket [ "AF_UNIX" ];
RestrictAddressFamilies = ["AF_INET" "AF_INET6"] ++ optionals cfg.enableUnixSocket ["AF_UNIX"];
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ];
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "multicast";
PrivateUsers = true;
ProcSubset = "pid";

View file

@ -1,3 +1,3 @@
final: prev: {
tasproxy = final.callPackage ./package.nix { };
tasproxy = final.callPackage ./package.nix {};
}

View file

@ -1,18 +1,18 @@
{ stdenv
, rustPlatform
, lib
}:
let
{
stdenv,
rustPlatform,
lib,
}: let
inherit (lib.sources) sourceByRegex;
src = sourceByRegex ./. [ "Cargo.*" "(src)(/.*)?" ];
src = sourceByRegex ./. ["Cargo.*" "(src)(/.*)?"];
in
rustPlatform.buildRustPackage rec {
pname = "tasproxy";
version = "0.1.0";
rustPlatform.buildRustPackage rec {
pname = "tasproxy";
version = "0.1.0";
inherit src;
inherit src;
cargoLock = {
lockFile = ./Cargo.lock;
};
}
cargoLock = {
lockFile = ./Cargo.lock;
};
}