I've long wanted to deploy AirPrint in my school. The school network however is split up in different VLANs, with the printers being in one VLAN and the end user devices in another. AirPrint by default uses Multicast DNS (mDNS), and since multicast traffic isn't routed, I was looking for a different approach.
In the end, I successfully managed to deploy AirPrint in my scenario using DNS Service Discovery (DNS-SD). The prerequisites are:
- A DNS server. Using Windows Server DNS is okay, however you will also need a Linux machine with BIND on it, since Windows can't handle the DNS entries required by Bonjour.
- A DHCP server.
- The
dns-sd
utility. It's integrated in macOS and you can download it for Windows (Bonjour SDK).
How DNS service discovery works
Connecting an Apple device to a single network with AirPrint enabled printers in it usually works out of the box. The device looks for printers using mDNS, which is fine in if you have only one network. If you have split up your network in different subnets however, you'll find that a device can't discover the printers or devices in another subnet. This is because multicast DNS traffic is not routed. There are solutions for relaying multicast traffic to other networks at router-level, but that also increases the traffic in your network.
So I was looking for a different solution, and found it to be DNS Service Discovery (DNS-SD). Using DNS-SD will allow you to publish information about services like printers in your DNS, where your clients can access it. This protocol is specified in RFC 6763.
When connecting a client to a network that offers DNS-SD, the following will happen.
- The client will request information about the network using DHCP.
- Among the information passed to the client are the DNS servers (DHCP option 6), the domain name (DHCP option 15) and the domain search list (DHCP option 119). Let's call the domain used in your network
<DOMAIN>
.
Warning: In my experiments, DNS-SD failed on Apple devices when your <DOMAIN>
ends in .local
. When using a .local domain, you must create a different domain that is passed to your Apple devices via DHCP.
After the client acquired this information, it checks for the availability of DNS-SD by issuing a DNS PTR request to lb._dns-sd._udp.<DOMAIN>
. The PTR record should point to a domain that will be used for DNS-SD. In my setup, I used bonjour.<DOMAIN>
for that.
A technical note: Section 11 of RFC 6763 states that also b._dns-sd._udp.<DOMAIN>
should be queried. So you should also point a PTR record from that domain to bonjour.<DOMAIN>
.
Further technicality: Since I was unaware that the DHCP domain name must not end in .local, I found my Apple devices issuing queries to the DNS reverse lookup zone (like lb._dns-sd._udp.<REVERSED NETWORK IP>.in-addr.arpa
). Configuring a different domain in DHCP that does not end in .local solved that for me.
The client now knows to query bonjour.<DOMAIN>
for DNS service discovery. When looking for a printer for example, it issues a PTR query to _ipps._tcp.bonjour.<DOMAIN>
. The server replies with a list of printers that the client can query for further information.
Setting up DNS-SD in a Windows Server Network
My setup is embedded into an Active Directory network that uses Windows Server. Since Windows Server DNS can't handle the DNS records required by AirPrint and some other DNS-SD services, I installed BIND on a Linux machine. This BIND is only used for the bonjour.<DOMAIN>
domain.
DHCP prerequisites
First, check that DHCP sends the domain name <DOMAIN>
to your clients using DHCP option 15. As stated above, <DOMAIN>
must not end with .local.
DHCP must also send the DNS search domain to the clients using DHCP option 119. As of today, you must add this DHCP option to Windows Server manually. There's an article describing how to do so.
Setting up DNS
In Windows Server DNS, create two pointer records that point to bonjour.<DOMAIN>
, the DNS-SD domain.
lb._dns-sd._udp.<DOMAIN> PTR bonjour.<DOMAIN>
b._dns-sd._udp.<DOMAIN> PTR bonjour.<DOMAIN>
After that, in Windows Server DNS add a delegation for bonjour.<DOMAIN>
to your Linux server running BIND on it. The zone file in BIND looks like that (you might want to set a higher TLL and refresh time after your setup is working).
$ORIGIN bonjour.<DOMAIN>.
$TTL 10
bonjour.<DOMAIN>. IN SOA ns.bonjour.<DOMAIN>. administrator.<DOMAIN>. (
2022091503 ; Serial
180 ; Refresh
180 ; Retry
180 ; Exipry
10800 ; Minimum
)
bonjour.<DOMAIN>. NS ns.bonjour.<DOMAIN>.
ns.bonjour.<DOMAIN>. A <LINUX MACHINE IP>
b._dns-sd._udp PTR @
lb._dns-sd._udp PTR @
Verify that your setup is working by issuing a PTR lb._dns-sd._udp.<DOMAIN>
query to your Windows DNS server. If everything is working correctly, you should get bonjour.<DOMAIN>
as a reply.
Adding AirPrint information to DNS
After your devices are using bonjour.<DOMAIN>
as DNS-SD search domain, you are ready to go. Now, we will publish information about the printers in this DNS zone. For that, you need a machine in the same subnet as the printers with the dns-sd
utility installed on it.
Run the command dns-sd -Z _ipps._tcp local
on the machine connected to the printer network. You will get a reply like this.
Browsing for _ipps._tcp.
; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp PTR @
; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.
_ipps._tcp PTR Canon\032iR-ADV\032C7570._ipps._tcp
_universal._sub._ipps._tcp PTR Canon\032iR-ADV\032C7570._ipps._tcp
Canon\032iR-ADV\032C7570._ipps._tcp SRV 0 0 443 <PRINTERDOMAIN>. ; Replace with unicast FQDN of target host
Canon\032iR-ADV\032C7570._ipps._tcp TXT "txtvers=1" "rp=ipp/print" "note=..." "qtotal=1" "priority=10" "ty=Canon iR-ADV C7570" "product=(Canon iR-ADV C7570)" "pdl=application/octet-stream,image/urf,image/pwg-raster,image/jpeg,application/pdf" "adminurl=http://<PRINTERDOMAIN>" "usb_MFG=Canon" "usb_MDL=iR-ADV C7580/7570 UFR II" "Transparent=F" "Binary=F" "TBCP=F" "Color=T" "Copies=T" "Duplex=T" "PaperCustom=T" "Bind=F" "Collate=T" "Sort=F" "Staple=F" "Punch=0" "PaperMax=tabloid-A3" "UUID=..." "usb_CMD=LIPSLX" "TLS=1.2" "Scan=T" "Fax=F" "URF=ADOBERGB24,CP255,DM1,PQ4,RS300,SRGB24,W8-16,FN3,IS1-4,OB10-40,V1.4" "kind=document,envelope,postcard" "print_wfds=F"
Copy your output and change <PRINTERDOMAIN>
to the printer domain (like printer01.bonjour.<DOMAIN>
). Note the line starting with _universal._sub
. This line must be added manually.
Add these records to the BIND zone configured previously. You will also need an A record for printer01.bonjour.<DOMAIN>
pointint to the IP address of your printer.
That's it! Ensure, that your clients can access the printer on port 80 as HTTP is used for AirPrint.
Further reading
There are comments.