Laser-Cut Custom-Fabric Dress Shirt

The Minecraft release party, MineCon, was this year in Las Vegas. In a flash of inspiration, I knew I’d found my first cosplay opportunity. Most people would wear cardboard boxes, which isn’t very Vegas. What Minecraft-themed costume would fit Vegas, aside from old people in sweatpants gambling their retirement checks away? A suit, of course! With a Notch-inspired Fedora, and Creeper-print fabric to tie it back to Minecraft. Hours of sewing later, I’m the proud owner of a Creeper shirt (and fedora.)
Continue reading

Arduino Nagios Display (aka LED Whiteboard)

The movie ‘Hackers’ came out in 1995, when I was still in elementary school. So by the time I grew up and watched it (along with the Matrix and Tron) I knew that the kinds of computer visualization depicted in those movies was something I wanted. I’m a very visual person (and I think computers are generally way more cerebral than visual) so I’ve always wanted a more visual, physical representation of computer systems. Imagine if we had a tricorder or sick bay analyzer that could show you every little invisible detail of complex systems like the environment, human bodies, or networks? This is one small step towards that.
Continue reading

Cheap disk duplication using dd (actually dcfldd)

Why buy an expensive disk or flash drive duplicator when you can make one yourself with Linux for free or cheap?

Here are the cloning scripts you can use to copy a disk and then write it back to a large number of target disks. Modify the IMAGE.img and /dev/DEVICE as desired (each “of=” is another output file, make sure you don’t get confused and accidentally set an “of=” to a device that you might not want to destructively overwrite!) It even beeps when it’s done! Make sure to mark the scripts as executable (chmod +x) so you can double click them, or run them by typing ./SCRIPT.sh in terminal. Continue reading

Automated WinSCP file transfers

This is the line I put in a Scheduled Task to download a remote directory and save it locally. You should be able to use it in reverse to upload something.

"C:Program FilesWinSCPWinSCP.exe" /console /log=winscp.log /command "option batch on" "option confirm off" "open USERNAME:PASSWORD@EXAMPLE.com -hostkey=""ssh-rsa 2048 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF"" " "get /home/backups/* c:backups*" "exit"

Separated for readability:
Continue reading

Reverse SSH tunnels for fun and profit

Ever needed to access, or maintain access, to a computer that’s behind a firewall? Just run one of these commands on that computer (in Linux or maybe Mac) and you’ll get a tunnel to that computer’s port 22 (SSH) over whatever port you type for the PORTNUM in the examples below.

First example: ssh -R PORTNUM:localhost:22 USERNAME@SERVERNAME

So if you ran the command ssh -R 5001:localhost:22 user@example.com you’d be able to login to example.com and then run ssh user@localhost.com -p 5001 to connect back to that computer.
Continue reading

IPsec, IKE, and ISAKMP: Encrypting communication in the cloud, VPN-tunnel-style

Long pretentious blog titles are apparently my new thing.

One big problem I have had in trying to use cloud infrastructure for Real World Applications is that a huge percentage of those apps (or their protocols) don’t communicate securely. For example, I just set up an SMB share (Windows fileshare) on the internet the other day. WHA?? Yeah it’s possible, and guess what? SMB is about as encrypted as FTP, which is to say “basically not at all.” So if you really need SMB between servers, and you’re in the cloud (or anywhere else where you give a rat’s ass about security, really, come on people) you’re gonna need to wrap some encryption around that protocol. Ideally you won’t have to deal with PPTP or buy a bunch of Cisco gear either. Enter IPsec.

Continue reading

LAMP: A Primer on Linux, Apache, MySQL and PHP

So I’m teaching a friend how to set up Linux, Apache, MySQL, and PHP. Here’s my version of teaching you how to do it.

Linux:

• Download and install Ubuntu (Server or Desktop.) See instructions here. Install with the default options, or just run the Desktop version from USB.

LINUX PRIMER:

• Remember that if you have trouble running a command, you might need to type sudo before it to run it as root (the administrator account on Linux machines. Most installing/repairing/uninstalling/configuring work requires root privileges.)

• To edit files, use nano (easiest), vim (hardcore), or gedit (if you’re running desktop not server). In Ubuntu Desktop, you access programs using the “Dash Home” (aka Ubuntu Menu at the top left) and typing a command or search keyword. For this guide we’ll be working out of the terminal, so type “terminal” and open the terminal program.

• From terminal, to edit a file like /etc/apache2/httpd.conf you’ll type vim /etc/apache2/httpd.conf. Other useful commands include cd for changing directories, ls for listing files in a directory, and find * -name "*a*" for finding everything under the current directory with “a” in the name.

