AppleScript execution depending on system event

Some time ago I had to create a script to execute on startup, do its job and reboot the computer if needed, but how do you prevent going in to rebooting loop? Luckily after a bit of wondering around I managed to find a solution – the system_profiler command! It gives the opportunity to track the hardware state and if there is any change it can be used to trigger a script execution.

I do not know about your experience with Macs and multiple displays, but according to mine it can get messy, especially if you have more then two displays or /god forbid! ;-)/ Apple plus other display manufacturers.

In my case the problem was not having all the displays on after initial boot, the main Philips display comes on, but both Apple Thunderbolt displays did not. After a reboot though everything comes back to normal. The task was to make a script checking the state of the screens and automatically reboot if there is a problem.

So this is the script I have made to solve the problem, you can tweak it the way you want and need /may be if you use it or post it somewhere mentioning me would be nice :-)/:

delay 15
set display to (do shell script “system_profiler SPDisplaysDataType | grep Thunderbolt; echo $?”)
if display = “1” then
    do shell script “open /Path/To/Your/Scripts/Reboot.app”
else
    display notification “No Need to Reboot!”
    delay 5
    quit
end if

Reboot.app is just a script to reboot the computer, you can make your own, use my previous posts or use any other means to achieve the goal.

And finally – if you insist on having your application windows exactly on the screen you want and at the location you want them to be, there is one very good application called Stay, it is not free, but does the job nicely.

Enjoy!

Advertisement

ApleScript examples for Mac OS X El Capitan

Time is tight as usual, so let’s not waste it and get on with the already delayed El Capitan post. 🙂

As some of you already know Apple introduced a new security feature to their latest OS X called System Integrity Protection (SIP). What it basically does is to limit access to sensitive parts of the OS, prevent code injection, etc. This is all fine probably for most users, but limits the possibilities of tweaking the system as well as flexibility of manipulating certain aspects of the OS’s behaviour.

So this brings some inconvenience when you try to automate certain aspects of your daily routine. For example the bless command will not work, you can no longer “empty trash” while a file is still engaged in a process, if disable SIP you can no longer do repair permissions on your system files as this feature has been removed from Disk Utility.

Simply said – if you want the full control over the OS you will have to disable SIP. I am not going in to details on how to do it, there are many articles on internet about that. Here are just few links if you are interested:

Apple’s official article – https://developer.apple.com/library/mac/documentation/Security/Conceptual/System_Integrity_Protection_Guide/ConfiguringSystemIntegrityProtection/ConfiguringSystemIntegrityProtection.html

 

XtraFinder’s article on how to partially disable SIP – https://www.trankynam.com/xtrafinder/sip.html

or this one for some more customisation – https://www.reddit.com/r/osx/comments/3hv3kk/update_on_rootless_the_configuration_mechanism/

 

Below you will find two AppleScripts, one for automating the process of repairing file permissions and the other one is for empting your trash.

First the script which does the permission repair. Before using it you will need to download and install the utility from here https://www.firewolf.science/2015/07/repairpermissions-v2-0-cli/

Make sure you follow the installation guidance, read the notes section – it is kind of important.

Alternatively if you do not want to use this utility you may prefer to do it differently by using repair_packages command following this tutorial: http://lifehacker.com/verify-and-repair-permissions-from-the-command-line-in-1741718667

 

And the script itself, change the necessary bits with your data or change it the way it suits you:

 

display dialog “Repair Disk Permissions” buttons {“VolumeName 1”, “Volume Name 2”, “QUIT”} default button “QUIT”

if button returned of result = “QUIT” then

     quit

else

     set diskVol to the button returned of the result as text

     tell application “Terminal”

          activate

          set RP to do script “sudo /usr/local/bin/RepairPermissions \”/Volumes/” & diskVol & “\” “

          delay 1

          tell application “System Events”

               keystroke “YourPassword” & return

          end tell

          set mainID to id of front window

          close (every window whose id ≠ mainID)

          repeat until busy of RP is false

               delay 1

          end repeat

     end tell

end if

delay 30

tell application “Terminal” to quit

 

The second script for empting the trash looks a bit bloated, but as AppleScript has no understanding of “go to” statement /at least I could not find any referral to it, though for some reason this statement is considered a bad practise/ I had no choice but to leave it as it is. Any suggestions are welcome.

As per my previous post regarding AppleScript you will have to adjust some details in the script:

 

 

do shell script “sudo nvram SystemAudioVolume=%80” password “YourPass” with administrator privileges

do shell script “defaults write com.apple.loginwindow TALLogoutSavesState -bool false” password “YourPass”with administrator privileges

set trashcontents to quoted form of (do shell script “ls ~/.Trash”)

if trashcontents = “” then

     tell application “Finder” to activate

     tell application “System Events”

          tell process “Finder”

               click menu item 13 of menu 1 of menu bar item “Apple” of menu bar 1

          end tell

     end tell

    delay 5

     tell application “System Events”

          tell process “loginwindow”

               activate

               click button 2 of window 1

          end tell

     end tell

else

     do shell script “sudo rm -rf ~/.Trash/*” password “YourPass” with administrator privileges

     delay 10

     tell application “Finder” to activate

     tell application “System Events”

          tell process “Finder”

               click menu item 13 of menu 1 of menu bar item “Apple” of menu bar 1

          end tell

     end tell

     delay 5

     tell application “System Events”

          tell process “loginwindow”

               activate

               click button 2 of window 1

          end tell

     end tell

end if

 

And that’s it for now, hope this helps not just me, but someone else too 🙂

 

 

 


Useful AppleScript examples

Here are some useful /I think/ AppleScript examples which can be used on their own or in other scripts. The presumption here is you already have an idea of how to use the Script Editor. Keep in mind some scripts might not behave as it should depending on your OS X and will need to be slightly adjusted. I will do separate post just for EL CAPITAN when I got some time. 🙂

Ways to open and close applications with apple script:

If you want or need to use the Terminal to open an application:

 

tell application “Terminal”

      do script “open /Applications/Safari.app; exit”

end tell

delay 2

tell application “Terminal” to quit

 

But if you prefer the short way of doing it you can just type

 

do shell script “open /Applications/Safari.app; exit”

 

or

 

tell application “Safari” to activate

 

And to close application few options are as follows

 

tell application “Safari” to quit

 

or

 

do shell script “killall Safari”

 

Closing Finder application will simply reload it, which is sometimes necessary

 

do shell script “killall Finder” password “YourPassword” with administrator privileges

 

Managing optical drives:

When the case is to manage optical drives using applescript my personal opinion is this is best done with the use of drutil command. To find more about the command you can man it and in terminal window you can:

 

$ drutil info

 

As an example to close the tray of optical drive with the name “DVD-RW GH41N” you can:

 

tell application “Terminal”

      do script “drutil tray close -drive ‘DVD-RW GH41N’; exit”

end tell

delay 3

tell application “Terminal” to quit

 

or if it is external one you can just

 

tell application “Terminal”

      do script “drutil tray close -drive external; exit”

end tell

delay 3

tell application “Terminal” to quit

 

To open the tray

 

tell application “Terminal”

      do script “drutil eject -drive ‘DVD-RW GH41N’; exit”

end tell

delay 3

tell application “Terminal” to quit

 

Automating shutdown and restart:

If the case is to shutdown or restart the computer with just a click of a button you can use the scripts below. They will also do some additional tasks like switching off the option of restarting the active application on boot, silence the startup chime, empty the trash can, which you may of course skip.

Reboot using terminal command:

 

do shell script “defaults write com.apple.loginwindow TALLogoutSavesState -bool false” password “YourPassword ” with administrator privileges

delay 2

do shell script “nvram SystemAudioVolume=%80” password “YourPassword ” with administrator privileges

delay 2

do shell script “shutdown -r now” password “YourPassword” with administrator privileges

 

Reboot using Mac OS X menu, mind though menu item 13 in the example might not be correct for you, so adjust it if necessary:

 

do shell script “defaults write com.apple.loginwindow TALLogoutSavesState -bool false” password “YourPassword” with administrator privileges

delay 2

do shell script “sudo nvram SystemAudioVolume=%80” password “YourPassword” with administrator privileges

delay 2

tell application “Finder” to activate

tell application “System Events”

      tell process “Finder”

       click menu item 13 of menu 1 of menu bar item “Apple” of menu bar 1

      end tell

end tell

delay 3

tell application “System Events”

      tell process “loginwindow”

       activate

       click button 2 of window 1

      end tell

end tell

 

To shutdown the computer, following the same order and logic as above use the examples below. Again mind menu item 15, the number might not be the same for you.

 

tell application “Finder”

      empty trash with security

end tell

do shell script “shutdown -h now” password “YourPassword” with administrator privileges

 

or

 

tell application “Finder”

      empty trash with security

end tell

delay 10

tell application “Finder” to activate

tell application “System Events”

      tell process “Finder”

       click menu item 15 of menu 1 of menu bar item “Apple” of menu bar 1

      end tell

end tell

delay 3

tell application “System Events”

      tell process “loginwindow”

       activate

       click checkbox 1 of window 1

       click button 2 of window 1

      end tell

end tell

 

Changing startup disk:

Something else which like me you can find useful is to quickly reboot to another Mac OS X installation. The first script is using script with buttons, which is faster, but Apple decided you do not need more then 3 buttons in a script dialog. So if you are having more than 3 bootable drives /some people do, trust me :-)/ you have to use a script with a list. Reboot.app in the examples is another script to reboot the computer, but you can do it differently.

The example script with the buttons:

 

display dialog “Select a startup disk” buttons {“NameOf HD1”, “NameOf HD2”, “QUIT”} default button “QUIT”

if button returned of result = “QUIT” then

      quit

else

      set bootVol to the button returned of the result as text

      do shell script “bless -mount \”/Volumes/” & bootVol & “\” -setBoot” password “YourPassword” with administrator privileges

      tell application “Reboot.app” to activate

end if

 

And for a list it might be something like this:

 

set Disks to {“1”, “2”, “3”, “4”, “5”}

set selectedDisk to {choose from list Disks with title “Startup Disk” with prompt “Choose Disk” default items “2” without multiple selections allowed and empty selection allowed}

do shell script “bless -mount \”/Volumes/” & selectedDisk & “\” -setBoot” password “YourPassword” with administrator privileges

tell application “Reboot.app” to activate

 

This is just an example script showing how to control an application with System Events, in this case Skype. Here the preferred web cam is picked from the list of available devices.

 

tell application “Skype” to activate

delay 5

tell application “System Events”

      tell process “Skype”

       click menu item 3 of menu 1 of menu bar item “Skype” of menu bar 1

      end tell

end tell

delay 5

tell application “System Events”

      tell process “Skype”

       set winName to the name of window 1

       if winName = “General” then

                   click button “Audio/Video” of toolbar 1 of window 1

                   click pop up button 2 of window 1

                   click menu item “FaceTime HD Camera (Display)” of menu 1 of pop up button 2 of window “Audio/Video”

       else

                   tell application “System Events” to keystroke “w” using command down

       end if

      end tell

end tell

 

That is quite enough for now, future scripts will be in separate posts, hope you found this information useful. Enjoy 🙂

 

 


OpenVPN client and server on Windows 7/8.1

Now – if you are having free time and wonder what to do you can certainly try to setup an OpenVPN server on a Windows machine… To save you some time / may be 🙂 / and to keep some record of what I have done – I am writing this quick article.

For a general idea on the subject and easy to follow guide to OpenVPN general setup and creation of the certificates you can read here:

https://community.openvpn.net/openvpn/wiki/Easy_Windows_Guide

Do not forget to run the installer as administrator on both client and server PC.

After this, as I am sure you will encounter some difficulties with the communication between your devices. Before testing any setups make sure windows firewall is off, this will save you a lot of frustration. Please read this article and decide for yourself what you are going to use/need from it:

http://blog.defron.org/2013/01/openvpn-server-on-windows.html

In my case I did not want all the traffic to be redirected through the VPN, so I left alone the option push “redirect-gateway def1 bypass-dhcp”. On my server configuration I had to have client-to-client and topology subnet options and float on the client configuration to have a successful ping between the client and the server. Also I changed the registry value of IPEnableRouter in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters from 0 to 1 on both client and server.

I did not try the

push “route-metric 512”

push “route 0.0.0.0 0.0.0.0”

trickery to sort the windows firewall issue as I did not wanted more mess in my already messy routing tables… 🙂 Instead I decided that I can live with the firewall disabled on the TAP interface only. Probably better solution – have a third party firewall on and the windows one off, now days all the bloated antivirus software comes with firewall built in.

Below are my client and server configuration files, might be useful. Good luck!

##################SERVER###########################
# Sample OpenVPN 2.0 config file for            #
# multi-client server.                          #
#                                               #
# This file is for the server side              #
# of a many-clients <-> one-server              #
# OpenVPN configuration.                        #
#                                               #
# OpenVPN also supports                         #
# single-machine <-> single-machine             #
# configurations (See the Examples page         #
# on the web site for more info).               #
#                                               #
# This config should work on Windows            #
# or Linux/BSD systems.  Remember on            #
# Windows to quote pathnames and use            #
# double backslashes, e.g.:                     #
# “C:\\Program Files\\OpenVPN\\config\\foo.key” #
#                                               #
# Comments are preceded with ‘#’ or ‘;’         #
#################################################

# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one.  You will need to
# open up this port on your firewall.
port 11194

# TCP or UDP server?
proto tcp
;proto udp

# “dev tun” will create a routed IP tunnel,
# “dev tap” will create an ethernet tunnel.
# Use “dev tap0” if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use “dev-node” for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key).  Each client
# and the server must have their own cert and
# key file.  The server and all clients will
# use the same ca file.
#
# See the “easy-rsa” directory for a series
# of scripts for generating RSA certificates
# and private keys.  Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see “pkcs12” directive in man page).
ca “C:\\Program Files\\OpenVPN\\config\\ca.crt”
cert “C:\\Program Files\\OpenVPN\\config\\server.crt”
key “C:\\Program Files\\OpenVPN\\config\\server.key”  # This file should be kept secret

# Diffie hellman parameters.
# Generate your own with:
#   openssl dhparam -out dh2048.pem 2048
dh “C:\\Program Files\\OpenVPN\\config\\dh2048.pem”

# Network topology
# Should be subnet (addressing via IP)
# unless Windows clients v2.0.9 and lower have to
# be supported (then net30, i.e. a /30 per client)
# Defaults to net30 (not recommended)
topology subnet

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 192.168.20.0 255.255.255.0

# Maintain a record of client <-> virtual IP address
# associations in this file.  If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt

# Uncomment this directive to allow different
# clients to be able to “see” each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server’s TUN/TAP interface.
client-to-client

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120

# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log

# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3
##################CLIENT########################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server.     #
#                                            #
# This configuration can be used by multiple #
# clients, however each client should have   #
# its own cert and key files.                #
#                                            #
# On Windows, you might want to rename this  #
# file so it has a .ovpn extension           #
##############################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Are we connecting to a TCP or
# UDP server?  Use the same setting as
# on the server.
proto tcp
;proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote your.server.net 11194
;remote my-server-2 1194

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server.  Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don’t need to bind to
# a specific local port number.
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

# SSL/TLS parms.
# See the server config file for more
# description.  It’s best to use
# a separate .crt/.key file pair
# for each client.  A single ca
# file can be used for all clients.
ca “C:\\Program Files\\OpenVPN\\config\\ca.crt”
cert “C:\\Program Files\\OpenVPN\\config\\CLIENT.crt”
key “C:\\Program Files\\OpenVPN\\config\\CLIENT.key”

# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the keyUsage set to
#   digitalSignature, keyEncipherment
# and the extendedKeyUsage to
#   serverAuth
# EasyRSA can do this for you.
remote-cert-tls server

# Enable compression on the VPN link.
# Don’t enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 3

float


Debian 7 Wheezy – L2TP VPN Server behind NAT with strongSwan and self-signed certificate authentication

As usual before everything else a few good and must read articles on the subject: https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/ – a very good tutorial on setting up strongSwan, http://www.manabii.info/2014/08/debian-wheezy-strongswan-l2tp-ipsec.html – another very good tutorial on L2TP strongSwan configuration /you will have to translate it from Japan unless you are a ninja :-)/ and of course the very important strongSwan wiki documentation at https://wiki.strongswan.org/projects/strongswan.

Why strongSwan and L2TP? Well after some research I have done on the available IPsec implementations for Linux I have decided to go for strongSwan because of its active development. As for L2TP I decided that a bit of overhead, which any modern hardware can handle the capability to use other protocols as well as IP over the VPN connection is worth the hassle.

 

STEP 1 – GENERAL PREPARATION

The assumption is you already have control over a DNS server, local network in range of 192.168.0.0/24, a server running Debian 7 Wheezy  with IP address 192.168.0.10 and as a good practice advises – first make sure your system is up to date, just run /do not forget to be a root user or use sudo when necessary/:

#apt-get update && apt-get upgrade

Normally Debian 7 will install strongSwan 4, but I wanted version 5 because it only runs the charon daemon which handles everything for you and you do not have to configure NAT-T – it is triggered for you automatically if needed. To do this you will have to alter the /etc/apt/sources.list file adding those lines in it:

deb http://ftp.debian.org/debian/ wheezy-backports main
deb-src http://ftp.debian.org/debian/ wheezy-backports main

After that you can run the set of commands which will update the sources, install the xl2tpd daemon /this is the software responsible for L2TP/ and install strongSwan:

#apt-get update
#apt-get install xl2tpd
#apt-get -t wheezy-backports install strongswan

Just to check you have the version 5 of strongSwan:

#dpkg -l | grep strong

The next important thing is to change the kernel parameter so it can route the VPN traffic /later on NAT will be configured/. To achieve this in a permanent way some parameters in /etc/sysctrl.conf must be set properly, you will need to have this:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0

To apply the changes run the following command:

#sysctl –p

 

STEP 2 – CERTIFICATES PREPARATION

Before generating certificates find out the fully qualified domain name of your VPN server, make sure an A record for it exist in your DNS server and use it as CN when generating certificates. To find your FQDN run the fallowing command:

#hostname –f

Now you are ready to generate the certificate authority key and certificate:

#cd /etc/ipsec.d/
#ipsec pki –gen –type rsa –size 4096 \
–outform pem \
> private/CA_Key.pem

#chmod 600 private/CA_Key.pem

#ipsec pki –self –ca –lifetime 3650 \
–in private/CA_Key.pem –type rsa \
–dn “C=GB, O=SomeName, CN=server.example.com” \
–outform pem \
> cacerts/CA_Cert.pem

 

Create the VPN Server Key and Certificate

#ipsec pki –gen –type rsa –size 2048 \
–outform pem \
> private/VPN_Server_Key.pem

#chmod 600 private/VPN_Server_Key.pem

#ipsec pki –pub –in private/VPN_Server_Key.pem –type rsa | \
ipsec pki –issue –lifetime 3650 \
–cacert cacerts/CA_Cert.pem \
–cakey private/CA_Key.pem \
–dn ” C=GB, O=SomeName, CN=server.example.com ” \
–san server.example.com \
–flag serverAuth –flag ikeIntermediate \
–outform pem > certs/VPN_Server_Cert.pem

 

Create Client Certificate

#ipsec pki –gen –type rsa –size 2048 \
–outform pem \
> private/ClientKey.pem

#chmod 600 private/ClientKey.pem

#ipsec pki –pub –in private/ClientKey.pem –type rsa | \
ipsec pki –issue –lifetime 3650 \
–cacert cacerts/CA_Cert.pem \
–cakey private/CA_Key.pem \
–dn ” C=GB, O=SomeName, CN=server.example.com ” \
–san user@example.com \
–outform pem > certs/ClientCert.pem

 

Export Certificate for the Client as PKCS#12

#openssl pkcs12 -export -inkey private/ClientKey.pem \
-in certs/ClientCert.pem -name “Client VPN Certificate” \
-certfile cacerts/CA_Cert.pem \
-caname “server.example.com” \
-out Client.p12

 

STEP 3 – SETTING UP srongSwan

There are few files used to configure strongSwan all located in /etc folder. The file /etc/strongswan.conf I left unchanged as it probably is set correctly for most users, but of course you can check its content and if you are sure you know what you are doing adjust it to your needs.
Next is the file /etc/ipsec.conf, which you can backup first before changing:

#cp /etc/ipsec.conf /etc/ipsec.conf.bac

Then you can create the configuration you need, mine looks like:

# ipsec.conf – strongSwan IPsec configuration file

# basic configuration

config setup
#       strictcrlpolicy=yes
#       uniqueids = no
charondebug=”cfg 2, dmn 2, ike 2, net 2″

# Add connections here.
conn L2TP
forceencaps=yes
auto=add
keyexchange=ikev1
keyingtries=3
rekey=no
ikelifetime=8h
lifetime=1h
type=transport
left=192.168.0.10
leftsubnet=0.0.0.0/0[udp/1701]
leftauth=pubkey
leftcert=VPN_Server_Cert.pem
right=%any
rightsubnet=0.0.0.0/0[udp/%any]
rightauth=pubkey
rightcert=ClientCert.pem
dpddelay=40
dpdtimeout=130
dpdaction=clear

include /var/lib/strongswan/ipsec.conf.inc

And finally the file /etc/ipsec.secrets has to be set so the client can log in. Mine is set as follows:

: RSA VPN_Server_Key.pem
#user1 : EAP “BigSecret”
#user2 : XAUTH “AnotherBigSecret”

It is not a bad idea to set the permissions:

#chmod 600 /etc/ipsec.secrets

To make sure ipsec service loads on boot:

#insserv ipsec

 

STEP 4 – SETTING UP L2TP

Three files must be configured so xl2tpd daemon to work properly. First one is /etc/xl2tpd/xl2tpd.conf where the global parameters are set and in my case it is like that:

[global]
[lns default]
ip range = 192.168.111.2 – 192.168.111.254
local ip = 192.168.111.1
length bit = yes
refuse chap = yes
require authentication = yes
name = l2tp
pppoptfile = /etc/ppp/l2tpd-options

The next one is obviously the file /etc/ppp/l2tpd-options where you set some PPP options and mine are set as:

name l2tp
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
nodefaultroute
lock
nobsdcomp
mtu 1280
mru 1280

And finally you set the PPP user in the file /etc/ppp/chap-secrets:

# client    server  secret      IP addresses
vpnuser    l2tp    “aPassword”  *

 

STEP 5 – SETTING UP NAT

We are almost there now. The final bit is to set up the NAT, which is done with iptables, but before that I recon it is not a bad idea to install the iptables-persistent package and have your rules saved and loaded properly on reboot. To do this you will have to:

#apt-get install iptables-persistent

Then you can create the rule and have it saved. To go for SNAT or Masquerading is a personal choice, but as you most likely will have a static IP address for your server probably SNAT is better:

#iptables -t nat -A POSTROUTING -j SNAT –to-source 192.168.0.10 -o eth+
#iptables-save > /etc/iptables/rules.v4

To check if your services are running you can see their status or/and network activity:

#service –status-all

or

#netstat -lnput | grep charon
#netstat -lnput | grep xl2tpd

Do not forget to forward UDP ports 500, 1701 and 4500 on your router.

And now the funny part…  Connecting your clients. Android devices connect effortlessly, just install your client certificate using the p12 file, put your PPP username and password as well as the server IP address /which will be the public address of your router/ or its DNS name /should resolve to your router’s public address/ and you are done.
Have not tried iOS device yet, but as Mac OS X connects I would assume there will not be a problem, though it was a bit tricky with the Mac. Make sure you install the client certificate in your System key chain and then make it trusted. Make sure you have a record in your DNS server with exactly the same name of your VPN server as it is in the certificate and when setting the connection do not use the IP address, use the domain name. If you do not do it this way you will not be able to connect.
Windows… well I could not manage to connect even a single Windows 7 client PC regardless of what I tried – switching off firewall and antivirus software, changing the configuration of the VPN server, had the certificates properly installed with MMC, and before you ask – yes, I have had the AssumeUDPEncapsulationContextOnSendRule in the registry set to 2. Nothing worked. Had a brief look at third party VPN clients for Windows, but could not find a good enough to support L2TP VPN with certificates. So if anyone have experience with this I will be happy to see what is wrong and where, I could not figure it out from the server logs.

“And that’s all I’ve got to say about that” – Forrest Gump 🙂

For now. 🙂


Linux – Bash script for complete system backup on external hard drive using rsync

*2022 Update. As this was written some time ago and time flies, some minor changes to the script are needed. Our old friend udisks is now depreciated so instead it’s successor udisksctl has to be used. You can comment the line and add a new one /I corrected the script here this way/ or just replace it with the new one.*

Now before you read this article I strongly advise you to read those once first if you think you are not too familiar with this subject.  The first one is located HERE and is a very good explanation on how to use rsync for full OS backup. The second one is a detailed explanation on backing up data on to external USB drive by Bobulous, which you can find HERE. The script in this article is a modified version of the original script created by Bobulous as I needed to achieve few other things as well.

It is kind of important to get your fstab file organized first. Do not forget to modify it so your external hard drive gets the same mount point every time it is mounted. For this you will have to find out what your drive UUID is. As an example, the line in my fstab file look like:

UUID=ff0ba5cf-dc79-4b96-a86b-a64f26154232 /mnt/sync ext4 user,noauto,noatime     0     0

As I wanted the drive to be used only for the purpose of system backup I did not want it working all the time, so I wanted not just to unmount, but eject it as well and switch it off after use. This is where udisks utility comes handy, if it is not installed on your system – you will have to install it so the script works as it should. But udisks does not use the UUID to handle the drive, so the correct device file mapping has to be found.

The first thing is to extract the UUID, this is done in variable declaration:

uuid=`cat /etc/fstab | grep ${mount_point} | cut -c 6-41`

Before using the script make sure the result of the commands is the UUID of your drive, take care of cut command and adjust it if the output is not exactly what you are expecting. Or instead of cut you can use sed command, which might be a bit more universal:

uuid=`cat /etc/fstab | grep ${mount_point} | sed -r ‘s_.*=(.*) ${mount_point}.*_\1_’`

though I haven’t tried it myself.

After the disk is successfully mounted the declaration of HDID takes care of finding the correct device file:

HDID=`ls -l /dev/disk/by-uuid/${uuid} | sed -r ‘ s_^.* -> ../../(…).$_\1_’`

If you are like me and find sed command often confusing – there is a great tutorial about it by Bruce Barnett.

The actual backup work is done by rsync command, but you may want to adjust it depending on your Linux distribution, I run it on Debian 7 and it works fine for me.

And this is the script itself, you can modify it to suit your needs:

#!/bin/bash

# Script to backup full ystem to the external USB drive.

# Specify the mount point here (DO NOT end mount_point with a forward-slash).

mount_point=’/mnt/sync’

 

# Set the backup path here (DO NOT end mount_point with a forward-slash).

backup_path=${mount_point}

 

#Find UUID by mount point

uuid=`cat /etc/fstab | grep ${mount_point} | cut -c 6-41`

 

echo “#####”

echo “”

# Check whether target volume is mounted, and mount it if not.

if ! mountpoint -q ${mount_point}/; then

                echo “Mounting the external USB drive.”

                echo “Mountpoint is ${mount_point}”

                if ! mount ${mount_point}; then

                                echo “An error code was returned by mount command!”

                                exit 5

                else echo “Mounted successfully.”

                     HDID=`ls -l /dev/disk/by-uuid/${uuid} | sed -r ‘ s_^.* -> ../../(…).$_\1_’`

                     echo “${HDID} is the backup drive ID”;

                fi

else echo “${mount_point} is already mounted.”;

fi

# Target volume **must** be mounted by this point. If not, die screaming.

if ! mountpoint -q ${mount_point}/; then

                echo “Mounting failed! Cannot run backup without backup volume!”

                exit 1

fi

 

echo “Preparing to transfer differences using rsync.”

 

echo “Backup storage directory path is ${backup_path}”

 

echo “Starting backup of / . . . “

 

rsync -aAXHhv /* ${backup_path}/ –progress –delete –exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}

 

# Ask user whether target volume should be unmounted.

echo -n “Do you want to unmount ${mount_point} and eject the drive (no)”

read -p “: ” unmount_answer

unmount_answer=${unmount_answer,,}  # make lowercase

if [ “$unmount_answer” == “y” ] || [ “$unmount_answer” == “yes” ]; then

                if ! umount ${mount_point}; then

                                echo “An error code was returned by command!”

                                exit 5

                else echo “Dismounted successfully.”

#                     udisks –detach /dev/${HDID}

udisksctl power-off -b /dev/${HDID}

                     echo “Disk ejected.”;

                fi

else echo “Volume remains mounted.”;

fi

 

echo “”

echo “####”


Windows batch script for auto reconnection to wireless network

 

Recently I had a client with an odd problem – a laptop randomly disconnecting from the WLAN connection. After ruling out all the possible software issues – OS setup, network configuration, drivers, etc. as well as the access point I was left with no choice but to think of something to go around this. And what I came up with was a looped batch script using netsh command. Now some of you may ask – why not powershell, it is modern – well I do not know much about it and from what I have read about network interface manipulation one could only enable or disable the interface, but that was not what I wanted anyway.

Just a bit of info for those who are not familiar with netsh command, to make the script working you will need some information regarding your wireless setup. You will need the SSID, profile name and the name of your WLAN interface. Using netsh command you can:

C:\>netsh wlan show all – this will give you the full information in relation to wireless network and all the info needed, but if you are not interested in all the details you can be more specific.

C:\>netsh wlan show networks – to find the SSID

C:\>netsh wlan show profile – to find the profile name

C:\>netsh wlan show interfaces – to find the name of the interface

Most likely your SSID and profile name are going to be the same. Of course you can just left click on the network connections icon in task bar’s notification area, move the pointer over the connected wireless network and in the popup message you will see your profile name and SSID. In Windows 7 the WLAN interface name is “Wireless Network Connection”, Windows 8 – “Wi-Fi”.

Now to the batch script, what it basically does is to check if default gateway exists and if it doesn’t – the netsh command to reconnect is executed. The script is looped, so it runs itself constantly with a delay you can adjust:

 

:loop

for /f “tokens=1-2 delims=:” %%a in (‘ipconfig^|find “Default”‘) do if not [%%b]==[] goto restart

netsh wlan connect ssid=”Wireless Network” Name=”Wireless Network” Interface=”Wireless Network Connection”

:restart

timeout /t 5

goto loop

 

Copy/Paste it in let say Notepad and save it as .bat file /BTW when copy/paste from the web content make sure you got the lines correctly/. Adjust it to your needs and to stop it you can interrupt it with Ctrl+C.

There is an annoying inconvenience thought – when you run the script the Command Prompt window is visible, but there is luckily a solution for that – wrapping it in a VBS /found this solution on internet, thanks to a man who’s name cannot sadly remember/ and run it in the background. So the VBS file looks like this:

 

Dim WinScriptHost

Set WinScriptHost = CreateObject(“WScript.Shell”)

WinScriptHost.Run Chr(34) & “C:\PathTo\mybat.bat” & Chr(34), 0

Set WinScriptHost = Nothing

 

Copy/Paste and change the path to the .bat file accordingly and save the file as .vbs. Now every time you need to keep your WLAN connection alive – start the VBS file. If you think it will be convenient you can add it to your start up items.

And that’s all. 🙂