Tag Archives: Linux

SFU!!! (Geek warning)

No, SFU does not mean what you might think. This is another geeky and technical post detailing how to get Matrix VOIP running as a self-hosted service. This is about the SFU or Selective Forwarding Unit, that is the VOIP backend driving your self-hosted matrixRTC instance. These are the components involved:

  1. A matrix homeserver where you have control over the .well-known/matrix/client file. Its installation not described here.
  2. An instance of the element-call widget. I chose not to self-host this for now and am simply using the provided https://call.element.io/. Self-hosting this would be possible and e.g. neccessary if your country/ISP blocks requests to call.element.io.
  3. Redis: messaging broker, turned out to be unneccessary
  4. lk-jwt-service: A small go binary providing auth tokens
  5. Livekit: The SFU or Selective Forwarding Unit. It takes a video/audio stream and multiplexes it to those users who need it. This way, users in a video conference do not need to send media to ALL other participants (which does NOT scale).
  6. A few rules poking holes into your firewall to make livekit work.
  7. Nginx proxying a few routes from livekit and lk-lwt-service to https://livekit.sspaeth.de.
  8. The livekit-provided TURN server. I have enabled it, but not verified that/if it actually works.

Details

My main domain is sspaeth.de, the homeserver lives on matrix.sspaeth.de, and everything livekit-related lives on livekit.sspaeth.de. I install this on a Debian server using a mix of local services and docker images. OK. Let’s start.

1. Homeserver configuration

You need to enable this in your config:

experimental_features:
  #room previews
  msc3266_enabled: true
# enable delayed events, so we quit calls that are interrupted somehow
max_event_delay_duration: 24h

2. Define the Element Call widget

First, when you start a video call, the Element Web or Element X Android/Ios clients (EW/EXA/EXI) look up where they load the element calls widget from. This is configured on https://sspaeth.de/.well-known/element/element.json. Just create a small text file containing:

{"call": {"widget_url": "https://call.element.io"}}

Modify this if you self-host element call. I was told that the long-term plan is to include a bundled element-call widget with clients in the future. So, this might be a temporary thing. Although, nothing is as permanent as a stopgap solution… 😉

3. Telling the participants which SFU to use

Second, we need to tell the clients which SFU to use. This is done by adding

"org.matrix.msc4143.rtc_foci":[
 {"type": "livekit",
  "livekit_service_url": "https://livekit.sspaeth.de"}]

to https://sspaeth.de/.well-known/matrix/client. I believe currently the starter of a video conference is the one deciding on the SFU which is used by participants.

4. Redis

Redis is a message broker, it is only needed for horizontal scaling of multiple livekit instances, apparently. So we can skip this step. YAY!
I used the Debian-supplied one by doing sudo apt install redis. You can configure redis to connect via a port or a socket. My /etc/redis/redis.conf contains these lines, so this is where I want to establish a connection:
unixsocket /run/redis/redis-server.sock
unixsocketperm 770
That is all I did about redis, nothing else was needed.

5. lk-jwt-service

It generates JWT tokens with a given identity for a given room, so that users can use them to authenticate against LiveKit SFU. I dabbled with creating a docker image for this, but that was too complicated for me. Given it is a single binary, I compiled it locally and just run it on the Debian server. This is how to do it:

a) Checkout the git repo at https://github.com/element-hq/lk-jwt-service, I put it into /opt/lk-jwt-service.
b) With a go compiler installed, compile it: /usr/lib/go-1.22/bin/go build -o lk-jwt-service (use just “go” instead of the full path if go it is in your PATH). If this suceeds, you’ll end up with the binary lk-jwt-service as a result. If you execute it from a shell, it will output: LIVEKIT_KEY, LIVEKIT_SECRET and LIVEKIT_URL environment variables must be set and exit.

Next, I create a systemd service to start it automatically: Note the values from LIVEKIT_SECRET and LIVEKIT_KEY which need to be taken from the livekit configuration.

[Unit]
Description=LiveKit JWT Service
After=network.target
[Service]
Restart=always
User=www-data
Group=www-data
WorkingDirectory=/opt/lk-jwt-service
Environment="LIVEKIT_URL=wss://livekit.sspaeth.de"
Environment="LIVEKIT_SECRET=this_is_a_secret_from_the_livekit.yaml"
Environment="LIVEKIT_KEY=this_is_a_key_from_the_livekit.yaml"
Environment="LK_JWT_PORT=8081"
ExecStart=/opt/lk-jwt-service/lk-jwt-service
[Install]
WantedBy=multi-user.target

P.S. Yes, it would be more elegant to include those environment variables in a separate file than hardcoding them in the service file.
P.P.S. Note, that I am running this on port 8081 instead of the default 8080 because 8080 is already in use on this box.

Last but not least, you need to proxy the output of two routes (/sfu/get and /healthz) on https://livekit.sspaeth.de. The nginx rules are in the nginx section.

If you enable and start the lk-jwt-service via systemctl, you should be able to open https://livekit.sspaeth.de/healthz in a web browser and get an empty webpage (aka HTTP STATUS 200). For testing purposes you can also start the service manually and observe its output by executing (in 1 line!): LIVEKIT_URL=wss://livekit.sspaeth.de LIVEKIT_SECRET=this_is_a_secret_from_the_livekit.yaml LIVEKIT_KEY=this_is_a_key_from_the_livekit.yaml LK_JWT_PORT=8081 /opt/lk-jwt-service/lk-jwt-service

6. livekit

I installed this one via precompiled docker and did not do the “Just execute this shell script as root and trust us”™.

I generated in initial configuration file using the livekit/generate image (to be written) and pruned most of the resulting stuff, as I do not run caddy for instance, and I do not want these scripts to be installing stuff on my main host.

6.1 Generating the initial configuration

docker pull livekit/generate
docker run --rm -it -v$PWD:/output livekit/generate

The above creates a folder with the name of domain you provided, containing the following files: caddy.yaml, docker-compose.yaml, livekit.yaml, redis.conf, init_script.sh.

I discarded most of the above (but built on the resulting livekit.yaml and docker-compose.yaml). I found particularly useful that it creates an API key and secret in livekit.yaml.

6.2 Final configuration and setup

This is my docker-compose.yaml file that I ended up using in order to built my livekit image:

services:
  livekit-docker:
    image: livekit/livekit-server:latest
    command: --config /etc/livekit.yaml
    restart: unless-stopped
    network_mode: "host"
    volumes:
      - ./livekit.yaml:/etc/livekit.yaml
      - /run/redis/redis-server.sock:/run/redis.sock

Running docker-compose up --no-start resulted in this output

Creating livekitsspaethde_livekit-docker_1 … done

This is my /etc/systemd/system/livekit.service file to get livekit started:

[Unit]
Description=LiveKit Server Container
After=docker.service
Requires=docker.service
After=network.target
Documentation=https://docs.livekit.io

[Service]
LimitNOFILE=500000
Restart=on-failure
WorkingDirectory=/etc/livekit
# start -a attaches STDOUT/STDERR so we get log output and prevents forking
ExecStart=docker start -a livekitsspaethde_livekit-docker_1
ExecStop=docker stop livekitsspaethde_livekit-docker_1

[Install]
WantedBy=multi-user.target

This is my final livekit.yaml config file

port: 7880
bind_addresses:
    - ""
rtc:
    tcp_port: 7881
    port_range_start: 50000
    port_range_end: 60000
    use_external_ip: true
    enable_loopback_candidate: false
turn:
    enabled: true
    domain: livekit.sspaeth.de
    # without a load balancer this is supposed to be port 443, and I am not using this, as my port 443 is occupied.
    tls_port: 5349
    udp_port: 3478
    external_tls: true
keys:
    # KEY: secret were autogenerated by livekit/generate
    # in the lk-jwt-service environment variables
    APIXCVSDFldksef: DLKlkddfgkjldhjkndfjkldfgkkldkdflkfdglk

6.1 Firewall rules

I allow inbound ports=7881/tcp and 3478,50000:60000/udp and these ports never go through the nginx proxy.

7. nginx configuration

I am not sure if all of those proxy headers actually need to be set, but they don’t hurt. These