• Also remember that the text to the left of your cursor (user@computer:folder$) shows you the current folder you’re in (such as ~ which is a shortcut for your home folder, /home/yourusername). Everything under Linux is stored as a file under the root directory (/) and so there are no C: or D: prefixes like in Windows. If you see a preceding slash (/home/user) that means “the user folder, under the home folder, under the root folder.” This is an important distinction because “home/user” could mean any home folder anywhere, depending on context. If your current folder is /var/www then you’d be talking about /var/www/home/user which might not even exist. So pay attention to slashes and context.

• Use of the arrow keys, and home/end/pgup/pgdn, will help a lot. You can press the up arrow to re-type previously entered commands, press Ctrl+R to do a reverse-search of previous commands, and open the ~/.bash_history file to see logs of your previous sessions.

• Use the Tab key to auto-complete things on the command line. To type “vim /etc/apache2/httpd.conf you can actually type “vim /etc/apahtt” (if there is no auto-completion, then you need to type more to be more specific.)

• Rule #1 of Linux is RTFM — this means either read the manual (by typing man in the terminal, for example “man vim” or “man find” or “man life”, OR just Google it. Copy the error or key words from the error into Google and hunt away! Finally, don’t be afraid to ask– but not before reading the man page and Google (or if you’re in a class, ask your neighbor or the instructor.) Open source software like Linux is all-volunteer, so help volunteers by asking intelligent questions — questions that you still have after attempting to find the answer yourself. For further reading, check out “How to Ask Questions the Smart Way” by ESR: http://is.gd/smartquestions

• To copy-paste from the Ubuntu Desktop terminal, highlight something with your mouse and press Ctrl+Shift+C (copy) or Ctrl+Shift+V (paste). You can also right-click and choose the copy or paste options.

(END LINUX PRIMER)

• Make sure you’re connected to the internet. Use the Wifi icon in the top right to connect to networks, or in terminal type ifconfig and ping 8.8.8.8 to check what might be wrong.

• Let’s start by typing sudo -i so that we become root and don’t have to type sudo after half this stuff. If you’ve got a password, it’ll ask you to type it.

• A brand-new Ubuntu install might not have its software repositories updated. Type apt-get update to fetch info about the latest software available.

• Run this command to install Vim, Apache, Git, MySQL, and PHP with my favorite plugins.
apt-get install vim apache2 git-core mysql-server php5 libapache2-mod-php5 php5-gd php5-curl php5-mysql php5-xsl php5-cli

• Pay attention to any errors during this process; problems here can result in a piece of software not working later on in this guide and retracing your steps sucks.

• MySQL should ask you for a root password. Make up something extremely long and random, and store it in a safe place for future reference. (In this case, a sticky note is actually more secure than a text file.) You’ll need to type this in when we get to the MySQL section and any other time you need to administer the MySQL server.

• This is my backup script (crontab) — to make a crontab, type crontab -e

# Below is for regular backups.
10 19 * * * /usr/bin/mysqldump --opt -uUSER DBNAME > /backups/DBNAME.sql
14 19 * * * /usr/bin/mysqldump --opt -uUSER mysql > /backups/mysql.sql
16 19 * * * tar -zcf /backups/etc-backup.tgz /etc
18 19 * * * tar -zcf /backups/www-backup.tgz /var/www

For the root user, create a /root/.my.cnf file (as root) with the following content:
[client]
password=PASSWORD

Note that USER, PASSWORD, and DBNAME should be replaced appropriately. Formerly the crontab script included a -pPASSWORD option (without a space) but this is less secure and reliable than the .my.cnf method.

If your backups aren’t created properly (0 filesize) it may be because the backup user’s password isn’t getting found. You can add --defaults-extra-file=/root/.my.cnf to the mysqldump command in your crontab.

Make sure you create /backups and that it is writeable by root (or whoever the cron job runs as.) Test the command before putting it in your crontab.

You’ll see that I’m doing a mysqldump of the database named ‘mysql’ — this is intentional as it is the database that holds configuration information including database users which you’ll probably want during a restoration.

Also, I’m doing a backup of /etc which is where most configuration files are stored. Half of a website is how it’s configured, so you’ll definitely want that during a restoration.

This should take care of most Apache/MySQL websites as long as all websites are stored in /var/www — if not, modify the script as needed.

• Finally, it would be a good idea to encrypt these files or at least make sure they’re chmod 700 — readable only by the folder owner and nobody else — because they will invariably contain passwords in the config files and mysql tables. Your mileage may vary and it’s your responsibility to make sure you’re adequately secured.

Don’t forget to copy your backups offsite. I typically add this line to a remote crontab -e:


15 21 * * 1 scp -r root@example.com:/backup /backups/latest/example

You’ll need to copy ~/.ssh/id_rsa.pub from the remote machine to the /root/.ssh/authorized_keys file on example.com though, to let scp run without a password. (Test scp manually so you can accept example.com’s key first.)

• Save, exit, and check back tomorrow to make sure the contents of /backups looks good (in nano, save is Ctrl+O and exit is Ctrl+X. In vim, you insert text by typing i, exit from insert mode with Escape, save is :w and exit is :q)

Apache:
Continue reading

ODBC Permissions for non-Administrators

While trying to install AFS ImageDepot Express for a user, I ran into some issues, namely the following error:

unable to configure local datasource

as well as a problem with “exclusive access to file” when trying to change the datasource in the program. Turns out that by giving the user Modify permissions on the Program FilesAFS folder and giving them Modify privileges to the registry key HKLMSoftwareODBC (and sub-keys, especially ODBC.iniAFS) the problem is solved.

On Subnets

I recently joined in a discussion on the Spiceworks Forums, reprinted here for your benefit.

First a lesson on what Class A/B/C means, and then a suggestion for supernetting:

The Class A/B/C designations are more or less meaningless now as we have CIDR (classless subnets) to give us nearly whatever subnet we want in any number space we want as long as the rest of the network allows it. Originally an IP address starting with 10 would automatically be divided into one big 10.0.0.0/8 subnet — i.e. a really huge networks. An address starting with 172 would automatically be divided into 172.x.0.0/16-sized subnets, and 192 would be divided into 192.x.x.0/24-sized subnets. See the explanation here. Problem is, that was really cumbersome for anyone who wanted an address starting with 10 but with a smaller network address range. CIDR was invented, and now you can have an internet IP address of 70.1.2.3/29 which is supposedly “Class A” because of the 70 but only gives me 6 usable IP addresses because of the /29 subnet (255.255.255.248.) Continue reading

Test-Driven IT

You’ve probably heard of test-driven programming, where the first thing a developer writes is an automated test, not the actual program code. This way when the code is written, it can instantly and repeatedly be tested to see if it works.

Why not do the same in an IT department, or any other endeavor for that matter? If automated testing is available, it should be used as early as possible in the endeavor so that as soon as a working state is achieved effort can be diverted to polishing or new tasks instead of wasting more time “making it work” when it already does.

How many times have you as a technician been troubleshooting a connection issue, and realized the problem had been fixed for awhile but you didn’t notice? If your first step had been to set up automated pings or http connection tests, you might have saved a lot of time and frustration. Tools like Nagios and IPmonitor are well equipped for this task. If you know of any other good tools, leave a comment!

Just some food for thought. Get some visualization or results of what you’re working on if at all possible.

IT Deployments for Noobs

How can an inexperienced “tech guy” help his organization IT-wise, if outsourcing isn’t on the table?

As an unwittingly frequent mentor to technical hopefuls, it’s hard to draw the line between “sure just follow these steps” and “it’s over your head, outsource if at all possible.” How do you distill half a decade of experience into an email? Here’s a case study: Continue reading

Security for Developers

Here’s the slides from my Technical Brownbag today at Gangplank.

Thanks for having me, guys! Please comment on your thoughts or anything you have to add.

Edit: One of the biggest security holes is the HTTPS issue. Please please PLEASE install and use an SSL cert on every webserver you run. WordPress, webmail, and anything else you run on your server is woefully insecure without HTTPS.

Also: Make separate database users for each app, and make their passwords at least 10 random characters. No sharing of users or passwords!

Security for Developers presentation slides (PDF)

Here’s the raw text of the slides: Continue reading

Security 101

Woman holding two cell phones at onceMost people are blissfully unaware of what security means in the 21st century, despite using 21st-century technology daily. Many nerds are aware of attacks like viruses, trojans, and phishing, and many computer users are familiar with the idea that passwords are important and that their hard drives’ data can always be recovered, but there are whole areas of security people are totally ignorant about.

This is a quick-n-dirty primer on security issues you probably don’t know about (or aren’t protecting yourself from.)

Continue reading

How to Solve ‘You do not have access to logon to this session’ error in Windows XP via Group Policy (GPO)

In order to login via Remote Desktop on Windows XP, you must be a member of the local machine’s Remote Desktop Users group. This is slightly different than on Windows Server, where you can modify the permissions of Terminal Services and define custom groups to be allowed access.

Additionally, you’ve probably tried to change the GPO setting under Computer Configuration, Windows Settings, Security Settings, Local Policies, User Rights Assignment for ‘Allow log on through Terminal Services’ and discovered that it still doesn’t work fully for non-Administrators.

The solution is to add the group, or the user, that you want to be able to login remotely, to the RDP computer’s local Remote Desktop Users group. You cannot add people to the Active Directory domain Remote Desktop Users group, because this group is “local” to the Domain Controller only. So how does an administrator add a user or group to all client workstations’ Remote Desktop Users groups without going to each computer manually? Use a GPO: Continue reading

Email to Honda

I recently had my car serviced for an intermittent, weird noise– it’s 3 years old and just started making a weird clutch noise over the past few months. My experience was pretty average (read: mildly frustrating) and my response to a Honda phone survey resulted in a disappointed voicemail from David, the service advisor I worked with, and an email from Honda asking for a lengthier fill-in-the-blanks survey. Here’s what I wrote in response to that survey email, word-for-word, typos and all: Continue reading

Right-Hand Navigation in Website Design

This is a comment I posted on WebProWorld after a quick Google search to see what the consensus was on right nav in webdesign. It represents my current analysis of the issue.

I think, when designing your site, you should know which direction visitors’ eyes will go. In L-to-R reading countries, this is top-left to bottom-right with few exceptions. In R-to-L reading countries, this is probably different.

There’s a new trend in websites (especially blogs) where the content is the message (and, to some extent, the navigation.) In this case, the designer is saying “those links on the right are useful, but you probably want to read this content first.” Continue reading

Javascript Countdown Timer

Better code for doing a date-based countdown in Javascript. The top results on Google appear to have been written in 1990 and are unnecessarily cumbersome– here’s a version I wrote for a quick Christmas “countdown” webpage.

One major advantage to my version is that it compensates for the date in a given timezone, so that it counts down to the same exact second regardless of time zone (assuming that everyone’s computer time is accurate) instead of “rolling” across time zones. This is done by taking advantage of the way numerical timestamps are stored (always in GMT) and the .toUTCString commands. For an even more accurate rollout, I used inline php code to populate the timestamp number and also perform some logic when the server thinks the time has been reached, so that users can’t simply change their computer’s clock to see the result (which in this case is just reloading, since my PHP should have replaced the server-side HTML by that point.)

If you’d like to see the inline PHP that handles the official rollout, leave a comment!

<script type="text/javascript">// <![CDATA[
/* Javascript Countdown Timer
* Will Bradley (www.willbradley.name) Dec. 2009
* Code released publicly without any warranty or license.
*/
function showtime() {
dateString = new Date().toUTCString();
now = Date.parse(dateString);
xmasDateString = new Date(1261724400000).toUTCString(); // The long number is December 25, 2009 in Javascript's .getTime() format. You can put almost any value in here, including plain english dates.
xmasDate = Date.parse(xmasDateString);
dd = xmasDate now;
dday=Math.floor(dd/(60*60*1000*24)*1);
dhour=Math.floor((dd%(60*60*1000*24))/(60*60*1000)*1);
dmin=Math.floor(((dd%(60*60*1000*24))%(60*60*1000))/(60*1000)*1);
dsec=Math.floor((((dd%(60*60*1000*24))%(60*60*1000))%(60*1000))/1000*1);
if(now > xmasDate)
{
// Put any "countdown done!" code here. I've got it reloading in order to pull new info via a coordinated PHP countdown, but you could put anything.
window.location.reload();
document.getElementById("secs").innerHTML = "Reload the page for your gift!";
}
else{
document.getElementById("secs").innerHTML =
dday + "<em>days</em>" +
dhour + "<em>hours</em>" +
dmin + "<em>minutes</em>" +
dsec + "<em>seconds</em>";
timerID = setTimeout("showtime()",1000);
}
}
// ]]></script>
<style type="text/css"><!
body { backgroundcolor: black; color: white; text-align: center;
font-family: Lucida Sans Unicode, Lucida Grande, sans-serif; font-size: 12px;
}
h1 { color: #ee0000; font-weight: bold; margin-top: 150px; font-size: 4em; text-transform: uppercase; }
h1 em { color: white; font-style: normal; margin: 0 0.5em 0 0.25em; font-size: 0.4em; }
></style>
<h1 id="secs"></h1>

view raw
countdown.html
hosted with ❤ by GitHub

Re: Gangplank Looking To Move Downtown

This is a reply to a post here: http://gangplankhq.com/2009/11/gangplank-looking-to-move-downtown/

Whether Tempe is a poser or Phoenix is sucky or Chandler is a thriving tech incubator is somewhat diluted by their public perception. I think perception is reality– if the public thinks something, it becomes a self-fulfilling prophecy.

Moving Gangplank to Buckeye would be a harder sell than moving it to Downtown Phoenix– people would whine either way, but Buckeye isn’t perceived as a technological place whereas Downtown Phoenix seems like an objectively logical choice. I’ve only lived in Phoenix since ’04, but Chandler/Mesa/Gilbert doesn’t seem like an objectively logical choice for technology incubators. It might be in practicality, but I think that would shock most Valley residents, and so unfortunately you’re working against public perception which is an uphill battle.

It’s hard to be “the best collab space in Phoenix” if you’re actually 10 miles outside of Phoenix and a 30 minute drive from the city center. If Gangplank doesn’t want to be, that’s fine, but it’d be helpful to explicitly state this so guys like myself don’t write short blog-essays in vain.

Necessary Discomfort

This was originally posted as a comment to http://mutiny.in/2009/01/01/divided-we-stand and inspired me to add similar philosophical discussions to my blog in the future. The thesis of the original post was, is complete globalization necessary to achieve peace?  My thoughts below.

Globalization in its most extreme, leading to the disintegration of homelands, somewhat fits with my ongoing theory that mutual discomfort is what makes us adult humans. I wouldn’t advocate the actual disintegration of a cultural identity, but I do believe every person needs to become more of a world citizen to some degree.

Discomfort toward constructive ends is necessary. If I never learned math or English, would I be able to earn a decent living? If I wasn’t forced to help with my parents’ business as a child, would I be a manager at age 22? If people never went to school or summer camp, would they grow and learn? Doing chores is uncomfortable. Being a member of society can be uncomfortable. Integrating into a new culture can be uncomfortable. Our fathers told us that dealing with this discomfort built our character and made us more mature, but we didn’t listen to them, and so we avoid discomfort all the time, to our own and to the world’s detriment.

I advocate discomfort. Sell your car and ride the train. Talk with homeless people and volunteer for women’s shelters. Visit a foreign country for a month or two and realize that although a foreign cultural system may not agree with ours, it is the system’s integrity that matters, not the system itself. We must find a way to integrate with foreign cultures or risk alienating our worldly neighbors. We can’t ask other cultures to integrate with us– this is a personal task and responsibility. Ideally we are able to integrate without fully abandoning our own culture or diluting either culture to irrelevance. These are uncomfortable tasks but necessary for our maturity and usefulness as human adults, in this new interconnected world where an American has the privilege and honor of commenting in an Indian publication.

BREAKING NEWS, Las Vegas: Monte Carlo Hotel on Fire

This just in: the Monte Carlo Hotel in Las Vegas is on fire. Stay tuned for pictures, coming as soon as wireless networks will allow.

http://www.montecarlo.com

Picture 1Picture 2Picture 3Picture 4Picture 5Picture 6Picture 7Picture 8Picture 9Picture 10Picture 11

Update: Photo credits Jason Gordy. “Fire started just before 11am. ” “[not a terrorist attack], noone’s hurt, everyone’s rescued, nobody’s trapped. Traffic is blocked for 2 miles around the casino, every road barricaded. The fire was in the South wing.”

Update 2: Jason Gordy live on KNBC! http://www.knbc.com/videostream/10954229/detail.html
http://www.knbc.com/news/15138601/detail.html?rss=la&psp=news
(Thanks to NBC!)

Notify and Walk

I just caught a bit on the news about Armitage’s “Notify and Walk” suggestion. Hey, for a former Bush official and someone who loves to gossip about the secret identities of CIA spies, he’s got a point.

Earlier this week, former Deputy Secretary of State Richard Armitage suggested a gradual reduction of U.S. troops, perhaps at a rate of about 5 percent every few months.

“We can’t win on the battlefield,” said Armitage, who served throughout Bush’s first term. “The problem is that this is now a political struggle being carried out amid chaos, and we can’t wish stability on the Iraqis. They have to be willing to fight for it.”

Asked if he thought that staying the course remains an option, Armitage replied: “If the definition of insanity is doing the same thing over and over again and expecting a different result, then clearly it isn’t. The problem is that you can change tactics in an hour, but it takes time to change strategy, and it’s too late for that now.” (The Mercury News)

What’s this, a beginning acceptance that our strategy in Iraq is insanity? Isn’t this the exact strategy that I’ve been suggesting for a year now? Ad hominem be damned, finally someone is seeing the light. The only wish I have is that we dramatically increase our social and political work while turning our battle strategy into a true peacekeeping mission. But as he said, it could be too late for that now. What ever happened to “winning the hearts and minds?”

President Bush says that “America will stay, we will fight, and we will win in Iraq.” Do you think he’ll ever realize that the second part is preventing the third part?