Use Irfanview in Linux with Wine

IrfanView is a very versatile little program that you can use to manipulate and view image files. I am very familiar with it and often find myself wishing I could use it in Linux. Well, it turns out I can!

There are a few things you need to do. First, install wine

#For debian-based distros
sudo apt-get install wine

After wine is installed, use it to install irfanview

wine iview442_setup.exe

If you get the following error, it means you don’t have mfc42.dll installed:

err:module:import_dll Library MFC42.DLL (which is needed by L"Z:\\home\\nicholas\\Downloads\\iview442_setup.exe") not foun

The solution is to use winetricks to install mcf42.dll (thanks to winehq for the soultion to this)

winetricks -q mfc42

Optionally you can make wine your default image program (or just have it in the list of available image handling programs.) The way to do this is to write a quick script and mark it executable (thanks to linuxquestions for the answer on how to do this)

#!/bin/sh
IRFANVIEW="C:\\Program Files\Irfanview (x86)\i_view32.exe"
ROOT_DRIVE="Z:\\"
for arg
do
	wine "$IRFANVIEW" "${ROOT_DRIVE}$(echo "$arg" | sed 's/\//\\/g')"
done

You may need to tweak it a little bit if you don’t have 64bit wine installed.  Save that file somewhere you will remember and then mark it executable with chmod +x.

Lastly, when you right click a file and do open with, simply point it to the above script. The result: wine goodness.

Exclude directories in find command

For some reason I had a hell of a time finding a way of excluding a directory from the ‘find’ command. I finally found a solution that works thanks to this website.

The solution for me was to add the following to my find command:

! -path "<directory to exclude>"

So to find all files modified less than 24 hours ago on my grandmother-in-law’s computer, I used the following command:

find . -mtime -1 ! -path "./AppData/*"

Grandma’s computer runs Windows 7 but I’ve configured Cygwin and ssh so I can use the tools I’m fimilar with. The above command excludes appdata and searches her user profile for all files modified today.

Persistent SSH tunnel for Windows

Over the years I’ve needed to access family members’ machines for remote support. The problem with parents and grandparents is walking them through certain prompts for services like join.me is quite problematic. To that end I’ve devised an open source way for me to automatically remote into their machine regardless of firewalls or machine location. This is possible thanks to cygwin, autoSSH, and NSSM. As long as the machine has internet access, I can get to it.

To pull this off you’ll need to install a few cygwin packages, copy over a private key file, create a batch script, and invoke NSSM to create a service to invoke the batch script on startup.

Cygwin

Obtain cygwin from here. You’ll need to use the graphical installer for the initial setup. Install the following packages:

  • ssh
  • autossh
  • wget (not necessary, but handy to have)

If cygwin is already installed, install it again. I wasted an hour once trying to figure out why it wasn’t working when the culprit turned out to be a buggy old version of cygwin itself.

Private key

For this to work you’ll need an SSH server configured for key authentication (no password.) On your SSH server:

  • Create new user for the Windows machine
  • Execute ssh-keygen as that user
  • Copy the contents of the .pub file into ~/.ssh/authorized_keys
  • Copy the private key (the one with no extension) to the Windows computer
  • Make sure permissions for the .ssh folder and everything inside of it is 600

GatewayPorts

One option that I really enjoy on my SSH server is the GatewayPorts option. This turns your SSH server into a gateway for any port forwards. Simply edit /etc/ssh/sshd_config and add

GatewayPorts yes

Save the file and restart the SSH service. Now if you create SSH tunnels your SSH server opens those ports for you to connect from other machines.

Create batch file

On the windows machine a simple command gets us up and running. Create a one-liner .cmd file on the Windows machine in a location of your choosing with the following:

c:\cygwin\bin\autossh.exe -M <random_port_number> -i <keyfile location>  -l <user> -R<remote_port:localhost:<local_port> -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null <remote address>

Update it to reflect the path of your cygwin installation if you installed somewhere other than the default location.

I add the reverse port forward option ( -R ) so that I can simply connect to my ssh server on the specified port and the connection will tunnel through to the Windows computer. In my case, I do -R5700:localhost:5900 which instructs my ssh server to listen on port 5700, then forward that connection to the Windows machine on port 5900 for VNC.

