pfSense as a Cisco AnyConnect VPN Client using OpenConnect

pfSense, as of 2016-03-01, does not support OpenConnect out of the box. However, it’s in the FreeBSD repository, and relatively easy to add:

# pkg
# pkg update -f
# pkg install openconnect
# rehash

You can now play around with the openconnect command and test your connection.

Next step: Autostart, and adding the tun interface to the pfSense GUI. The GUI will, by default, ignore any interface named “tun*”, while openconnect will refuse to work with any interface not named “tun*”. Brilliant. The easiest workaround for this special case seems to be renaming the VPN interface after creation.

I made a script that automates checking if the connection is up, and (re-)starting it if it is not.
Replace the options in the “settings” section with appropriate values for your setup, and you should be good to go.

The “test” field should be a command that returns 0 when the connection is up, and anything else when it’s broken. I used netcat’s port testing feature on the remote desktop port of a server I needed to be able to connect to, but you can just as easily use things like ping with a limited count or similar.

#!/bin/sh

# settings
user="vpnuser"
pass="P4ssw0rd"
host="vpn.server.here.com"
test="nc -v -w 10 -z 172.16.0.4 3389"
tmpif="tun69"
iface="ocvpnc1"
pidfile="/tmp/${iface}.pid"
script="/usr/local/sbin/vpnc-script"


# env
openconnect="/usr/local/sbin/openconnect"
ifconfig="/sbin/ifconfig"


# func
ifkill()
{
        $ifconfig "$1" down 2>/dev/null || :
        $ifconfig "$1" destroy 2>/dev/null || :
}


# check if we're already running
if [ -n "$test" ] && $test; then
        echo "Connection is already up"
        exit 0
fi


# clean up previous instance, if any
if [ -e "$pidfile" ]; then
        read pid <"$pidfile"
        echo "Killing previous pid: $pid"
        kill -TERM "$pid"
        rm "$pidfile"
fi
ifkill "$tmpif"
ifkill "$iface"


# open vpn connection
echo "$pass" |\
$openconnect \
        --background \
        --pid-file="$pidfile" \
        --interface="$tmpif" \
        --user="$user" \
        --passwd-on-stdin \
        --script="$script" \
        "$host"


# rename the interface
if [ "$iface" != "$tmpif" ]; then
        echo "Renaming $tmpif to $iface"
        $ifconfig "$tmpif" name "$iface"
fi

Next, use crontab -e and add an entry to run the script regularly.

*/5 * * * * /root/openconnect-vpn >/dev/null 2>&1

Again, replace the path and timing with your own preferred values.

With the connection established, you can now go ahead and add the interface in the “assignment” tab of the GUI and set up appropriate rules for it.

CAUTION: Adding an interface that’s not available at boot time to the GUI will cause pfSense to think something is wrong on subsequent reboots and ask you to configure interfaces. I am not currently aware of a workaround for this, other than to not add the interface, controlling rules directly from the script instead. Please use the workaround below to avoid this issue, and make sure to verify that it works before leaving a pfSense box at a remote site unattended.

Interface boot workaround

The following workaround was offered by “DJC” in the comments section:

  1. Install “Shellcmd” in PfSense WebConfigurator:
    System => Package Manager => Available Packages
    Find Shellcmd and INSTALL
  2. Navigate to Shellcmd:
    Services => Shellcmd
  3. Add the following item in Shellcmd:
    Command: /sbin/ifconfig tun create; /sbin/ifconfig tun0 name ocvpnc1
    Shellcmd Type: earlyshellcmd
    Description: Create tunnel interface for OVPNC1 at boot

Squid Compile with SSL support under Debian Jessie

Here’s how:

apt-get update

# install required dev packages
apt-get install -y openssl devscripts build-essential libssl-dev

# install debian squid3 source code
apt-get source -y squid3

# install all required dependeny packages
apt-get build-dep -y squid3

