Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions files/paperless-virtual-printer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM debian:bullseye-slim
ARG USERNAME=print PASSWORD=print
ENV \
PRINTER_ID=Paperless \
PRINTER_NAME=Paperless \
HOSTNAME=127.0.0.1 \
OUTPUT_SUBPATH=vprint \
OUTPUT_USERNAME=$USERNAME

# Dependenicies
RUN apt-get update
RUN apt-get install -y --no-install-recommends cups printer-driver-cups-pdf gettext

# Cups config/setup
RUN useradd -G lp,lpadmin -s /bin/bash -p "$(openssl passwd -1 $PASSWORD)" $USERNAME

# discoverability
RUN apt-get install -y avahi-daemon
RUN sed -i 's/.*enable\-dbus=.*/enable\-dbus\=no/' /etc/avahi/avahi-daemon.conf

# Copy configs
WORKDIR /opt/vp
COPY . .

CMD ["./entrypoint.sh"]
9 changes: 9 additions & 0 deletions files/paperless-virtual-printer/cups-pdf.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Cups PDF printer to /mnt

Out /mnt/output
AnonDirName /mnt/output
Label 0
AnonUser ${OUTPUT_USERNAME}

Grp lpadmin
DecodeHexStrings 1
190 changes: 190 additions & 0 deletions files/paperless-virtual-printer/cupsd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#
# Configuration file for the CUPS scheduler. See "man cupsd.conf" for a
# complete description of this file.
#

# Log general information in error_log - change "warn" to "debug"
# for troubleshooting...
LogLevel warn
PageLogFormat

# Deactivate CUPS' internal logrotating, as we provide a better one, especially
# LogLevel debug2 gets usable now
MaxLogSize 0

# Only listen for connections from the local machine.
Listen *:631
Listen /run/cups/cups.sock
ServerAlias *

# Show shared printers on the local network.
Browsing On
BrowseLocalProtocols dnssd

# Default authentication type, when authentication is required...
DefaultAuthType Basic
DefaultEncryption Never

# Web interface setting...
WebInterface Yes

# Restrict access to the server...
<Location />
Order allow,deny
Allow all
</Location>

# Restrict access to the admin pages...
<Location /admin>
Order allow,deny
Allow all
</Location>

# Restrict access to configuration files...
<Location /admin/conf>
AuthType Default
Require user @SYSTEM
Order allow,deny
</Location>

# Restrict access to log files...
<Location /admin/log>
AuthType Default
Require user @SYSTEM
Order allow,deny
</Location>

# Set the default printer/job policies...
<Policy default>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default

# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
Order deny,allow
</Limit>

<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

<Limit All>
Order deny,allow
</Limit>
</Policy>

# Set the authenticated printer/job policies...
<Policy authenticated>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default

# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
AuthType Default
Order deny,allow
</Limit>

<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
AuthType Default
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
AuthType Default
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

<Limit All>
Order deny,allow
</Limit>
</Policy>

# Set the kerberized printer/job policies...
<Policy kerberos>
# Job/subscription privacy...
JobPrivateAccess default
JobPrivateValues default
SubscriptionPrivateAccess default
SubscriptionPrivateValues default

# Job-related operations must be done by the owner or an administrator...
<Limit Create-Job Print-Job Print-URI Validate-Job>
AuthType Negotiate
Order deny,allow
</Limit>

<Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
AuthType Negotiate
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

# All administration operations require an administrator to authenticate...
<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# All printer operations require a printer operator to authenticate...
<Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
AuthType Default
Require user @SYSTEM
Order deny,allow
</Limit>

# Only the owner or an administrator can cancel or authenticate a job...
<Limit Cancel-Job CUPS-Authenticate-Job>
AuthType Negotiate
Require user @OWNER @SYSTEM
Order deny,allow
</Limit>

<Limit All>
Order deny,allow
</Limit>
</Policy>
30 changes: 30 additions & 0 deletions files/paperless-virtual-printer/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
set -e

declare -r usermap_original_uid=$(id -u print)
declare -r usermap_original_gid=$(id -g print)
declare -r usermap_new_uid=${USERMAP_UID:-$usermap_original_uid}
declare -r usermap_new_gid=${USERMAP_GID:-${usermap_original_gid:-$usermap_new_uid}}

if [[ ${usermap_new_uid} != "${usermap_original_uid}" ]]; then
echo "${log_prefix} Mapping UID to $usermap_new_uid"
usermod --non-unique --uid "${usermap_new_uid}" print
else
echo "${log_prefix} No UID changes"
fi

if [[ ${usermap_new_gid} != "${usermap_original_gid}" ]]; then
echo "${log_prefix} Mapping GID to $usermap_new_gid"
groupmod --non-unique --gid "${usermap_new_gid}" print
else
echo "${log_prefix} No GID changes"
fi

cat cups-pdf.conf | envsubst > /etc/cups/cups-pdf.conf
cat cupsd.conf | envsubst > /etc/cups/cupsd.conf
cat printers.conf | envsubst > /etc/cups/printers.conf
cat vprint.service | envsubst > /etc/avahi/services/vprint.service
cp /usr/share/ppd/cups-pdf/CUPS-PDF_noopt.ppd /etc/cups/ppd/${PRINTER_ID}.ppd

/usr/sbin/avahi-daemon --daemonize
exec /usr/sbin/cupsd -f
22 changes: 22 additions & 0 deletions files/paperless-virtual-printer/printers.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Printer configuration file for CUPS v2.2.10
# Written by cupsd
# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING
<DefaultPrinter ${PRINTER_ID}>
UUID urn:uuid:b5105127-039f-3bdc-6153-762925a06b8f
Info ${PRINTER_NAME}
Location
MakeModel Generic PostScript Printer
DeviceURI cups-pdf:/
State Idle
StateTime 1666751881
ConfigTime 1666751900
Type 8400972
Accepting Yes
Shared Yes
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy retry-job
</DefaultPrinter>
22 changes: 22 additions & 0 deletions files/paperless-virtual-printer/vprint.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" ?><!DOCTYPE service-group SYSTEM 'avahi-service.dtd'>
<service-group>
<name replace-wildcards="yes">${PRINTER_NAME}</name>
<service>
<type>_ipp._tcp</type>
<subtype>_universal._sub._ipp._tcp</subtype>
<port>631</port>
<txt-record>adminurl=http://${HOSTNAME}/printers/${PRINTER_ID}</txt-record>
<txt-record>txtvers=1</txt-record>
<txt-record>qtotal=1</txt-record>
<txt-record>Transparent=T</txt-record>
<txt-record>URF=DM3</txt-record>
<txt-record>rp=printers/${PRINTER_ID}</txt-record>
<txt-record>note=Virtual ${PRINTER_NAME}</txt-record>
<txt-record>product=(Generic PostScript Printer)</txt-record>
<txt-record>ty=Generic PostScript Printer</txt-record>
<txt-record>printer-state=3</txt-record>
<txt-record>printer-type=0x800004</txt-record>
<txt-record>application/postscript</txt-record>
<txt-record>pdl=application/octet-stream,application/pdf,application/postscript,application/vnd.cups-raster,image/gif,image/jpeg,image/png,image/tiff,image/urf,text/html,text/plain,application/msword,application/pclm,application/rss+xml,application/sgml</txt-record>
</service>
</service-group>
8 changes: 8 additions & 0 deletions group_vars/docker/vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ all_container_users:
gid: 215
hosts:
- memory_alpha
- username: paperless-printer
uid: 216
gid: 216
groups:
- archive
- scanners
hosts:
- memory_alpha

container_user_opts:
shell: /usr/sbin/nologin
Expand Down
28 changes: 27 additions & 1 deletion host_vars/memory_alpha/vars.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ target_os: ubuntu

appdata_path: /mnt/zfs/appdata
archive_path: /mnt/zfs/archive
paperless_consume_path: /mnt/transient/paperless/consume

media_downloads_mountpoint: "/mnt/zfs/media-downloads"

Expand Down Expand Up @@ -580,7 +581,7 @@ docker_compose_projects:
owner: paperless
group: archive
mode: "u+rwx,g+rwx"
- source: /mnt/transient/paperless/consume
- source: "{{ paperless_consume_path }}"
target: /usr/src/paperless/consume
owner: paperless
group: scanners
Expand Down Expand Up @@ -666,8 +667,33 @@ docker_compose_projects:
restart: unless-stopped
labels:
- "traefik.enable=false"
- service_name: virtual-printer
build:
context: virtual-printer
src: paperless-virtual-printer
restart: unless-stopped
environment:
USERMAP_UID: "{{ (container_users | selectattr('username', 'equalto', 'paperless-printer') | list | first).uid }}"
USERMAP_GID: "{{ (nas_groups | selectattr('name', 'equalto', 'scanners') | list | first).gid }}"
networks:
- virtual-printer-vlan
volumes:
- source: "{{ paperless_consume_path }}"
target: /mnt/output
create: false
ports:
- 631:631
networks:
- name: paperless
- name: virtual-printer-vlan
driver: macvlan
driver_opts:
parent: "{{ ansible_default_ipv4.interface }}"
ipam:
config:
- subnet: "192.168.5.0/24"
ip_range: "192.168.5.134/32" # Static IP
gateway: "192.168.5.1"
- name: proxy
external: true
alias: "{{ traefik_docker_network }}"
Expand Down