Siege 3.0.7 Release

Here’s the format for a location header,  Location: absolute_url

Unfortunately, many developers don’t care about standards and Internet Exploder is famous for letting them get away with it. When siege followed the letter of the law, I was inundated with bug reports that weren’t bugs at all. If siege is confused by Location: /haha that’s your developer’s problem, not mine. Against my better judgement and beginning with siege-3.0.6, I started constructing absolute_urls from relative paths. Unfortunately, my parser missed a usecase: localhost. Siege 3.0.6 will barf on this:

Location: http://localhost/haha_or_whatever

Technically, I didn’t miss localhost. If you look at url.c:459 you’ll see this:

// XXX: do I really need to test for localhost?

It didn’t occur to me that people would run siege on the same server as their webserver.  My bad. There are many tests besides load tests.

All siege users running version 3.0.6 should upgrade to siege-3.0.7.tar.gz

Posted in Siege | Leave a comment

It Knows Me Better Than I Know Myself….

robotI write a lot of software with which I interact. If it’s easy for me, then it’s easy for you. I try to keep it easy for me. JoeDog’s Pinochle is the first program against which I’ve competed. It’s been a surreal experience.

The program was designed to be competitive against me. Tonight it took two out of three games. The damn thing knows me inside and out. And why not? I wrote it. And while I can exploit some knowledge of its inter-workings, I can’t predict all its behavior. It was designed to learn bidding from experience.

Bidding is the hardest aspect of this game. The team that wins the bid has an incredible opportunity to earn a lot of points. At the same time, overbids come at a large price. A failure to make the bid means the bid is deducted from your score.

When the game was first released, its bids were implemented programmatically. I like to think I’m a pretty good programmer but that version of the game played like a moran. To improve it, I had the game play itself hundreds of thousands of times. It would store those results and use them to generate future bids.

This implementation has resulted in a much more competitive program. Now it bids more aggressively — much more aggressively. It bids like me which is odd because I didn’t tell it to do that. I told it to learn from its experience and as a result of that experience, its personality morphed into mine.


Posted in Applications, Java, Pinochle, Programming | Leave a comment


Today I’m pleased to announce the first public release of JoeDog’s Pinochle. It’s a computerized version of the classic card game. It plays a four-player variation in which you are paired with a computer player against two computer players. Exciting!

This project is notable for several reasons: 1.) It’s the first time I’ve released software with a graphical interface and 2.) it’s the first major project I’ve completed in java.

JoeDog’s Pinochle is the culmination of hundreds of hours of work over the past several years. The groundwork was laid on planes and trains. It offered an enjoyable way to pass the time as I sat in traveling tubes. Last September I finally achieved a functioning version of the game. Since then, I’ve honed its ability to play a descent game.

Because pinochle maintains a strict set of rules for governing play, most of the “intelligence” in this game was implemented programmatically. Unfortunately, its original ability to assess and bid a hand was very weak. In order to improve that, I’ve built experience into the game. It played itself for hundreds of hours and stored those outcomes. Now when it bids a hand, it consults past experience to shape future results. A skilled human can still beat it but give me time. It will get better with each ensuing release.


I’m currently honing the game’s ability to beat the pants off you people. That may take some time. Once I’ve built adequate intelligence into the game I’d like to add more variation. A double-deck version will be added at some later date. I’d also like to add three and five player variations.


This game is currently licensed under the terms of shareware. It contains some code that was published without licensing terms and the author has not answered my inquiries about its license. It’s probably in the public domain but until I get verification I can’t release it under an open source license. If you’d like a copy of the code, send me an email. Until then, enjoy the binaries.

Posted in Applications, Pinochle | Leave a comment

An Old Dog Learns A New Trick

Beginning with version 3.0.6-beta2, siege reacts differently to –reps=once.

In the past, when you invoked –reps=once, each siege user would invoke each URL in the file exactly one time. If urls.txt contained 100 files and you ran -c10 –reps=once, siege would finish its business with 1000 hits.

That was then.

This is now: siege runs each URL in the file exactly once. If you run -c10 –reps=once, then siege will split the file among all 10 users and hit each URL one time. Whereas in the past, you’d finish with 1000 hits, you now finish with 100 hits.

This should give you greater control by making tests more precise.

Posted in Applications, Siege | Leave a comment

Fido Learns A New Trick

I use Mondoarchive to create Linux recovery disks. Each server writes ISO images to a shared volume on a weekly basis. If any file inside that directory is older than seven days, then a server failed to create an ISO. In order to monitor this directory for failure, I added a new feature to fido. Exciting!

Starting with version 1.1.0 (click to download), fido can monitor a file or directory to see if it — or any file inside it — is older than a user configurable period of time. If fido discovers a file whose modification date exceeds the configured time, it fires an alert.

The following example illustrates how to configure the use case above:

/export {
  rules = exceeds 8 days
  exclude = ^\.|^lccns178$|^lccns179$|^lccns335$|lccns336$
  throttle = 12 hours
  action = /etc/fido/

This file block applies to “/export” which is a directory. Since it’s a directory, the rules apply to every file inside it. In this case ‘rules’ is pretty straight forward. We’re looking for files that exceed eight days in age. This rule will always follow this format: exceeds [int] [modifier]. The modifier can be seconds, minutes, hours or days. If you take the long view — if you’re concerned about events far into the future — then you’ll have to do some math. We don’t designate years so you’ll have to use 1825 days if you want to be alerted five years out.

We also find a new feature inside this block. ‘exclude’ takes a regular expression and tells fido which files to ignore. Currently, ‘exclude’ only works inside a file block with an exceeds rule but I plan to make better use of it.

Finally we notice one final feature that we’ve never seen before. The ‘throttle’ directive tells fido how long to wait between alerts. In this scenario, fido will trigger an alert the second it finds a file which exceeds 8 days. If the problem is not addressed within twelve hours, it will fire another alert. Alerts will continue in twelve hour intervals until the problem is corrected.

I hope you enjoy these features. If there are enhancements you’d like to see, feel free to contact me either in the comments or by email.

Posted in Applications, Fido | Leave a comment

Siege 3.0.4 Becomes Part of the Problem

Siege 3.0.4 was just released. It contains a feature that I’ve added with a certain amount of reluctance. To understand the feature and the reason for my trepidation, let’s visit RFC 2616 and read what it has to say about Location headers:

For 3xx responses, the location SHOULD indicate the server's
preferred URI for automatic redirection to the resource. The 
field value consists of a single absolute URI.
    Location = "Location" ":" absoluteURI
An example is:

That’s pretty clear, right? The value of a location header must be an absolute URI. Yet a large number of developers ignore that directive. Here’s the response from a server running SquirrelMail, a popular web-based email program:

     HTTP/1.1 302 Found
     Date: Tue, 17 Sep 2013 16:50:52 GMT
     Server: CERN/1.0A
     X-Powered-By: PHP/5.2.5
     Location: src/login.php
     Content-Length: 0
     Connection: close
     Content-Type: text/html; charset=WINDOWS-1251

Although that Location header violates RFC 2616, nearly every web client will follow it to SquirrelMail’s intended destination. I say “nearly every client.” Until version 3.0.4, siege wouldn’t have followed it any where. It would have scratched its head and said, “Fsck it. Next URL.”

It is with some reluctance that I’ve included siege in the community of clients that allow developers to circumvent established standards. This convention has created a slew of bad coding practices on the world wide web. Didn’t close a table with an end tag? That’s okay, M$ will close it for you. Used a relative URI in a Location header? Don’t worry, siege will normalize it for you.

Ironically, version 3.0.4 includes one other feature enhancement. Its default User-agent is now in full compliance with RFC 2616. You win some, you lose some. And so it goes….

Posted in Applications, Siege | 5 Comments

Siege 3.0.3 and URL Encoding

URL encodingURL encoding aka URL escaping aka percent encoding is a mechanism for converting URL characters into a format that can be transmitted by HTTP. Reserved characters are replaced by a hexadecimal value preceded with a ‘%’ which is an escape character. If a URL contains a space, for example, it must be encoded for transmission. Your browser takes a space and reformats it as %20.

Siege, on the other hand, does nothing. It expects you to encode your own damn URLs … that is, until now! Percent encoding is available in siege starting with version 3.0.3-beta2. When it emerges from beta, the first stable version to support this feature will be 3.0.3.

Really? Siege has been around since 1999 and you’re only now adding this feature?

Well, you guys never asked and I haven’t had much need for it. Lately, however, I’ve noticed many of you are asking about json. I suspect URL escaping will be helpful to those folks. Consider this:

siege -g ‘{ “Hello” : “world” }’

 GET /siege/echo.php?q=%7B%20%22Hello%22%20:%20%22world%22%20%7D HTTP/1.0
 Accept: */*
 User-Agent: JoeDog/1.00 [en] (X11; I; Siege 3.0.3-beta2)
 Connection: close

Booya! Just make sure you single quote the URL like in the example above.

Since URL escaping is in its early stages, I’ve provided a mechanism for disabling it. Inside $HOME/.siegerc add the following: url-escaping = false The default value is true.

Anything else in version 3.0.3-beta2 that we should know about?

Why yes! We changed behavior for -g/–get. When you retrieve a page using -g/–get, siege sets its protocol to HTTP/1.0 so the page is human readable. We don’t need to read chunked encodings and neither do you.


H/T: Your JoeDog would like to give a shout out to the folks at wget from whom he completely stole most of the code necessary to implement URL escaping. Cheers.


Posted in Applications, Siege | 1 Comment

How To Stop A WordPress Dictionary Attack

You guys! Lest we forget, Your Joe Dog was under attack!

Apparently there’s a widespread dictionary attack that uses tens of thousands of malwared computers to attack WordPress sites. Your JoeDog uses WordPress as a CMS. Your JoeDog was attacked!

The extent of the attack was not initially clear. I was alerted by sluggish performance. I noticed a lot of POSTs to wp-login.php. Those POSTs appeared in the access log like this: - - [17/Jun/2013:09:06:42 -0400] "POST /wp-login.php HTTP/1.0" 
200 3444 "-" "Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/2010 Firefox/19.0"

I have a script that allows me to quickly block IP addresses with iptables. So I started harvesting addresses and blocking them. Done and done.

Except the attacker seemed to have an endless supply of IP addresses. The attack persisted no matter how many addresses I blocked.

Take a look at the log entry above. The referer field is empty. A JoeDog Fellow suggested I block all POSTs that don’t include a referer. Afterall, you don’t POST out of the blue – you submit a form in your browser. I blocked those types of requests with a simple mod_rewrite rule:

 RewriteCond %{HTTP_REFERER} ^-?$
 RewriteRule ^/(wp-login.php|wp-admin) - [F,NS,L]

Done and done. Amiright? Sadly, no….

Continue reading “How To Stop A WordPress Dictionary Attack” »

Posted in Security, Wordpress | 4 Comments

Your Joe Dog Is Under Attack

Wanted: Kevin MitnickThis site has been under attack for several weeks now. The attacker is using an unthrottled brute force dictionary attack. He seems to have an unlimited supply of IP addresses. After examining some of the source addresses, I’ve concluded that we’re on the wrong end of a bot net.

I’ve been harvesting IP addresses and blocking them as fast as I can. I’ve also added Rewrite rules to deny these attempts based on his request signature. Those rules reduce overhead since his requests won’t generate database transactions. Yet no matter how many timeouts he gets and no matter how many Access Denied responses he endures, the attacks persist.

Because this dictionary attack is unthrottled, the affect is, at times, not unlike a DOS attack. Your Joe Dog is a public service with shallow pockets. We simply don’t have the resources to eat these attacks and provide you with snappy service. Bare with us as we deal with this asshole.

UPDATE: While it provides additional inconvenience, I applied an access control to the page he’s attacking. You can protect a single file inside a FilesMatch block like this:

 <FilesMatch "wp-login.php">
   AuthType Basic
   AuthName "Kiss my fscking ass"
   AuthUserFile /path/to/my/file
   Require user franklindelanoroosevelt

Obviously, some of that information was obfuscated but “Kiss my fscking ass” really is the realm I’m using.

The benefit to this approach is two-fold: 1. Apache doesn’t expend much effort to say, “401 gimme a password!” 2. If this layer is cracked, he still has to bust the next one before I reset the password on the first one….


Posted in Security, Wordpress | 1 Comment

Siege and the Single Cookie

An emailer wondered if siege could be configured to refuse cookies. I had a vague recollection on the matter. My brain cells were all, “Yeah, sure, you can disable cookies.”

The best place to look for more esoteric features is inside $HOME/.siegerc If you don’t have one, you can generate a new one with this command: siege.config That command will place a new one inside your home directory. ‘siege.config’ is designed to build a resource file which is compatible with your version of the program.

I checked the latest version of that file and I found nothing to disable cookies. Really? That seems like a no-brainer. Why wouldn’t we allow users to disable that? “Sorry,” I replied. “Siege can’t disable cookies.”

Yet my own response was bothersome. I was certain you could turn that off so I checked the code with ‘egrep cooki *.c’ Sure enough, siege parses siegerc for ‘cookie’ which accepts true or false. The latter disables cookie support.

Documentation for this feature has been added to siege-3.0.1-beta4. The feature itself is available in just about every contemporary version of siege that’s floating around the Internets. Just add ‘cookies = false’ to your siegerc file to disable their support.

Posted in Applications, Siege | 2 Comments

Recent Comments

  • Tim: For those who enjoy playing at home and are extra OCD … they’ll spot something wrong with this....
  • roshni: Hi jeff, I need your help regarding running urls in a file containing post directives. Could you please send...
  • Alle: In seige, what does the pink result mean?
  • Windows User: Nice collection of Perl modules. Thanks for sharing.
  • Jeff Fulmer: No idea. What do you see in the webserver’s logs?