# reconfigure
cd squid3-3.4.8/
vi debian/rules

root@jessie:~/squid3-3.4.8# diff /tmp/rules debian/rules 
46c46,48
< --with-default-user=proxy
--- 
> 		--with-default-user=proxy \
> 		--enable-ssl \
> 		--with-open-ssl="/etc/ssl/openssl.cnf"

# build package
debuild -us -uc

# install
cd ..
apt-get install logrotate
dpkg -i *.deb
apt-get install -f

# test
root@jessie:~# squid3 -v
Squid Cache: Version 3.4.8
configure options:  '--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=${prefix}/include'
'--mandir=${prefix}/share/man' '--infodir=${prefix}/share/info' '--sysconfdir=/etc'
'--localstatedir=/var' '--libexecdir=${prefix}/lib/squid3' '--srcdir=.' '--disable-maintainer-mode'
'--disable-dependency-tracking' '--disable-silent-rules' '--datadir=/usr/share/squid3'
'--sysconfdir=/etc/squid3' '--mandir=/usr/share/man' '--enable-inline' '--disable-arch-native'
'--enable-async-io=8' '--enable-storeio=ufs,aufs,diskd,rock' '--enable-removal-policies=lru,heap'
'--enable-delay-pools' '--enable-cache-digests' '--enable-icap-client'
'--enable-follow-x-forwarded-for'
'--enable-auth-basic=DB,fake,getpwnam,LDAP,MSNT,MSNT-multi-domain,NCSA,NIS,PAM,POP3,RADIUS,SASL,SMB'
'--enable-auth-digest=file,LDAP' '--enable-auth-negotiate=kerberos,wrapper' '--enable-auth-ntlm=fake,smb_lm'
'--enable-external-acl-helpers=file_userip,kerberos_ldap_group,LDAP_group,session,SQL_session,unix_group,wbinfo_group'
'--enable-url-rewrite-helpers=fake' '--enable-eui' '--enable-esi' '--enable-icmp' '--enable-zph-qos'
'--enable-ecap' '--disable-translation' '--with-swapdir=/var/spool/squid3'
'--with-logdir=/var/log/squid3' '--with-pidfile=/var/run/squid3.pid' '--with-filedescriptors=65536'
'--with-large-files' '--with-default-user=proxy' '--enable-ssl'
'--with-open-ssl=/etc/ssl/openssl.cnf' '--enable-linux-netfilter' 'build_alias=x86_64-linux-gnu'
'CFLAGS=-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wall'
'LDFLAGS=-fPIE -pie -Wl,-z,relro -Wl,-z,now' 'CPPFLAGS=-D_FORTIFY_SOURCE=2' 'CXXFLAGS=-g -O2 -fPIE
-fstack-protector-strong -Wformat -Werror=format-security'

Shamelessly stolen from http://www.panticz.de/Squid-Compile-with-SSL-support-under-Debian-Jessie

Error 0x80041002 from PowerShell after upgrade to Windows 10

On a box I just upgraded, we run a script that’s supposed to add a new scheduled task. After the upgrade, attempting to create a new trigger would return this beauty:

PS C:\Users\User> New-ScheduledTaskTrigger -AtStartup
New-ScheduledTaskTrigger : Method "NewTriggerByStartup" not found
+ CategoryInfo          : ObjectNotFound: (PS_ScheduledTask:Root/Microsoft/...S_ScheduledTask) [New-ScheduledTaskTrigger], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041002,New-ScheduledTaskTrigger

The solution was to run this magic batch file that re-registers a whole slew of DLL files with the system, and then reboot.

net stop winmgmt
c: 
cd %systemroot%\system32\wbem 
rd /S /Q repository
 
regsvr32 /s %systemroot%\system32\scecli.dll 
regsvr32 /s %systemroot%\system32\userenv.dll
 
