CARP and DHCP – how to make them be friends

Hi all

I was working on a redundant firewall for the LAN - the server running VMware that it was running on crashed at 1am and it took nearly 15 hours to get it back online – and one of the prerequisites was that it had to get the address from DHCP.  The LAN gets a linkback to the local university by means of a pair of Ubiquiti RocketDishen and the computer the stuff runs on has the IP address that DHCP gives out, NATting the address to the firewall VM (that runs pfSense).  All well and good… until the hard drive fails.

I felt this would be an excellent application for CARP and set out creating a couple of VMs to test my theories.  pfSense, being based on FreeBSD, has CARP support so theoretically you could enable it on both nodes and set it to get its address from DHCP.  Unfortunately, it seems that you can’t simply throw “dhcp” into the hostname.carp0 file and hope for the best – life, it seems, is not that kind, and you wind up with a CARP interface stuck in INIT phase.

So what you need to do is give CARP a temporary static IP, then run dhclient in rc.local to pick up the address.  Whatever you do, DO NOT USE 0.0.0.0 – it will result in a default route to 0.0.0.0 that will block any and all traffic.  I’m not kidding.  It doesn’t even need to be on the same network – I use 1.0.0.1 – as long as DHCP comes in after the fact and overrides it.

I now have a DHCP-enabled CARP interface that stays up when one router bites the dust.  Nice.

Here are the config files I used:

/etc/hostname.carp0:

inet 1.0.0.1 255.255.255.255 NONE vhid 1 pass floppagoppagoo carpdev em0 description "Uplink cluster"

/etc/hostname.carp1:

inet 10.10.10.1 255.255.255.0 10.10.10.255 vhid 2 pass floppagoppagay carpdev em1 description "LAN cluster"

/etc/hostname.em0:

up description "Uplink interface"

/etc/hostname.em1:

up description "LAN interface"

That easy.  Oh, and if you want to run DHCP, I recommend using another system.  DHCP tends to fail terribly when a failover situation occurs.  You could do a periodic refresh of the DHCP leases between them, but it’s better to just have a separate system for the purpose, especially if you intend to run a captive portal.

Work Smarter, Not Harder: Adding multiple rows to a table in Jet SQL

Hi all

I had a table for metadata that I had 25 rows to add to. Simple solution, right? Nope.

INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '5', 'red, Likely, Major');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '6', 'red, Almost Certain, Moderate');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '7', 'red, Unlikely, Catastrophic');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '8', 'yellow, Occasional, Major');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '9', 'yellow, Likely, Moderate');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '10', 'yellow, Almost Certain, Minor');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '11', 'yellow, Rare, Catastrophic');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '12', 'yellow, Unlikely, Major');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '13', 'yellow, Occasional, Moderate');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '14', 'yellow, Likely, Minor');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '15', 'yellow, Almost Certain, Negligible');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '16', 'yellow, Rare, Major');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '17', 'yellow, Unlikely, Moderate');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '18', 'yellow, Occasiona,l, Minor');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '19', 'yellow, Likely, Negligible');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '20', 'yellow, Rare, Moderate');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '21', 'green, Unlikely, Minor');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '22', 'green, Occasional, Negligible');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '23', 'green, Rare, Minor');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '24', 'cyan, Moderate, Negligible');
INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '25', 'cyan, Rare, Negligible');

That only greets me with “Extra characters after SQL”. Argh. Trying multiple value lines fails too:

INSERT INTO metadata (metadata_group, metadata_text, metadata_desc) VALUES('risk', '5', 'red, Likely, Major'),
('risk', '6', 'red, Almost Certain, Moderate');
('risk', '7', 'red, Unlikely, Catastrophic');
('risk', '8', 'yellow, Occasional, Major');
('risk', '9', 'yellow, Likely, Moderate');
('risk', '10', 'yellow, Almost Certain, Minor');
('risk', '11', 'yellow, Rare, Catastrophic');
('risk', '12', 'yellow, Unlikely, Major');
('risk', '13', 'yellow, Occasional, Moderate');
('risk', '14', 'yellow, Likely, Minor');
('risk', '15', 'yellow, Almost Certain, Negligible');
('risk', '16', 'yellow, Rare, Major');
('risk', '17', 'yellow, Unlikely, Moderate');
('risk', '18', 'yellow, Occasiona,l, Minor');
('risk', '19', 'yellow, Likely, Negligible');
('risk', '20', 'yellow, Rare, Moderate');
('risk', '21', 'green, Unlikely, Minor');
('risk', '22', 'green, Occasional, Negligible');
('risk', '23', 'green, Rare, Minor');
('risk', '24', 'cyan, Moderate, Negligible');
('risk', '25', 'cyan, Rare, Negligible');

