{"version":"https:\/\/jsonfeed.org\/version\/1","title":"blog.laubacher.io","home_page_url":"https:\/\/blog.laubacher.io\/","feed_url":"https:\/\/blog.laubacher.io\/blog.json","description":"technology blog","author":{"name":"C\u00e9dric Laubacher"},"items":[{"title":"Keycloak with 2FA as Nextcloud backend","date_published":"2021-02-10T15:01:01+00:00","id":"https:\/\/blog.laubacher.io\/keycloak-with-2fa-as-nextcloud-backend","url":"https:\/\/blog.laubacher.io\/keycloak-with-2fa-as-nextcloud-backend","content_html":"
I've searched for a tutorial on how to use Keycloak as a user Backend for Nextcloud for weeks, but wasn't able to find one fitting my needs.<\/p>\n
I wanted a solution that fulfills the following criteria:<\/p>\n
This setup reduces the amount of passwords and 2FA needed for different services.\nIt also reduces the amount of logins, as you only need to login to one account.<\/p>\n
I used the following software:<\/p>\n
I assume you already have set up Nextcloud and an instance of Keycloak with a realm and users with the following URLs:<\/p>\n
example.com<\/code><\/li>\n<\/ul>\nKeycloak Configuration<\/h2>\nAdd Client in Keycloak<\/h3>\n\n- In the Keycloak admin console, select your realm<\/li>\n
- Create a new client:
Configure<\/code> > Clients<\/code> > Create<\/code>\n\nClient ID<\/code>: nextcloud<\/code><\/li>\n<\/ul><\/li>\n- Save and edit the new client\n
\nAccess Typ<\/code>: confidential<\/code><\/li>\nValid Redirect URIs<\/code>: https:\/\/cloud.example.com\/apps\/oidc_login\/oidc<\/code> or https:\/\/cloud.example.com\/*<\/code><\/li>\n<\/ul><\/li>\n- Copy the the secret under
Credentials<\/code><\/li>\n<\/ul>\nCreate\/Modify Groups<\/h3>\n
Create groups as you like, eg. admin<\/code>, and add your users to them. The groups will be mapped 1:1 to those in Nextcloud.\nNote that groups won't be created automatically in Nextcloud (Open PR<\/a>).<\/p>\nAdd a new attribute to the groups: Manage<\/code> > Groups<\/code> > GROUP_NAME<\/code><\/strong> > Attributes<\/code> > Add<\/code><\/p>\n\nKey<\/code>: nextcloudquota<\/code><\/li>\nValue<\/code>: 549755813888<\/code> This is the size in bytes, here 512GiB<\/li>\n<\/ul>\nAdd Mappers<\/h3>\n\n- \n
Create a new Mapper: Configure<\/code> > Clients<\/code> > nextcloud<\/code> > Mappers<\/code> > Create<\/code><\/p>\n\nName<\/code>: Nextcloud Quota<\/code><\/li>\nMapper Type<\/code>: User Attribute<\/code><\/li>\nUser Attribute<\/code>: nextcloudquota<\/code><\/li>\nToken Claim Name<\/code>: nextcloudquota<\/code><\/li>\nClaim JSON Type<\/code>: String<\/code><\/li>\n<\/ul>\n<\/li>\n- \n
Create another Mapper: Configure<\/code> > Clients<\/code> > nextcloud<\/code> > Mappers<\/code> > Create<\/code><\/p>\n\nName<\/code>: Groups Mapper<\/code><\/li>\nMapper Type<\/code>: Group Membership<\/code><\/li>\nToken Claim Name<\/code>: groups<\/code><\/li>\nFull group path<\/code>: OFF<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\nConfigure Nextcloud<\/h2>\n\n- Install OpenID Connect Login<\/a> from the App Store<\/li>\n
- \n
Edit the config.php<\/code> file (there are no UI settings) with the according settings:<\/p>\n<?php\n$CONFIG = array (\n\/\/ STANDARD NEXTCLOUD CONFIG\n\n\/\/ Some Nextcloud options that might make sense here\n'allow_user_to_change_display_name' => false,\n'lost_password_link' => 'disabled',\n\n\/\/ OIDC SPECIFIC CONFIG\n\n\/\/ URL of provider. All other URLs are auto-discovered from .well-known\n'oidc_login_provider_url' => 'https:\/\/auth.example.com\/auth\/realms\/example.com',\n\n\/\/ Client ID and secret registered with the provider\n'oidc_login_client_id' => 'nextcloud',\n\/\/ the secret you copied from Keycloak\n'oidc_login_client_secret' => '$SECRET',\n\n\/\/ Automatically redirect the login page to the provider\n'oidc_login_auto_redirect' => true,\n\n\/\/ Redirect to this page after logging out the user\n'oidc_login_logout_url' => 'https:\/\/auth.example.com\/auth\/realms\/example.com\/protocol\/openid-connect\/logout?redirect_uri=https%3A%2F%2Fcloud.example.com%2F',\n\n\/\/ Quota to assign if no quota is specified in the OIDC response (bytes)\n\/\/ 15GB\n'oidc_login_default_quota' => '549755813888',\n\n\/\/ Hide the NextCloud password change form.\n'oidc_login_hide_password_form' => true,\n\n\/\/ Attribute map for OIDC response\n'oidc_login_attributes' => array (\n 'id' => 'preferred_username',\n 'name' => 'name',\n 'mail' => 'email',\n 'quota' => 'nextcloudquota',\n 'groups' => 'groups',\n),\n\n\/\/ Set OpenID Connect scope\n'oidc_login_scope' => 'openid profile',\n\n\/\/ Disable creation of new...<\/code><\/pre><\/li><\/ul>","tags":["software","Nextcloud","LDAP","Keycloak","security"]},{"title":"The perfect nginx config","date_published":"2020-12-24T10:20:35+00:00","id":"https:\/\/blog.laubacher.io\/the-perfect-nginx-config","url":"https:\/\/blog.laubacher.io\/the-perfect-nginx-config","content_html":"I use docker for all of my applications running on my unRAID server, but for nginx I didn't find any image that fulfilled all my needs. So I wrote my own dockerimage which you can find here: https:\/\/github.com\/Starbix\/dockerimages\/tree\/master\/nginx<\/a>.<\/p>\nThe following is my config and should explain what most things do and why.<\/p>\n
nginx.conf<\/strong><\/p>\nThis limits the maximal connections per IP<\/p>\n
worker_processes auto;\npid \/nginx\/run\/nginx.pid;\ndaemon off;\npcre_jit on;\n\nevents {\n worker_connections 2048;\n use epoll;\n}\n\nhttp {\n limit_conn_zone $binary_remote_addr zone=limit_per_ip:10m;\n limit_conn limit_per_ip 128;\n limit_req_zone $binary_remote_addr zone=allips:10m rate=150r\/s;\n limit_req zone=allips burst=150 nodelay;<\/code><\/pre>\n
The custom log format is needed for nginx amplify<\/a> (statistics and more)<\/p>\n include \/nginx\/conf\/mime.types;\n default_type application\/octet-stream;\n\n log_format main_ext '$remote_addr - $remote_user [$time_local] \"$request\" '\n '$status $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\" '\n '\"$host\" sn=\"$server_name\" '\n 'rt=$request_time '\n 'ua=\"$upstream_addr\" us=\"$upstream_status\" '\n 'ut=\"$upstream_response_time\" ul=\"$upstream_response_length\" '\n 'cs=$upstream_cache_status' ;\n\n access_log \/nginx\/logs\/nginx_access.log main_ext;\n error_log \/nginx\/logs\/nginx_error.log warn;<\/code><\/pre>\n
The maximum upload size is 25GB\nnginx doesn't send that the webserver is nginx<\/code> but server<\/code><\/p>\n client_max_body_size 25G;\n\n aio threads;\n aio_write on;\n sendfile on;\n keepalive_timeout 15;\n keepalive_disable msie6;\n keepalive_requests 100;\n tcp_nopush on;\n tcp_nodelay on;\n server_tokens off;\n more_set_headers 'Server: secret';<\/code><\/pre>\n
Content will be encoded in brötli<\/a> (which Safari now supports)<\/p>\n gzip off;\n\n brotli on;\n brotli_static on;\n brotli_buffers 16 8k;\n brotli_comp_level 6;\n brotli_types\n text\/css\n text\/javascript\n text\/xml\n text\/plain\n text\/x-component\n application\/javascript\n application\/x-javascript\n application\/json\n application\/xml\n application\/rss+xml\n application\/vnd.ms-fontobject\n font\/truetype\n font\/opentype\n image\/svg+xml;<\/code><\/pre>\n
This will include all config files from \/sites-enabled. The following configuration is the part you'll configure yourself.<\/p>\n
include \/sites-enabled\/*.conf;\n include \/nginx\/custom_sites\/*.conf;\n include \/nginx\/conf.d\/stub_status.conf;\n}<\/code><\/pre>\nThe preceding configuration is part of the included nginx.conf of my Dockerimage.\n
<\/p>\n
\/sites-enabled\/default.conf<\/strong><\/p>\nThese TLS parameters currently result in a 100% score in all categories on https:\/\/www.ssllabs.com\/ssltest<\/a><\/p>\n\n- OCSP stapling is enabled you can learn more about it here<\/a><\/li>\n
- I use hybrid certificates<\/a><\/li>\n<\/ul>\n
upstream php-handler {\n server unix:\/php\/run\/php-fpm.sock;\n}\n\nssl_protocols TLSv1.2 TLSv1.3;\nssl_ciphers [TLS13+AESGCM+AES256|TLS13+CHACHA20]:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;\nssl_ecdh_curve secp521r1:secp384r1;\nssl_prefer_server_ciphers on;\nssl_session_cache shared:SSL:20m;\nssl_session_timeout 15m;\nssl_session_tickets off;\nssl_stapling on;\nssl_dyn_rec_enable on;\nresolver 1.1.1.1 1.0.0.1 ipv6=off;\nssl_stapling_verify on;\n#RSA certificates\nssl_certificate \/certs\/example.com\/fullchain.pem;\nssl_certificate_key \/certs\/example.com\/key.pem;\n#ECDSA certificates\nssl_certificate \/certs\/example.com_ecc\/fullchain.pem;\nssl_certificate_key \/certs\/example.com_ecc\/key.pem;\n\nssl_trusted_certificate \/certs\/example.com\/fullchain.pem;<\/code><\/pre>\n
I use custom HTTP error pages and I used this for creating them: https:\/\/github.com\/AndiDittrich\/HttpErrorPages<\/a><\/p>\nerror_page 400 401 402 403 404 500 501 502 503 520 521 533 \/error\/HTTP$status.html;<\/code><\/pre>\n
This server redirects all of the unencrypted connections to https. It uses the same url, except when it's accessed over the IP address, then it redirects to the root of the domain.<\/p>\n
server {\n listen 8000 default_server;\n server_name _;\n include \/sites-enabled\/headers.conf;\n\n if ($host ~ \"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b\" ) {\n return 301 https:\/\/example.com$request_uri;\n\n }\n\n return 301 https:\/\/$host$request_uri;\n}<\/code><\/pre>\n
This server redirects unused subdomains.<\/p>\n
server {\n listen 4430 ssl http2;\n server_name www.example.com;\n return 301 https:\/\/example.com$request_uri;\n include \/nginx\/conf.d\/hsts.conf;\n include \/sites-enabled\/headers.conf;\n}<\/code><\/pre>\n
This is the server that listens on the root of the domain, in my case it redirects to the media<\/code> subdomain.<\/p>\nserver {\n listen 4430 ssl http2 default_server;\n #listen [::]:4430 ssl http2;\n server_name example.com;\n include \/nginx\/conf.d\/hsts.conf;\n include \/sites-enabled\/headers.conf;\n\n return 301 https:\/\/media.example.com$request_uri;\n\n location \/error\/ {\n alias \/www\/errorpages\/;\n internal;\n }\n\n }<\/code><\/pre>\n
I use Organizr<\/a> to organize (duh) all of my apps I regularly use. Definitely check it out if...<\/p>","tags":["software","Plex","nginx"]},{"title":"Use Plex credentials for Nextcloud","date_published":"2018-02-16T16:31:00+00:00","id":"https:\/\/blog.laubacher.io\/use-plex-credentials-for-nextcloud","url":"https:\/\/blog.laubacher.io\/use-plex-credentials-for-nextcloud","content_html":"This tutorial will show you how you can use your and your friend's Plex login to login to Nextcloud.<\/p>\n
Setup LDAP-for-Plex<\/h3>\n
First you need to setup this<\/a> piece of software, you can install it natively or use my docker for which you can find the tutorial here<\/a>.<\/p>\nIf you use unRAID you can add https:\/\/github.com\/Starbix\/docker-templates<\/a> to your template repositories if you want to use the docker template.<\/p>\nSetup Nextcloud<\/h3>\n\n- \n
You need to enable LDAP user and group backend<\/code> in Nextcloud which is an official app.<\/p>\n<\/li>\n- \n
Then go into the LDAP user and group backend<\/code> settings and set like the following pictures:<\/p>\n<\/li>\n<\/ul>\n Use the IP your LDAP for Plex instance runs on<\/em><\/p>\n
\n<\/p>\n
\n<\/p>\n
\n<\/p>\n
\n<\/p>\n
\n<\/p>\n
\n<\/p>\n
\n<\/p>\n
Note:<\/strong> It doesn't add the Plex users to the Plex.tv group automagically, you need to do that manually.<\/p>","tags":["Plex","cloud","Nextcloud","LDAP"],"image":"\/user\/pages\/blog\/use-plex-credentials-for-nextcloud\/1.png"},{"title":"Hyperion on Odroid C2","date_published":"2017-10-09T18:29:00+00:00","id":"https:\/\/blog.laubacher.io\/hyperion-on-odroid-c2","url":"https:\/\/blog.laubacher.io\/hyperion-on-odroid-c2","content_html":"I wrote this tutorial because Hyperion doesn't support Odroid C2 out of the box and I didn't find an easy tutorial for it. I'm using LibreELEC, but with minor changes it'll work on any other OS.<\/p>\n
Requirements<\/h4>\n\n- Odroid C2<\/li>\n
- Arduino Uno<\/li>\n
- APA102 LED stripe<\/li>\n
- USB type B to USB type A cable<\/li>\n
- Jumper cables<\/li>\n
- 5V Power Supply<\/li>\n<\/ul>\n
Introduction<\/h3>\n
I'm not going into how to create the Hyperion config and how to install the LEDs on your TV. There are already a lot tutorials for that, like Awesome Pi<\/a>. Instead of the WS2801 LEDs I recommend the APA102 LEDs which have better colors and the cabling needs to be different as we're going to use an Arduino between the LEDs and Odroid.<\/p>\nNow, there are two problems with the Odroid C2. The first one is, that it doesn't support SPI, a serial communication interface used to communicate with the APA102. This can be solved by using an Arduino between the Odroid and the LEDs.\nThe second problem is, that there's no official hyperion binary for the Odroid C2. Which meant that I had to compile it on my own, but more on that later.<\/p>\n
Hardware<\/h3>\n
First you need to prepare your Arduino. For that you need to download the Arduino IDE from here<\/a>.\nAfter you've installed the Arduino IDE, you need to select your Board Type under Tools>Board<\/strong> where you select Arduino\/Genuino Uno and just below you also need to select the serial port for the Arduino, this can change from computer to computer.\nYou then need to paste the code from here<\/a> into the IDE and then upload it to the Arduino.\nYou can then plug the LED pins into the Arduino with jumper cables. SPI data out is digital pin 11 and clock is digital pin 13. If you want to test if you've connected it correctly you can also uncomment the test pattern part. You should then see a red, green and blue flash.<\/p>\nSoftware<\/h3>\n
Now comes the interesting part. <\/p>\n
So you don't have to compile Hyperion for yourself, I have a Github Repository<\/a> with precompiled binaries. If you don't trust me, you can also compile them yourself. I also have a slightly modified Gtihub Repo<\/a> for that, as it won't compile otherwise. You need to use this command: cmake -DENABLE_DISPMANX=OFF -DENABLE_SPIDEV=OFF -DENABLE_AMLOGIC=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..<\/code><\/p>\nInstall LibreELEC<\/a> on your Odroid.<\/p>\nIn order to install Hyperion on your Odroid you need to make sure to enable SSH<\/strong>, you might need to restart after that. Then you need to connect to it over SFTP. For that I use Cyberduck, but any other SFTP client should work. Navigate to \/storage<\/code> and create a hyperion<\/code> directory.<\/p>\nTo get the files you need to put into the hyperion<\/code> folder, navigate to my precompiled binaries<\/a>. There are different folders for different binaries. You need to use the hyperion (v1) odroid-aml patched<\/strong>. Upload its content to the previously created hyperion<\/code> directory. Make sure you delete my config and replace...<\/p>","tags":["Odroid C2","software","hardware"]},{"title":"Unlimited Plex Server on unRAID","date_published":"2017-09-12T17:27:00+00:00","id":"https:\/\/blog.laubacher.io\/unlimited-plex-server-on-unraid","url":"https:\/\/blog.laubacher.io\/unlimited-plex-server-on-unraid","content_html":"This tutorial is not as detailed as https:\/\/hoarding.me<\/a> so I suggest first reading through that tutorial to get a broad view of how it rclone, Sonarr and Radarr work with the cloud.<\/p>\nunRAID makes running a cloud based unlimited Plex server not as easy as it's on Ubuntu. So here's a tutorial for unRAID.<\/p>\n
Required Plugins<\/h2>\n\n- Community Applications<\/a><\/li>\n
- CA User Scripts (search in Community Applications)<\/li>\n
- rclone or rclone-beta by Waseh (search in Community Applications)<\/li>\n
- unionfs<\/a><\/li>\n
- plexdrive<\/a><\/li>\n<\/ul>\n
To install the needed plugins, just enter <\/p>\n
https:\/\/raw.githubusercontent.com\/Squidly271\/community.applications\/master\/plugins\/community.applications.plg<\/code><\/pre>\nto Plugins > Install Plugin<\/strong>.\nAfter refreshing the site you should see a new Tab called Apps<\/strong>, under that Tab you just search for User Scripts<\/strong> and rclone<\/strong> and install both of those plugins.<\/p>\nFor our setup we also need unionfs and plexdrive for which I didn't find any plugin, so I wrote my own. Install it like Community Applications with https:\/\/raw.githubusercontent.com\/Starbix\/unRAID-plugins\/master\/plugins\/unionfs.plg<\/a> and https:\/\/raw.githubusercontent.com\/Starbix\/unRAID-plugins\/master\/plugins\/plexdrive.plg<\/a>.<\/p>\nTo edit your rclone config, SSH into your server and execute rclone config<\/code>.<\/p>\nAdd the following remotes:<\/p>\n
Name Type\n==== ====\ngdrive drive\ngdrivecrypt crypt (\"remote\" = \"\/mnt\/disks\/pd\/crypt\")\nuploadcrypt crypt (\"remote\" = \"gdrive:crypt\")<\/code><\/pre>\nNote: Use the same password for the crypt remotes.<\/p>\n
Then create the config file of plexdrive using<\/p>\n
plexdrive mount \/mnt\/disks\/pd -c \"\/mnt\/user\/appdata\/plexdrive\" -o allow_other -v 2<\/code><\/pre>\nthen upload mountcheck files used for checking whether everything is mounted properly or not<\/p>\n
touch mountcheck\nrclone copy mountcheck uploadcrypt:Series -vv --no-traverse\nrclone copy mountcheck uploadcrypt:Movies -vv --no-traverse\nrclone copy mountcheck uploadcrypt: -vv --no-traverse\n<\/code><\/pre>\nThen go to <\/p>\n