Category Archives: Internet

Securely run a low memory/low CPU Minecraft server

If you’ve got next to no memory and CPU available to run a Minecraft server, don’t fret. Cuberite is what you’re after. At them moment, Cuberite isn’t bug-free, nor indiscernible from a genuine Minecraft server, but it’s quite usable – and instead of needing 4GB+ of RAM, it needs less than 300MB. And it needs next to no processing power: some people run Cuberite on their Raspberry Pi and have plenty of CPU available.

I would at this point go on about how this is a significant point of difference between C++ and Java, but Java optimizes for something different to C++.  I got into an interesting discussion with Cathy about this after reading a question someone had about what Java was trying to be good at. I used to think that VB was the new COBOL, but clearly Java is the new COBOL; those Java programs are going nowhere, they’re verbose and easy to understand and maintain.

A point to note: The Minecraft protocols are bandwidth heavy, I found if I wanted to run a server at home I’d be able to have one, perhaps two players. Thus is Internet in Australia. Instead I’ve dropped this onto a free AWS VPS instance and bandwidth is no problem.

Still, it’s a random piece of software off the Internet, so we’re going to give it its own user account for our own safety. Let’s install the software:

curl -sSfL https://download.cuberite.org | sh
sudo mv Server /usr/local/cuberite
cd /usr/local/cuberite

Cuberite allows configuration through a web interface.  We now enable webadmin.ini
[User:admin]
; Please restart Cuberite to apply changes made in this file!
Password=yourstrongpassword
[WebAdmin]
Ports=8080
Enabled=1

Port 8080 is the alternative html port (http/https).  You could cd into webadmin and run GenerateSelfSignedHTTPSCertUsingOpenssl.sh and get https serving, but your browser will barf on the certificate. Instead, let’s use a LetsEncrypt certificate, one that we installed earlier. First we make our one-line shell script for running the daemon:

sudo useradd -c "Cuberite server" -f -1 -M -r cuberite
chown -R cuberite:`whoami` /usr/local/cuberite/
sudo nano /etc/init.d/cuberite.sh

#!/bin/sh
### BEGIN INIT INFO
# Provides: cuberite
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: cuberite
# Description: Cuberite server, a Minecraft server lookalike
### END INIT INFO
cd /usr/local/cuberite
sudo -u cuberite /usr/local/cuberite/Cuberite -d &

Next we set it going when the box starts up:

sudo chmod +x /etc/init.d/cuberite.sh
sudo update-rc.d cuberite.sh defaults

Before we can go to the website we need to allow user cuberite to get to the certificates:

sudo groupadd privkey_users
sudo usermod -aG privkey_users cuberite
sudo sudo chmod g+rx /etc/letsencrypt/live/
sudo sudo chmod g+rx /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/cert1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/chain1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/privkey1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/fullchain1.pem
sudo chown root:privkey_users /etc/letsencrypt/live/
sudo chown root:privkey_users /etc/letsencrypt/live/example.com/
sudo -u cuberite ln -s /etc/letsencrypt/live/example.com/cert.pem /usr/local/cuberite/webadmin/httpscert.crt
sudo -u cuberite ln -s /etc/letsencrypt/live/example.com/privkey.pem /usr/local/cuberite/webadmin/httpskey.pem

Changing these permissions doesn’t affect apache2’s ability to get them.
The reason we’ve used a group here is to allow both Cuberite and any other app (for example, exim) to access the private keys; just add any other user that needs to use the private keys to the privkey_users group.

Remember to punch a firewall hole for port 8080. Fire up Cuberite now:

sudo service cuberite restart

And check if that worked, there should be about one entry:

ps -aux | grep cuberitps -aux | grep cuberit

If not, you can check in the logs directory to see what’s wrong.

So now:

sudo lsof -i :8080
https://example.com:8080/

should be secure.  Note the https is mandatory, as your browser will use http if you fail to specify a protocol.

Trustworthy email: authentication using exim4, SPF, DKIM and DMARC

The email authentication technologies we’re about to implement are, according to the authentication authorities, all you need to be regarded as being from your domain when you send email, and someone else not being from your domain.  Effect: your emails can be considered trustworthy by email receivers who use these technologies. If they don’t use these technologies, they can’t tell.

