Pitfall-Free Howto/Guide to StartCom/StartSSL Class 2 Organization Validation/Certification

...in just three not-so-simple steps.

A couple quick notes before we begin: I threw this article together over a period of weeks, so the layout is a bit... odd. At some point I'll come back to this article and clean it up, however for now, I think it does the job of conveying the process to a new StartSSL user. Also, I use the names "StartCom" and "StartSSL" interchangeably, so don't look any deeper into the name usage than that.

A few weeks ago, I started the process of renewing several StartCom certs for my employer, and started to become familiar with the processes and pitfalls of identity and organization validation with StartCom. After delving into the process head-first, it became evident that this might not be as straight-forward as one might expect. However, I think that once you know what to expect, the process should go much more smoothly.

Also, please note that this how-to merely documents what I did to get a cert, and what pitfalls I ran into along the way. Therefore, your requirements and path may (and probably will) vary from mine. For instance, the tax document I submitted was a "State of Delaware Annual Franchise Tax Report". This document lists all of the items shown on StartCom's requirements. Your document(s) may not.

First, let's understand the steps required in obtaining Class 2 Org validation. Basically, you keep escalating your level of validation, providing increasingly trusted levels of personal and organization documentation as you go. Here's a rough outline:

  • Get Email Address validation with StartSSL (free)
    • Sign up
    • Validate email
    • Get personal client cert (for browser) via website
      • Back it up!!!
  • Get Personal Class 2 validation (~$60)
    • Submit 2 forms of ID
      • 1 Photo ID (i.e.: Driver's license)
      • 1 other form of ID. May be photo (i.e.: Passport), OR non-photo (i.e.: birth certificate)
    • AND submit either:
      • Phone bill showing your name, current address, AND (most importantly) phone number.
        • May be land line or cell

        OR

      • Request for certified mail validation
        • Delivery will take ~2.5 to 5 weeks (from Israel)
          • If expedited service is required, you may additionally request express mail (~4-5 bus. days) for approx $30.
    • Wait for call or letter, and verify provided code on StartSSL website control panel.
  • Get Organization Class 2 validation (~$60)
    • Submit tax document which contains:
      • Name of CEO
      • Names of Directors
      • Co. Address (not sure if this is an actual requirement)
      • Co. Phone number (not sure if this is an actual requirement)
    • AND submit StartSSL's "Delegate Authorization Letter" (https://www.startssl.com/authorization-letter-class2-organizational-validation.pdf) with:
      • Your name, title as delegate
      • Name and signature of CEO, President, or Director (CFO also appears to work. Other C?? titles may suffice)
    • Have your signatory receive a phone call from StartCom to verify your authorization.
  • Validate your domain(s)
    • Perform the "Domain Name Validation" validation wizard for each new or expiring domain
    • Confirm validation using code sent to email
  • Generate Certs
    • Perform the "Web Server SSL / TLS Certificate" certificate wizard
      • Only new/expired certs or certs expiring within 2 weeks may be renewed (when the existing cert is with StartCom)
    • Generate password-protected key / cert pairs
      • Keep that password safe and backed up!
    • Save key to .key file, cert to .crt file (ie, wildcard.mydomain.com.key, wildcard.mydomain.com.crt)
  • Install Certs
    • Decrypt (strip password protection from) key file
    • Place decrypted key and crt files on webserver
    • Configure Apache SSL
    • Reload Apache
    • Verify correct cert in web browser
  • ???
  • PROFIT!!!

And now for the more elaborate explanation:

1) Get your email address set up, and obtain a website authentication certificate. This is free. Go to the Control Panel and click Sign Up. Fill out the forms and submit. Soon you should receive an authentication code via email. You will submit this to the StartCom site, and then wait for another email that has a verification link, which you'll click. Once that's done, you'll get a personal client certificate for your browser. Follow the instructions in the email/website on how to backup this certificate. Don't skip this! Think of this as cert the key to your account. If you lose it, you're likely going to have to a hard time regaining access. Back it up to an external storage medium (perhaps even encrypted as well - TrueCrypt is good for this).

2) Get yourself a Class 2 validation. This will cost you ~$60 (with one potential caveat, described below). This is where things start to get more complex. You'll need two scanned or photographed forms of documentation that prove that you exist, AND a means of verifying that the person submitting the documentation is actually you. For the two forms of identification, one must be a photo ID (afaik), and another can be another photo ID (such as a passport) OR something that simply proves you exist, such as a birth certificate (this is what I used). Submitted photos/scans must be of "high" quality, but less than 1400x1400 resolution. The second half of this, and this is where I got hung up, is the verification that the person submitting the information is YOU. StartCom apparently trusts phone companies, because you "just" need to submit an invoice/bill showing your name, address, and phone number. This can be either a scan/photo or a PDF. This is where I got hung up. My current cell service is not in my name, and I have Ooma VOIP for home phone service, which doesn't do traditional paper or PDF invoicing. Attempts to submit website screenshots, or PDFs of a webpage will likely be rejected. StartCom needs to be able to verify that you own the number you say you do, and then call you at that number to verify that you submitted the request (presumably with a code conveyed by voice, then submitted to the StartCom website). In lieu of a verified phone number, your next/only option is a registered mail letter from StartCom (in Israel). They claim this takes 3-5 business days. That may be true if you lived in Israel. I live in the US. Internet rumor has it that this letter takes ~5 weeks to get to the US destinations. I'll see if one of my letters end up taking this long (see update below... took ~2 weeks). The alternative is to request express mail delivery, which costs ~$30. This will take approximately 4-5 business days. I opted for this to expedite the process. Once you receive the letter, it will contain a code which you submit via the StartCom website control panel. Shortly after, StartCom should send you confirmation that you have been personally Class 2 verified.

3) Get your Organization Class 2 verified (another ~$60). This part is still in progress for me. I will be updating as I go along. First step appears (at least for now) that I have to obtain a yet-to-be-identified tax document from our finance/accounting department that proves that our company is recognized to exist by either the State or the US. Also, it's not clear if I, as an employee of the company, can submit the tax documentation and as a result get access to create these certs, OR do I also need to submit an authorization form that delegates me to make cert changes on behalf of the company. Sure would be nice if StartCom would clear some of this up on their website, or at least on their forums.

More on this as the mystery unfolds...

Update 5/28: A few updates

  • Today I received my initially-requested snail-mail letter from StartCom. The letter was requested late on the 10th, so that means it takes 14-16 postal days (Mon-Sat) to get to Minneapolis, MN. But of course, YMMV.
  • In the case of my company, the tax document used was a Delaware Annual Franchise Tax Report (as the company is incorporated in Delaware). Your document will almost surely be different. My recommendation is to ask your accountant or executive for a copy of the Articles of Incorporation applicable to your state.
  • Unless you are the CEO, President, or a Director of the company/org you are applying for, you'll need to fill out the  StartSSL Delegate Authorization Letter, printed on company letterhead, and have one of the aforementioned individuals sign it. Currently I'm attempting to use our CFO's signature to see if that is sufficient. If not, I'll be going to CEO to get the required signature.