“Expected ;” it says. Then after a bit of googling, I get the idea to use subqueries with unions instead! Yeah… uh, no.

INSERT INTO metadata (metadata_group, metadata_text, metadata_desc)
SELECT 'risk', '5', 'red, Likely, Major'
UNION SELECT 'risk', '6', 'red, Almost Certain, Moderate'
UNION SELECT 'risk', '7', 'red, Unlikely, Catastrophic'
UNION SELECT 'risk', '8', 'yellow, Occasional, Major'
UNION SELECT 'risk', '9', 'yellow, Likely, Moderate'
UNION SELECT 'risk', '10', 'yellow, Almost Certain, Minor'
UNION SELECT 'risk', '11', 'yellow, Rare, Catastrophic'
UNION SELECT 'risk', '12', 'yellow, Unlikely, Major'
UNION SELECT 'risk', '13', 'yellow, Occasional, Moderate'
UNION SELECT 'risk', '14', 'yellow, Likely, Minor'
UNION SELECT 'risk', '15', 'yellow, Almost Certain, Negligible'
UNION SELECT 'risk', '16', 'yellow, Rare, Major'
UNION SELECT 'risk', '17', 'yellow, Unlikely, Moderate'
UNION SELECT 'risk', '18', 'yellow, Occasiona,l, Minor'
UNION SELECT 'risk', '19', 'yellow, Likely, Negligible'
UNION SELECT 'risk', '20', 'yellow, Rare, Moderate'
UNION SELECT 'risk', '21', 'green, Unlikely, Minor'
UNION SELECT 'risk', '22', 'green, Occasional, Negligible'
UNION SELECT 'risk', '23', 'green, Rare, Minor'
UNION SELECT 'risk', '24', 'cyan, Moderate, Negligible'
UNION SELECT 'risk', '25', 'cyan, Rare, Negligible';

I get a nice and unhelpful “syntax error” pointing to the first subquery. Huh, guess you need a table to select from for unions. let’s give that a spin:

INSERT INTO metadata (metadata_group, metadata_text, metadata_desc)
SELECT 'risk', '5', 'red, Likely, Major' FROM dual
UNION SELECT 'risk', '6', 'red, Almost Certain, Moderate' FROM dual
UNION SELECT 'risk', '7', 'red, Unlikely, Catastrophic' FROM dual
UNION SELECT 'risk', '8', 'yellow, Occasional, Major' FROM dual
UNION SELECT 'risk', '9', 'yellow, Likely, Moderate' FROM dual
UNION SELECT 'risk', '10', 'yellow, Almost Certain, Minor' FROM dual
UNION SELECT 'risk', '11', 'yellow, Rare, Catastrophic' FROM dual
UNION SELECT 'risk', '12', 'yellow, Unlikely, Major' FROM dual
UNION SELECT 'risk', '13', 'yellow, Occasional, Moderate' FROM dual
UNION SELECT 'risk', '14', 'yellow, Likely, Minor' FROM dual
UNION SELECT 'risk', '15', 'yellow, Almost Certain, Negligible' FROM dual
UNION SELECT 'risk', '16', 'yellow, Rare, Major' FROM dual
UNION SELECT 'risk', '17', 'yellow, Unlikely, Moderate' FROM dual
UNION SELECT 'risk', '18', 'yellow, Occasiona,l, Minor' FROM dual
UNION SELECT 'risk', '19', 'yellow, Likely, Negligible' FROM dual
UNION SELECT 'risk', '20', 'yellow, Rare, Moderate' FROM dual
UNION SELECT 'risk', '21', 'green, Unlikely, Minor' FROM dual
UNION SELECT 'risk', '22', 'green, Occasional, Negligible' FROM dual
UNION SELECT 'risk', '23', 'green, Rare, Minor' FROM dual
UNION SELECT 'risk', '24', 'cyan, Moderate, Negligible' FROM dual
UNION SELECT 'risk', '25', 'cyan, Rare, Negligible' FROM dual

Nope. At this point it would’ve been quicker to just enter the damn data. So let’s try our unioned subquery within ANOTHER subquery, giving the fields from the first query names so we can refer to them:

INSERT INTO metadata (metadata_group, metadata_text, metadata_desc)
SELECT metadata_group, metadata_text, metadata_desc FROM (
 SELECT 'risk' AS metadata_group, '5' as metadata_text, 'red, Likely, Major' as metadata_desc FROM dual
 UNION SELECT 'risk', '6', 'red, Almost Certain, Moderate' FROM dual
 UNION SELECT 'risk', '7', 'red, Unlikely, Catastrophic' FROM dual
 UNION SELECT 'risk', '8', 'yellow, Occasional, Major' FROM dual
 UNION SELECT 'risk', '9', 'yellow, Likely, Moderate' FROM dual
 UNION SELECT 'risk', '10', 'yellow, Almost Certain, Minor' FROM dual
 UNION SELECT 'risk', '11', 'yellow, Rare, Catastrophic' FROM dual
 UNION SELECT 'risk', '12', 'yellow, Unlikely, Major' FROM dual
 UNION SELECT 'risk', '13', 'yellow, Occasional, Moderate' FROM dual
 UNION SELECT 'risk', '14', 'yellow, Likely, Minor' FROM dual
 UNION SELECT 'risk', '15', 'yellow, Almost Certain, Negligible' FROM dual
 UNION SELECT 'risk', '16', 'yellow, Rare, Major' FROM dual
 UNION SELECT 'risk', '17', 'yellow, Unlikely, Moderate' FROM dual
 UNION SELECT 'risk', '18', 'yellow, Occasiona,l, Minor' FROM dual
 UNION SELECT 'risk', '19', 'yellow, Likely, Negligible' FROM dual
 UNION SELECT 'risk', '20', 'yellow, Rare, Moderate' FROM dual
 UNION SELECT 'risk', '21', 'green, Unlikely, Minor' FROM dual
 UNION SELECT 'risk', '22', 'green, Occasional, Negligible' FROM dual
 UNION SELECT 'risk', '23', 'green, Rare, Minor' FROM dual
 UNION SELECT 'risk', '24', 'cyan, Moderate, Negligible' FROM dual
 UNION SELECT 'risk', '25', 'cyan, Rare, Negligible' FROM dual
);

Success!

So there you have it.  Oh, and to create those queries?  Just dump the data into Notepad++ and do a replace with regular expressions.

Work Smarter, Not Harder: Manually refreshing RemoteApp and Desktop Connections feeds

Greetings

At work we run Windows Server 2008 R2 servers, with a bunch running published applications through RemoteApp and Desktop Connections. Great guns, especially once we figured out that we could drop them into our Windows 7 computers’ Start Menu and drop shortcuts on the desktop. Now it really feels like you’re running it on your computer! Neat.

The best part of it is being able to regulate who sees what through AD groups – allowing us to restrict access to apps that we have limited licenses for. So, naturally, every so often we get a request to provide access to an application secured like this, and we’re usually more than happy to provide access depending on licensing levels. So we add them to the group and get them to log off, then back on again… except the newly-provided app doesn’t appear! So we’d log in and manually refresh the feed by digging through the Control Panel… not fun, especially since the icons like to not appear all at once so we go to click it and end up clicking on Programs and Features instead.

So ho hi, ho hi, off Googling goes I. I find this post from a fellow by the name of “JayJay19671967″ who found the solution after finding questions of this nature nearly a year old with no response. It was one line:

rundll32 tsworkspace,TaskUpdateWorkspaces

That’s it. Takes all of 5 seconds. It’s in our login script, in the same section where it sets the connection up in the first place.

Work Smarter, Not Harder: Adding a VPN connection to a computer you’ve deployed

Greetings, and welcome to the first of my “Work Smarter, Not Harder” posts.

A bane in our side whenever we deploy a laptop is forgetting to set up the VPN connection – or the RAS phonebook mysteriously disappearing when we image a particular machine. This usually means trying to catch the poor bugger at a (usually remote) site to set it up manually. I, being a systems admin and therefore inherently lazy, beg to differ.

As it turns out, the RAS phonebook is stored in C:\ProgramData\Microsoft\Network\Connections\Pbk and is called “rasphone.pbk” – to deploy this VPN connection, simply create the folder and copy the already set up file in.

I hope this has proved to be helpful for you.

New Toy

Long story short, I won a bet with my wife about whether our baby would be alive, which meant $20 no questions asked.  This was a little more than that, but there were no problems.

Oh my, that is an interesting device you have there…

Bazinga!

The Deploy CS-6.  Not a new dart gun, but it’s shiny and white!  Not only that, fast reload (with additional clip canisters), quite nice range, a “stealth” mode (let’s face it, it’s not going to fool anyone) and a flashlight for nighttime combat.

Nerf – because hey, we have to prepare for the zombie apocalypse somehow.