At the very least, Google will be less likely to think your email is spam.

PTR record

A PTR record can be obtained from your host’s nameserver – it’s a reverse DNS record for your IP address. If the PTR record points at ec2-23-65-53-221.ap-southeast-2.compute.amazonaws.com rather than example.com (your domain), and you’re claiming to be sending mail from example.com, what’s the email recipient meant to think?

host 23.65.53.221

will tell you what the host for that IP is. Lodge a ticket with your hosting provider and get that PTR record changed to example.com. This might take about a day.

SPF record

Create a Sender Policy Framework record on your nameserver:

TXT @ "v=spf1 a mx -all"

This says “for my domain, I will only send email from IP addresses listed on the nameserver”.  Nameserver changes take time to propagate.

After your nameserver changes have propagated, you can go to https://dmarcian.com/spf-survey/ to check out if you got it right.

DKIM

DomainKeys Identified Mail is where things get more involved.  We’re doing this on a Debian Linux, like Ubuntu for exim4. We’re making our signing key 2048 bits, which is long enough to make life slightly unpleasant for us. Fortunately for you I’ve written a bash script that outputs the TXT record we need to create on the nameserver – because some nameservers (I’m looking at you, Gandi) can’t hold “long” strings – it’s broken into “small” strings:

sudo apt install openssl
cd /etc/exim4
sudo openssl genrsa -out dkim.private 2048
sudo openssl rsa -in dkim.private -out dkim.public -pubout -outform PEM
echo $(echo $(date -u +%Y%m%d && echo '.domainkey.example.com') | sed -e 's/[ ]//g' && echo $(echo ' TXT "v=DKIM1; p="' && echo $(grep 'PUBLIC KEY' -v dkim.public) | sed -e 's/[ ]//g' | fold -w200 | sed -e 's/\(.*\)/"\1"/g'))

which gives something like
20170419._domainkey TXT “v=DKIM1; p=” “MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvCNqU0Njd4YQ4e89T3FNc+uyOS2JwUqynGk7uwcSYHjIE2MGRuTxi56s4JgPKSnCVlBkJlUnXQHXFp2UGnLm8SADtjRMfWwpNxz6TmzXBpMnNZV1zvuoBBdcxh0Qg1TtCSACtWM6ehml0BmOHVA8Ippqj9iRlP2HMjuVMxZXewN9eJl”
“c6zsyOwQPvVKpJ+Rdvr+pPkDztAVTw7mNSeyy+TL6O/3L9sl7A19Yx8jLHKuGUh9LutVuv1VP16e7GwlnA3Zqn5C1jyY5Qvr2SEHZMcE3VzD7XKZtZWbpkGh+A5S15NrOH4k9tbVfNbjft6Y1jUJRTT+4DD0ZEVlr4zO+WQIDAQAB”

That all goes into one nameserver TXT record, spaces and all.  The world will join up the ” ” and get one big string. Note the bold number up there? That’s the selector. That a number needs to get larger with each new key.  Periodically you’re going to have to reissue your key because security.  You know what gets larger as time goes by?  The date.  Use the date.  If you screw up, use tomorrow’s date, etc.

Once you’ve got our public key out to the public via our public nameserver, we need to get exim to sign the payloads:

sudo nano conf.d/main/01_exim4-config_listmacrosdefs

After the line CONFDIR = /etc/exim4, add:

#DKIM loading
DKIM_CANON = relaxed
DKIM_DOMAIN = ${sender_address_domain}
DKIM_PRIVATE_KEY = CONFDIR/dkim.private
DKIM_SELECTOR = 20170419

and reload the mail server

sudo service exim4 restart

After an appropriate delay for nameserver propagation, use https://protodave.com/tools/dkim-key-checker/?selector=20170419&domain=example.com to check your work.
If that works out, mailto:check-auth@verifier.port25.com from example.com to ensure everything checks out:

echo -e "Test my DKIM plz\nMsg Body\n.\n\n" | mail -v check-auth@verifier.port25.com

DMARC

