antipaucity

fighting the lack of good ideas

charge for carry-on luggage

Airlines over the past several years have begun charging for all kinds of things that used to be “free” (they weren’t ever “free”, they just hid the cost in your ticket price).

One of the worst offenders to this list of fees, though, is the inane charge for your first checked bag whereas carry-on baggage is free. Southwest doesn’t charge for your first two checked bags – and other airlines won’t if you have status or book your flight with their branded credit card – which is the model all airlines should use. But they need to add charging for anything for than your FAA-recognized “personal item”.

Why? Because finding overhead bin space for bulky carry-on bags is what slows most boardings to a crawl. And it is what makes most travelers most frustrated when getting on the plane – not in the first or second boarding groups? They’re going to check your bag(s) for you anyway because all the bin space is taken. (Add-in the ridiculous seat pitch, and you can hardly put anything but a small backpack or purse down by your feet anyway.)

My solution: give the first (and maybe second) checked bags away for free. But charge heavily for carry-on baggage that is more than a personal item (ie your laptop case or purse). (I’d allow an exception for items purchased in-airport from the duty-free shops – they can be carried-on free, too.) By “heavily”, I mean at least $50.

And I would eliminate that crazy practice of gate-checking your bag when getting onto a commuter flight: just check the bag and don’t bottleneck the jetway getting on and off for the rest of us who weren’t as narcissistic as to think bringing our roll-aboards onboard was a good idea.

With the TSA  suggesting everyone arrive at least 2 hours before their flight, there is no reason you wouldn’t have time to check your bags. And with the hassle of trying to navigate a crowded terminal dragging your wheelie duffel behind you, everyone should love the idea of just getting it at baggage claim.

“But what about lost bags?” I hear you ask. Lost and misdirected baggage happens. But it’s pretty rare. It’s something that has happened to me the sum total of 3 times in my flying life (the last 18 years, several of which included flying frequently for work). And of those 3 instances, only 1 ended up with the bag going to the wrong airport – each of the other two ended up with the bag arriving before I did.

Frontier Airlines gets it right (almost – on the carry-on aspect they do, but they still charge for checked bags). Mash Southwest’s checked policy with Frontier’s charging for carry-ons, and you would have a worlds-better flight experience.

The other major benefit to this plan: your time going through TSA will be shorter – the fewer bags that have to be scanned, the less time it will take to get through.

setting-up etherpad in centos 6

To add to my tutorial collection, here’s how to setup EtherPad on CentOS 6 (x64). As in the IRC tutorial, I used a Digital Ocean VM for this 🙂

What is EtherPad? It’s an open-source collaborative text editor that works like Google Docs – ie, all editors/viewers can see changes from everyone else in realtime.

Here’s how I did it: (props to the EtherPad docs and this other tutorial on Node.js)

  • acquire a CentOS server – I used Digital Ocean
  • make sure you have enough swap space (if you use the smallest Digital Ocean “droplet”, you really need to give yourself 2-4G swap)
    • dd if=/dev/zero of=/swapfile bs=8192 count=524288
    • mkswap swapfile
    • swapon swapfile
    • add this line to the end of your /etc/fstab:
      • /swapfile swap swap defaults 0 0
  • run the following as root:
    • yum -y install gzip git-core curl python openssl-devel && yum groupinstall
    • yum -y install screen gcc gcc-c++ make wget curl
      • note – it’s not always called “gcc-c++”; make sure you use the correct package name for your platform
      • you can find out the correct package name by doing a `yum provides */g++` search
    • yum -y upgrade
      • bring everything up to date – it’s equivalent to `yum -y update –obsoletes`
    • adduser etherpad
    • su – etherpad
    • git clone git://github.com/ry/node.git
    • cd node && ./configure && make && make install
    • cd
    • git clone git://github.com/ether/etherpad-lite.git
    • cd etherpad-lite
    • screen bin/run.sh
  • load http://127.0.0.1:9001 in your browser (substitute the IP/DNS name of your server as appropriate – mine was http://107.170.150.57:9001)
  • for maintenance purposes, you should also do a `git pull origin` for EtherPad periodically