Create service

The Non-suciking service manager is a nifty little program that lets us turn anything into a windows service. Once it’s a service it can be started automatically on startup, even if nobody has logged in yet.

Obtain NSSM from here and extract it to a location you can remember. Then, open an administrator command prompt, cd to the directory containing nssm.exe, and enter the following:

nssm.exe install autossh

A GUI will open up. Specify the location of your batch file in the Path: section, then click Install service.

Once this is done, start the service by running services.msc, looking for your service, right click and select start. Make sure the startup type is set to automatic.

That’s it! If your keys are in the right place and the permissions are correct, the computer will automatically (and silently) log into your SSH server and create a tunnel for you. Autossh will continually try to re-connect in the event of connection loss. Awesome.

Reverse SSH

You can also configure cygwin to be an SSH server for your windows host. This will allow you to SSH into the machine if you specify -R<random_port:localhost:22 in your batch file. Here are a few notes for getting ssh working

  • Open up a cygwin terminal and execute the command:
    ssh-host-config
  • Once the SSH server is configured, tweak the SSH configuration to allow logging in with blank passwords (many of my family do not use a password to log into the machine.) Simply un-comment the line “PermitEmptyPasswords no” and change no to yes. Then, restart the ssh service. (thanks to this blog for the insight)

Connect Linux OpenVPN client to Netgear VPN Server

My parents got a shiny new Netgear R80000 wireless router which supports OpenVPN out of the box. The client configuration it generates doesn’t work right away, though, when I try to connect from my Linux Mint desktop. The connection is successful but I can’t ping or reach anything on the other network.

I discovered on this forum that you must add a couple options to the config file the router produces. You can do this either on the command line or by modifying the config file. The options are to add an interface to the VPN and to  create a route to the network, like so:

--ifconfig 192.168.1.5 255.255.255.0 --route 192.168.1.1

I took the generated non-windows VPN configuration from their router, unzipped it on my linux desktop, and then ran this command:

sudo openvpn --config parents.ovpn --ifconfig 192.168.1.5 255.255.255.0 --route 192.168.1.1

It worked like a charm.

Fix erroneous DM Splunk Missing Forwarders alert

For some time now Splunk has been alerting me to “missing” forwarders even though all of those forwarders are working perfectly fine. It turns out to be a glitch in the Deployment Monitor app. After much digging I found this Splunk article which explains it:

https://answers.splunk.com/answers/188784/after-update-to-splunk-enterprise-62-why-does-the.html

The fix is fairly simple, thankfully. You have to edit the macros.conf of the Deployment Monitor app to add this small snippet right before the first pipe:

NOT eventType=*

The default path for this configuration file is:

/opt/splunk/etc/apps/SplunkDeploymentMonitor/default/macros.conf

The relevant stanza in my macros.conf is below:

[forwarder_metrics]
definition = index="_internal" source="*metrics.log" group=tcpin_connections NOT eventType=* | eval sourceHost=if(isnull(hostname), sourceHost,hostname) | eval connectionType=case(fwdType=="uf","universal forwarder", fwdType=="lwf", "lightweight forwarder",fwdType=="full", "heavy forwarder", connectionType=="cooked" or connectionType=="cookedSSL","Splunk forwarder", connectionType=="raw" or connectionType=="rawSSL","legacy forwarder")| eval build=if(isnull(build),"n/a",build) | eval version=if(isnull(version),"pre 4.2",version) | eval guid=if(isnull(guid),sourceHost,guid) | eval os=if(isnull(os),"n/a",os)| eval arch=if(isnull(arch),"n/a",arch) | fields connectionType sourceIp sourceHost sourcePort destPort kb tcp_eps tcp_Kprocessed tcp_KBps splunk_server build version os arch guid

Crop pictures with ImageMagick’s mogrify

I recently needed a quick and dirty way to crop the bottom chunk of a large batch of scanned photos. Thanks to Linux and FOSS, this is possible with a fantastic tool known as imagemagick.