proxy_set_header Connection “upgrade”;
proxy_set_header Upgrade $http_upgrade;

are actually important though (they enable the switch from https to websocket)!

server {
    access_log /var/log/nginx/livekit.sspaeth.de.log;
    error_log /var/log/nginx/livekit.sspaeth.de.error;
    listen 123.123.123.123:443 ssl;
    listen [dead:beef:dead:beef:dead:beef:dead:beef]:443 ssl;
    ssl_certificate XXXX;
    ssl_certificate_key XXXX;
    server_name livekit.sspaeth.de;

    # This is lk-jwt-service
    location ~ ^(/sfu/get|/healthz) {
        proxy_pass http://[::1]:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Server $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;
    }
    #and this is livekit
    location / {
       proxy_pass http://localhost:7880;
       proxy_set_header Connection "upgrade";
       proxy_set_header Upgrade $http_upgrade;
       #add_header Access-Control-Allow-Origin "*" always;

       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-Server $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;
    }
}

TL;DR: Matrix & Nextcloud setup (geek warning)

This is the BARE minimum of the specific configuration of my setup. Read the detailed setup post here.

Synapse

Synapse runs locally on port 8008 and is served on matrix.sspaeth.de. The only change needed, is to set up MAS as the OIDC server. I put the below in a separate OIDC.yaml file in the conf.d subdirectory of my synapse config:

experimental_features:
  msc3861:
    enabled: true
    issuer: https://auth.sspaeth.de/
    # Matches the `client_id` in the MAS config
    client_id: 00000000000000000SYNAPSE00
    # Matches the `client_auth_method` in the MAS config
    client_auth_method: client_secret_basic
    # Matches the `client_secret` in the MAS config
    client_secret: 1234CLIENTSECRETHERE56789
    # Matches the `matrix.secret` in the MAS config
    admin_token: 0x97531ADMINTOKENHERE13579

MAS

MAS runs locally on port 8080 and is served on auth.sspaeth.de. Below are snippets that I either added to or where I modified the defaults in config.yaml.

# Set up the client talking to Synapse.
clients:
  - client_id: 00000000000000000SYNAPSE00
    client_auth_method: client_secret_basic
    client_secret: 1234CLIENTSECRETHERE56789
    redirect_uris:
      - https://openidconnect.net/callback
# Tell MAS about Synapse and how to talk locally to it:
matrix:
  homeserver: sspaeth.de
  secret: 0x97531ADMINTOKENHERE13579
  endpoint: http://localhost:8008/

This should be OK for local password auth through MAS, but the next section is what I added to configure Nextcloud as an upstream OIDC provider:

upstream_oauth2:
  providers:
  - id: 01B2BSNY1QVVS9ZG3JTVDHNYYE
    # Note, above value is used in the Nextcloud config in the Redirection URI
    human_name: Nextcloud
    issuer: "https://cloud.sspaeth.de"
    client_id: "THISISMYLONGANDSECRETNEXTCLOUDCLIENTID" # needs to be configured in the Nextcloud OIDC settings
    client_secret: "THISISMYLONGANDSECRETNEXTCLOUDCLIENSECRET" # needs to be configured in the Nextcloud OIDC settings
    token_endpoint_auth_method: "client_secret_post"
    scope: "openid profile email"
    claims_imports:
        localpart:
          action: require
          template: "{{ user.preferred_username }}"
        displayname:
          action: suggest
          template: "{{ user.name }}"
        email:
          action: suggest
          template: "{{ user.email }}"
          set_email_verification: import
# Only allow upstream IdP, no local passwords
passwords:
  enabled: false

Nextcloud

The OpenID Connect app/plugin adds the central config option OpenID Connect clients. In this I have set:

Name 	auth.sspaeth.de
# Redirect URI uses the upstream_oauth2->providers->id value from my MAS config
Redirection URI: https://auth.sspaeth.de/upstream/callback/01B2BSNY1QVVS9ZG3JTVDHNYYE
Client Identifier: THISISMYLONGANDSECRETNEXTCLOUDCLIENTID
Secret: THISISMYLONGANDSECRETNEXTCLOUDCLIENTSECRET
Signing Algorithm: RS256
Type: confidential
Flows: Code & Implicit Authorization Flow
Limited to Groups: matrix # my choice to only allow specific users to log in.

