# Ssh cups

## Recruit0

I'm trying to setup my laptop so I can print to my university's printer after SSHing in. I must be able to do this without root access so some solutions won't work. The printer is a HP LaserJet 9000 or 9040... MFP (not sure bout MFP part). I tried setting up a SSH tunnel and port forwarding but didn't work. I thought CUPS uses lp/lpr so I thought with SSH I could make CUPS send commands through the connection but can't find instructions online.

----------

## pianosaurus

What end is it you don't have root access on? Both? This should be simple enough with port forwarding if you have root access on your laptop.

----------

## Recruit0

Yes I have root access to my laptop lol. Sorry bout that. I mean I should be able to do this without root access to the (university's) server (asked other people earlier and pointed me to instructions that required root access on the server). I tried port forwarding but it didn't work   :Confused:  The terminal I SSHed with spit out messages about "administratively not allowed" or something along those lines. Although, idk what I'm doing so I probably didn't port forward correctly.

----------

## pianosaurus

Ah yes, they disabled port forwarding in the server, then. You could use lp and lpr directly through SSH, of course:

```
cat filename | ssh username@host lp
```

Use lp -d to print to a particular printer, if I remember correctly. If that works, you could probably set up a print-to-file printer in your local CUPS, and then pipe that file to ssh like above. If you get that working, you could automate the piping later.

----------

## Recruit0

Yeah I can lp -d to a printer and the piping makes sense but how would I automate this? So that when I print to file, something automatically intercepts and sends that file to the printer. This sounds like it will work.

----------

## Hu

How automated do you want it?  If you are willing to run a simple script each time you have work to print, this shell fragment could work:

```
#!/bin/sh

cd /my/print/directory

find . -type f -print0 | while read -d $'\0' job ; do

    ssh username@host lp < $job

    mv $job ../finished-jobs/

done
```

This will read each of the files in the directory, print them, then move them aside.  If the print job succeeded and you are happy with the quality, you can then remove the file from the finished-jobs directory.

If you want it fully automated, something like the above could be combined with a daemon that watches the directory with inotify, so that it detects new jobs and prints them immediately.  That could be a bit problematic if the daemon detects the job and begins printing before the document source finishes writing the job, which is why I recommend requiring manual action to trigger the loop.

----------

## pianosaurus

Fully automated watcher script (run on system startup):

```
#!/bin/bash

PRINTDIR="/path/to/printdir"

USER="username"

HOST="hostname"

inotifywait -e close_write -rqm --format %w%f "$PRINTDIR" | while read FILE; do

  ssh "$USER"@"$HOST" lp < "$FILE" && rm "$FILE"

done
```

It requires sys-fs/inotify-tools, and you must be able to log into hostname without a password (see http://linuxproblem.org/art_9.html). Also, it deletes files after passing them along, so don't move stuff in there. That way, printing to a file in this directory should be pretty much the same as printing directly.

Addendum: The problem Hu mentioned is very unlikely. It only happens if CUPS should close and reopen the file before finishing the writing. It would be silly of it to do so, as output to a printer is continuous.

----------

## Recruit0

I was kind of hoping that I could do something like this:

* Setup daemon

* Daemon will only work when I SSH/setup a tunnel to the server

So after running the daemon all I have to do is SSH in to setup a connection then I can print from OpenOffice/Firefox/etc. I'd prefer password authentication for security... unless the passwordless login is secure enough?

EDIT: Is PRINTDIR a specific directory or I can set it to whatever? I mounted my /tmp as tmpfs.

----------

## Hu

 *Cuber wrote:*   

> 
> 
> Addendum: The problem Hu mentioned is very unlikely. It only happens if CUPS should close and reopen the file before finishing the writing. It would be silly of it to do so, as output to a printer is continuous.

 

Neat.  I had not used inotify before, and was concerned about a scenario where any write to the file would alert the daemon.  Assuming the argument to -e does what its name implies, my concern is indeed unlikely to be relevant here.

Recruit0: if you are concerned about security, you could modify the script to dispatch files only when it is able to reuse an existing master-mode ssh connection.  You would then manually ssh into the remote system through an authentication method of your choice, and the session you start would provide access for the daemon.  Refer to the ssh configuration options ControlMaster and ControlPath.  The BatchMode option may also be useful for preventing ssh from prompting the script for input.

----------

## pianosaurus

 *Recruit0 wrote:*   

> EDIT: Is PRINTDIR a specific directory or I can set it to whatever? I mounted my /tmp as tmpfs.

 

You can set it to whatever you want, but make sure nothing else uses it (so don't use /tmp directly), as everything put inside will be printed and deleted. Also, you should use a directory only you have write access to.

For the password less thing, it is arguably even more secure than manual password entry. All the same security measurements are used, except nobody can see you type your password any longer. The backside is that if someone should get access to your local account, the now also have access to your remote account through ssh.

Otherwise, you can look into what Hu said about master-mode connections. I have never used it, but it seems like a good idea. You could start such a connection before the inotify-wait line, and change the current ssh line to use it. That should prompt you for a password when you first start the script.

 *Hu wrote:*   

> Assuming the argument to -e does what its name implies

 

Indeed it does. I find it extremely practical. I use it along with the file app and firefox to pop up a box asking me if I want to save the video I'm currently watching on youtube.

----------

## Hu

The script as proposed will not run ssh until a printable job is ready, so it could be started at boot or initial login, before the ssh connection is established.  It is only necessary that the ssh connection be up and running in master mode before the first file to be printed triggers the script to run ssh.

If you wanted to be fancy, you could make the script use a second inotifywait to watch for the creation of the master-mode socket, so that if a print job appears while no socket is present, the script sleeps until you connect.  That would allow you to print files before connecting, and have them be picked up and printed immediately.  As presently proposed, the file will not be deleted, but the ssh will fail and the script will go back to sleep without printing anything.  A junk job would then be required to wake it up and retry the failed runs.

----------

## pianosaurus

 *Hu wrote:*   

> As presently proposed, the file will not be deleted, but the ssh will fail and the script will go back to sleep without printing anything.  A junk job would then be required to wake it up and retry the failed runs.

 

Actually, a junk job wouldn't make it retry, since it only tries when the file is closed for writing. However, you could easily retry them all by cd-ing to the directory in a terminal and running touch *.

----------

## Hu

Oops, yes.  I am still thinking in terms of classic systems where you only know that the directory has changed, and then manually rescan the directory.

----------