Domain-based Message Authentication, Reporting and Conformance is where the wheels can come off if you screwed anything up.  We’re going to set things up so that when you screw it up, computers scold you rather than putting your emails in the bin.

You will need to create two dmarc reporting accounts.  Servers will email you a (surprisingly detailed) report card on how you’re doing with your implementation. It’s best if these accounts are on the same domain, because technically you need to be or it’ll be ignored (Google will happily mail reports off-domain even if the other domain hasn’t said that’s okay).  Yours are dmarc_failures@example.com and dmarc_summary@example.com, according to the following nameserver entry:

_dmarc.example.com. 1800 IN TXT "v=DMARC1;p=none;pct=100;ruf=mailto:dmarc_failures@example.com;rua=mailto:dmarc_summary@example.com"

none is the consequence for screwing up. none is where we’ll start at, and see what the reporting records say to us.  After a while, you’ll be comfortable that everything is ticking along nicely, and you’ll up the consequent to quarantine (shove it in spam) or reject (burn it).

After your nameserver changes have propagated, you can go to https://dmarcian.com/dmarc-inspector/ to check out if you got it right.

As a human, to read the records sent to you, upload the files to https://dmarcian.com/dmarc-xml/

Making a captcha deamon for spamgourmet installations

For those of you following along at home, this is part of a cookbook style instruction set for getting spamgourmet going, but because of screwed up permission logic I can’t post this section there.

The captcha is for validating humanity when creating spamgourmet accounts. We’re going to limit what parts of the OS it can tromp over:

sudo useradd -c "captcha server for spamgourmet" -f -1 -M -r captcha
sudo /bin/mkdir -p /var/www-spamgourmet/captchasrv/
sudo chown -R captcha /usr/local/lib/spamgourmet/captchasrv/
sudo chown -R captcha /var/www-spamgourmet/captcha

Now we make our one-line shell script for running the daemon

sudo nano /etc/init.d/captcha.sh

#!/bin/sh
### BEGIN INIT INFO
# Provides:          captchasrv
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: captchasrv
# Description:       captcha daemon for spamgourmet
### END INIT INFO
sudo -u captcha perl /usr/local/lib/spamgourmet/captchasrv/captchasrv.pl &

Next we get it going

sudo chmod +x /etc/init.d/captcha.sh
sudo update-rc.d captcha.sh defaults

And check if that worked, there should be about four entries:

ps -aux | grep captc

Now the captcha server will start whenever the computer starts.

Installing a secure Apache webserver to run Perl

So, you want to run Perl on the web, because it’s the 90s all over again. You want HTTPS, because… no, there’s no because.  You want HTTPS.  Who wouldn’t?  Here’s what you do on a Debian Linux such as Ubuntu:
sudo apt-get install apache2 libapache2-mod-perl2
mod-perl is an Apache module that allows Perl programs to be executed from Apache.

Our goal is to get /var/www/html/index.pl running at http://www.example.com/index.pl:

#!/usr/bin/perl
print "Hello World"

Disable the default Apache virtual host:

sudo a2dissite 000-default.conf

Create an example.com.conf file in /etc/apache2/sites-available with your text editor, replacing instances of example.com with your own domain name in both the configuration file and in the file name /etc/apache2/sites-available/example.com.conf

<VirtualHost *:80>
     ServerName example.com
     ServerAlias www.example.com
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     <Directory /var/www/>
              Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
              AllowOverride None
              AddHandler cgi-script .pl
              Require all granted
     </Directory>
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
     ServerName example.com
     ServerAlias www.example.com
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
     <Directory /var/www/>
              Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
              AllowOverride None
              AddHandler cgi-script .pl
              Require all granted
     </Directory>
</VirtualHost>
</IfModule>

If you have multiple sites, you’ll want to do things with DocumentRoot to isolate them from each other. But that’s for another post.

You might add in DirectoryIndex /index.pl to make http://www.example.com/ execute your program.

The Directory section above allows you to isolate executable code from served code, which is good practice. For this example we’re dumping the executable in with everything else, which is questionable.

Repeat this process for any other domains you host.

sudo a2ensite example.com.conf
sudo ln -r -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/example.com.conf
sudo service apache2 restart