That was simple wasn’t it? Again, this is just specific config changes to all components to get things running. Check out the detailed post on my setup and nginx proxy configuration.

Matrix server with Nextcloud login

This is a pretty geeky description of my matrix homeserver setup using Matrix-authentication-service and Nextcloud as the authentication source. It might be useful to others or future me. If not interested in technical details, please skip this post. A minimal version highlighting just the necessary configuration can be found in this TL;DR post. This is the slightly extended version explaining my setup.

Continue reading

Customizing the Librem5 ringtone (works for Mobian too)

The Librem5 has a single ringtone included, and while it is nice, it is not aggressive enough for me, I wanted to customize it. So here is how I went about. The same will work for the Pinephone on Mobian which uses the same software stack, I think.

The terminology in this howto is quite confusing. So be aware that a 1) sound theme, a 2) feedback theme, and 3) feedback profiles are three different things.

1) The first one defines in which directories a sound file is looked up (the freedesktop theme will serve as fallback, if a sound is not defined). 2) The feedback theme connects event names and sound files (or visual/haptic feedback) and also defines various feedback profiles. 3) Those profiles are full, quiet and silent, providing profiles within a theme. OK, so let us get started and explain how to customize sounds. The testing it all section at the end of this blog post lets you easily test your results.

TL,DR; the quickie on the L5 / Mobian

#on the L5: as user purism
cp -pr /usr/share/sounds/librem5 ~/.local/share/sounds/mysound
mv YOURCOOLRINGTONE.ogg ~/.local/share/sounds/mysound/stereo/phone-incoming-call.oga
gsettings set org.gnome.desktop.sound theme-name mysound
# probably a reboot is needed...?!
#on Mobian: as user mobian
mkdir -p ~/.local/share/sounds/mobian/stereo
cp -pr /usr/share/sounds/freedesktop/index.theme ~/.local/share/sounds/mobian
mv YOURCOOLRINGTONE.ogg ~/.local/share/sounds/mobian/stereo/phone-incoming-call.oga
gsettings set org.gnome.desktop.sound theme-name mobian
# probably a reboot is needed...?!

Setting a sound theme

To check the current sound theme, issue:

gsettings get org.gnome.desktop.sound theme-name

On a Librem 5, the sound theme name will be “librem5“, which means that the default sound theme (src) installed at /usr/share/sounds/librem5 is being used. Go there, and check out the sounds in there, if you like. On the Mobian, the theme-name is simply set to “freedesktop“, ie no special theme-name has been set.

To create a new sound theme, I copied over the /usr/share/sounds/librem5 to /usr/share/sounds/spaetz (and renaming the theme in the index.theme file). If you want to do this as a local user, you can also place the directory in the ~/.local/share/sounds directory. Then set the sound theme to your new name, and you are done:

gsettings set org.gnome.desktop.sound theme-name YOURTHEMEDIRECTORNAMEYHERE

Once again, to check the currently set sound theme use: gsettings get org.gnome.desktop.sound theme-name

If all you wanted to achieve is to customize the sound, ie switch out sound files, you are done here. If you need to change the notifications or want to connect events and sounds in a different manner, read on.

Connecting Events and Sounds

feedbackd is used to connect events and feedback. The configured sound theme is used by the feedback theme definitions stored in /usr/share/feedbackd/themes/default.json which connects events to various types of feedback. Possible themes for various devices are in this src repo. And all possible event names are listed here. The docs however state that currently only a single hard coded feedback theme ‘default‘ can be used. So /usr/share/feedbackd/themes/default.json is the file to modify if you want to use a different sound name for an event, or let the vibrator vibrate longer (or shorter).

As an alternative to switching sound themes, in order to customize ringtones for instance, one could also connect e.g. the phone-incoming-call event to a different ogg sound file name (sound files usually use an .oga file suffix) and simply place that in the fallback directory at ~/.local/share/sounds/freedesktop. Modifying the effect name to your sound file name should be sufficient then (untested):

   {
      "event-name" : "phone-incoming-call",
      "type"       : "Sound",
      "effect"     : "phone-incoming-call"
    },

