Raspberry Pi bluetooth console
Sometimes you want to connect to a bluetooth on the console. Likely because you screwed something up with the network or filewall settings.
You could plug in a screen and keyboard, but that’s a hassle. And maybe you didn’t prepare the Pi to force the monitor to be on even if it’s not connected at boot. Then it just doesn’t work.
Even more of a hassle is to plug in a serial console cable into the GPIO pins.
But modern Raspberry Pi’s have bluetooth. So let’s use that!
Setting up the service on the raspberry pi
Create /etc/systemd/system/bluetooth-console.service
with this content:
[Unit]
Description=Bluetooth console
After=bluetooth.service
Requires=bluetooth.service
[Service]
ExecStart=/usr/bin/rfcomm watch hci0 1 getty rfcomm0 115200 vt100
Restart=always
RestartSec=10
StartLimitIntervalSec=0
[Install]
WantedBy=multi-user.target
This sets up a console on bluetooth channel 1 with a login prompt. But
it doesn’t work yet. Apparently setting After
, Required
, and even
Requisite
doesn’t prevent systemd from running this before setting
up bluetooth (timestamps in the logs don’t lie). Hence the restart stuff.
I also tried setting ExecStartPre
/ ExecStartPost
there to enable
Bluetooth discoverability, since something else in the boot process
seems to turn it back off if I set it here.
So I did a terribly ugly solution and added this to /etc/rc.local
(
while true; do
sleep 20
/bin/hciconfig hci0 piscan
done
) &
If it works it’s not stupid?
Connecting from a laptop or something
Use the bluetooth address from hcitool dev hci0
on the raspberry pi,
and bind channel 1 to rfcomm0.
rfcomm bind rfcomm0 XX:YY:ZZ:AA:BB:CC 1
This will make your laptop connect to the raspberry pi on
demand. Which means it’ll take a few seconds once you actually try to
connect. Alternatively you can use rfcomm connect
, which connects
immediately, but then continues running in the foreground.
Then you can run minicom
or screen /dev/rfcomm1 115200
and be
connected to a terminal.
Security
This currently has no PIN to connect over bluetooth. So anyone could just connect and start bruteforcing the password.
So I recommend setting up one-time passwords such as OTPW.
If you don’t trust bluetooth security then you should also assume that anyone can see your connection. And potentially hijack it after you log in. So log out as soon as you’re done. And if the connection mysteriously seems to “hang”, then pull the power to the device. Though it’s far from perfect.
You may also be subject to a MitM attack. This clearly needs more work.
So maybe it would be better to run a network, IP over bluetooth, and use SSH.
But adding more dependencies like that could backfire. What if the thing I broke was SSH, and that’s the reason I need the console? Then I still need to drag out console cables and such.
TODO
I should update this post when I bother setting up a bluetooth PIN. Hell, I don’t even know if not using a PIN means the bluetooth encryption is essentially plaintext.
Also I need to experiment more with making sure it’s not pairable and discoverable 24/7.
Telling bluetoothctl
pairable no
and discoverable no
seems to do
it, but this will have to be all for now.
I’ll post this even though it’s not done, since I don’t know when I’ll next get to it.
Update
Jesus christ this takes 35%
CPU on a
raspberry pi because rfcomm watch
checks if the child process has
exited once every 200 nanoseconds.
And it’s been that way since 2006.
This really shows how underused Bluetooth is. This bug has not been found for 16 years, presumably because nobody bothers with bluetooth because it’s so often full of compatability problems anyway.
For now I’ve built my own fixed version of rfcomm
.