Firefox lpr workaround

For some reason unknown to mankind, Firefox doesn’t allow you to print via lpr any more.

It used to be that if you had lpr enabled on the line gtk-print-backends= in your ~/.config/gtk-3.0/settings.ini, you would be able to print directly to lpr.

But recently (I’m using Firefox 60 at the moment) this doesn’t work.

After this workaround I only kept “file” in my settings.ini.

[Settings]
gtk-print-backends=file

Workaround

My workaround was to create a simple script that watches a folder, if it finds a PDF, print it using lpr and then remove the file.

Then a simple systemd user script to get it running in the background.

The “printy” script

Most beautiful bash script ever.

#!/usr/bin/env bash

PRINTDIR="/tmp/printy"

mkdir -p "$PRINTDIR"

while true; do 
  sleep 2

  for file in "$PRINTDIR"/*.pdf; do
    if [ -f "$file" ]; then
      cat "$file" | lpr -l && rm "$file"
    fi
  done
done

Change PRINTDIR to where you’ll print PDF:s to from Firefox.

systemd unit script

[Unit]
Description=Fucked up Firefox printing workaround script

[Service]
ExecStart=/home/ogg/bin/printy
Restart=always
RestartSec=2

[Install]
WantedBy=default.target

Save file in ~/.config/systemd/user/printy.service.

To keep the script running after you login/logout and reboot. Enable “lingering” in systemd.

As root, run: systemctl enable-linger ogg

Then enable and start the script:

systemctl --user enable printy

and

systemctl --user start printy

Conclusion

If you do the above, whenever you need to print anything from Firefox, use “Print to file” and place the PDF in /tmp/printy (if you use my script above).

Use Let’s Encrypt SSL certificate on Mikrotik RouterOS

These are step by step instructions how to import and use a Let’s Encrypt SSL certificate on your Mikrotik routerboard.

There are a number of Let’s Encrypt clients out there. But my favourite so far is acme.sh by . The only requirement is a shell. Works fine running as a unprivileged user as well.

In the steps below, I’m using DNS validation, but of course you can use web based as well.

In that case forward a port to the computer running acme.sh and use –standalone and –httpport (if you use a non standard port) instead of –dns.

Installation

  1. Download and install acme.sh. Or, if you’re in “dont-really- care-what-i-download-and-run”-mode:
    $ curl https://get.acme.sh | sh
  2. Then issue a new certificate:
    $ acme.sh --issue --dns -d router.mydomain.com
  3. Add the TXT record displayed to your DNS. Look for this:
    Domain: '_acme-challenge.router.mydomain.com' 
    TXT value: 'iamNo7r3alIaHacK3rbutItc4nBfunM3ss1nGaroUnD'
  4. After you’ve added your TXT record, issue a renewal:
    $ acme.sh --renew -d router.mydomain.com                                                                                                              [205/397] 
    [thu 12 jan. 2017 20:06:09 CET] Renew: 'router.mydomain.com' 
    [thu 12 jan. 2017 20:06:09 CET] Single domain='router.mydomain.com' 
    [thu 12 jan. 2017 20:06:09 CET] Getting domain auth token for each domain 
    [thu 12 jan. 2017 20:06:09 CET] Verifying:router.mydomain.com 
    [thu 12 jan. 2017 20:06:14 CET] Success 
    [thu 12 jan. 2017 20:06:14 CET] Verify finished, start to sign. 
    [thu 12 jan. 2017 20:06:15 CET] Cert success.
  5. Install your cert. And yes, you should specify the same file for –capath and –certpath.
    $ acme.sh --installcert -d router.mydomain.com \
              --capath /home/ogg/certs/router.mydomain.com.cer \
              --certpath /home/ogg/certs/router.mydomain.com.cer \
              --keypath /home/ogg/certs/router.mydomain.com.key
    [thu 12 jan. 2017 20:18:03 CET] Installing cert to:/home/ogg/certs/router.mydomain.com.cer
    [thu 12 jan. 2017 20:18:03 CET] Installing CA to:/home/ogg/certs/router.mydomain.com.cer
    [thu 12 jan. 2017 20:18:03 CET] Installing key to:/home/ogg/certs/router.mydomain.com.key

    You now have two files to upload to your Mikrotik device. router.mydomain.com.cer and router.mydomain.com.cer.

  6. Upload the two files to your Mikrotik. I’m assuming you have ssh enabled and can login.
    $ scp router.mydomain.com.key kutersv16-sw1:router.mydomain.com.key
    router.mydomain.com.key                              100% 1337     1.6KB/s   00:00
    $ scp router.mydomain.com.cer kutersv16-sw1:router.mydomain.com.cer
    router.mydomain.com.cer                              100% 8888     1.6KB/s   00:00
  7. SSH into your router and import the certificates
    /certificate import file-name=router.mydomain.com.cer
    /certificate import file-name=router.mydomain.com.key
    

    you can then verify they’re imported. Remember the name of your certificate (used in the last step).

    /certificate print
    Flags: K - private-key, D - dsa, L - crl, C - smart-card-key, A - authority, I - issued, R - revoked, E - expired, T - trusted
     #        NAME                       COMMON-NAME                 SUBJECT-ALT-NAME         FINGERPRINT                   
     0 K    T router.mydomain.com.cer_0  router.mydomain.com         DNS:router.mydomain.com  133713371337133713371337133...
     1   L  T router.mydomain.com.cer_1  Let's Encrypt Authority X3                           713371337133713371337133713...
  8. Final step, tell your www-ssl service to use the certificate.
    /ip service set www-ssl certificate=router.mydomain.com.cer_0

And that’s it!

acme.sh already have set up a cronjob for you doing the renewal. You can then use a shell script to automatically upload after renewal. To do so, point to that script –reload-cmd <scriptpath> for it to be run after renewal.

On the Mikrotik side, you can write a script that checks if there are any certs to import, import them. You can then run this using the Scheduler. Maybe once a day/week or so to make sure you never have outdated certificates.

Example scripts

install_cert.rsc
upload.bash

Hairpin NAT example

Here is an example config to configure a hairpin NAT on Mikrotik.

In this example I have a webserver on 192.168.88.80 and my Mikrotik router is on 192.168.88.1. After adding these rules I can access my webserver via my public IP from inside the LAN. Which is a nice feature.


/ip firewall nat
add action=masquerade chain=srcnat comment="default configuration" out-interface=ether01-WAN to-addresses=0.0.0.0
add action=masquerade chain=srcnat comment="hairpin nat" dst-address=!192.168.88.1 src-address=192.168.88.0/24
... other NAT rules
add action=dst-nat chain=dstnat comment="Forward port 80 to webserver on 192.168.88.80" dst-address=!192.168.88.1 dst-address-type=local dst-port=80 protocol=tcp \
to-addresses=192.168.88.80 to-ports=80

More information can be found here.

Use dnsmasq to resolve tld

When I develop webstuff, I sometimes use a vagrant box for the development. This is how I use dnsmasq to resolve all domains ending with <insert tld here> to one and the same IP (be it your local IP or that of, in my case, a vagrant box).

First. Install dnsmasq.

/etc/dnsmasq.conf

# listen only to this IP
listen-address=127.0.0.1

# file with dns servers
resolv-file=/etc/resolv.dnsmasq.conf

# resolve all .app tlds to this IP
address=/.app/192.168.10.10

/etc/resolv.dnsmasq.conf

Using this, you can use more than three servers (in Linux the max is 3, see /usr/include/resolv.h).

nameserver 10.0.0.47
nameserver 8.8.8.8
nameserver 8.8.4.4

/etc/resolv.conf

And finally use your dnsmasq server in your resolv.conf file.

nameserver 127.0.0.1

Whitelist senders in amavis

If you scan your outgoing mail, there may be times you don’t want check for spam on outgoing mail from a specific adress.

In that case, create a file listing the adresses you wish to whitelist, eg. /etc/amavisd.whitelist.

Then add the following rule to your amavisd.conf file.

read_hash(\%whitelist_sender, '/etc/amavisd.whitelist');
@whitelist_sender_maps = (\%whitelist_sender);

$interface_policy{'10026'} = 'VIRUSONLY';
$policy_bank{'VIRUSONLY'} = { # mail from the pickup daemon
 bypass_spam_checks_maps => ['@whitelist_sender_maps'], # don't spam-check this mail
 bypass_banned_checks_maps => ['@whitelist_sender_maps'], # don't banned-check this mail
 bypass_header_checks_maps => ['@whitelist_sender_maps'], # don't header-check this mail
};

The result being that you get virus checks but no spam checking. The headers are still added but look like:

X-Virus-Scanned: amavisd-new at mail.mrrobot.com
X-Spam-Flag: NO
X-Spam-Score: 0
X-Spam-Level:
X-Spam-Status: No, score=x required=6.2 WHITELISTED tests=[]
	autolearn=unavailable

and not like before

X-Virus-Scanned: amavisd-new at mail.mrrobot.com
X-Spam-Flag: YES
X-Spam-Score: 7.025
X-Spam-Level: *******
X-Spam-Status: Yes, score=7.025 required=6.2 tests=[BAYES_40=-0.001,
	DNS_FROM_AHBL_RHSBL=2.699, FSL_HELO_NON_FQDN_1=0.001,
	HELO_LOCALHOST=3.828, MISSING_MID=0.497, RCVD_IN_SORBS_DUL=0.001]
	autolearn=no

Tested on amavisd-new-2.8.0.

Alesis Multimix Firewire 12

I own an old (really old in technology years) Alesis MultiMix Firewire 12. It’s a pretty decent mixer with a firewire interface which allows you to record up to 12 channels simultaneously. It was my first “semi- professional” audio interface and it served me well. Up until it got old (or more probable is that I “upgraded” to something fancier).

Anyway. I was reading a forum post over at Alesis, and saw more than one thread with complaints that there are no recent drivers for this board.

I hadn’t used my Multimix Firewire 12 in years, so I took it out of the closet and plugged it in. Again, no drivers availble. But, what the hell. I downloaded the latest ones from Alesis “legacy” page (they’re released in 2011 i think) and installed them. The installation went just fine. No smoke or anything. Kind of disappointing.

Anyway, after a reboot. I have managed to use it without hiccup for an hour or so. And it is rock solid. I tried Propellerheads Reason with 64 samples buffer size and works just fine. The input latency I get is about 3ms. Which is really good.

Alesis Multimix driverI have not tried recording multiple tracks at once. But one channel works just fine. No clipping, pops, and whatnot I remembered I occasionally had with this board back in the day when I didn’t have a “supercomputer” and ran Windows.

On a side note. If you actually run the driver installer it clearly says under requirements, “Mac OS X 10.7.0 or higher”. Last I checked, 10.10.5 (which I’m on as I’m writing this) is “higher” =D.

Maybe I also should mention I’m *not* using Apple hardware. I’m on a “hackintosh” I built about 3-4 years ago. So your milage may vary, of course.

But, to all folks complaining. Do less complaining and more experimenting. You could actually end up surprised and the drivers might actually “just work”.

I for sure am going to use this board more, since I’ve had some trouble with my Motu 828mk3 lately with lockups and freezes when just mixing. And the Motu is still “supported” and has drivers dated October 2014. But I’m not complaining. I know I’m on my own when I run a Hackintosh.

Postfix fix wrong sender address

So, I, ahem, “forgot” to change sender address on one of our servers the other day which resulted in a bunch of undeliverable mails on the mailserver which got rejected because the sender domain didn’t exist anymore. This is how I fixed it.

First, I created a map file in which you map out the old wrong address and the new shiny working one as such:

vim /etc/postfix/sender_canonical
sender@oldomain.nx  sender@newexistingdomain.com

run

postmap /etc/postfix/sender_canonical

then add following line to /etc/postfix/main.cf

sender_canonical_maps = hash:/etc/postfix/sender_canonical

after that reload postfix config

service postfix reload

requeue all deferred mails (or use -i to requeue specific id)

postqueue -f

then you can flush the queue if you don’t want to wait

postfix flush

and voila! Now all old mails that were “stuck” should be delivered successfully!

Suspend/resume all Vagrant boxes on system shutdown/startup

So, we’ve been using Vagrant a lot lately at work, and one thing that bugged me was whenever i shutdown my computer, it wouldn’t because I forgot to suspend or halt my running Vagrant boxes before shutting down.

So, I wrote a simple init script that suspends all running boxes, nice and easy. It should handle multiple users also (I have not tested this thou).

#!/bin/sh -e
### BEGIN INIT INFO
# Provides:          something warm and fuzzy 
# Required-Start:    vboxdrv
# Required-Stop:     vboxdrv
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts suspended vagrant boxes and suspends running vagrant boxes
# Description:       
### END INIT INFO

# presumably only users with valid login shells are running vagrant boxes
validShells=$(cat /etc/shells | grep -v "#" | sed ':a;N;$!ba;s/\n/|/g')
userList=$(grep -E "$validShells" /etc/passwd | awk -F ':' ' { print $1 } ' | tr "\\n" " ")

case $1 in
  start)
    # loop thru every user
    for user in $userList; do
      # loop thru users suspended boxes
      for vm in $(su -c "vagrant global-status" $user 2>/dev/null | grep saved | awk ' { print $5 } '); do
        cd $vm >/dev/null
        su -c "vagrant up" $user
        su -c "vagrant status" $user > /dev/null # update global-status cache
      done
    done
  ;;
  stop)
    for user in $userList; do
      for vm in $(su -c "vagrant global-status" $user 2>/dev/null | grep running | awk ' { print $5 } '); do
        cd $vm > /dev/null
        su -c "vagrant suspend" $user
        su -c "vagrant status" $user > /dev/null # update global-status cache
      done
    done
  ;;
  status)
    for user in $userList; do
      echo "$user's vagrant box status"
      echo "------------------------------------------------------------------------"
      su -c "vagrant global-status 2> /dev/null" $user
      echo
      echo
    done
  ;;
  *)
    echo "Usage: $0 {start|stop|status}" >&2
    exit 1
  ;;
esac

exit 0

Installation

Edit /etc/init.d/vagrant-boxes and paste the above script and save (or download it from here and save it to /etc/init.d/vagrant-boxes). On debian/ubuntu etc, run

# update-rc.d vagrant-boxes defaults 99 01

Number 99 is the sequence number and should be larger than (in my case Virtualbox number 20, which by the way is the default on Debian distros). The second number is the sequence when shutting down the computer. So, it might be good to do first of all.

SSH connections using ProxyCommand

Scenario, you have a bunch of servers on your LAN with no access to the internet and you want to be able to connect to them via a specific server.

In this case, all your servers you wan’t to connect to resolves to *.example.tld. Hence, *.example.tld in the Host line. You can of course have a single host here. Tips, if you do set Host to *.example.tld and then proxy via for example in.example.tld, it will not work (I don’t have an explanation). I opted simply to use another domain for the “incomming connection” server.

Anyway, add lines similar to these to your ~/.ssh/config
 

Host *.example.tld
ProxyCommand ssh proxy.someother.tld 'nc -w 120 %h %p'

and you’re set!

Now when you ssh to server1.example.tld ssh will actually connect using the command ssh proxy.someother.tld 'nc -w 120 server1.example.tld'.

Pretty neat and very, very useful!