Some notes on the above:

  • if you already have swap space and/or don’t want to worry about it (though I recommend you do), you can skip it
  • I’ve put the `-y` option after every `yum` call presuming you really mean to run it, and you don’t care about dependencies
    • if you aren’t using a fresh server (EtherPad certainly doesn’t require it’s own), you may want to be a little more cautious about the `yum` commands 🙂
  • you should create a start-up script to ensure EtherPad is running if you need to reboot
  • the EtherPad docs have all kinds of further things you can do – this is just a “get it going and start using it” tutorial 🙂

setting up an unreal irc server on centos 6

Ever want to run an IRC server? I recently set one up at irc.datente.com using a Digital Ocean VM running CentOS 6.5 x64.

Here’s what I did, if you want to replicate the process for yourself (full documentation available from Unreal’s website):

  • acquire CentOS 6.5 x64 server (as I mentioned, I used Digital Ocean)
  • `yum -y install screen wget gcc`
  • `yum -y upgrade`
  • `adduser unreal`
  • `su – unreal`
  • download Unreal to your server (http://www.unrealircd.com/downloads/unreal/source – `wget http://www.unrealircd.com/downloads/Unreal3.2.10.2.tar.gz`)
  • `tar zxf Unreal*.gz`
  • `cd Unreal*`
  • `make clean`
  • `./Config`
    • answer prompts – most can be left default
  • `make`
  • `cp doc/example.conf unrealircd.conf`
  • edit unrealircd.conf (use your editor of choice)
    • see sample config file below for what I did (minus passwords / emails)
  • if all has gone well, start Unreal
    • `screen ./unreal start`
  • create a startup script to ensure Unreal launches on reboot as user `unreal`

That’s it. Thankfully, while the config file isn’t pleasant to play with, it’s a lot better than it used to be.

loadmodule "src/modules/commands.so";
loadmodule "src/modules/cloak.so";

include "help.conf";
include "badwords.channel.conf";
include "badwords.message.conf";
include "badwords.quit.conf";
include "spamfilter.conf";

me
{
        name "your.irc.server.tld";
        info "Your IRC Server";
        numeric 1;
};

admin {
        "Your Name";
        "yournick";
        "your@email.tld";
};

class           clients
{
        pingfreq 90;
        maxclients 500;
        sendq 100000;
        recvq 8000;
};

class           servers
{
        pingfreq 90;
        maxclients 10;          /* Max servers we can have linked at a time */
        sendq 1000000;
        connfreq 100; /* How many seconds between each connection attempt */
};

allow {
        ip             *@*;
        hostname       *@*;
        class           clients;
        maxperip 25;
};

/* Passworded allow line */
allow {
        ip             *@255.255.255.255;
        hostname       *@*.passworded.ugly.people;
        class           clients;
        password "f00Ness";
        maxperip 1;
};

allow channel {
        channel "#WarezSucks";
        class "clients";
};

oper youroperatornick {
        class           clients;
        from {
                userhost bob@smithco.com;
        };
        password "yourpassword";
        flags
        {
                netadmin;
                can_zline;
                can_gzline;
                can_gkline;
                global;
        };
};

listen         *:6697
{
        options
        {
// uncomment this line if you chose to compile Unreal with SSL support
//              ssl;
                clientsonly;
        };
};

listen         *:8067;
listen         *:6667;

/* not linking to any other servers right now
link            hub.mynet.com
{
        username        *;
        hostname        1.2.3.4;
        bind-ip         *;
        port            7029;
        hub             *;
        password-connect "LiNk";
        password-receive "LiNk";
        class           servers;
                options {
                        /* Note: You should not use autoconnect when linking services */
                        autoconnect;
                        ssl;
                        zip;
                };
};
*/

ulines {
        services.roxnet.org;
        stats.roxnet.org;
};

drpass {
        restart "I-love-to-restart";
        die "die-you-stupid";
};

log "ircd.log" {
        /* Delete the log file and start a new one when it reaches 20MB, leave this out to always use the 
           same log */
        maxsize 20971520;
        flags {
                oper;
                connects;
                server-connects;
                kills;
                errors;
                sadmin-commands;
                chg-commands;
                oper-override;
                spamfilter;
        };
};

alias NickServ { type services; };
alias ChanServ { type services; };
alias OperServ { type services; };
alias HelpServ { type services; };
alias StatServ { type stats; };

alias "identify" {
        format "^#" {
                target "chanserv";
                type services;
                parameters "IDENTIFY %1-";
        };
        format "^[^#]" {
                target "nickserv";
                type services;
                parameters "IDENTIFY %1-";
        };
        type command;
};

