Share printer via AirPrint with NixOS

I started to migrate my ARM homeserver to NixOS and was able to configure the printer together with AirPrint enabled network sharing. Here’s a short how-to.

Update June 2022: Starting with newer Cups printing server versions (> 2.4), AirPrint support is already included and the configuration should be easier. See the section below for an updated instruction.

The following excerpt of my NixOS system configuration includes following sections:

  • Firewall rules to open ports for the printing server CUPS. Please note that these ports will be accessable to all interfaces on all networks using this configuration scheme.
  • Printing service CUPS with optional driver specification. listenAddresses and extraConf is required to share the printer on the network without authentication.
  • Avahi daemon for broadcasting zero-conf services on the network, especially configured to announce our network printer. This is what will make your printer appear on your Android or Apple phone.
  • The last section is the device configuration for our USB attached printer. This of course is different depending on the printer model you’ll use.
networking.firewall = {
  allowedTCPPorts = [ 631 ];
  allowedUDPPorts = [ 631 ];
};

services = {
  printing = {
    enable = true;
    drivers = with pkgs; [
 foo2zjs ];
    browsing = true;
    defaultShared = true;
    listenAddresses = [ "0.0.0.0:631" ];
    extraConf = ''
      <Location />
        Order allow,deny
        Allow all
      </Location>
    '';
  };
  avahi = {
    nssmdns = true;
    enable = true;
    ipv4 = true;
    ipv6 = true;
    publish = {
      enable = true;
      addresses = true;
      workstation = true;
    };
    openFirewall = true;
    extraServiceFiles = {
      airprint = "/etc/nixos/airprint.service";
    };
  };
};

hardware.printers = {
  ensurePrinters = [
  {
    name = "Dell_1250c";
    location = "Home";
    deviceUri = "usb://Dell/1250c%20Color%20Printer?serial=YNP023240";
    model = "Dell-1250c.ppd.gz";
    ppdOptions.PageSize = "A4";
  }
  ];
  ensureDefaultPrinter = "Dell_1250c";
};

The following file defines the network printer for the Avahi daemon and is referenced above. You’ll habe to change name, url and supported printing modes according to your needs.

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name>Dell 1250c</name>
  <service>
    <type>_ipp._tcp</type>
    <subtype>_universal._sub._ipp._tcp</subtype>
    <port>631</port>
    <txt-record>txtver=1</txt-record>
    <txt-record>qtotal=1</txt-record>
    <txt-record>rp=printers/Dell_1250c</txt-record>
    <txt-record>ty=Dell 1250c</txt-record>
    <txt-record>adminurl=http://192.168.178.2:631/printers/Dell_1250c</txt-record>
    <txt-record>note=Dell 1250c</txt-record>
    <txt-record>priority=0</txt-record>
    <txt-record>product=(GPL Ghostscript)</txt-record>
    <txt-record>printer-state=3</txt-record>
    <txt-record>printer-type=0x801046</txt-record>
    <txt-record>Transparent=T</txt-record>
    <txt-record>Binary=T</txt-record>
    <txt-record>Fax=F</txt-record>
    <txt-record>Color=T</txt-record>
    <txt-record>Duplex=F</txt-record>
    <txt-record>Staple=F</txt-record>
    <txt-record>Copies=T</txt-record>
    <txt-record>Collate=F</txt-record>
    <txt-record>Punch=F</txt-record>
    <txt-record>Bind=F</txt-record>
    <txt-record>Sort=F</txt-record>
    <txt-record>Scan=F</txt-record>
    <txt-record>pdl=application/octet-stream,application/pdf,application/postscript,image/jpeg,image/png,image/urf</txt-record>
    <txt-record>URF=W8,SRGB24,CP1,RS600</txt-record>
  </service>
</service-group>

I already described how to setup this network printer on Linux, Windows and your phones in an earlier post.

Unfortunately this setup is still too complicated in my opinion. Hopefully native AirPrint support will be available in the upcoming Cups 2.4 version by OpenPrinting as suggested by this pull request.

Updated instruction (June 2022)

Starting with Cups 2.4 which is already included in the latest NixOS 22.05 release, it should now be possible to share the printer for AirPrint clients with following configuration

networking.firewall = {
  allowedTCPPorts = [ 631 ];
  allowedUDPPorts = [ 631 ];
};

services = {

  printing = {
    enable = true;
    drivers = [ pkgs.foo2zjs ]; # dell 1250c
    browsing = true;
    defaultShared = true;
    listenAddresses = [ "*:631" ];
    allowFrom = [ "all" ];
    extraConf = ''
      DefaultPaperSize A4
    '';
  };

  avahi = {
    enable = true;
    nssmdns = true;
    openFirewall = true;
    publish = {
      enable = true;
      userServices = true;
    };
  };

};

hardware.printers = {
  ensurePrinters = [
    {
      name = "Dell_1250c";
      location = "Home";
      deviceUri = "usb://Dell/1250c%20Color%20Printer?serial=YNP023240";
      model = "Dell-1250c.ppd.gz";
      ppdOptions = {
        PageSize = "A4";
      };
    }
  ];
  ensureDefaultPrinter = "Dell_1250c";
};

Replace the printer and driver configuration according to your setup. Note that the network access to your Cups printing server can and should be further restricting using the interface or firewall configuration.

💬 Are you interested in our work or have some questions? Join us in our public Signal chat pi crew 👋
🪙 If you like our work or want to supprot us, you can donate MobileCoins to our address.

Leave a Reply

Your email address will not be published. Required fields are marked *