Debian Container for Isolating Close-source Printer Drivers
Main idea:
- Put the close-source printer drivers in a Debian container with CUPS installed
- The main system will communicate with the container via CUPS network printing
Modification since the last version:
- Stop using
systemd-nspawnthat is a part of thesystemdbloatware.
Install relevant packages:
1
2sudo pacman -S debootstrap debian-archive-keyring
sudo pacman -S lxc dnsmasqCreate the Debian container:
1
sudo lxc-create -n debian-printer -t download -- -d debian -r bookworm -a amd64
Set up network interface:
1
2
3# /etc/default/lxc-net
USE_LXC_BRIDGE="true"1
2
3
4
5
6
7# First enable the service
sudo systemctl start lxc-net
sudo systemctl enable lxc-net
# Or
sudo rc-service lxc-net start
sudo rc-update add lxc-net default
Now, check that lxcbr0 is up and running:
1 | ip addr show lxcbr0 |
1 | # /etc/lxc/dnsmasq.conf |
Then set the IP address at /var/lib/lxc/debian-printer/config
- Starting the container:
1 | sudo lxc-start -n debian-printer |
Install CUPS
First, enter the container’s shell:1
sudo lxc-attach -n debian-printer
Temporarily set up the routing table:
1
2
3
4ip link set eth0 up
ip addr add 10.0.3.50/24 dev eth0
ip route add default via 10.0.3.1
printf 'nameserver 1.1.1.1\nnameserver 8.8.8.8\n' > /etc/resolv.confThen, inside the container, install CUPS:
1
2
3
4
5
6
7apt update
apt install cups usbutils
systemctl enable cups
systemctl start cups
dpkg --add-architecture i386
apt update
apt install libc6:i386 libstdc++6:i386Install the close-source printer drivers:
On the host:1
sudo cp hl3045*.deb /var/lib/lxc/debian-printer/rootfs/root/
Then, inside the container:
1
dpkg -i hl3045cnlpr-1.1.2-1.i386.deb hl3045cncupswrapper-1.1.2-2.i386.deb
Create a stable syslink for the printer on the host (change the idVendor and idProduct values based on
lsusboutput):1
2# Find the correct info
udevadm info -a -n /dev/usb/lp01
2# /etc/udev/rules.d/99-brother-hl3045cn.rules
SUBSYSTEM=="usbmisc", KERNEL=="lp*", ATTRS{idVendor}=="04f9", ATTRS{idProduct}=="004e", SYMLINK+="usb/brother_hl3045cn"Configure device passthrough
1
2
3
4
5
6
7
8# /var/lib/lxc/debian-printer/config
# Allow usblp printer character devices.
# /dev/usb/lp0 is usually major 180.
lxc.cgroup2.devices.allow = c 180:* rwm
# bind only the stable printer path to /dev/usb/lp0:
lxc.mount.entry = /dev/usb/brother_hl3045cn dev/usb/lp0 none bind,create=file 0 0Configure CUPS on the subsystem:
1
2
3
4
5
6
7
8# /etc/cups/cupsd.conf
...
Listen 0.0.0.0:631
...
# Then in each of the <Location> sections, add:
Allow 192.168.50.1
...
# FileDevice Yes1
2
3
4systemctl restart cups
lpadmin -p HL3045CN -E \
-v file:///dev/usb/lp0 \
-P /opt/brother/Printers/hl3045cn/cupswrapper/brother_hl3045cn_printer_en.ppd1
2# /etc/cups/cups-files.conf
FileDevice yesConfiguring auto-start of the container:
1
2
3# /var/lib/lxc/debian-printer/config
lxc.start.auto = 1
lxc.start.delay = 5
Info for non-usblp printers
Use USBIP to forward the whole USB device to the container.
The container’s virtual bus will be visible on the host as a new USB device, but it should not interfere with the host’s USB subsystem.
Appendix: Using systemd-nspawn
Deprecated: I no longer use bloatware
Install relevant packages:
1
sudo pacman -S debootstrap debian-archive-keyring
Create the Debian container:
1
2
3
4
5
6sudo mkdir -p /var/lib/machines/debian-printer
sudo debootstrap \
--arch=amd64 \
--include=dbus,libpam-systemd \
stable \
/var/lib/machines/debian-printerRemember to set the password for the root user in the container.
Install CUPS
First, enter the container’s shell:1
sudo systemd-nspawn -D /var/lib/machines/debian-printer
Then, inside the container, install CUPS:
1
2
3
4
5apt update
apt install cups usbutils
systemctl enable cups
systemctl start cups
apt install libc6:i386 libstdc++6:i386Install the close-source printer drivers:
On the host:1
sudo cp hl3045*.deb /var/lib/machines/debian-printer/root/
Then, inside the container:
1
2
3dpkg --add-architecture i386
apt update
dkpg -i hl3045cnlpr-1.1.2-1.i386.deb hl3045cncupswrapper-1.1.2-2.i386.debCreate a stable syslink for the printer on the host (change the idVendor and idProduct values based on
lsusboutput):1
2# Find the correct info
udevadm info -a -n /dev/usb/lp01
2# /etc/udev/rules.d/99-brother-hl3045cn.rules
SUBSYSTEM=="usbmisc", KERNEL=="lp*", ATTRS{idVendor}=="04f9", ATTRS{idProduct}=="004e", SYMLINK+="usb/brother_hl3045cn"Configure the network for the host:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# /etc/systemd/network/70-printer-veth.network
[Match]
Kind=veth
Name=ve-debian-p*
[Link]
RequiredForOnline=no
[Network]
# Default to using a /28 prefix, giving up to 13 addresses per container.
Address=192.168.50.1/30
LinkLocalAddressing=no
DHCPServer=no
IPv6AcceptRA=no
IPv6SendRA=no1
2sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkdConfigure the network for the container:
1
2
3
4
5sudo systemd-nspawn \
-D /var/lib/machines/debian-printer \
--network-veth \
--bind=/dev/usb/brother_hl3045cn:/dev/usb/lp0 \
--boot1
2
3
4
5
6
7
8# /etc/systemd/network/70-container-ve.network
[Match]
Name=host0
[Network]
Address=192.168.50.2/30
LinkLocalAddressing=no
IPv6AcceptRA=no1
2sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkdCheck both machines with
ip addr.Configure CUPS on the subsystem:
1
2
3
4
5
6
7
8# /etc/cups/cupsd.conf
...
Listen 0.0.0.0:631
...
# Then in each of the <Location> sections, add:
Allow 192.168.50.1
...
FileDevice Yes1
2
3
4systemctl restart cups
lpadmin -p HL3045CN -E \
-v file:///dev/usb/lp0 \
-P /opt/brother/Printers/hl3045cn/cupswrapper/brother_hl3045cn_printer_en.ppdCreate nspawn service for the container:
1
2
3
4
5
6
7
8
9
10
11# /etc/systemd/nspawn/debian-printer.nspawn
[Exec]
PrivateUsers=yes
Capability=
Boot=yes
[Network]
Private=yes
[Files]
Bind=/dev/usb/brother_hl3045cn:/dev/usb/lp0Create the printer on the host:
1
2
3
4lpadmin -p brother \
-E \
-v ipp://192.168.50.2:631/printers/HL3045CN \
-m everywhere
Then update config on the host:
1 | #/etc/systemd/system/[email protected]/override.conf |
1 | sudo systemctl daemon-reload |
Purging the container:
1 | sudo machinectl stop debian-printer |