Add oauth2_proxy and use for calibre
oauth2_proxy is a service that allows adding authentication via proxy
headers to arbitrary web applications. As calibre doesn't support OIDC
directly, we can configure oauth2_proxy with nginx to lock users out of
calibre until they authenticate with keycloak, and then provide the
username to calibre to authenticate without a password
Change-Id: I933a6df20143ac2bd25513a4bcd2817cf6228191
Reviewed-on: https://git.clicks.codes/c/Clicks/NixFiles/+/203
Tested-by: Skyler Grey <minion@clicks.codes>
Reviewed-by: Samuel Shuert <coded@clicks.codes>
diff --git a/modules/common/calibre.nix b/modules/common/calibre.nix
index c11d0a8..88df2c2 100644
--- a/modules/common/calibre.nix
+++ b/modules/common/calibre.nix
@@ -29,9 +29,9 @@
calibreLibrary = "${config.services.nextcloud.datadir}/data/clicks-services/files/calibre";
reverseProxyAuth = {
- enable = false;
- header = "keycloak_oidc";
- }; # TODO: setup keycloak auth with oauth2_proxy
+ enable = true;
+ header = "X-User";
+ };
};
};
}
\ No newline at end of file
diff --git a/modules/common/oauth2_proxy.nix b/modules/common/oauth2_proxy.nix
new file mode 100644
index 0000000..17d9cd0
--- /dev/null
+++ b/modules/common/oauth2_proxy.nix
@@ -0,0 +1,44 @@
+{config, ...}: {
+
+ sops.secrets.OAUTH2_PROXY_CLIENT_SECRET = {
+ mode = "0400";
+ owner = config.users.users.root.name;
+ group = config.users.users.root.group;
+ sopsFile = ../../secrets/oauth2_proxy.env.bin;
+ format = "binary";
+ };
+
+ services.oauth2_proxy = {
+ enable = true;
+
+ keyFile = config.sops.secrets.OAUTH2_PROXY_CLIENT_SECRET.path;
+
+ httpAddress = "http://127.0.0.255:1034";
+ nginx.virtualHosts = [ "calibre.coded.codes" ];
+ reverseProxy = true;
+
+ provider = "keycloak-oidc";
+ clientID = "oauth2_proxy";
+
+ setXauthrequest = true;
+
+ email.domains = [ "*" ];
+
+ extraConfig = {
+ oidc-issuer-url = "https://login.clicks.codes/realms/master";
+ code-challenge-method = "S256";
+ redis-connection-url = "unix://${config.services.redis.servers.oauth2_proxy.unixSocket}";
+ session-store-type = "redis";
+ cookie-csrf-per-request = "true";
+ cookie-secure = "true";
+ cookie-csrf-expire = "5m";
+ whitelist-domain = ".clicks.codes,.coded.codes,.thecoded.prof,.starrysky.fyi,.crawling.us";
+ skip-provider-button = "true";
+ };
+ };
+
+ services.redis.servers.oauth2_proxy = {
+ enable = true;
+ user = "oauth2_proxy";
+ };
+}
diff --git a/secrets/oauth2_proxy.env.bin b/secrets/oauth2_proxy.env.bin
new file mode 100644
index 0000000..98e668d
--- /dev/null
+++ b/secrets/oauth2_proxy.env.bin
@@ -0,0 +1,32 @@
+{
+ "data": "ENC[AES256_GCM,data:Zgow44phbLPBDrrTPHEzjRjj1cGq/jp82Gi2X3FSgOIR1/HvzrwkPqihAfpTVXGGWg2AnTkZlAg9VL5JK+6WE6idDVhoThNgmiynbdIJ8Xt4slOOCcHejfQxH+LMVUmABsSizZu9jaxEgAC7Sm+3tgyi4VwbSPxNv+gqLdtisWiW073F,iv:/QSTFzTHOE94e+PdUvDxDvzKGv+9msKDYSwGG1EcdvI=,tag:1ifrE/mCm0P6C8AoaZrrHg==,type:str]",
+ "sops": {
+ "kms": null,
+ "gcp_kms": null,
+ "azure_kv": null,
+ "hc_vault": null,
+ "age": [
+ {
+ "recipient": "age15mv77dpnh5762gk5rsw2u79uza4tg8cu6r3nlwjudlzmdqqck3ss6mg9dy",
+ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTR25uWUVmTXRiTFFWS1Bv\nTG5wbHdYa0NNWFBEamF2UEk1V3ZJa1paS0ZBCkEzZnBxS2tkY1NYTE4xbnNzQlJh\nVE82dTc4OFVtWk4rNUM4Mm0zRTR1QjQKLS0tIDhENzRjRXNTV2dtSGg1dnpES3M0\nenZjRFl0YzZRNlZwbURWSFdyUFhSNU0K3BWlOc9HReuwb+Jz1NQul1YQNJQI/hye\na9dD3B3LPbDbj3daVTVmZhjaLQWDEyV6krClViVSWsb1qTxRnRunHg==\n-----END AGE ENCRYPTED FILE-----\n"
+ },
+ {
+ "recipient": "age1m7k864feyuezllp2hj4edkccn36rthrvfw969j6f0l3c0mhh5emsnfx6pd",
+ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4K0EwZUFib3VhVkhzYVJS\ncm01cTlLVHFsTmYxYU9LVXhQSmhKRUtNbkJRCkNqcjBZcUlyNkJncVZ6eG9TQ2l2\nMlRYcXUraHVHbFc5RFBsTWZvTk9jRzQKLS0tIEVoM2RQalY5MldKNmlBSlpVSFli\nOHd0RGJUTkJNK2k2cjlCaVB1VzBxKzgK1qLgZI6S9ZJJmmQiGdlaKS6cpRtC+lIZ\nX1CXrRJUVXdCAfUb2IM/qeT7ra3W/u/aC7z4aRUub3i5L6R+cscxyA==\n-----END AGE ENCRYPTED FILE-----\n"
+ },
+ {
+ "recipient": "age1fxxnmkeuqhhct93c43pwkzhuzzq8857s5hye6pgfpku70kjn4ecqtamfqr",
+ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxaUpoWXIraEJJV2Y3TmIx\nd0VYcVZkSTc5cE1MTmlOYnBUY05iRU5VU2xRCldPa1dYbGVwL3orSzhjYmkxSTBP\ndDYyY0MwKzF4aXU3Wm5QR2YwR0xqTGcKLS0tIExydWoyZEFVRmdaMzZIR09XaHgz\nUEVpZDdScGM5M1pZN1doS01JbU5NM0kKY+xTNFAIVpMYT5MsKbUEWCkwZZtf04Pa\nKcAhqlTpE6Bl3ufeIjNEAf4k+JXQ1k03kcxqQjZijQDnrOwqt9y1Qw==\n-----END AGE ENCRYPTED FILE-----\n"
+ },
+ {
+ "recipient": "age1zunqahfz404x7v8x0gs4hv5kq2xlyvqmukhlwvpymj74805jcunq4r7ugv",
+ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXT3NGVlY2SnBZTUZBQlEx\nWCtuWGI2cW9CNjlIWjBaNVpIS3RKbVVuU0djCktBV0t1cG43K1VqZmd4eVd0OWdw\nV2NaTE5NdG1hditxWm1qaU5UZXp0c1kKLS0tIE95ekxGWTByMzBKZCtBM29Ib2d1\nQ09TZjg2OEZlcFMwdHU5ZXM1ZTZRY1EKiq8snnEBO9lL2PL2/RyYQtCwmc4T7dYm\n2l/LbpuQKdV7SfFhGQsbJmivHIGvcvMkMiomZfSYjySDaUs3LBRtDA==\n-----END AGE ENCRYPTED FILE-----\n"
+ }
+ ],
+ "lastmodified": "2023-12-23T03:06:13Z",
+ "mac": "ENC[AES256_GCM,data:/xGGlnlAVnGMOHPPG7gFIHbMpYmWmyeQAev/gmfjJeX/NYueOX9QyNWXjWiIkhAkR7uA+uwSJahTHY9adALe/c12nbYlJXyxtCzm/25kSRTyseb4SD9QLOvUXLFdlhrA3aMyh3yvWq5u6yTtjYuSTDSuOvlJF+w2TGWTMni661s=,iv:ZZzEcoSOWVSvYs0IhMpkjovWqkqaqIOJhZ2aQNA1r3k=,tag:D3VSn+ZD5mQ1LC4/shQDlw==,type:str]",
+ "pgp": null,
+ "unencrypted_suffix": "_unencrypted",
+ "version": "3.8.1"
+ }
+}
\ No newline at end of file