Simply install imagemagick to get the necessary tools

#Assuming you have a redhat based distro
sudo yum install ImageMagick*

Once installed use the mogrify tool (part of ImageMagick) to quickly chop the bottom part off:

mogrify -chop 0x45+0+0 -gravity South *.jpg

The above example chops the bottom 45 pixels off of every picture in the directory you’re in. Thanks to this site for the info. Handy.

Install multiple xenserver patches at once

I came across a need to install multiple patches manually (via SSH) on one of my xenservers. It’s quite tedious to do this manually so I found a way to here.)

Download all the patch .zip files to a directory your xenserver can access. Then, extract them all with this command:

find *.zip -exec unzip {} \;

Next, upload all the .xsupdates:

find *.xsupdate -exec xe patch-upload file-name={} \;

This spits out a bunch of UUIDs. Make note of these. You will also need to get your host-uuid by using the

xe host-list

command.

Lastly, a quick for loop applies the patches we want (replace the UUIDs with those of the patches uploaded earlier and the host-uuid with yours)

for file in c3520494-be00-4133-afb3-adf8ab5edb11 7fea2d85-7ce1-428c-a92f-57e37551d6f1 d9862b7f-9be6-4672-b9a8-4f52f776fd03 a424dfe5-8be8-4bd6-a49e-62620e369a43 e28bb0ae-e43f-46d9-9147-c7dc712508eb; do xe patch-apply uuid=$file host-uuid=46f8ef28-8ee1-44b5-967c-b8e48585094b; done

That did the trick for me. After applying the patches I came across this post which appears to have a much better script. Whatever works.

Use OpenVPN from within crouton chroot

Update: Google released a ChromeOS update that broke the openvpn script. Find the updated version here.

Update 3/29/17: Added a DNS suffix line to fix broken DNS


I posted a little while ago about how to get openvpn working on your chromebook. That guide required that you run openvpn outside your chroot on the chromebook instance itself.

Lately I’ve been really feeling the need to have openvpn run within a crouton chroot instead. The solution is to take the script from the post above and divide it into two parts. One part you will still have to run outside your chroot but you will only have to do it once on each reboot. The other part can safely live inside your chroot.

First, on your chromebook itself (not in a chroot) make a small script to tell the shill service not to kill tun0:

sudo echo "
#!/bin/bash

#Allows the tun0 device to function
sudo stop shill
sudo start shill BLACKLISTED_DEVICES=tun0" > /usr/local/bin/shill

chmod +x /usr/local/bin/shill

Next, create this script within your chroot. Be sure to modify the environment variables to suit your setup.

#!/bin/bash

CONF_DIR="/path/to/directory/openvpn/config/is/in"
CONF_FILE="FILENAME_OF_OVPN_FILE"
NAMESERVER="IP_OF_DNS_SERVER_YOU_WANT_TO_USE"
SEARCH="DNS_SUFFIX_YOU_WANT_TO_USE"

cd "$CONF_DIR"

# Add google DNS on top of current ones, since openvpn command does not do it
sudo sed -i "1s/^/# new DNS\nsearch $SEARCH\nnameserver $NAMESERVER\n# old DNS\n/" /etc/resolv.conf

sudo openvpn --config "$CONF_FILE" --dev tun0

# When ctrl-c is hit remove tun0 and cleanup the DNS
sudo openvpn --rmtun --dev tun0
sudo sed -i '/# new DNS/,/# old DNS/d' /etc/resolv.conf
trap 2

Voila, we now have openvpn working inside our chroots again.

Install Guacamole 0.9.9 on Ubuntu 15.10

Lately I’ve been trying to upgrade my installation of Guacamole 0.9.8 to 0.9.9. You’d think it would be simple. It is not. I ended up just blowing up my 0.9.8 VM and starting over, this time with Ubuntu 15.10. I found this excellent guide which got me most of the way there, with one small hiccup that took way more time than it should have to figure out.

I will paste the guide I got from the above site for convenience with my added notes for clarification on parts that I had trouble with.

Installation

#!/bin/bash
# WORKING ON UBUNTU 15.10 WITH GUAC 0.9.9 AND TOMCAT8

#Update Everything
apt-get update && apt-get -y dist-upgrade

#Install Stuff
#You will be prompted for a mysql root password. Remember this for the configuration step; change MYSQLROOTPASSWORD to whatever you enter here.
apt-get -y install libcairo2-dev libpng12-dev libossp-uuid-dev libfreerdp-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev mysql-server mysql-client mysql-common mysql-utilities tomcat8

# Install libjpeg-turbo-dev
wget -O libjpeg-turbo-official_1.4.2_amd64.deb http://downloads.sourceforge.net/project/libjpeg-turbo/1.4.2/libjpeg-turbo-official_1.4.2_amd64.deb
dpkg -i libjpeg-turbo-official_1.4.2_amd64.deb

# Add GUACAMOLE_HOME to Tomcat8 ENV
echo "" >> /etc/default/tomcat8
echo "# GUACAMOLE EVN VARIABLE" >> /etc/default/tomcat8
echo "GUACAMOLE_HOME=/etc/guacamole" >> /etc/default/tomcat8

#Download Guacamole Files
wget -O guacamole-0.9.9.war http://downloads.sourceforge.net/project/guacamole/current/binary/guacamole-0.9.9.war
wget -O guacamole-server-0.9.9.tar.gz http://sourceforge.net/projects/guacamole/files/current/source/guacamole-server-0.9.9.tar.gz
wget -O guacamole-auth-jdbc-0.9.9.tar.gz http://sourceforge.net/projects/guacamole/files/current/extensions/guacamole-auth-jdbc-0.9.9.tar.gz
wget -O mysql-connector-java-5.1.38.tar.gz http://dev.mysql.com/get/Downloads/Connector/j/mysql-connector-java-5.1.38.tar.gz

#Extract Guac
tar -xzf guacamole-server-0.9.9.tar.gz
tar -xzf guacamole-auth-jdbc-0.9.9.tar.gz
tar -xzf mysql-connector-java-5.1.38.tar.gz

# MAKE DIRECTORIES
mkdir /etc/guacamole
mkdir /etc/guacamole/lib
mkdir /etc/guacamole/extensions

# Install GUACD
cd guacamole-server-0.9.9
./configure --with-init-dir=/etc/init.d
make
make install
ldconfig
systemctl enable guacd
cd ..

# Move files to correct locations
mv guacamole-0.9.9.war /etc/guacamole/guacamole.war
ln -s /etc/guacamole/guacamole.war /var/lib/tomcat8/webapps/
cp mysql-connector-java-5.1.38/mysql-connector-java-5.1.38-bin.jar /etc/guacamole/lib/
cp guacamole-auth-jdbc-0.9.9/mysql/guacamole-auth-jdbc-mysql-0.9.9.jar /etc/guacamole/extensions/

Configuration

# Configure guacamole.properties 
echo "mysql-hostname: localhost" >> /etc/guacamole/guacamole.properties 
echo "mysql-port: 3306" >> /etc/guacamole/guacamole.properties 
echo "mysql-database: guacamole_db" >> /etc/guacamole/guacamole.properties 
echo "mysql-username: guacamole_user" >> /etc/guacamole/guacamole.properties
 
# This is where you will want to change "PASSWORD" 
echo "mysql-password: PASSWORD" >> /etc/guacamole/guacamole.properties 
rm -rf /usr/share/tomcat8/.guacamole 
ln -s /etc/guacamole /usr/share/tomcat8/.guacamole 

# Restart Tomcat Service 
service tomcat8 restart

#Configure the MySQL database
#Make sure you change MYSQLROOTPASSWORD and PASSWORD
mysql -u root -pMYSQLROOTPASSWORD
create database guacamole_db;
create user 'guacamole_user'@'localhost' identified by 'PASSWORD';
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';
flush privileges;
quit

