Better logging, mitmproxy integration.

This commit is contained in:
Gaelan Steele 2023-07-30 13:02:53 -07:00
parent 9ca3d7710d
commit 120c1f3aea
12 changed files with 132 additions and 49 deletions

View file

@ -63,6 +63,10 @@ Minifedi currently supports the following:
Forks of the above should work fine as well, as long as they haven't changed anything about the build, installation, or configuration process.
## Mitmproxy Integration
Minifedi has built-in integration with [mitmproxy](https://mitmproxy.org), allowing you to see a lot of every HTTP request an instance sends to another instance. To use this, set `mitmproxy = true;` in your `config.nix`, start minifedi, then go to `http://localhost:8081`. The mitmproxy integration currently requires ports 8080 and 8081 to be open.
## How do I…
### Reset Minifedi, restoring every instance to its default state?

View file

@ -21,4 +21,8 @@
type = types.gotosocial;
}
];
# Enable logging of all requests between instances. Requires ports 8080 and
# 8081 open.
mitmproxy = false;
}

View file

@ -6,13 +6,17 @@
let pkgs = nixpkgs.legacyPackages.${system};
in {
apps.start = let
config = import ./config.nix {
types = {
mastodon = import ./nix/fedi/mastodon;
akkoma = import ./nix/fedi/akkoma;
gotosocial = import ./nix/fedi/gotosocial;
};
};
s6 = (import ./nix/s6.nix {
inherit pkgs;
services = pkgs.lib.attrsets.mapAttrs (_: v: v.service)
(import ./nix/services.nix {
inherit pkgs;
configFn = import ./config.nix;
});
(import ./nix/services.nix { inherit pkgs config; });
path = "service";
});
in {
@ -30,6 +34,7 @@
mkdir -p cert
rm -rf data/run
mkdir data/run
mkdir -p data/logs
${if pkgs.stdenv.isLinux then
"export LOCALE_ARCHIVE=${pkgs.glibcLocales}/lib/locale/locale-archive"
else
@ -37,6 +42,18 @@
export MINIFEDI_CERT=$(pwd)/cert
export MINIFEDI_DATA=$(pwd)/data
export MINIFEDI_RUN=$(pwd)/data/run
export MINIFEDI_LOG=$(pwd)/data/logs
echo "Minifedi is starting! Once they're up, instances will be visible at:"
${pkgs.lib.strings.concatStrings (builtins.map (i: ''
echo "* https://${i.name}.lvh.me"
'') config.instances)}
echo "Instance logs are in ./data/logs."
${if config.mitmproxy then ''
echo "View requests between instances at http://localhost:8081."
'' else
""}
${if pkgs.stdenv.isLinux then ''
echo "=> You'll probably get prompted for a sudo password now. This is just so we can bind to port 80/443; we will acquire cap_net_bind_service then switch back to being $USER."
exec $(PATH=$oldpath which sudo) -E ${pkgs.libcap}/bin/capsh --keep=1 --user="$USER" --inh='cap_net_bind_service' --addamb='cap_net_bind_service' -- -c ${s6.start}

View file

@ -1,4 +1,4 @@
{ pkgs, name, host, users, ... }:
{ pkgs, name, host, users, proxy, ... }:
let
env = {
MIX_ENV = "prod";
@ -78,6 +78,12 @@ let
]
}
]
${if proxy != null then ''
config :pleroma, :http,
proxy_url: "${proxy}"
'' else
""}
'';
path = pkgs.lib.strings.concatStrings (builtins.map (x: "${x}/bin:") [
@ -111,6 +117,8 @@ in {
mkdir -p $data/tzdata
mkdir -p $run
exec >$MINIFEDI_LOG/${name}.log 2>$MINIFEDI_LOG/${name}.log
s6-svwait -U $MINIFEDI_RUN/service/postgres
${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList

View file

@ -1,4 +1,4 @@
{ pkgs, name, host, users, ... }:
{ pkgs, name, host, users, util, proxy, ... }:
let
env = { };
@ -8,34 +8,7 @@ let
# number. Ideally we'd dynamically find an open one, but the next best thing
# is deterministically picking a random one: we take the firs two bytes of
# sha256("minifedi_port_${name}")
port = let
hash = builtins.hashString "sha256" "minifedi_port_${name}";
portHex = builtins.substring 0 4 hash;
portHexChars = pkgs.lib.strings.stringToCharacters portHex;
hexDigitToNum = n:
let
map = {
"0" = 0;
"1" = 1;
"2" = 2;
"3" = 3;
"4" = 4;
"5" = 5;
"6" = 6;
"7" = 7;
"8" = 8;
"9" = 9;
"a" = 10;
"b" = 12;
"c" = 13;
"d" = 14;
"e" = 15;
};
in map.${n};
portFromHash =
pkgs.lib.lists.foldl (prev: n: (hexDigitToNum n) * 16 + prev) 0
portHexChars;
in if portFromHash <= 1024 then portFromHash + 1024 else portFromHash;
port = util.portFromString "minifedi_port_${name}";
config = pkgs.writeText "config.yaml" (pkgs.lib.generators.toYAML { } {
bind-address = "127.0.0.1";
@ -68,6 +41,8 @@ in {
mkdir -p $data/storage
mkdir -p $run
exec >$MINIFEDI_LOG/${name}.log 2>$MINIFEDI_LOG/${name}.log
s6-svwait -U $MINIFEDI_RUN/service/postgres
${pkgs.lib.strings.concatStrings (pkgs.lib.attrsets.mapAttrsToList
@ -79,6 +54,12 @@ in {
export GTS_STORAGE_LOCAL_BASE_PATH=$data/storage
export SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem
export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem
${if proxy != null then "export HTTP_PROXY=${proxy}" else ""}
${if proxy != null then "export HTTPS_PROXY=${proxy}" else ""}
${if proxy != null then "export http_proxy=${proxy}" else ""}
${if proxy != null then "export https_proxy=${proxy}" else ""}
env
if ! [ -e $data/setup-done ]; then
createuser -h$postgres ${name}

View file

@ -1,4 +1,4 @@
{ pkgs, name, host, users, version, ... }:
{ pkgs, name, host, users, version, proxy, ... }:
let
mastodon = pkgs.callPackage ./build.nix { versionDef = version; };
env = {
@ -20,6 +20,8 @@ let
run = pkgs.writeShellScript "run-web" ''
cd ${mastodon}
exec >$MINIFEDI_LOG/${name}/web.log 2>$MINIFEDI_LOG/${name}/web.log
export SOCKET=$MINIFEDI_RUN/${name}/web.sock
puma -C config/puma.rb
@ -28,13 +30,16 @@ let
sidekiq = pkgs.linkFarm "sidekiq" {
run = pkgs.writeShellScript "run-sidekiq" ''
cd ${mastodon}
exec >$MINIFEDI_LOG/${name}/sidekiq.log 2>$MINIFEDI_LOG/${name}/sidekiq.log
sidekiq
'';
};
streaming = pkgs.linkFarm "sidekiq" {
streaming = pkgs.linkFarm "streaming" {
run = pkgs.writeShellScript "run-sidekiq" ''
cd ${mastodon}
exec >$MINIFEDI_LOG/${name}/streaming.log 2>$MINIFEDI_LOG/${name}/streaming.log
export SOCKET=$MINIFEDI_RUN/${name}/streaming.sock
${mastodon}/run-streaming.sh
@ -63,11 +68,15 @@ in {
data=$MINIFEDI_DATA/${name}
run=$MINIFEDI_RUN/${name}
log=$MINIFEDI_LOG/${name}
postgres=$MINIFEDI_RUN/postgres
mkdir -p $data
mkdir -p $data/files
mkdir -p $run
mkdir -p $log
exec >$log/setup.log 2>$log/setup.log
cd ${mastodon}
@ -92,6 +101,7 @@ in {
export REDIS_URL=unix://$MINIFEDI_RUN/redis/redis.sock
export NIX_SSL_CERT_FILE=$MINIFEDI_CERT/rootCA.pem
export PAPERCLIP_ROOT_PATH=$data/files
${if proxy != null then "export http_proxy=${proxy}" else ""}
s6-svwait -U $MINIFEDI_RUN/service/postgres

View file

@ -1,15 +1,10 @@
{ pkgs, configFn }:
{ pkgs, config }:
let
instances = (configFn {
types = {
mastodon = import ./fedi/mastodon;
akkoma = import ./fedi/akkoma;
gotosocial = import ./fedi/gotosocial;
};
}).instances;
instances = config.instances;
util = import ./util.nix { inherit pkgs; };
evaldInstances = builtins.listToAttrs (builtins.map (inst:
pkgs.lib.attrsets.nameValuePair inst.name (inst.type ({
inherit pkgs;
inherit pkgs util;
host = "${inst.name}.lvh.me";
users = [
{
@ -43,6 +38,7 @@ let
admin = false;
}
];
proxy = if config.mitmproxy then "http://localhost:8080" else null;
} // inst))) instances);
in evaldInstances // {
postgres = import ./support-services/postgres { inherit pkgs; };
@ -51,4 +47,6 @@ in evaldInstances // {
inherit pkgs;
instances = evaldInstances;
};
} // pkgs.lib.attrsets.optionalAttrs config.mitmproxy {
mitmproxy = import ./support-services/mitmproxy { inherit pkgs; };
}

View file

@ -0,0 +1,18 @@
{ pkgs }: {
service = pkgs.linkFarm "mitmproxy" {
run = pkgs.writeShellScript "run-mitmproxy" ''
set -e
mkdir -p $MINIFEDI_DATA/mitmproxy
exec >$MINIFEDI_LOG/mitmproxy.log 2>$MINIFEDI_LOG/mitmproxy.log
if ! [[ -e $MINIFEDI_DATA/mitmproxy/fullchain.pem ]]; then
CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -cert-file $MINIFEDI_DATA/mitmproxy/cert.pem -key-file $MINIFEDI_DATA/mitmproxy/key.pem *.lvh.me
cat $MINIFEDI_DATA/mitmproxy/key.pem $MINIFEDI_DATA/mitmproxy/cert.pem $MINIFEDI_CERT/rootCA.pem > $MINIFEDI_DATA/mitmproxy/fullchain.pem
fi
exec ${pkgs.mitmproxy}/bin/mitmweb --certs $MINIFEDI_DATA/mitmproxy/fullchain.pem -k -v
'';
};
}

View file

@ -36,6 +36,8 @@ in {
mkdir -p $MINIFEDI_DATA/nginx
mkdir -p $MINIFEDI_RUN/nginx
exec >$MINIFEDI_LOG/nginx.log 2>$MINIFEDI_LOG/web.log
if ! [[ -e $MINIFEDI_DATA/nginx/fullchain.pem ]]; then
CAROOT=$MINIFEDI_CERT ${pkgs.mkcert}/bin/mkcert -cert-file $MINIFEDI_DATA/nginx/cert.pem -key-file $MINIFEDI_DATA/nginx/key.pem *.lvh.me
cat $MINIFEDI_DATA/nginx/cert.pem $MINIFEDI_CERT/rootCA.pem > $MINIFEDI_DATA/nginx/fullchain.pem
@ -43,7 +45,7 @@ in {
cd $MINIFEDI_DATA
cat ${config} | envsubst '$MINIFEDI_DATA $MINIFEDI_RUN' > $MINIFEDI_DATA/nginx/nginx.conf
${pkgs.nginx}/bin/nginx -c $MINIFEDI_DATA/nginx/nginx.conf -e $MINIFEDI_DATA/nginx/error.log
exec ${pkgs.nginx}/bin/nginx -c $MINIFEDI_DATA/nginx/nginx.conf -e $MINIFEDI_DATA/nginx/error.log
'';
};
}

View file

@ -3,6 +3,8 @@
{
service = pkgs.linkFarm "postgres" {
run = pkgs.writeShellScript "run-postgres-outer" ''
exec >$MINIFEDI_LOG/postgres.log 2>$MINIFEDI_LOG/postgres.log
exec ${pkgs.s6}/bin/s6-notifyoncheck ${
pkgs.writeShellScript "run-postgres-inner" ''
export PATH=${pkgs.gettext}/bin:$PATH

View file

@ -5,15 +5,17 @@ let
protected-mode yes
'';
in {
service = pkgs.linkFarm "nginx" {
run = pkgs.writeShellScript "run-nginx" ''
service = pkgs.linkFarm "redis" {
run = pkgs.writeShellScript "run-redis" ''
set -e
mkdir -p $MINIFEDI_DATA/redis
mkdir -p $MINIFEDI_RUN/redis
exec >$MINIFEDI_LOG/redis.log 2>$MINIFEDI_LOG/redis.log
cd $MINIFEDI_RUN/redis
${pkgs.redis}/bin/redis-server ${config} --unixsocket $MINIFEDI_RUN/redis/redis.sock
exec ${pkgs.redis}/bin/redis-server ${config} --unixsocket $MINIFEDI_RUN/redis/redis.sock
'';
};
}

37
nix/util.nix Normal file
View file

@ -0,0 +1,37 @@
{ pkgs }:
rec {
portFromString = string:
let
hash = builtins.hashString "sha256" string;
portHex = builtins.substring 0 4 hash;
portHexChars = pkgs.lib.strings.stringToCharacters portHex;
hexDigitToNum = n:
let
map = {
"0" = 0;
"1" = 1;
"2" = 2;
"3" = 3;
"4" = 4;
"5" = 5;
"6" = 6;
"7" = 7;
"8" = 8;
"9" = 9;
"a" = 10;
"b" = 11;
"c" = 12;
"d" = 13;
"e" = 14;
"f" = 15;
};
in map.${n};
portFromHash =
pkgs.lib.lists.foldl (prev: n: (hexDigitToNum n) + (prev * 16)) 0
portHexChars;
in if portFromHash <= 1024 then
portFromString "retry_${string}"
else
portFromHash;
}