mofcomp cimwin32.mof 
mofcomp cimwin32.mfl 
mofcomp rsop.mof 
mofcomp rsop.mfl 
for /f %%s in ('dir /b /s *.dll') do regsvr32 /s %%s 
for /f %%s in ('dir /b *.mof') do mofcomp %%s 
for /f %%s in ('dir /b *.mfl') do mofcomp %%s 
echo DONE

I found the batch file here, intended to fix another issue with the same error code.

A few group policies I use on Windows 10

Disable the lock screen, always showing a login prompt:
Group Policy Editor (gpedit.msc) => Computer Configuration => Administrative Templates => Control Panel => Personalization => Do not display the lock screen

Disallow the use of OneDrive:
Group Policy Editor (gpedit.msc) => Computer Configuration => Administrative Templates => Windows Components => OneDrive => Prevent the usage of OneDrive for file storage

Wiping an (Azure) SQL Server database, deleting all tables

Just for personal reference

USE [mydb]
GO

WHILE(EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY'))
BEGIN
  DECLARE @sql0 NVARCHAR(2000)
    SELECT TOP 1 @sql0=('ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME
    + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
    FROM information_schema.table_constraints
    WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'

  EXEC (@sql0)
  PRINT @sql0
END

GO

DECLARE @sql1 NVARCHAR(2000)
DECLARE @sql2 NVARCHAR(2000)
WHILE(EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES))
BEGIN
  DECLARE c1 CURSOR FOR
  SELECT
    ('DROP TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']') as sql1,
    ('DROP VIEW [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']') as sql2
    FROM INFORMATION_SCHEMA.TABLES
  OPEN c1
  FETCH NEXT FROM c1 INTO @sql1, @sql2
  WHILE @@FETCH_STATUS <> -1
  BEGIN
    EXEC (@sql1)
    PRINT @sql1
    EXEC (@sql2)
    PRINT @sql2
	FETCH NEXT FROM c1 INTO @sql1, @sql2
  END
  DEALLOCATE c1
END

GO

Mounting and using KVM raw image files on the host system

Boldly stolen from David Champion at the University of Chicago, and archived for personal reference. All credits to that page.

kpartx will scan a block device — e.g., your /dev/loop0 — and create device-mapped specials under /dev/mapper for the partitions. Then you can address individual partitions. (N.B.: When done, before you can losetup -d the greater block device, you have to delete the device-mapped specials!)

Here’s a bit of terminal action to illustrate:

# First map the loop device to your KVM disk image. Note that some older versions of losetup don't have the --show option, and will output the used loop device upon being given -v only
$ losetup -fv --show /kvm/watercooler.mwt2.org.img 
Loop device is /dev/loop0

# No partitions!    
$ ls /dev/loop0* /dev/mapper/loop0*
ls: /dev/mapper/loop0*: No such file or directory
/dev/loop0

# Use kpartx -a to discover and device-map the partitions.
$ kpartx -av /dev/loop0
add map loop0p1 : 0 204800 linear /dev/loop0 2048
add map loop0p2 : 0 16930816 linear /dev/loop0 206848
add map loop0p3 : 0 16416768 linear /dev/loop0 17137664

# Look, partitions.
$ ls /dev/loop0* /dev/mapper/loop0*
/dev/loop0  /dev/mapper/loop0p1  /dev/mapper/loop0p2  /dev/mapper/loop0p3

# Fiddle with /dev/loop0p1 et al.

# Try to un-loop the file.  You can't, because kpartx's partition devices are still mapped.
$ losetup -d /dev/loop0
ioctl: LOOP_CLR_FD: Device or resource busy

# Ask kpartx to unmap.
$ kpartx -dv /dev/loop0
del devmap : loop0p1
del devmap : loop0p2
del devmap : loop0p3

# Now you can un-loop.
$ losetup -d /dev/loop0

Hardening IIS and scanning for SSL-related vulnerabilities – IISCrypto

I stumbled upon this great tool to set all the relevant registry entries (WTF?) to allow only the cryptographic algorithms that are considered secure to be negotiated with the server.

I archived it here (CLI version), for my personal reference, but if you prefer (and you should, frankly) you can get it from the author’s site.

Also, make sure to scan your page using, for example, this tool when you’re done.

UPDATE (February 19, 2019): New version 3.0: GUI / CLI

Tool tip: “vbetool” runs real-mode video BIOS code to alter hardware state

This is so damn useful to turn on and off remote displays through SSH, for wall-mounted information screens and similar.

Available in your friendly neighbourhood Linux distribution.

VBETOOL(1) User Commands VBETOOL(1)

NAME
  vbetool - run real-mode video BIOS code to alter hardware state

SYNOPSIS
  vbetool [[vbestate save|restore]|[vbemode set|get]|[vgamode]|[dpms on|off|standby|suspend|reduced]|[post [romfile]]|[vgastate on|off]|[vbefp pan‐
  elid|panelsize|getbrightness|setbrightness|invert]]

DESCRIPTION
  vbetool uses lrmi in order to run code from the video BIOS. Currently, it is able to alter DPMS states, save/restore video card state and attempt
  to initialize the video card from scratch.

OPTIONS
  vbetool takes the following options:

  vbestate
    vbetool will use the VESA 0x4f0f extensions to save or restore hardware state. This will be sent to or read from stdin. This information is
    highly hardware specific - do not attempt to restore state saved from a different machine. This command will not work unless you are at a
    text console, as it interferes badly with X.
 
  dpms
    vbetool will use the VESA 0x4f10 extensions to alter the power management state of your screen. "On", "off", "standby", "suspend" and
    "reduced" are acceptable further options and determine which state will be activated.
 
  vbemode
    vbetool will get or set the current VESA mode. "get" will return the current mode number on stdout - "set" will set the mode to the next
    argument.
 
  vgamode
    vbetool will set the legacy VGA mode to the following numeric argument.
 
  post
    vbetool will attempt to run BIOS code located at c000:0003. This is the code run by the system BIOS at boot in order to intialise the video
    hardware. Note that on some machines (especially laptops), not all of this code is present after system boot - as a result, executing this
    command may result in undefined behaviour. This command must be run from a text console, as it will otherwise interfere with the operation
    of X. This command takes an optional argument which is the location of a file containing a ROM image. If provided, this image will be mapped
    to the c000 segment and used instead of the system's video BIOS.
 
  vgastate
    vbetool will enable or disable the current video card. On most hardware, disabling will cause the hardware to stop responding until it is
    reenabled. You probably don't want to do this if you're using a framebuffer.
 
  vbefp
    vbetool will execute a VESA flat panel interface call.
      panelid will provide information about the panel
      panelsize will provide the size of the panel
      getbrightness will provide the current screen brightness as an integer
      setbrightness accepts an integer as an argument and will set the screen brightness to that
      invert will invert the colours of the screen
 
BUGS
  Switching dpms modes may interact badly with X on some systems.
 
  The vbestate command may behave in strange ways.
 
  The post command may result in the execution of arbitrary code that happens to be lying around in the area where chunks of your video BIOS used to
  be.
 
  The VESA specification does not require that "vbemode get" provides the correct mode if the current mode was set via some means other than the VESA
  BIOS extensions.
 
  The VESA flat panel interface ceased development at the proposal stage. panelid and panelsize will work on many machines, but the other arguments
  are unlikely to be implemented on available hardware.
 
AUTHOR
  vbetool was written by Matthew Garrett <mjg59@srcf.ucam.org>, based on code from read-edid by John Fremlin <john@fremlin.de>, LRMI (http://source‐
  forge.net/projects/lrmi/) and XFree (http://www.xfree86.org). It is released under the terms of the GNU General Public License.

vbetool 0.2 31 December 2004 VBETOOL(1)