Punch holes in your firewall for ports 80 and 443.  Navigate to http://www.example.com/index.pl to check all is okay. You ought to see Hello World displayed for your website.

Having security used to be a pain.  SSL certificates signed by a recognised CA cost money, and then you’d have to keep them up to date, and there wasn’t process automation, so you’d do all that stuff by hand.  LetsEncrypt address all these problems, handing out free certificates and scripted everything.

Now it’s time for the S part of HTTPS:
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
sudo certbot --apache

certbot renew
If that works, we’ll automatically renew our 90-day certificates every month:
echo '@monthly root /usr/bin/certbot renew >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab

Done.  You’ll never have to worry about certificates again. Now alter your Apache sites-available file (look in /etc/apache2/sites-available/) to include the (optional) redirect HTTP to HTTPS and the mandatory location of the SSL certificates:

<VirtualHost *:80>
....
# Only allow HTTPS
RewriteEngine on
RewriteCond %{SERVER_NAME} = example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
...
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Now make the secure version live, and in the process the insecure one… shy? When a request is made for a http page, like http://example.com/index.html, the response will be “Here’s https://example.com/index.html where what you asked for has moved to… forever!”:
sudo service apache2 restart
Now requesting http://www.example.com/index.pl ought to deliver you to https://www.example.com/index.pl

Install exim4 STARTTLS using a free LetsEncrypt certificate

Here we are on a Debian Linux, such as Ubuntu and we want to run a mail server. Exim4 is currently the most popular email server, but getting it up and working for free is a hassle – who wants to pay for a SSL certificate, on an ongoing basis? And then there’s the maintenance of the security of it – constant renewal, renouncing and re-installation of the certificates.

Wherever you see example.com, swap in your Fully Qualified Domain Name. That may be mail.example.com
It’s assumed you’re not logged in as root, but user ubuntu
Wherever you see 1.2.3.4, swap in your machine’s local IP address, from
ifconfig | grep "inet addr" | grep -v "127.0.0.1"

Security is all handled automatically by LetsEncrypt’s certbot. I’ll let you look that one up yourself. Run it up and get your certificate for example.com

Once you’ve got that handled, punch a hole in your firewall so that port 25 can get through from the outside world to your machine. Be aware: the outside world is filled full of botnets trying to hack into your machine.  After installing exim, keep an eye on the logs in /var/log/exim4/ for a while.

Let’s install exim4:
sudo apt-get install exim4
sudo dpkg-reconfigure exim4-config

  • pick “Internet site”
  • system mail name is example.com
  • IP address is 1.2.3.4 (the one returned by ifconfig, not the externally accessable one)
  • Other destinations: example.com
  • No relays
  • No smarthost
  • No Dial-on-Demand
  • mbox format (or whatever)
  • Split the files
  • ubuntu for postmaster mail

Check we’re now running a mail server:
sudo netstat -napt
should show
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 1.2.3.4:25 0.0.0.0:* LISTEN 25700/exim4

Now we have a mail server, the world needs to find it. Check your nameserver setting to ensure mail is destined this machine.  You probably want only one MX record.

Check the Internet can send mail to our server. After allowing for the appropriate propagation delay for your nameserver changes, use gmail or something to send an email to ubuntu@example.com – you should be able to read it by typing
mail

Now it’s time to enable MTA-MTA link encryption for secure transport of mail, by enabling STARTTLS on exim4 using our LetsEncrypt certificate
sudo nano /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
Enable STARTTLS by adding/setting in the tlsoptions section:
MAIN_TLS_ENABLE = yes
MAIN_TLS_CERTKEY = no

before any of the IF shenanigans. Also add/replace pointers to the certificates:
tls_certificate = /etc/letsencrypt/live/example.com/fullchain.pem
tls_privatekey = /etc/letsencrypt/live/example.com/privkey.pem