Although there is only a single feedback theme, it offers various feedback profiles, which is what we know as the normal, silent, vibrate-only profiles on other mobile phones. These can also be set and retrieved programmatically:

Feedback Profiles

In Settings->Notifications one can conveniently change the overall profile between loud and silent ones. Using the command line, you can use:

gsettings get org.sigxcpu.feedbackd profile
in order to retrieve the current profile and
gsettings set org.sigxcpu.feedbackd profile full|quiet|silent (one of the three possible values)
in order to set the current feedback profile. The description says:

full: Use configured events from the full, quiet and silent parts of the feedback them.

quiet: Use quiet and silent part from of the feedback theme. This usually means no audio feedback.

silent: Only use the silent part from the feedback theme. This usually means to not use audio or vibra.

Per app profiles

In Settings->Notifications one can conveniently change the profile also per application (so silence your chat messages but have loud sound when the alarm clock wants to go off).

Advanced stuff: One can set the feedback profile of an individual application via GSettings. E.g. for an app with app id sm.puri.Phosh to set the profile to quiet do:

gsettings set org.sigxcpu.feedbackd.application:/org/sigxcpu/feedbackd/application/sm-puri-phosh/ profile quiet

Testing it all

To simulate events and see/listen to the sounds use the fbcli utility (just fbcli will simulate an incoming phone call). The following (taken from the docs), will simulate an incoming message once:

fbcli -t -1 -E message-new-instant
# or play the alarm clock sound for 10 seconds:
fbcli -t 10 -E alarm-clock-elapsed

Note: while fbcli picked up a new sound theme immediately, a quick test on calling myself led to no ringtone sound at all. After a reboot, the new sound played fine. Please report if this was a glitch or seems to be the case indeed.

TODO: So what is the “Do not disturb” setting doing then 🙂
TODO: find out what happens when both /usr/share/sounds/librem5 and ~/.local/share/sounds/librem5 exist

Pinephone

It is great to use a phone that runs *real* Linux. (Although I do own the OpenMoko, and the Nokia N770 too :-)). Here are a few technical notes to myself how to tweak it:

#GNOME software daemon uses obscene amounts of memory and I update manually anyway 
rm /etc/xdg/autostart/gnome-software-service.desktop

Connecting Keepassxc Portable on Windows with Firefox

I am using the excellent KeepassXC on all my computers, it works on Windows (work-supplied laptop), Linux (home) and there are mobile clients too. On my Windows work laptop I am using the PortableApps version. The keepassxc devs offer a portable zip for download (KUDOS!) but I do like the seamless upgrades and the start menu the PortableApps platform offers. So far, so good.

However, I – seemingly like many others – have trouble to connect the portable version with the Firefox browser extension to enable autofill. After lots of trial and error and debugging attempts (debugging led to no more detail than “key exchange failed”, unfortunately), I have gotten it working. See below what I did, in the hope that it might be useful for others and for future reference to myself (I posted this in the portable app forum too -and- as the problem seems widespread as an issue in the keepassxc issue tracker. It was quickly closed there as the devs don’t want to support PortableApps versions, fair enough, but would perhaps saved them a few support requests if the information were to be find in their development wiki):

Initial Problem PortableApps Keepassxc (2.5.3)
Some things worked as intended:

  • I had a registry key under “Computer\HKEY_CURRENT_USER\Software\Mozilla\NativeMessagingHosts\org.keepassxc.keepassxc_browser”,
  • it pointed to the correct org.keepassxc.keepassxc_browser_firefox.json file
  • which pointed to a correct path “C:\Users\spaetz\bin\PortableApps\KeePassXCPortable\App\KeePassXC\keepassxc-proxy.exe”

When I started Firefox, I got a running keepassxc-proxy.exe process as a Firefox child process. However, trying to connect, all I got is a “key exchange failed” error. Turning on add-on debugging led to the same result and not more helpful information.
When I turned off the use of a proxy in the keepassxc settings (Browser integration -> Advanced), starting Firefox actually also started a keepassxc instance automatically, however all I still got was a “key exchange failed” error. NO combination of options, deleting of keepassxc and/or the browser extension, deletion of registry entries, or using a fresh Firefox profile helped.