#Populate the database
#Make sure you change MYSQLROOTPASSWORD
cat guacamole-auth-jdbc-0.9.9/mysql/schema/*.sql | mysql -u root -pMYSQLROOTPASSWORD guacamole_db

After that it should be as simple as logging into your shiny guacamale server as guacadmin/guacadmin.

It wasn’t that simple for me. When I tried to log in all I got was a blank page. Reading the log file /var/log/tomcat8/localhost.<date>.log revealed the following:

Error querying database. Cause: java.sql.SQLException: Access denied for user 'guacamole_user '@'localhost' (using password: YES)

I kept changing and double checking the password for guacamole and couldn’t figure out why it was getting access denied. I even manually logged into mysql with that username and password and it worked, yet guacamole would not load in the browser.

After staring at the log long enough I realized that there is a space before the closing tick on the username. Aha! There were pesky trailing spaces in my guacamole.properties. Removing those spaces did the trick. Always some mundane detail!

Finally I have guacamole 0.9.9 working.

Xenserver NFS SR from FreeNAS VM hack

I have a Citrix xenserver 6.5 host which hosts a FreeNAS VM that exports an NFS share. I then have that same xenserver host use that NFS export as a SR for other VMs on that same server. It’s unusual, but it saves me from buying a separate server for VM storage.

The problem is if you reboot the hypervisor it will fail to connect to the NFS export (because the VM hosting it hasn’t booted yet.) Additionally it appears Xenserver does not play well at all with hung NFS mounts. If you try to shutdown or reboot your FreeNAS VM while Xenserver is still using its NFS export, things start to freeze. You will be unable to do anything to any of your VMs thanks to the hung NFS share. It’s a problem!

My hack around this mess is to have FreeNAS, not Xenserver, control starting and stopping these VMs.

First, create public/private key pair for ssh into xenserver

ssh-keygen

This will generate two files, a private key file and a public (.pub) file. Copy the contents of the .pub file into the xenserver’s authorized_keys file:

echo "PUT_RSA_PUBLIC_KEY_HERE" >> /root/.ssh/authorized_keys

Copy the private key file (same name but without .pub extension) somewhere on your FreeNAS VM.

Next, create NFS startup and shutdown scripts. Thanks to linuxcommando for some guidance with this.  Replace the -i argument with the path to your SSH private key file generated earlier. You will also need to know the PBD UUID of the NFS store. Discover this by issuing

xe pbd-list

Copy the UUID for use in the scripts.

vi nfs-startup.sh
#!/bin/bash
#NFS FreeNAS VM startup script

SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i <PRIVATE_KEY_LOCATION> -l root <ADDRESS_OF_XENSERVER>"

#Attach NFS drive first, then start up NFS-reliant VMs
$SSH_COMMAND xe pbd-plug uuid=<UUID_COPIED_FROM_ABOVE>

sleep 10

#Issue startup commands for each of your NFS-based VMs, repeat for each VM you have
$SSH_COMMAND xe vm-start vm="VM_NAME"
...
vi nfs-shutdown.sh
#!/bin/bash
#NFS FreeNAS VM shutdown script
#Shut down NFS-reliant VMs, detach NFS SR

#Re-establish networking to work around the fact that Network goes down before this script is executed within FreeNAS
/sbin/ifconfig -l | /usr/bin/xargs -n 1 -J % /sbin/ifconfig % up
SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i <PRIVATE_KEY_LOCATION> -l root <ADDRESS_OF_XENSERVER>"

#Issue shutdown commands for each of your VMs
$SSH_COMMAND xe vm-shutdown vm="VM_NAME"

sleep 60

$SSH_COMMAND xe pbd-unplug <UUID_OF_NFS_SR>

#Take the networking interfaces back down for shutdown
/sbin/ifconfig -l | /usr/bin/xargs -n 1 -J % /sbin/ifconfig % down

Don’t forget to mark them executable:

chmod +x nfs-startup.sh
chmod +x nfs-shutdown.sh

Now add the scripts as a startup task in FreeNAS  and shutdown task respectively by going to System / Init/Shutdown Scripts. For startup, Select Type: Script, Type: postinit and point it to your nfs-startup.sh script. For shutdown, select Type: Script and Type: Shutdown.

Success! Now whenever your FreeNAS VM is shut down or rebooted, things will be handled properly which will prevent your hypervisor from freezing.