alias "services" {
        format "^#" {
                target "chanserv";
                type services;
                parameters "%1-";
        };
        format "^[^#]" {
                target "nickserv";
                type services;
                parameters "%1-";
        };
        type command;
};

alias "identify" {
        format "^#" {
                target "chanserv";
                type services;
                parameters "IDENTIFY %1-";
        };
        format "^[^#]" {
                target "nickserv";
                type services;
                parameters "IDENTIFY %1-";
        };
        type command;
};

alias "glinebot" {
        format ".+" {
                command "gline";
                type real;
                parameters "%1 2d Bots are not allowed on this server, please read the faq at http://www.example.com/faq/123";
        };
        type command;
};

files
{
        /* The Message Of The Day shown to users who log in: */
        /* motd ircd.motd; */

        /*
         * A short MOTD. If this file exists, it will be displayed to
         * the user in place of the MOTD. Users can still view the
         * full MOTD by using the /MOTD command.
         */
        /* shortmotd ircd.smotd; */

        /* Shown when an operator /OPERs up */
        /* opermotd oper.motd; */

        /* Services MOTD append. */
        /* svsmotd ircd.svsmotd; */

        /* Bot MOTD */
        /* botmotd bot.motd; */

        /* Shown upon /RULES */
        /* rules ircd.rules; */

        /*
         * Where the IRCd stores and loads a few values which should
         * be persistent across server restarts. Must point to an
         * existing file which the IRCd has permission to alter or to
         * a file in a folder within which the IRCd may create files.
         */
        /* tunefile ircd.tune; */

        /* Where to save the IRCd's pid. Should be writable by the IRCd. */
        /* pidfile ircd.pid; */
};

/*
tld {
        mask *@*.fr;
        motd "ircd.motd.fr";
        rules "ircd.rules.fr";
};
*/

/* note: you can just delete the example block above,
 * in which case the defaults motd/rules files (ircd.motd, ircd.rules)
 * will be used for everyone.
 */

ban nick {
        mask "*C*h*a*n*S*e*r*v*";
        reason "Reserved for Services";
};

ban ip {
        mask 195.86.232.81;
        reason "Delinked server";
};

ban server {
        mask eris.berkeley.edu;
        reason "Get out of here.";
};

ban user {
        mask *tirc@*.saturn.bbn.com;
        reason "Idiot";
};

ban realname {
        mask "sub7server";
        reason "sub7";
};

except ban {
        /* don't ban stskeeps */
        mask           *stskeeps@212.*;
};

deny dcc {
        filename "*sub7*";
        reason "Possible Sub7 Virus";
};

deny channel {
        channel "*warez*";
        reason "Warez is illegal";
        class "clients";
};

vhost {
        vhost           i.hate.microsefrs.com;
        from {
                userhost       *@*.image.dk;
        };
        login           stskeeps;
        password        moocowsrulemyworld;
};

set {
        network-name            "Datente";
        default-server          "irc.datente.com";
        services-server         "irc.datente.com";
        stats-server            "irc.datente.com";
        help-channel            "#datente";
        hiddenhost-prefix       "rox";
        /* prefix-quit          "no"; */
        /* Cloak keys should be the same at all servers on the network.
         * They are used for generating masked hosts and should be kept secret.
         * The keys should be 3 random strings of 5-100 characters
         * (10-20 chars is just fine) and must consist of lowcase (a-z),
         * upcase (A-Z) and digits (0-9) [see first key example].
         * HINT: On *NIX, you can run './unreal gencloak' in your shell to let
         *       Unreal generate 3 random strings for you.
         */
        cloak-keys {
                "aoAr1HnR6gl3sJ7hVz4Zb7x4YwpW";
                "aaAr1HnR6gl3sJ7hVz4Zb7x4YwpW";
                "aeAr1HnR6gl3sJ7hVz4Zb7x4YwpW";
        };
        /* on-oper host */
        hosts {
                local           "locop.roxnet.org";
                global          "ircop.roxnet.org";
                coadmin         "coadmin.roxnet.org";
                admin           "admin.roxnet.org";
                servicesadmin   "csops.roxnet.org";
                netadmin        "netadmin.roxnet.org";
                host-on-oper-up "no";
        };
};