Possible Solution

I noted that there are actually 2 binaries:
BINARY1:
C:\Users\spaetz\bin\PortableApps\KeePassXCPortable\KeePassXCPortable.exe (248kb) and
BINARY2:
C:\Users\spaetz\bin\PortableApps\KeePassXCPortable\App\KeePassXC\KeePassXC.exe (7094kb)

The latter is also the directory which contains the keepassxc-proxy.exe. The binary in the former directory is what is started when one starts keepassxc through the PortableApps menu.

IF I directly start the latter binary, the Firefox extension is able to connect to the running keepassxc. If I start the former, I will get a key exchange failed error. Somehow, in this case the proxy will probably try to talk to the wrong binary. (not sure what weird wrapper the first binary is).

I autostart BINARY2 now on system start (Hit WIN-R, type shell:startup and paste a “link” to the correct keepassxc.exe) and that seems to do the trick for me. I realize that this is not the fault of keepassxc, but given the multitude of reported errors and the unhelpful error message I think this might be of use for other users of the Portable Version. It might be useful on the wiki if confirmed by other users of the portable version on windows….

Home Assistent Pitfalls

I have been playing with Home Assistent. Yes, our home should be smart too :-). But I am not giving up my privacy, so only a local solution was considered! Here are a few pitfalls that I experienced when configuring Home Assistant, I hope they are useful to you too.

FritzBox device tracker:

I have a FritzBox from AVM, so I installed the “platform: fritz” module to track devices in our WLAN. However, that led to mysterious “Failed to establish connection to FRITZ!Box with IP: 169.254.1.1” errors. Debugging the underlying package “fritzconnection”, it turns out that you need to turn on “Zugriff für Anwendungen zulassen” AND “Statusinformationen über UPnP übertragen” in your Homenetwork->Network Settings, to make it work. This will turn on TR-64 and the transmission of the necessary status information. Error handling of this package could be a tad better….

FritzBox DECT switch (Fritz DECT 210):

the “platform: fritzdect” module is supposed to handle The Fritz DECT 210 remote switch. However, I still haven’t gotten it to work. I receive error messages in the form:

 File "/usr/local/lib/python3.6/dist-packages/homeassistant/components/switch/f
ritzdect.py", line 157, in update
 self.state = actor.get_state()
 File "/home/hassio/.homeassistant/deps/lib/python3.6/site-packages/fritzhome/a
ctor.py", line 56, in get_state
 int(self.box.homeautoswitch("getswitchstate", self.actor_id))
ValueError: invalid literal for int() with base 10: 'inval'

Notifications via XMPP/Jabber:

I have managed to receive notification messages via XMPP when certain things happen. Now I need to come up with smart rules, to make things smart….

ARTICLE WILL BE UPDATED AS I PLAY MORE WITH HOME ASSISTANT.

CIFS mount on Linux

If you start running into mysterious CIFS mount errors on a recent Debian (“mount error(95): Operation not supported“) or autofs stops working (“mount(generic): failed to mount //192.168.178.2/YY (type cifs) on /home/YYY”),

try to add “vers=2.0” (or vers=1.0) to your mount options. Recent kernels default to samba version 3, which apparently is not supported by many boxes (including my Synology)

Using an HTTP proxy when a VPN is used

Background: When I connect to my University’s VPN service I need to use a HTTP proxy in order to access the WWW. I use GNOME and Network-Manager. The Openconnect plugin manages to establish the VPN connection nicely, but previously I had to enable the proxy in Firefox manually afterwards. This is my solution on how to set GNOMEs http proxy settings automatically when a VPN connection with the name “UniiHH” is established and works by using a script in /etc/Network-Manager/dispatch.d.

This is my 10_enablevpnproxy (needs permission 755):

#!/bin/sh -e
# Script to set up the University of Hamburg web proxy when the Openconnect VPN connected
# credits to https://wiki.ubuntuusers.de/NetworkManager/Dispatcher/

VPN_CONNECTION_NAME="UniHH"
USER="spaetz"

# VPN connection started or stopped?
case "$2" in
    vpn-up)
    active_vpn=$(nmcli -t --fields NAME con show --active|grep "${VPN_CONNECTION_NAME}" -q)
    if $active_vpn; then
        # VPN to UNI HH was started
    else
        #Irrelevant VPN started, do nothing
        exit 0
    fi
    # gsettings will fail if dbus is not launched with:
    # "dconf-WARNING **: failed to commit changes to dconf: Cannot autolaunch D-Bus without X11 $DISPLAY
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy mode 'manual' 
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy.http host 'proxy.uni-hamburg.de'
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy.http port 3128
    ##gsettings set org.gnome.system.proxy.ftp host 'proxy.localdomain.com'
    ##gsettings set org.gnome.system.proxy.ftp port 3128
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy.https host 'proxy.uni-hamburg.de'
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy.https port 3128
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy ignore-hosts "['localhost', '127.0.0.0/8', '10.0.0.0/8', '192.168.0.0/16', '172.16.0.0/12' , 'fc00::/8' , '*.fritz.box' ]"
        ;;
    vpn-down)
    # Disable all proxies on VPN shutdown, this might be to simple
    # for your case, it works for me.
    echo "VPN connection was stopped"
    sudo -u "$USER" dbus-launch gsettings set org.gnome.system.proxy mode 'none'
        ;;
esac
exit 0;

The script is run as root by network-manger so, I needed to hardcode the user whose proxy settings I want to modify in the script. And admittedly the part about calling sudo -u $USER dbus-launch multiple times is quite clumsy and should be solved more elegantly. The problem is that gsettings needs to a) run as the user whose values we want to change and b) needs access to a running dbus-session or it will spit out:

Cannot autolaunch D-Bus without X11 $DISPLAY

Helpful links were: https://wiki.archlinux.org/index.php/proxy_settings https://wiki.ubuntuusers.de/NetworkManager/Dispatcher/ http://askubuntu.com/questions/645968/error-cannot-autolaunch-d-bus-without-x11-display

P.S. Of course, sudo needs to be installed for this script.

Getting WiFi rtl8723be to work in Debian

After crashing my previous laptop, I bought a HP 15-ba055ng that contains a rtl8723be Wifi card. However, under Linux the connection would become instable after a short while and refuse to reconnect. I needed to do a series of things to fix this:

  1. Apparently only 1 antenna is connected to the card while the card is configured to use a different antenna slot, leading to an abysmal signal. A new parameter was introduced in kernen 4.0.7 (or so) that lets on select the antenna in the kernel module.
    Create a file /etc/modprobe.d/rtl8723be.conf and enter

    options rtl8723be ant_sel 1

    (the default is 0). This let to a much better signal reception (as visible by doing iwlist scanning). But it still did not help, connection got refused after a while.

  2. Some other options need to be changed to make it work. Most people say that disabling sleep parameter fwlps (FW control power save, default 1) helped. So, that would be adding fwlps=0 to the above line. I did that.In addition some claim, that setting ips=0 or msi=1 has helped them to get a better reception. Try it, I use ips=0, but msi=1 seemed not necessary, so that my current options look like this: options rtl8723be ant_sel=1 ips=0 fwlps=0
  3. Some claim that windows fasstboot mode needs to be disabled in order to make WiFi work reliably. (in case you dualboot) However, I have not tried that yet, nor found it necessary.

All this is on a Debian Jessie system. On a final note: I find it pretty sad that a laptop sold in 2016 has no 5Ghz capabilities. I did not even fact-check that before my purchase as it did not occur to me that this could be an issue.

Relevant links I used for trouble-spotting (plus a ton of other links I forgot about):

  • https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1461174/comments/35
  • https://unix.stackexchange.com/questions/229221/rtlwifi-rtl8723befw-bin-wireless-stop-working-then-laptop-needs-to-reboot-to
  • http://askubuntu.com/questions/635625/how-do-i-get-a-realtek-8723be-wireless-card-to-work
  • https://ubuntuforums.org/showthread.php?t=2304607&page=4
  • https://bugzilla.kernel.org/show_bug.cgi?id=83641#c1