Blog Entry

Setting up Secure MPD Control from Android


EDIT:

I've found a better solution for this setup here.

Setting up Secure MPD Control from Android

This post documents setting up secure MPD control. You will be able to control MPD running on your host Linux system via an MPD client on your Android device. By using firejail, the client connection will be restricted to only accessing MPD, and cannot access the internet through the ssh connection.

Note that sshd configuration is not covered in this post, and it is expected for you to know how to.

Requirements:

Note it is expected that your system is using systemd.

Setting up the Host

Securing access

Creating the user to log into

Create a new user that uses firejail as its default shell:

sudo useradd -m -s /bin/firejail jailuser

Note we created the user that will accept ssh connections as jailuser. If you use a different username, be sure to keep track of that as later parts in this post refer to jailuser.

Creating the bridge interface

Create a systemd service that will start a bridge interface that the firejail instance of the new user will use:

Place the following snippet in /etc/systemd/system/jailuser_br.service

[Unit]
Description=Set up bridge interface for jailuser

[Service]
Type=oneshot
ExecStart=/usr/bin/brctl addbr jailuser_br
ExecStart=/usr/bin/ip addr add 192.168.2.1/30 dev jailuser_br
ExecStart=/usr/bin/ip link set jailuser_br up
RemainAfterExit=yes
ExecStop=/usr/bin/ip link set jailuser_br down
ExecStop=/usr/bin/brctl delbr jailuser_br

[Install]
WantedBy=multi-user.target

This oneshot service will create a new interface for the jail to connect to. Note that we are using the 192.168.2.0/30 subnet, and assigned 192.168.2.1 to the host system. You will need to sudo systemctl daemon-reload after creating the file to make systemd aware of it (unless you choose to reboot first), then sudo systemctl enable jailuser_br to make systemd execute it on every boot. If you want to create the interface now, do sudo systemctl start jailuser_br.

Restricting the new user

Create the directory in jailuser's home that will have the firejail config for the login shell (note jailuser by default cannot access this file).

sudo mkdir -p /home/jailuser/.config/firejail

Place the following snippet in /home/jailuser/.config/firejail/default.profile:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Firejail profile for default
# This file is overwritten after every install/update
# Persistent local customizations
include default.local
# Persistent global definitions
include globals.local

# generic gui profile
# depending on your usage, you can enable some of the commands below:

include disable-common.inc
# include disable-devel.inc
# include disable-exec.inc
# include disable-interpreters.inc
include disable-passwdmgr.inc
include disable-programs.inc
# include disable-xdg.inc

# apparmor
caps.drop all
# ipc-namespace
# machine-id
# net none
net jailuser_br
ip 192.168.2.2
#netfilter
netfilter /etc/firejail/dropallbutmpd.net
# no3d
# nodbus
# nodvd
# nogroups
nonewprivs
noroot
# nosound
# notv
# nou2f
# novideo
protocol unix,inet,inet6
seccomp
# shell none
shell /bin/bash
# tracelog

# disable-mnt
# private
# private-bin program
# private-cache
# private-dev
# private-etc alternatives
# private-lib
# private-tmp

# memory-deny-write-execute

Note this snippet is a copy of /etc/firejail/default.profile except with a few changes:

Restricting the network in which the user has access to

Place the following snippet in /etc/firejail/dropallbutmpd.net

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

#allow all loopback traffic
-A INPUT -i lo -j ACCEPT

# allow ping etc.
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# allow access to mpd
-A INPUT -p tcp --sport 6600 -s 192.168.2.1 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --dport 6600 -d 192.168.2.1 -m state --state NEW,ESTABLISHED -j ACCEPT

COMMIT

The dropallbutmpd.net file will enforce dropping of all connections except to the host's MPD (at port 6600). If your MPD is listening on a port other than 6600, you will have to change that in the previous snippet. You may also have to change the 192.168.2.1 if you are using a different local subnet and address for the host. Right now, those two entries refer to the host's ip address in the bridge interface.

Other configuration

Finally, if you have a firewall configured, you will need to allow connections from 192.168.2.0/30 to the host at port 6600 over tcp. For example, configuration for ufw can be used as follows:

ufw allow in proto tcp from 192.168.2.0/30 to any port 6600

Setting up the Client

As mentioned before, sshd configuration is not covered in this post, but you are expected to have set up a key set up for an ssh client to connect to the host with. The ssh client must be set up to forward local connections at 6600 to 192.168.2.1:6600, which is equivalent to something like ssh -L 6600:192.168.2.1:6600.

Prior to using your MPD client, you will need to access your host system with the ssh client and have port 6600 forwarded to the host. It is kind of inconvenient, but it is the price we must pay to secure the connection.

You will need to install an MPD client on your Android device. I've gotten this setup to work with M.A.L.P., which is available on the F-Droid app repository.

Make sure your MPD client has set up a connection to localhost:6600, including the password that your MPD has been set up with if it is set.

Using the setup

Your host should have the jailuser user created, have configuration for that user's firejail shell set up in /home/jailuser/.config/firejail/default.profile, sshd should be configured for that user, /etc/firejail/dropallbutmpd.net should exist and enforce the restricted network, and the jailuser_br interface should be up.

All that's left is to connect to the host's sshd with the ssh client on your Android device, and then open the MPD client to interface with the host's MPD.

When the client logs in as jailuser on your host, the session will log in with the /bin/firejail shell (which isn't actually a shell but ends up running a restricted /bin/bash session by default), which will automatically load the profile in /home/jailuser/.config/firejail/default.profile and enforce the restricted network for the session. The internet will be unavailable in the session, and only connections to the host's ip (192.168.2.1) at port 6600 will be available, which should be what your MPD on the host is listening on.

Comments:

There are no comments for this post.