set {
        kline-address "your@email.tld";
        modes-on-connect "+ixw";
        modes-on-oper    "+xwgs";
        oper-auto-join "#opers";
        options {
                hide-ulines;
                /* You can enable ident checking here if you want */
                /* identd-check; */
                show-connect-info;
        };

        maxchannelsperuser 10;
        /* The minimum time a user must be connected before being allowed to use a QUIT message,
         * This will hopefully help stop spam */
        anti-spam-quit-message-time 10s;
        /* Make the message in static-quit show in all quits - meaning no
           custom quits are allowed on local server */
        /* static-quit "Client quit";   */

        /* You can also block all part reasons by uncommenting this and say 'yes',
         * or specify some other text (eg: "Bye bye!") to always use as a comment.. */
        /* static-part yes; */

        /* This allows you to make certain stats oper only, use * for all stats,
         * leave it out to allow users to see all stats. Type '/stats' for a full list.
         * Some admins might want to remove the 'kGs' to allow normal users to list
         * klines, glines and shuns.
         */
        oper-only-stats "okfGsMRUEelLCXzdD";

        /* Throttling: this example sets a limit of 3 connection attempts per 60s (per host). */
        throttle {
                connections 3;
                period 60s;
        };

        /* Anti flood protection */
        anti-flood {
                nick-flood 3:60;        /* 3 nickchanges per 60 seconds (the default) */
        };

        /* Spam filter */
        spamfilter {
                ban-time 1d; /* default duration of a *line ban set by spamfilter */
                ban-reason "Spam/Advertising"; /* default reason */
                virus-help-channel "#help"; /* channel to use for 'viruschan' action */
                /* except "#help"; channel to exempt from filtering */
        };
};


group admin in the era of facebook

Along the difficulties of initially building a good group/community, comes the hassles of managing said [virtual] community – especially on the book of the face.

I am a coadmin on the Ontario & Western Railways Historical Society Inc Facebook group. My friend Peter is a coadmin of the Linux Mint group.

Something both of us have noticed is the ridiculous spam problem Facebook groups have developed over the past 1-2 years. It’s not a new problem, of course – Stack Overflow has had problems since very early on, too: they printed A Theory of Moderation to outline the issues they were seeing, and how they planned to handle it.

The real problem at the root of all the spam lies, though, not in technology, but in people.

Even with active community self-regulation, moderators occasionally need to intervene. Moderators are human exception handlers, there to deal with those (hopefully rare) exceptional conditions that should not normally happen, but when they do, they can bring your entire community to a screaming halt – if you don’t have human exception handling in place.

Spam doesn’t arise on its own – it’s all developed by people. Until the people problem of spam can be addressed, it will continue. Sadly, technology, in and of itself, cannot deal with the people problem.

So instead we have human admins and moderators whose [typically volunteer] job is to ensure that the communit[y|ies] keeps to a general standard, as defined by the community itself. By assuming technology could be made that would fix the problem, we’re asking the wrong question: human behavior needs to be addressed and improved; while technology is wonderful and can aid in the process, it is no panacea.

Encouragements for moderation teams can come in the form of gamification (the SO model), community accolade, or just the individual admin’s personal satisfaction.

The drawback is that this task can become so overwhelming at times and in places that it those tasked with caring for the community, when the community itself won’t do anything about the problem(s), give up because they adopt the view that it’s everyone’s problem, and presume that since it is everyone’s problem, it’s not “theirs”.

What are the solutions to these issues? I can think of a few – but many remain yet unanswered:

  1. the community must encourage the admins
    • if the community isn’t doing something to make their admins feel appreciated, the admins will, eventually, leave
  2. better tech
    • it’s not possible to solve all problems with technology, but there are certainly many areas that can be improved in this regard
  3. community engagement and education
    • seasoned community members and admins alike need to take the time to “mentor” new community members to make sure they stick to the guidelines of that community
    • community members need to be proactive in assisting the moderators when inappropriate items are posted, or conversation degrades below the stands of the group
  4. a willingness to say “no”
    • admins and the general community needs to be willing to tell some people they are not welcome
    • this should [almost] never be in a hateful, grudge-bearing manner, but it must be done to ensure the integrity of the community in the long-term
  5. a willingness to morph
    • the flip side of (4) is that the community needs to be willing on a regular basis:
      • review its own guidelines
      • change / modify rules
      • find new admins
      • welcome new members who aren’t yet versed in the ways of the group ( related to (3) above)