The MAIN_TLS_CERTKEY = no entry fixes an exim4 log message
2017-04-16 09:13:24 TLS error on connection from your.home.ip.com (IcePlanet) [5.6.7.8] (cert/key setup: cert=/etc/exim4/exim.crt key=/etc/exim4/exim.key): Error while reading file.
You will see this when testing with swaks:
$ swaks -a -tls -q HELO -s example.com -au test -ap '<>'
=== Trying example.com:25...
=== Connected to example.com.
< - 220 your.vps.host.com ESMTP Exim 4.86_2 Ubuntu Sun, 16 Apr 2017 09:13:24 +0000 -> EHLO IcePlanet
< - 250-your.vps.host.com Hello your.home.ip.com [5.6.7.8]
STARTTLS
< ** 454 TLS currently unavailable *** STARTTLS attempted but failed -> QUIT
< - 221 your.vps.host.com closing connection
=== Connection closed with remote host.

Allow exim (which when running runs as user Debian-exim) to get to the certificates:

sudo groupadd privkey_users
sudo usermod -aG privkey_users Debian-exim
sudo sudo chmod g+rx /etc/letsencrypt/live/
sudo sudo chmod g+rx /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/cert1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/chain1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/privkey1.pem
sudo chown root:privkey_users /etc/letsencrypt/archive/example.com/fullchain1.pem
sudo chown root:privkey_users /etc/letsencrypt/live/
sudo chown root:privkey_users /etc/letsencrypt/live/example.com/

Changing these permissions doesn’t affect apache2’s ability to get them.
The reason we’ve used a group here is to allow both exim and any other app (for example, a secondary service that wants to use 8080 to serve up a configuration page) to access the private keys; just add any other user that needs to use the private keys to the privkey_users group.

These permission changes prevent the following error message in your log file:
2008-06-03 08:27:35 TLS error on connection from me.at.home.com ([1.2.3.4]) [5.6.7.8] (cert/key setup: cert=/etc/ssl/certs/server.pem key=/etc/ssl/private/server.key): Error while reading file.

Restart the service and the TLS settings ought to be working
sudo service exim4 restart
Test STARTTLS is working from another machine
swaks -a -tls -q HELO -s example.com -au test -ap '<>'
There shouldn’t be any obvious complaining.

Done!

Comment spammers try to get clever

On my personal blog, on a post about the Melbourne public transport smartcard Myki, this comment popped into the moderation queue:

I found another very uefsul behaviour this morning.I don’t touch off when I get home at night. While, this seems weird how do they know I got off in Zone 1 (for which I have a pass) and didn’t travel into Zone 2 (for which I should be charged Money)? But, the fare manual says that if you have a MyKi Pass and you touch on in a zone for which that pass is valid (Parliament in my case) then there is no default fair.So, every morning when I touch on, it tells me deducting fare for previous trip . Which is $0.00. Cool.This morning I forgot to touch on some power issues on our line, got to chatting with the Station Hosts, just forgot. When I got to Parliament, I fully expected the gates to deny me egress and I’d have to do the silly thing where you act exasperated and they just wave you through the end gate even though you’re holding nothing but a wallet in your hand (MyKi works while in the wallet).BUT, it let me through. Seems that it’s happy enough that I started a trip (at Parliament) last night, spent 16 hours travelling and ended my trip back where I started. So it let me out basically a touch off of the trip home last night.Bizarre. But uefsul.

At first glance, it looked on-topic. But I was suspicious because the user link was to facebook.com/profile.php?id=XYZ (I’ve removed the ID) — and it came in the middle of a bunch of other (less-relevant) comments linking to similar URLs.

Googling around for key words in the comment, I found that it’s a copy of a comment from a completely different blog, with various misspellings inserted, and paragraph breaks removed. The original:

I found another very useful behaviour this morning.

I don’t touch off when I get home at night. While, this seems weird – how do they know I got off in Zone 1 (for which I have a pass) and didn’t travel into Zone 2 (for which I should be charged Money)? But, the fare manual says that if you have a MyKi Pass and you touch on in a zone for which that pass is valid (Parliament in my case) then there is no default fair.

So, every morning when I touch on, it tells me “deducting fare for previous trip”. Which is $0.00. Cool.

This morning I forgot to touch on – some power issues on our line, got to chatting with the Station Hosts, just forgot. When I got to Parliament, I fully expected the gates to deny me egress and I’d have to do the silly thing where you act exasperated and they just wave you through the end gate even though you’re holding nothing but a wallet in your hand (MyKi works while in the wallet).

BUT, it let me through. Seems that it’s happy enough that I started a trip (at Parliament) last night, spent 16 hours travelling and ended my trip back where I started. So it let me out – basically a touch off of the trip home last night.

Bizarre. But useful.

It seems the spammers are trying to get a bit more clever at sneaking their comment posts past moderators.

I still don’t know why, given WordPress has used NoFollow on their comment links for about ten years now.

Spam from Cotap

Subject line: “You’ve been added as a contact on Cotap”

Email text: “Cotap is a secure texting app for teams. View the [company name] directory. [link]

“Are you using WhatsApp, GroupMe, or iMessage to text your coworkers? See why Cotap is better for work.”

Yeah, no, this is spam, and it sounds like quite a few people are getting them.

Cotap was formed by former Yammer people… there’s speculation that when they left Yammer, they took a copy of the Yammer email list with them.

In any case, don’t fall for their trap. Don’t do business with spammers.

In fact, why on earth would you trust your business messaging to spammers?

Turn off Twitter’s autoplay videos

I don’t know how much bandwidth Twitter’s new autoplay videos are burning up, but fortunately it can be turned off.

Unhelpful web help

Just… just… wrong. So wrong.

FlickrHelp
Firstly, note the error message “Enter a valid email addresss”. Where, pray tell, ought I do this?  Why do I need to upload any attachment again?  Why do I have to prove I’m a human time-after-time, when all I’m doing is wrestling with your completely broken attempt at a web form?

Have they noticed that no-one is submitting help requests via this form, what with its refusal to accept said requests?

Dear Flickr: stop sucking balls.

Where did I take that photo?

I couldn’t find anyone extracting out the geolocation geotagging EXIF data from their photographs so they could pull it up on something like Google Maps.  There are stand-alone programs with embedded maps, but the bits and bobs lying around on the average system ought to be enough to just generate a URL to a mapping website.  The following bash script echoes the  URL that geolocates your JPEG.  Because my camera doesn’t emit it, I couldn’t be bothered dealing with the seconds part of a location, but I did detect that you don’t have a camera the same as mine.  Drop a line if you’ve used this and fixed it.

#!/bin/bash
# emit a hyperlink to google maps for the location of a photograph
declare Seconds=""
Seconds=`exif -m --ifd=GPS --tag=0x02 $1 | grep -oP "[\d|\d\.]+$"`
if (( $Seconds=='0' ))
then
  Seconds=`exif -m --ifd=GPS --tag=0x04 $1 | grep -oP "[\d|\d\.]+$"`
fi
if (( $Seconds!='0' ))
then
  echo
  echo "Script does not support seconds being specified"
  exit
fi
echo -n "https://maps.google.com.au/?q="
declare NorthSouth=`exif -m --ifd=GPS --tag=0x01 $1`
if [ "$NorthSouth" == "S" ] 
then
  echo -n "-"
fi
echo -n `exif -m --ifd=GPS --tag=0x02 $1 | grep -oP "^[\d|\d\.]+"`
echo -n "%20"
echo -n `exif -m --ifd=GPS --tag=0x02 $1 | grep -oP "(?<= )[\d|\d\.]+,"`
declare EastWest=`exif -m --ifd=GPS --tag=0x03 $1`
if [ "$EastWest" == "W" ]
then
  echo -n "-"
fi
echo -n `exif -m --ifd=GPS --tag=0x04 $1 | grep -oP "^[\d|\d\.]+"`
echo -n "%20"
echo -n `exif -m --ifd=GPS --tag=0x04 $1 | grep -oP "(?<= )[\d|\d\.]+(?=,)"`
echo

Gmail: wrong messages ended up in deleted/spam folders

Anybody else get this warning?

Gmail warning

This article has some more detail — it appears to have only affected GMail mobile/iPad apps.

I’ve checked — nothing seems to have accidentally fallen into the Bin/Trash or Spam folders.

Just goes to show, even GMail/Google ain’t perfect.