Update 6/4: Eventually I got a signature from our CFO. I submitted the document to StartCom, and within a few hours I got an email back they they were unable to reach anyone at the listed office number. Presumably they tried to contact our CFO. I asked them to try again, and soon after got an email stating that the Class 2 Org Validation is complete! Once that was done, I was able to log into the StartCom control panel and perform Domain Name Validation(s) for each of our domains. It appears they offer a number of hostmaster/postmaster addresses as options to send a validation email to your domain. In addition to our other TLD's, they offered hostmaster@our_main_domain.com. Not sure how they linked them to our main corporate domain (possibly public WHOIS data), but they did. Up next, cert generation!...

Update 6/7: This ended up being the most straightforward process of the entire adventure. In my case, the web service in use was Apache. This process will likely vary for an MS-based/IIS server. Once your domain(s) is/are validated, you can go back into the StartSSL control panel, go the the certificates wizard, and select "Web Server SSL/TLS Certificate". Set a password for you keyfile and generate the key. Keep good tabs on this password as it's what decrypts your private key for use on your webserver. Save the resulting key text out to a file named something like "wildcard.mydomain.com.key". Continue on and select your domain, and enter/add your subdomain(s) or subdomain wildcards as needed (see notes below regarding restrictions). Once the cert is generated, save the text into a file named something like "wildcard.mydomain.com.crt". Keep these files safe and backed up!

A few other notes related to this: Note that a subdomain wildcard only applies to the level of that wildcard. So for instance, *.mydomain.com would cover test.mydomain.com, byt not test1.test2.mydomain.com. For that, you need to specify wildcards for each recursive level, ie *.test2.mydomain.com. Also note that domains that still have active StartSSL certs (or are not expiring within 2 weeks) are not able to be renewed. If you must renew them, you must revoke the existing cert, which costs approx $25. Be aware that you could still generate certs for individual specific (sub)domains instead to avoid going through the revocation process.

You can now proceed to install the cert on your webserver, however note that hte .key file is password protected/encrypted. You must strip the password in order to allow your web service to start up unattended. Here's a quick command to do that:

openssl rsa -in wildcard.mydomain.com.key > wildcard.mydomain.com.decrypted.key

You can then take the decrypted key and use it in your Apache config. Please note however that you must take care to restrict access to your server so that your private key is not copied by unauthorized persons. They alternative to this is to leave password protection on, but intervene manually by entering in the password each time Apache is (re)started.
So there you have it! At some point I'll probably come back to this article and clean it up. For now, I just wanted to get the information out there to help my fellow interweb users. Good luck!

Routed OpenVPN HOWTO

This is my OpenVPN HOWTO. There are many like it, but this one is mine.

It seems every few months I get asked the question by one of my friends "How do I set up a VPN?". Sometimes the person is looking to set up a MS VPN variant, other times, OpenVPN. The principles and concepts seem simple to me, now, however for someone new to VPN architectures and perhaps even routing, it can be confusing. This is my attempt to make the mysterious understandable. Since roadwarrior (individual laptop clients) configs are fairly well documented by the official OpenVPN wiki, I'll concentrate on a simple routed, LAN-to-LAN VPN networking concept, and cover roadwarrior config as an afterthought.

My weapon of choice distro-wise is CentOS, however these instructions could be applied to any other distro (ie, Ubuntu) with a basic understanding of your particular platform's networking configuration methods. Really, OpenVPN can run on just about anything, including Windows, if you feel so inclined. However, you'll probably get the most bang for your buck (free) using Linux. In my test environment, running stock CentOS 6.4, I had the scenario below running on a server with less than 90MB of total system memory usage.

Why CentOS?
(BEGIN RANT)
I have two main reasons for promoting the use of CentOS:
1) CentOS is based upon RedHat Enterprise Linux (RHEL), which currently enjoys status as the most vendor-supported OS in enterprise environments. Translation? Knowledge of an RHEL derivitaves like CentOS is marketable skill to put on your resume. Yes, Ubuntu is gaining popularity in tech circles, but still doesn't compare to RHEL for vendor support. There's a reason both VMWare and Citrix use RHEL derivitaves as their baremetal OS.
2) CentOS has long-term-support (LTS). I've used Fedora for years, and I enjoy(ed) playing with some of the bleeding-edge features it offers. But the bleeding edge is on a double-edged sword. Fedora has a relatively aggressive release and support schedule. Install Fedora X, and expect that Fedora Z will replace it in about a year, leaving version X effectively without support. This gets to be a pain when you need to "yum update" your system just a year or so after you installed it. CentOS however has a support schedule that will ensure you likely have updates for far more years than the lifecycle of your hardware. For example CentOS 6, released in 2011, reaches EOL in late 2020. That's almost 10 years of support, on a free platform!
(END RANT)

First, let's diagram the network we are going to design:

Remote Office 1 (10.101.0.x/24)
|
VPN Tunnel (10.200.101.1/30)
|
Main Office (10.100.0.x/24)
|
VPN Tunnel (10.200.102.1/30)
|
Remote Office 2 (10.102.0.x/24)

For this guide, we're going to assume you want all remote offices to have routing enabled to each other (via the Main office).

Note that the IP addresses above are just for example. You could create your own IP addressing scheme with FAR better utilization of the the private address space. The subnets I have used (ie 10.200.x.x/16) are just for increased clarity.

Each OpenVPN server/endpoint can have one interface (assuming you are doing NAT/firewalling elsewhere on your network), OR you could have dual interfaces: One on the LAN, the other on the WAN/Internet connection. It's up to you depending on where you want to do your firewalling. For the purposes of this guide, we're putting the VPN server behind another firewall.

On your firewall
Forward UDP port 1194 for your external internet connection to the internal IP of your VPN servers/endpoints, ie:

Main Office 10.100.0.5:1194
Remote Office 1 10.101.0.5:1194
Remote Office 2 10.102.0.5:1194

If for some reason UDP/1194 were blocked by your ISP, you could switch to something like TCP/80, but for the purposes of this guide, we'll stick with the default UDP/1194.

On each server/endpoint
Install your base OS. I chose to just install CentOS 6.4 minimal installation with the default options. Once installed, get networking set up and run

yum update

and get everything up-to-date.

Install the EPEL Repo configs

yum install http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Turn off the built-in firewall (remember, we're using a 3rd party device for this). You could leave it on, but then you'd have to configure it to pass traffic to/from your VPN tunnel interface. I'll leave that up to you to figure out should you choose to do so.

chkconfig iptables off ; service iptables stop

Install the OpenVPN packages and dependencies:

yum install openvpn

Server (Main Office)

Copy the the easy-rsa environment to /etc/openvpn/easy-rsa, do some config prep, and alter the vars file

cp -rp /usr/share/openvpn/easy-rsa/2.0 /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa/
cp -rp vars vars.orig
cp -rp openssl-1.0.0.cnf openssl.cnf
vi vars

Go down to "KEY_COUNTRY" and edit the Country, Province, etc, down to the OU, ie:

export KEY_COUNTRY="US"
export KEY_PROVINCE="MN"
export KEY_CITY="Minneapolis"
export KEY_ORG="Muchtall"
export KEY_EMAIL="me@my.domain.com"
export KEY_EMAIL=me@my.domain.com
export KEY_CN=vpn.mydomain.com
export KEY_NAME=MuchtallOpenVPNServer
export KEY_OU=Muchtall

Now generate your server's certificate authority:

. ./vars
./clean-all
./build-ca

Accept the defaults for the prompts (we already set them)

Now build the server key

./build-key-server vpn.mydomain.com

Similar to above, accept the default prompts. You will have to answer "y" to the questions "Sign the certificate? [y/n]:" and "1 out of 1 certificate requests certified, commit? [y/n]"

Now generate certs/keys for each remote site

./build-key remote-office-1
./build-key remote-office-2

Rinse, repeat on the prompts.

And generate the Diffie-Hellman parameters:

./build-dh

Great! Our certificates are all set up!

Next time you want to generate a new client key, just run

cd /etc/openvpn/easy-rsa/
. ./vars
./build-key remote-office-3

Now, let's set up the configs. There's a sample config at /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf, however we're going to set one up using this template, just to keep things simple:

port 1194
proto udp
dev tun
ca easy-rsa/keys/ca.crt
cert easy-rsa/keys/vpn.mydomain.com.crt
key easy-rsa/keys/vpn.mydomain.com.key
dh easy-rsa/keys/dh1024.pem
server 10.200.0.0 255.255.0.0
ifconfig-pool-persist ipp.txt
# Tell clients that we can handle routes for these networks
push "route 10.100.0.0 255.255.0.0"
push "route 10.101.0.0 255.255.0.0"
push "route 10.102.0.0 255.255.0.0"
client-config-dir ccd
# Tell OpenVPN that it routes for anything within these subnets
route 10.101.0.0 255.255.0.0
route 10.102.0.0 255.255.0.0
client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3

Now create the ccd directory

mkdir /etc/openvpn/ccd

And lets create the client-specific configs to route each individual subnet to the respective site:

# In /etc/openvpn/ccd/remote-office-1
iroute 10.101.0.0 255.255.255.0

And

# In /etc/openvpn/ccd/remote-office-2
iroute 10.102.0.0 255.255.255.0

Good? Good!

Normally, IP subnets for the tunnels are allocated as new tunnels connect to the server. Let's pre-set the IPs for each tunnel. This part isn't necessary, however I like to do this to assist with clarity in troubleshooting with traceroutes. In /etc/openvpn/ipp.txt:

remote-office-1,10.200.101.4
remote-office-2,10.200.102.4

And re-set the SELinux permissions on the ipp.txt file

restorecon -v './ipp.txt'

Now we're ready to start the the OpenVPN service up:

service openvpn restart

Check the syslog to see if anything serious got spit out:

tail -100 /var/log/messages

You should see something similar to this:

May 7 14:54:53 mainoffice openvpn[13362]: OpenVPN 2.2.2 x86_64-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Aug 10 2012
May 7 14:54:53 mainoffice openvpn[13362]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
May 7 14:54:53 mainoffice openvpn[13362]: Diffie-Hellman initialized with 1024 bit key
May 7 14:54:53 mainoffice openvpn[13362]: TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
May 7 14:54:53 mainoffice openvpn[13362]: Socket Buffers: R=[229376->131072] S=[229376->131072]
May 7 14:54:53 mainoffice openvpn[13362]: ROUTE default_gateway=10.0.3.2
May 7 14:54:53 mainoffice openvpn[13362]: TUN/TAP device tun0 opened
May 7 14:54:53 mainoffice openvpn[13362]: TUN/TAP TX queue length set to 100
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip link set dev tun0 up mtu 1500
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip addr add dev tun0 local 10.200.0.1 peer 10.200.0.2
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add 10.101.0.0/16 via 10.200.0.2
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add 10.102.0.0/16 via 10.200.0.2
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add 10.200.0.0/16 via 10.200.0.2
May 7 14:54:53 mainoffice openvpn[13362]: Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
May 7 14:54:53 mainoffice openvpn[13369]: UDPv4 link local (bound): [undef]:1194
May 7 14:54:53 mainoffice openvpn[13369]: UDPv4 link remote: [undef]
May 7 14:54:53 mainoffice openvpn[13369]: MULTI: multi_init called, r=256 v=256
May 7 14:54:53 mainoffice openvpn[13369]: IFCONFIG POOL: base=10.200.0.4 size=16382
May 7 14:54:53 mainoffice openvpn[13369]: IFCONFIG POOL LIST
May 7 14:54:53 mainoffice openvpn[13369]: remote-office-1,10.200.101.4
May 7 14:54:53 mainoffice openvpn[13369]: remote-office-2,10.200.102.4
May 7 14:54:53 mainoffice openvpn[13369]: Initialization Sequence Completed
May 7 14:54:53 mainoffice kernel: tun0: Disabled Privacy Extensions

Once you've verified based upon the above output that everything is running fine, go ahead and mark the service to start automatically

chkconfig openvpn on

Client Configs (Remote Offices)
On each server, create the file "/etc/openvpn/vpn.mydomain.com.conf", and populate with the following:

client
dev tun
proto udp
remote 192.168.56.100 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert remote-office-1.crt
key remote-office-1.key
comp-lzo
verb 3

Be sure to change the cert name as appropriate.

Copy the ca.crt, remote-office-1.key, and remote-office-1.crt to the /etc/openvpn/ directory of the client. Repeat for Office 2.

Set the permissions on the key file so that it can't be copied by non-root users.

chmod 600 /etc/openvpn/remote-office-1.key

Start the OpenVPN service

service openvpn start

Check the output of syslog for similar output:

May 7 16:26:39 remote-office-1 openvpn[1566]: OpenVPN 2.2.2 x86_64-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Aug 10 2012
May 7 16:26:39 remote-office-1 openvpn[1566]: WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
May 7 16:26:39 remote-office-1 openvpn[1566]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
May 7 16:26:39 remote-office-1 openvpn[1566]: LZO compression initialized
May 7 16:26:39 remote-office-1 openvpn[1566]: Control Channel MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
May 7 16:26:39 remote-office-1 openvpn[1566]: Socket Buffers: R=[229376->131072] S=[229376->131072]
May 7 16:26:39 remote-office-1 openvpn[1566]: Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
May 7 16:26:39 remote-office-1 openvpn[1566]: Local Options hash (VER=V4): '41690919'
May 7 16:26:39 remote-office-1 openvpn[1566]: Expected Remote Options hash (VER=V4): '530fdded'
May 7 16:26:39 remote-office-1 openvpn[1567]: UDPv4 link local: [undef]
May 7 16:26:39 remote-office-1 openvpn[1567]: UDPv4 link remote: x.x.x.x:1194
May 7 16:26:39 remote-office-1 openvpn[1567]: TLS: Initial packet from x.x.x.x:1194, sid=f439995e ac9dd302
May 7 16:26:39 remote-office-1 openvpn[1567]: VERIFY OK: depth=1, /C=US/ST=MN/L=Minneapolis/O=Muchtall/OU=Muchtall/CN=vpn.mydomain.com/name=MyOpenVPNServer/emailAddress=me@my.domain.com
May 7 16:26:39 remote-office-1 openvpn[1567]: VERIFY OK: depth=0, /C=US/ST=MN/L=Minneapolis/O=Muchtall/OU=Muchtall/CN=vpn.mydomain.com/name=MyOpenVPNServer/emailAddress=me@my.domain.com
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
May 7 16:26:39 remote-office-1 openvpn[1567]: Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
May 7 16:26:39 remote-office-1 openvpn[1567]: [vpn.mydomain.com] Peer Connection Initiated with 192.168.56.150:1194
May 7 16:26:41 remote-office-1 openvpn[1567]: SENT CONTROL [vpn.mydomain.com]: 'PUSH_REQUEST' (status=1)
May 7 16:26:41 remote-office-1 openvpn[1567]: PUSH: Received control message: 'PUSH_REPLY,route 10.100.0.0 255.255.0.0,route 10.101.0.0 255.255.0.0,route 10.102.0.0 255.255.0.0,route 10.200.0.0 255.255.0.0,topology net30,ping 10,ping-restart 120,ifconfig 10.200.101.6 10.200.101.5'
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: timers and/or timeouts modified
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: --ifconfig/up options modified
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: route options modified
May 7 16:26:41 remote-office-1 openvpn[1567]: ROUTE default_gateway=10.0.3.2
May 7 16:26:41 remote-office-1 openvpn[1567]: TUN/TAP device tun0 opened
May 7 16:26:41 remote-office-1 openvpn[1567]: TUN/TAP TX queue length set to 100
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip link set dev tun0 up mtu 1500
May 7 16:26:41 remote-office-1 kernel: tun0: Disabled Privacy Extensions
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip addr add dev tun0 local 10.200.101.6 peer 10.200.101.5
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add 10.100.0.0/16 via 10.200.101.5
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add 10.101.0.0/16 via 10.200.101.5
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add 10.102.0.0/16 via 10.200.101.5
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add 10.200.0.0/16 via 10.200.101.5
May 7 16:26:41 remote-office-1 openvpn[1567]: Initialization Sequence Completed

And verify that the routing is taking place

ping 10.100.0.1

Set the openvpn service to start automatically

chkconfig openvpn on

Repeat these steps for the Office 2 client. And verify that you can ping across both tunnels to Office 1

Roadwarrior Config (this is optional)
As an afterthought, I said I'd cover Roadwarrior configuration. Here's a basic rundown:

- Generate a new cert/key pair for your username using the above ./build-key commands
- Install OpenVPN for Windows (if you're on Mac or Linux, you likely know how to do this already)
- Copy the ca.crt, username.crt, and username.key files to "C:\Program Files\OpenVPN\config\"
- Create a config file named C:\Program Files\OpenVPN\config\vpn.mydomain.com.ovpn with these contents:

client
dev tun
proto udp
remote vpn.mydomain.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert myusername.crt
key myusername.key
comp-lzo
verb 3

Right-click on the OpenVPN GUI in the taskbar and click "Connect".

Excel Formula to Convert Polycom 8020/8440 Serial Number to MAC Address

This is an obscure tip, but it thought it was cool enough to post as it comes in handy when scanning in inventory with a barcode scanner. This works on Polycom 8400's (8440/8450) and 8000's (8020/8002)., and probably any other Polycom SIP device.

This formula will take the serial number in the column to the left and convert it to a MAC address.

="00907A"&REPT(0,6-LEN(DEC2HEX(VALUE(RIGHT(INDIRECT("RC[-1]",0),LEN(INDIRECT("RC[-1]",0))-3)))))&DEC2HEX(VALUE(RIGHT(INDIRECT("RC[-1]",0),LEN(INDIRECT("RC[-1]",0))-3)))

Export/Import Grindstone XML to Google/iCal/ICS

I recently started using Grindstone to track my daily workload, and I've been using a number of calendars on Google to not only share classifications of appointments, but to track historical data (Android call logs, etc). I kind of expected that Grindstone would have iCal/ICS export capability, but sadly it does not appear so. You can, however, export to XML. So I thought I'd write up a Perl script to convert the XML data into an ICS file ready for import into Google Calendars. Feel free to download it and use to to convert your Grindstone XML files into iCal data.

Here's the Perl script: grindstone2ics.txt (Save as .pl, not .txt)

If you are on Windows with ActivePerl installed, here's a batch file that you can drag-and-drop your XML file onto. Place it in the same folder as "grindstone2ics.pl": grindstone2ics.bat

Let me know if this helped you!

Simple Script to Mount Disk Image Partitions Looped on Linux

Every so often I have to recover a drive to a disk image on Linux, and before I transfer the data back to a physical drive, I like to mount the disk image check on it's status. Mounting a partition from a disk image is slightly more complicated than mounting just an image of a partition, so I thought I'd post a shortcut to doing so. This information was derived from the how-to posted here (http://madduck.net/blog/2006.10.20:loop-mounting-partitions-from-a-disk-image/). You will need to alter three variables: DISKIMAGE, DISKPARTITION, and the mount path at the end of command.

DISKIMAGE=/media/usbdisk/mydiskimage.img ; DISKPARTITON=2 ; mount -o loop,offset=$((`fdisk -lu $DISKIMAGE 2> /dev/null | grep -P "$DISKPARTITON\s+\**\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]+" | sed 's/\*//g' | awk '{print $2}'` * `fdisk -lu $DISKIMAGE 2> /dev/null | grep "^Units" | awk -F"= " '{print $3}' | awk '{print $1}'`)) $DISKIMAGE /media/recovereddisk/

Hope this helps someone else save some time!

Whitelisting Incoming Calls on Asterisk

For some reason, this is a topic that I couldn't seem to find a simple HOWTO online for, so I had to create my own.

I ran into a situation where I have a large number of auto-answering intercom boxes connected to an Asterisk system. The intercoms are programmed to pick up immediately upon ringing, allowing the caller to communicate with the room's occupant without any action taken by the occupant. These intercom lines are assigned a DID number from the outside world in a large metro area. See the problem? The occupants were getting a number of calls from locals whom had dialed the wrong number. Sometimes the caller wouldn't hear a response, so they'd call back repeatedly, to the irritation of the occupant. For our scenario, blacklisting wasn't a good option. In metro areas, misdialed numbers are common, and rarely from the same person. I needed to only allow a handful (~20-50) of callers that we knew would be calling the intercoms legitimately. Furthermore, it would be useful to have a notice played for a blocked caller to that they knew either to not try calling again, or to contact us to whitelist the number.

Here are the rules I used in Asterisk to achieve this goal. First, in extensions.conf, I created a macro for whitelisting:

; Only allows calls from numbers in the whitelist DB
[macro-inbound-whitelist]
exten => s,1,GotoIf(${DB_EXISTS(whitelist/${CALLERID(num)})}?:blacklisted,s,1)
exten => s,2,Dial(${ARG1})

Then, if you don't have a blacklisted context already, create one:

[blacklisted]
exten => s,1,Playback(not-taking-your-call)
exten => s,3,Hangup

Next, change your inbound call config to use the inbound-whitelist macro:

exten => 5551234567,1,Macro(inbound-whitelist,SIP/123)
exten => 5551234567,2,Hangup

Reload the asterisk config and make a test call. You should get a recording saying that it (Asterisk) is not taking your call.

Now add your number to the whitelist:

asterisk -r
database put whitelist 5551230000 1

And do another test call.

One last word of warning. I did once run into a condition where our telco provider abruptly stopped sending caller ID through our PRI. When this happens, ALL calls show up as null/blank calling numbers. In these instances, ALL calls to your whitelist-protected extensions will be blocked (at least from outside). To temporarily disable whitelisting until the problem is resolved, simply comment out the "exten => s,1,GotoIf ..." line and reload asterisk.

Hopefully this saved someone else out there some time.

UPDATE: I found that comparing against two whitelists (a customer whitelist, and our support number whitelist) can be handy. Use this line instead if you want similar logic:

exten => s,1,GotoIf($[ ${DB_EXISTS(whitelist-${ARG2}/${CALLERID(num)})} | ${DB_EXISTS(whitelist-support/${CALLERID(num)})} ]?:blacklisted,s,1)

Also with this option, I can treat the whitelist name as an argument in my macro call:

exten => 5551234567,1,Macro(inbound-whitelist,SIP/123,customername)

In this case, the whitelist DB would be named "whitelist-customername".

Installing Fedora 16 on XenServer 6

Credit for this procedure goes to Major Hayden at Racker Hacker (http://rackerhacker.com/2012/02/11/installing-fedora-16-in-xenserver/). My procedure just uses an alternate, minimal kickstart file that gives you more control over the installation using the Anaconda GUI.

- Start an installation using the RedHat 6.0 64bit template
- In the installation wizard, use these advanced options: console=hvc0 serial ip=dhcp nogpt vnc ks=/"content/f16onxen6.ks
- Connect to the installer GUI using VNC and the IP shown in the console.

Proceed as normal! If you care to see the source of the kickstart: /"content/f16onxen6.ks

Cisco ASDM-IDM Launcher: Stuck on "Contacting the device. Please wait..."

I recently ran into an issue on Windows 7 64-bit where ADSM-ISM Launcher failed to connect to my ASAs. Launching the application from a shortcut, and attempting to connect resulted in the launcher halting on "Contacting the device. Please wait...". And waiting didn't help. Opening the java console revealed another error which didn't get me any useful results on Google:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.security.ssl.X509TrustManagerImpl cannot be cast to com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager

However, if I "re-installed" ASDM via the "dm-launcher.msi", the first time it was spawned by the installer, everything worked fine. Subsequent launches from the application shortcuts failed. A quick check with Process Explorer revealed the issue. The dm-launcher installer launched the java app using "C:\Windows\SysWOW64\javaw.exe", whereas the shortcut would use "C:\Windows\system32\javaw.exe".

The ultimate fix ended up being updating all my ASDM shortcuts to use "C:\Windows\SysWOW64\javaw.exe". Now everything is working great!

UPDATE 2/25/2013: So the pain continues with Java 7. If you have upgraded your JRE, you probably saw a recurrence of this issue. In that case, I recommend pointing your shortcut(s) directly to the version 1.6/6 JRE instead:
"C:\Program Files\Java\jre6\bin\javaw.exe"

Hope this helps someone else out there.

If you found this helpful, maybe you'd like to send a thank you from my wishlist?

Forcing RDP Connections Fullscreen on a Specific Monitor (Saving Window Position)

One of the frustrations I have/had with Remote Desktop connections on multi-monitor workstations (with unique display resolutions mind you) is that there's no way within the RDP GUI to save the position of a fullscreen RDP session. So if your RDP session opens up on display 2 each time, good luck getting it to display properly on display 1 or 3 unless you have identical resolutions on each display. Even then, it's a hassle to restore the RDP session to windowed mode and move the the preferred display each time you connect.

Hassle no more: There is a solution. All you need is notepad and a little understanding of how display coordinates work (don't worry, I'll explain).

First off, save your RDP session to an RDP shortcut (ie, Acme.rdp). Open notepad and drag the RDP file into the window. Notpad should open the source of the RDP file for your perusal. You'll see some lines similar to this buried within the file:

screen mode id:i:2
use multimon:i:0
desktopwidth:i:1920
desktopheight:i:1080
winposstr:s:0,1,50,170,250,370

Set "screen mod id" and "use multimonitor" as shown above. The settings "desktopwidth", "desktopheight", and "winposstr" will vary depending upon the resolution and physical position of the display you iwsh to use as the destination.

First, an explanation of the winposstr variables we are concerned with (in order):
s: Not applicable
0: Not applicable
1: Sets the RDP session to start windowed (screen mode id sets it to be fullscreen after launch)
50: Pixel distance from the left-hand edge of display 1 to the left edge of the RDP window
170: Pixel distance from the upper edge of display 1 to the upper edge of the RDP window
250: Pixel distance from the left-hand edge of display 1 to the RIGHT edge of the RDP window. Difference between this and the left edge must be >= 200! (250 - 50 = 200)
370: Pixel distance from the upper edge of display 1 to the LOWER edge of the RDP window. Difference between this and the upper edge must be >= 200! (370 - 70 = 200)

Note again that the window dimensions MUST be greater than or equal to 200x200. If it is less, RDP will completely ignore your windows placement dimensions and go with defaults, defeating the purpose of this process.

Now that you know what the numbers mean, you need to understand where to place the window (by pixel dimension) in order to get it to come up on the proper display each time. You have two options: The complex/geeky way, or the simple way.

The Complex Way

Screen coordinates are all relative to the upper left edge of display 1. This position is 1,1. So if You have a single display system with a resolution of 800x600, the lower right corner of the screen is position 800,600. If you have two displays at 800x600 positioned like this in display properties:

[1][2]

...the lower right corner of display 2 would be 1600x600

If the displays were physically reversed:

[2][1]

..the lower LEFT corner of display 2 would be -800,600

Based upon this information, and using some simple math, you should be able to estimate window position amongst your displays. Now, this will get slightly more complex if your displays are offset on the Y axis, so what you might prefer is the...

Simple Way
Download and install the free AutoHotKey Basic. It comes with a nice utility called "AutoIt3 Window Spy". Run this utility and fire up your RDP session in windowed mode. Then, move the RDP window into your desired destination display. Try to keep the Active Window Info screen visible when you do this.
You should see something similar to this in the Active Window Info window:

>>>>>>>>>>( Active Window Position )<<<<<<<<<<
left: 434 top: 700

Now, lets use those numbers to create the winposstr settings:

winposstr:s:0,1,434,700,634,900

Note that I added 200 to the window position (634,900) creating a window size of 200x200.

Adjust the display width and height settings to match your destination screen.

Go ahead and save the RDP file and try connecting again. The RDP session should now open on the correct screen each time you use this shortcut.

Authenticating to MS SQL Server on a Different Domain Using Windows Authentication (Windows 7)

When trying to connect to an MSSQL server on another domain (of which you are not a member), you'll probably run into the issue where selecting the Windows Authentication option in the SQL Server connection dialog grays out the username and password. Here are two workarounds:

Scenario
SQL Server: sqlserver.mydomain.com
Domain: MYDOMAIN
MYDOMAIN Username: joe.user

A) Create Saved Credentials
Go to the Control Panel --> User Accounts --> Manage Your Credentials (in left-hand pane) --> Add a Windows Credential

Address: sqlserver.mydomain.com
User Name: MYDOMAIN\joe.user
Password: (password for joe.user on MYDOMAIN)
Click OK

Now, when you fire up SQL Server Management Studio, enter your server name (sqlserver.mydomain.com) and select Windows Authentication. THE USERNAME WILL BE GRAYED OUT but that's fine. The connection will authenticate properly anyhow. Go ahead and connect.

B) RunAs Command Line (requires user interaction for password)
Open a command line and run this:
runas /netonly /user:MYDOMAIN\joe.user "C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe -S sqlserver.mydomain.com -E"
(You will need to alter the SQL Management Studio exe path as is applicable to your PC)
When prompted on the command line, enter the password for joe.user.
SQL Management Studio should load and automatically connect to the SQL server.

If you are unable to connect with either of these scenarios, check the firewall settings on the remote system.

Credit where credit is due (references):
http://stackoverflow.com/questions/849149/connect-different-windows-user-in-sql-server-management-studio-2005-or-later
http://support.microsoft.com/kb/306541
http://social.msdn.microsoft.com/forums/en-US/sqlsecurity/thread/ed11ff0f-b59c-48bc-ba92-277f1c3e3107/

If you found this helpful, maybe you'd like to send a thank you from my wishlist?

Overcoming the the Zyploit error when using Unrevoked

If when your try rooting your phone with Unrevoked, you encounter the error "process com.unrevoked.zysploit has stopped unexpectedly" during the initial rooting process, you probably have an application interfering with Zysploit, or a bad install of Zysploit itself. Try removing the following apps (from Manage Applications") in order, and retry between apps:
- Zyploit
- Wireless Tether
- Comcast Xfinity

If someone out there could help confirm what app ultimately fixed this issue, I would appreciate it so I can report the confirmation here. I my case, I started with uninstalling Comcast Xfinity, then with Wireless Tether and Zysploit. Once I did that, Unrevoked worked great.

Restreaming ASF to MP3 Via Icecast and VLC

Say you have an internet radio stream that you like to listen to. You like to actually get up from your computer once in a while and go outside, so you want to play it on your iPhone/Blackberry/G1/Treo/Centro/Pre/Whatever as you're out and about. But wait! Due to poor decision making by your beloved stream provider, your favorite stream is only in Microsoft's poorly-supported ASF streaming format. There's no MP3 or OGG options! Many if not all of the phones I just mentioned may/will not play these streams, at least not natively. MP3 on the other hand, is ubiquitous (though, given, not truly as free as OGG). One option you may have, if you run your own Linux server, is to download the ASF stream, re-encode it to MP3, and re-stream it via your own Icecast server. Icecast is easy enough to set up, however information on setting up the VLC portion of this workaround online seems a little slim online, so I thought I'd make a post simplifying the setup.

First off, check to make sure your VLC has "Shout" Shoutcast/Icecast output support:

vlc --list | grep access_output_shout

You should see the following in the output:

access_output_shout IceCAST output

If not, you may need to either re-install with a version of VLC that supports shout output, or recompile it with shout support.

Then run the following command, altering the items in bold for your purposes (all on one line):

cvlc "http://classicalstream2.publicradio.org/classical" ':sout=#transcode{acodec=mp3,ab=192,channels=2}:duplicate{dst=std{access=shout,mux=raw,dst=source:YOURPASSWORD@your.icecast.server.com:8000/mpr.mp3}}' --sout-shout-mp3 --sout-shout-name="MPR MP3 Restream" --sout-shout-description="Restreaming of MPR" --sout-shout-url="http://minnesota.publicradio.org" --sout-shout-genre="Liberal Tripe" --loop

Assuming you have already properly set up your Icecast server, you should now have a mountpoint running the stream you have just created.

Note that VLC seems to have problems parsing some ASX playlist files. You may need to download the ASX file with wget to investigate what the actual stream URL is. For example, the stream above came from "http://minnesota.publicradio.org/tools/play/streams/classical.asx", which had these contents:

<ASX version="3.0">
   <ABSTRACT>The Windows Media Stream for MPR's Classical Music Service</ABSTRACT>
   <TITLE>MPR Classical Windows Stream</TITLE>
   <AUTHOR>Minnesota Public Radio</AUTHOR>
   <COPYRIGHT>2009 Minnesota Public Radio</COPYRIGHT>
   <MOREINFO HREF = "http://minnesota.publicradio.org" />
   <ENTRY>
      <TITLE>MPR Classical Windows Stream Underwriter</TITLE>
      <COPYRIGHT>2009 Minnesota Public Radio</COPYRIGHT>
      <REF HREF="http://ondemand2.publicradio.org/ondemand/joinnow.wma"/>
      <BANNER HREF="http://www.publicradio.org/applications/underwriters/images/prepend/content/joinnow.gif">
          <MOREINFO HREF = "https://contribute.publicradio.org/"></MOREINFO>
      </BANNER>
   </ENTRY>
   <ENTRY>
      <TITLE>MPR Classical Windows Stream</TITLE>
      <COPYRIGHT>2009 Minnesota Public Radio</COPYRIGHT>
      <REF HREF="http://classicalstream2.publicradio.org/classical"/>
      <BANNER HREF="http://www.publicradio.org/applications/underwriters/images/prepend/content/joinnow.gif">
          <MOREINFO HREF = "https://contribute.publicradio.org/"></MOREINFO>
      </BANNER>
   </ENTRY>
</ASX>

As you can see, the first item in the playlist is NPR's obligatory call (**cough** commercial **cough**) for donations (http://ondemand2.publicradio.org/ondemand/joinnow.wma). The second is your actual stream URL (http://classicalstream2.publicradio.org/classical). You'll want to use the stream URL in your VLC command.

Also, I have seen cases where VLC pukes on some ASF streams. Though I haven't confirmed this, it appears to be a bug with downsampling/resampling (http://mailman.videolan.org/pipermail/vlc-devel/2009-February/056823.html). In these cases, you may need to look that the 1.0.0 prerelease versions, which may not be available on your distro release (Fedora, for example, doesn't have it until 11). Good luck!

UPDATE 10/27/09: It would appear that the precompiled RPMs offered on the VLC site for 1.0 or higher do not contain support for shout output. Not a big deal. Just download the source RPM (e.g., from http://download1.rpmfusion.org/free/fedora/development/source/SRPMS/) install the sources (rpm -Uvh vlc-1.0.3-0.1_rc.fc12.src.rpm), and edit the vlc.spec file (usually found in ~/rpmbuild/SPECS/). Look for a line that says "--enable-realrtsp \" and add a line below it that says "--enable-shout \". Save and close the file, then run "rpmbuild -ba vlc.spec". After it recompiles, install the updated RPMs (cd ~/rpmbuild/RPMS/x86_64/ ; yum --nogpgcheck reinstall vlc-core-1.0.3-0.1_rc.fc11.x86_64.rpm vlc-1.0.3-0.1_rc.fc11.x86_64.rpm). Make sure to alter the above paths to reflect your architecture, Fedora release, and vlc version.

Recovering a PPPoE password from an Actiontec M1000

If you ever get into a situation where you can't find the password used on your Qwest DSL account, and you have an Actiontec M1000 router (or similar), give this procedure a shot:

- You can find your account username on the Quick Setup page, listed as "PPP Username"
- Set your router admin password if you have not already done so. Take note of the username and password you set. It's important.
- Go to Start --> Run and enter "telnet 192.168.0.1"
- Login with your admin account and password, i.e., admin/admin
- Run this command "cat /var/tmp/pppoe_password". The output is your account password.
- Confirm your account credentials by logging in at at http://www.qwest.net

Good luck!

Update 5/29/2013: You may also want to check out my updated post: Recovering the PPP Username and Password from a Centurylink Actiontec C1000A

HOWTO: Forwarding a USB device to a Guest VM in Xen on Fedora

This procedure works with fully virtualized VMs. I would assume it works with paravirtualized VMs as well...

Shut down and power off your VM

Unplug and re-plug your USB device to see what it appears as in dmesg, then run
    dmesg | grep ^usb

See these lines?:
    usb 3-2: USB disconnect, address 7
    usb 3-2: new low speed USB device using uhci_hcd and address 8
    usb 3-2: configuration #1 chosen from 1 choice

This indicates that it is connected to Bus 003 as Device 008. Now run this:
    lsusb

Now look a device at Bus 003 Device 008:
    Bus 003 Device 008: ID 04b9:0300 Rainbow Technologies, Inc.

Note the ID...
    04b9:0300

Open the config.sxp file for the domain, usually located at:
    "/var/lib/xend/domains//config.sxp"

Look for a section similar to this:

    (platform
        ((usb 1)
            (device_model /usr/lib64/xen/bin/qemu-dm)
            (boot c)
            (rtc_timeoffset -18008)
            (pae 1)
            (apic 1)
            (localtime 1)
            (acpi 1)
        )
    )
   
Add your USB device:

    (platform
        ((usb 1)
            (device_model /usr/lib64/xen/bin/qemu-dm)
            (boot c)
            (rtc_timeoffset -18008)
            (pae 1)
            (apic 1)
            (localtime 1)
            (acpi 1)
            (usbdevice host:04b9:0300)
        )
    )

Restart xend:
    /etc/init.d/xend restart

Start your VM

Extending (Resizing) LVM/XFS Xen images

Documentation on this procedure out on the interwebs seems rather sparse, so I thought I'd post the procedure I use to expand Xen images that use LVM and XFS. The same procedure should work fine if you use EXT3, you probably will just have to substitute the proper e2/3fs command for xfs_growfs.

## FROM THE VM HOST:
### Shutdown VM
xm shutdown VMName

## Backup the image
## (Optional, though highly suggested until you get this procedure tested in your deployment
cp -rp /var/lib/xen/images/VMName.img /var/lib/xen/images/VMName.img.bak

## Add 5GB to the image (takes approximately 4 seconds per Gig)
dd if=/dev/zero bs=1M count=5000 >> /var/lib/xen/images/VMName.img

## Loop the image
kpartx -av /var/lib/xen/images/VMName.img

## Run "fdisk /dev/loop2"
## Enter these commands
## (double check to make sure the partition numbers apply in your case)
#p-rint
#d-elete
#2-(partition 2)
#n-ew
#p-rimary
#2-(partition 2)
#<enter>-(Defaults to first available cylinder)
#<enter>-(Defaults to last available cylinder)
#t-ype
#2-(partition 2)
#8e-(Linux LVM)
#p-print
#w-rite

# Delete the loop and re-add it (to reload partiton table)
kpartx -dv /var/lib/xen/images/VMName.img
kpartx -av /var/lib/xen/images/VMName.img

# Check the Physical Volume size
pvdisplay

#  --- Physical volume ---
#  PV Name               /dev/dm-3
#  VG Name               VolGroup00
PV Size               3.71 GB / not usable 20.42 MB
#  Allocatable           yes
#  PE Size (KByte)       32768
#  Total PE              118
Free PE               1
#  Allocated PE          117
#  PV UUID               OjLnup-7iYu-ErtB-WMvN-gY0v-FbLw-gW6cEB

## Resize the Physical Volume
pvresize /dev/mapper/loop2p2

# Check the PV size again
# Take note of the Free PE (physical extents), 158 in this case
pvdisplay

#  --- Physical volume ---
#  PV Name               /dev/dm-3
#  VG Name               VolGroup00
PV Size               8.59 GB / not usable 1.05 MB
#  Allocatable           yes
#  PE Size (KByte)       32768
#  Total PE              275
Free PE               158
#  Allocated PE          117
#  PV UUID               OjLnup-7iYu-ErtB-WMvN-gY0v-FbLw-gW6cEB

## Delete the loop
kpartx -dv /var/lib/xen/images/VMName.img

## Boot the VM
xm start VMName

### FROM WITHIN THE VM
## Check the LV size of LogVol00
lvdisplay

## Resize the logical volume using the free extents from above (158).
lvresize -l +158 /dev/VolGroup00/LogVol00

## Check the LV size again to confirm the increased space
lvdisplay

## Resize the filesystem (in this case, XFS)
xfs_growfs /dev/mapper/VolGroup00-LogVol00

# Check for the increased space
df -h

## Finally, delete the backup FROM THE VM HOST:
/var/lib/xen/images/VMName.img.bak

### You're Done!

I always enjoy knowing that documentation like this helped someone. Post a comment and let me know if this helped you.

Good luck!

Enabling Input Audio Monitoring on Dell Latitude D820

I recently re-installed XP on my Dell Latitude
D820 for the third time in 2 years and ran into a familiar problem: My
line-in audio was not being played through the speakers. By default,
the Dell driver, R171789 (SIGMATEL STAC 92XX C-Major HD Audio) does not
come with the input monitor enabled. You can modify the driver INI
file(s) manually to enable this and other related options.

Backup these files (make a copy in the same directory named 92XXM2-2.INI.orig):
    C:\DELL\drivers\R171789\WDM\92XXM2-2.INI
    C:\Program Files\SigmaTel\C-Major Audio\WDM\92XXM2-2.INI
    C:\Program Files\SigmaTel\C-Major Audio\DellXPM_5515v131\WDM\92XXM2-2.INI

Edit each one and change the following settings to reflect what is shown:
    EnableInputMonitor    = hex: 1
    DigitalInputMonitor     = hex: 1
Additionally you can/should turn on these options that allow for greater control of the sound card options:
    To see all of the config tabs (that I know of):
       Config_Tab = dword: 0x000000ff
    To see all of the Advanced config options:
       Config_Adv = dword: 0x000fffff
    To allow sample rate adjustment:
       Config_Rates = dword: 0x000000ff
    To disable automatic input switching (helps avoid feedback)
       RecordPriority = dword: 0xffffffff
   

Here is a copy of my edited 92XXM2-2.INI
file (enables the Levels tab and Automatic Input selection
en/disabling). Alternately, if you are so-inclined, you could open
regedit and
alter these settings manually. However when you do so, the changes get
wiped out by a re-install of the driver, so altering the INI file is
really your best bet.

You
can now uninstall the device you have in device manager and re-install.
Reboot to ensure you apply the change to the Sigmatel chipset.

After
rebooting, plug in your device. A pop-up should prompt you for the
input type. You may choose to tell it to no longer prompt you for this
change. Then, go into the Volume Control, uncheck mute on Input
Monitor,
got to Options, Properties, select Line-in and you should hear your
input. Also, you may choose to drop the volume on the Internal Mic down
to 0%. This will help you avoid horrible feedback should you switch to
the internal mic.

If
you don't have a D820, it possible that your INI file may be different.
To identify what the proper INI file is,  open regedit and search for
this string:
    SigmaTel High Definition Audio CODEC
Look for
the key named "DriverDesc". In this folder/tree you should also see
"IniPath". Open this key and look at the name of the INI file in the
path. This should be the correct INI for your model.

UPDATE 2/11:
If you feel inclined to do so you can change, with a decent amount of
granularity, which options you can see in the Advanced tab. This is
done by flipping individual bits on or off in the Config_Adv registry
setting. Here are the applicable decimal values for each option:

1 Power Management Amplifier Power Mangement
2 Sampling Rate Sampling Rate adjustment
4 SPDIF AC3/PCM en/disable and Rate Adjustment
8 SPDIF Digital Out en/disable and Rate Adjustment

16

SPDIF

Digital Out en/disable 

32

Dolby

Dolby Digital Live en/disable 

64

Noise Suppression

Noise Suppression en/disable 

128

ASIO

Latency/Rate adjustment, ASIO monitor en/disable 

256

Pop-ups

Jack reconfiguration pop-up en/disable

512

HDMI

HDMI output en/disable 

1024

Bass Management

Bass Routing and boost dB adjustment 

2048

Microphone Selection

Automatic Microphone Selection en/disable 

4096

Internal Speakers

Internal Speaker Muting options 

8192

Headphone Configuration

Redirected headphone en/disable 

16384

(Unknown)

 

32768

Multi-Streaming

Multi-stream retasking en/disable 

65536

Speaker Mute Controls

Additional internal speaker muting options 

To enable or disable any of these options, just add or subtract it's
decimal value (shown) from the decimal value you see in regedit (when
the decimal radio is selected). For example, to display configuration
options for Pop-ups, Microphone Selection, and Noise Suppression, just
add 256+2048+64. This gives you 2368, which you can paste into regedit
when you select the decimal radio. This will convert to 940 in hex.

Postfix/Exchange Unknown User Filtering HOWTO

Annoyed by Exchange's lack of SMTP features? Tired of thousands of NDR messages to invalid email addresses for unknown users plugging up your mailserver? Try my new HOWTO on setting up an Exchange/Postfix mail filtering server on Ubuntu.

Integrated Windows Authentication in Firefox

I've been trying to get Firefox reeady for deployment everywhere in our organization. Here's one less thing to workaround: Integrated Windows Authentication in Firefox. Basically I just needed to add/modify the following values:

network.automatic-ntlm-auth.trusted-uris = intranet
network.negotiate-auth.delegation-uris = intranet
network.negotiate-auth.trusted-uris = intranet

This allowed my to browse straight to http://intranet/ without logging in.

You can add more domains to each setting with comma-separated domains.

Disabling the ''Security Code'' feature of PHP-Nuke

Run the following commands:

cd /www/docs/mydomain.com/
grep -R "extension_loaded("gd")" * | awk -F":" '{print $1}' | sort | uniq

Wait at least 30 seconds. It's searching all the files in this directory. Each of the files returned will contain the string 'extension_loaded("gd")', which must be replaced with "0" to make those IF statments false. For example, admin.php contains the line:

if (extension_loaded("gd") AND ($gfx_chk == 1 OR $gfx_chk == 5 OR $gfx_chk == 6 OR $gfx_chk == 7)) {

Modify it so that it says this:

if (0 AND ($gfx_chk == 1 OR $gfx_chk == 5 OR $gfx_chk == 6 OR $gfx_chk == 7)) {

If you are leet, and know VI, a simple replace command would be:

:1,$s/extension_loaded("gd")/0/g

And that should be it!

HowTo Set Up PHP Nuke (a quick guide)

This is more of a technical FYI, not really a practical guide for Linuxwhore.com server users :-). Well, actually, I suppose everything except for the mysql commands could be performed by users, the rest needs to be granted by root.

      mkdir phpnuke
      cd phpnuke/
      tar -zxvf ../PHP-Nuke-6.8.tar.gz
      cd html/
      cp -rp * /www/docs/mysite.com/
      cd ..
      mysqladmin -p -u root create mynuke
      mysql -p -u root mynuke < sql/nuke.sql
      mysql -p -u root
        USE mysql;
        GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON mynuke.* TO mynuke@localhost IDENTIFIED BY 'mypass';
        FLUSH PRIVILEGES;
        exit
      cd /www/docs/mysite.com/
      vi config.php
      ### Change the following
      $dbuname = "mynuke";
      $dbpass = "mypass";
      $dbname = "mynuke";
Open http://mysite.com/admin.php and set the super user info.

Peruse and customize!