I am sure there are many many more items that can be added to this list. But this is the starting point for every successfully-maintained community I’ve ever seen.

What others would you add, or what would you change?

make your accomplishments seem effortless – law 30 – #48laws by robert greene

Law 30

Your actions must seem natural and executed with ease. All the toil and practice that go into them, and also all the clever tricks, must be concealed. When you act, act effortlessly, as if you could do much more. Avoid the temptation of the revealing how hard you work – it only raises questions. Teach no one your tricks or they will be used against you. –Robert Greene, The 48 Laws of Power (review)

extended file attributes with ext[2|3|4]

Most Unix/Linux users, and – hopefully – all admins are familiar with the standard 9 bits of permissions typically supported on various *nix file systems:

---------
rwxrwxrwx
uuugggooo

Where “u”, “g”, and “o” indicate “user”, “group”, and “other” while “rwx” indicates whether the item can be read, written, or executed.

Also of note are file ownerships in the form of

user:group

So a file might be owned by warren:warren with read/write privileges only for the owner: rw-rw----.

That’s pretty handy.

How many of you know there are hidden permissions that do not show up in a normal use of ls -l?

I didn’t until last week – and I’ve been using Linux for more than a decade 🙁

Turns out that – at least with ext2, etx3, and ext4 filesystems – there are a variety of other attributes that can be assigned to a file. One of them is the immutable flag*.

(Using a related command to ls, lsattr, a person can view the extended attribute flags of a file.)

In specific, the immutable flag disallows even the owner from deleting his/her own file! There was the source of a very ornery issue I ran into while doing an upgrade last week of a customer’s management environment. The upgrade installer ran into an issue wherein it interrupted its own process. But when it did, it left the filesystem in an inconsistent state – specifically with regards to an SSL certificate file and the machine identifier file (agent.srv and mid, if you’re curious) having the immutable flag set. When attempting to pick back up with the upgrade, the installer failed more [apparently] asymptomatically (and esoterically) than I had ever seen before.

After several exchanges with senior product support, a working fix of running chattr -i /path/to/file was provided. Neither myself, nor any of the senior admins at my customer had ever heard of chattr. So off to the man pages. Turns out that chattr is quite the command – but it’s not well publicized (at least, I don’t think it is).

If you run into a file you own, but cannot delete, be sure to inspect the extended attributes with lsattr, and fix any mis-set flags with chattr.


*The entire list of alterable flags: “append only (a), compressed (c), no dump (d), extent format (e), immutable (i), data journalling (j), secure deletion (s), no tail-merging (t), undeletable (u), no atime updates (A), synchronous directory updates (D), synchronous updates (S), and top of directory hierarchy (T).” Non-modifiable, but visible with lsattr, flags: “huge file (h), compression error (E), indexed directory (I), compression raw access (X), and compressed dirty file (Z)”.

kaching

I had been playing with a fun stock market simulator/investing application on Facebook until yesterday. It was called kaching (now defunct). The authors decided to focus their efforts on their for-pay service, kaching.com, and drop the free app on facebook.

That’s all well and good – folks making money does not bother me.

What does bother me is when the maintainers of the application say they are expressly not inviting the 60,000+ users to their new service. A reply I received to a post I made when I found out the app was being removed from one of their admins was incredibly unprofessional and rude. He said they weren’t inviting the facebook users because they were not likely to want to use it, and wouldn’t pay for it.

My request was for the app to be kept up, just have maintenance on it cease and no new features be added. Keeping the app alive would have cost them next to nothing. Removing it has alienated 60,000+ people who [almost] all complained, and have made comments like I am right now warning people away from their “premium” services.

I’m all for folks making money: that is, after all, how bills get paid. I’m all for having a closed platform – if that’s what you want to do (though open platforms seem to last longer and work better overall… but that’s an entire series of posts in its own right). But using 60,000 folks on facebook to effectively beta test your premium services, and then drop them just because you want to refocus, does not bode well for professionalism or future success. No, none of us paid to use the app. But an awful lot of us had a lot of fun playing with it.

Shame they’ve decided to upset 60,000 people in such a way. Even more of a shame is that they used 60,000 people as guinea pigs without telling us.

Active, free alternatives on facebook: