GitLab on Fedora 18

I am using a RackSpace cloud running Fedora 18 to install GitLab are a replacement for GroundWarp’s Gitolite server.  Here are some install instructions for getting it running on CentOS6/RHEL6 (the commerical systems based on Fedora.) iconv-devel

Dependency Installation:

Start by doing yum install/groupinstall the following packages and any dependencies they find.

  • yum install ruby mysql -server git redis ruby-devel
  • yum groupinstall “Development Tools”
  • yum install mysql libxslt-devel libyaml-devel libxml2-devel gdbm-devel libffi-develzlib-devel openssl-devel libyaml-develreadline-devel curl-devel openssl-devel pcre-develmemcached-devel valgrind-devel mysql-devel ImageMagick-devel ImageMagick libicu libicu-devel libffi-devel rubygem-bundler

Start your database servers and configure them to start on boot.

systemctl start redis.service
systemctl enable redis.service
systemctl start mysqld.service
systemctl enable mysqld.service

MySQL Server Setup:

Start by logging into the mysql shell:

mysql -u root

Then we create the database we will need, and create a user who can edit/manage that database.

create database gitlabdb;
grant usage on *.* to gitlabuser@localhost identified by “inventapasswordhere”;
grant all privileges on gitlabdb.* to gitlabuser@localhost;

Service User and SSH Configuration:

Create the user account that the GitLab service will be running under.  This will also be used to build some of the necessary dependancies. After creating the user switch to that user’s login.

useradd git
passwd git
su -l git

From here forward (unless otherwise specified) make sure you are logged in as the git user.  The remaining configuration is done as that user.

The next steps are required for setting up the SSH keys pairs for your user account (git uses SSH in the background for most of its tasks.)  Choose the defaults, but make sure to supply a paraphrase (not just a password) when prompted by ssh-keygen.

cat ~/.ssh/ >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

GitLab Shell:

gitlab-shell needs to be installed built/installed for this user.  The following steps sets everything up and builds the packages directly from github (which is the easiest way honestly.)

cd ~
mkdir gitlab-shell
git clone gitlab-shell/
cd gitlab-shell
cp config.yml.example config.yml

Now you are going to want to use a text editor (nano,vim, etc…) to edit the following change to your config.yml file.

gitlab_url: “”

Now run the gitlab-shell installer


Download & Configure GitLab:

Next we will setup our gitlab folders, download Gitlab, and begin configuring it to our set-up

cd ~
mkdir gitlab-satellites
mkdir gitlab
git clone gitlab.
cd gitlab
git checkout 5-2-stable
mkdir tmp/pids/
mkdir public/uploads/
mkdir tmp/sockets/
chown -R git.git log/ tmp/
chmod -R u+rX log/ tmp/ public/uploads/
cp config/gitlab.yml.example config/gitlab.yml

Next you will need to make changes (again with your text editor) to the newly copied config/gitlab.yml file.


Database Configuration:

Our next steps involve configuring the GitLab application database interfaces (remember there are two) and creating initial data entries.

cd ~/gitlab
cp config/puma.rb.example config/puma.rb
cp config/database.yml.mysql config/database.yml

Now configure your database file (the database.yml file you just copied) using your text editor and change the following settings under the production header. (Comment out all the lines under development and testing):

database: gitlabdb
username: gitlabuser
password: “YourSuperSecretPasswordFromTheDatabaseSetupAbove”

We need to install a couple Ruby gems and then  initialize the database.  You do this by running the following commands (note the “without” command tells the bundle to NOT install PostgreSQL gems.):

gem install charlock_holmes –version ‘’
gem install thor –version ‘0.18.1’

gem install rb-inotify
bundle install –deployment –without development test postgres
bundle exec rake gitlab:setup RAILS_ENV=production

Git Environment Setup:

We need to setup a couple of environmental variables for our local git user. Simply type this:

git config –global “GitLab”
git config –global “”

A Life Spent Making Mistakes

Couple other bash tips to help with more robust code.  The main improvement I learned from the previous link is the trap function.  This function lets you cleanup when specific system signals get sent from the OS, like INT (what gets sent to a program when Ctrl+c is typed) and the TERM signal.  A great example is:

trap “rm -f $lockfile; exit” INT TERM EXIT

In this case a lockfile is being removed just before closing a bash script.   You can get a full list of all the different system signals with the kill -l command.

The other major bash tool that I have used without ever really understanding what it did is the eval expression.  If you have ever written a sysinit configuration script, you know that you use eval to basically load/set variables from other subscripts or external files.  The reason eval does this is explained here.  The quick explanation is that eval forces bash to evaluate a second time any code reference passed to it.  So setting bash variables in-line is as easy as:

eval $(LANG=C grep -F “DEVICE=” ifcfg-$i)

One last bash builtin that may come in handy for some, the shopt function sets and displays bash built-in extended capabilities.  See the link for the man page with some examples.

Overall, I am consistently amazed at the power and flexibility of the Linux command line.

Trust the Engineer

(Update 11/20/2017: Additional link for AWS & new versions of Fedora.  Still a useful post.)

A client project along with my “Hacking & Countermeasures” class has recently necessitated a need for my own VPN for use in wireless applications. I needed to connect the VPN to my server rack and the system needed to be an “in-house” system I could turn up myself (sorry Cisco, no ASA for me.)  Finally, it needed to be an SSL based VPN solution as I have had entirely too many issues with locations filtering nonstandard Internet traffic effectively blocking IPSec VPN access on their networks.

I use Rackspace for my server infrastructure, so it only took me about 15 minutes to get the physical (errr… cloud… damn… whatever) Linux machine (Fedora 17 x64) up and running but actually setting up OpenVPN was significantly more challenging that I originally had considered.  The problem wasn’t the lack of documentation (actually the opposite was generally true.)  The problem is that VPN connectivity is so inherently picky, and there are SO many options, that getting a specific configuration running for a specific distribution can be a little overwhelming.

So, for my own personal benefit, here is some of the information I needed to get OpenVPN working on a Fedora 17 server routing http traffic as well as direct traffic to my private subnet.  OpenVPN will be configured to use port 443 (the standard web SSL port) using the TCP protocol.)  As OpenVPN uses SSL, and we will be using TCP on the HTTPS port, all the traffic will look like standard secure web traffic to the network, effectively keeping it from being filtered.

On the Server (as root):

  • Start by install openvpn and other support packages:
    • yum install openvpn pkcs11-tools pkc11-dump
  • We will use the easy-rsa script toolkit to create our shared keys.  So start by coping the example easy-rsa files into your home directory:
    • cp -ai /usr/share/openvpn/easy-rsa/2.0 ~/easy-rsa
    • cd ~/easy-rsa
  • Next you will need to edit the vars file.  Basically it is ID information for your server certificate.  The values other than the PKCS11_MODULE_PATH (which will be set to /usr/lib64/ on x64 machines) are not particularly critical but don’t leave them blank!  Mine looked something like this:

export KEY_CITY=”Norman”
export KEY_ORG=”Rockerssoft”
export KEY_EMAIL=””
export KEY_CN=rockerssoft-vpn
export KEY_NAME=rockerssoft-vpn-key
export KEY_OU=rockerssoft-vpn
export PKCS11_MODULE_PATH=/usr/lib64/

  • Now we generate our server keys and setup our openvpn service directories:
    • . vars
    • ./clean-all
    • ./build-ca
    • ./build-inter $( hostname | cut -d. -f1 )
    • ./build-dh
    • mkdir /etc/openvpn/keys
  • Now with our keys built, we need to copy all of them (along with our certificates and template configuration information) into our service directory.
    • cp -ai keys/$( hostname | cut -d. -f1 ).{crt,key} keys/ca.crt keys/dh*.pem /etc/openvpn/keys/
    • cp -ai /usr/share/doc/openvpn-*/sample-config-files/roadwarrior-server.conf /etc/openvpn/server.conf
  • The config file we just copied to /etc/openvpn/server.conf will need to be edited for your specific server configuration.  If you have problems connecting later on it is most like an issue with either the server configuration file or the client configuration file not matching.  As we want the system to be a full VPN proxy for all internet traffic start by adding the following to the BOTTOM of your config file:
    • comp-lzo yes
    • push "redirect-gateway def1"
  • In /etc/openvpn/server.conf, edit the port number and add a line to have openvpn use tcp instead of udp for port 443.  This should be somewhere between line 9 and 12 and should look something like this when you are done.

port 443
proto tcp-server

  • In /etc/openvpn/server.conf, edit the cert and key file location names somewhere between line 17 and 20.  Add the full path to your key/cert files we moved two steps previous.  They should look something like this (notice the /etc/openvpn/keys preceding each entry:)

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/bob-vpn-1.crt
key /etc/openvpn/keys/bob-vpn-1.key
dh /etc/openvpn/keys/dh1024.pem

  • After you have modified your server configuration files, you will need to tell the Linux Security subsystem (aka SELinux) to recognize the to file layout.  To do this type the following command:
    • restorecon -Rv /etc/openvpn
  • If you need to test your server settings you can run openvpn directly, say to debug your config file,  this way (press Ctrl+c to stop it):
    • openvpn /etc/openvpn/server.conf
  • Finally, you can turn the openvpn server on and enable it so that it starts during future reboots as well.
    • systemctl enable openvpn@server.service
    • systemctl start openvpn@server.service
  • Now that the server is running you will need to configure the firewall to allow vpn traffic connections AND route all your traffic through the system (via Network Address Translation.)  Start by backing up your old iptables configuration and enabling NAT forwarding in the Linux kernel:
    • mv /etc/sysconfig/iptables /etc/sysconfig/iptables.old
    • sysctl -w net.ipv4.ip_forward=1
  • Open up your favorite text editor and copy the following iptable rules into the file.  You will need to save the file as /etc/sysconfig/iptables.  This configuration assumes that eth0 is your public IP address and eth1 is your private.  If this is backwards just change eth0 to eth1 and vice versa.  Also it keeps port 22 open for ssh connectivity.

# Modified from iptables-saved by Bob Rockers
:OUTPUT ACCEPT [118860:18883888]
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp –dport 443 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -j REJECT –reject-with icmp-host-prohibited
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i eth1 -o tun+ -j ACCEPT
-A FORWARD -i eth0 -o tun+ -m state –state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j REJECT –reject-with icmp-host-prohibited

  • To make NAT work across reboots you will need to modify the /etc/sysctl.conf file and change the line net.ipv4.ip_forward = 0to the following:
    • net.ipv4.ip_forward = 1
  • To make everything permanent type the following:
    • sysctl -p /etc/sysctl.conf
  • Now restart your firewall configuration:
    • systemctl restart iptables.service

That should take care of our server configuration. I will follow this post up with client configurations for Windows and Fedora 17 KDE installs. Please feel free to email any fixes/updates to the above configuration if you see something.  Below are a couple of the links I used to get this configuration working:

Finally, the above solution is susceptible to a man-in-the-middle attack from another client impersonating the server (not a problem for my setup as I personally know everyone who I have issued client certificates to.)  The solution is sign the server certificate with a tls-server only key and force clients to check this status on connection.  There is more documentation for this setup here and specifics about the easy-rsa setup here.  At some point I will update this tutorial to fix that issue but, for now, this has been a long enough post.

If you can prove you don’t need it

For years, I have watched the number of technology companies that operate without debt.  The trend has always been popular among IT/IS companies because of the fundamental instability of intellectual property over hard assets.  The logic is hard to argue with.  If everything you “own” of value only has value as a direct cause of its perceived importance, then a shift of public perception doesn’t just hurt your brand, but fundamentally devalues your property.

Think of it this way; if tomorrow everyone stopped trusting Google for their search results (say, you know, someone found out their code sent all our personal information to the Chinese) then overnight they could loose 95% of their US market share.  How much is Google’s code-base worth at that point?  Currently Google is trading at 183 billion so a 95% loss in usage would probably translate to a market value somewhere south of 3-5 billion.

Physical assets don’t behave the same way.  1,000,000 lbs of steal doesn’t just loose 98% of its value overnight.  Even in heavily over-inflated markets things like… I don’t know… homes, don’t loose 98% of their value.  People may be upset that their 350,000 home is now worth 260,000 but just image if one NIGHT your $350,000 home was worth $7,000.  THAT is the danger for companies whose primary assets are intellectual property.

I will give you another concrete example.  Once upon a time there was a company who made A LOT of money in the energy trading business.  Basically the company had sold off almost ALL its physical assets because they made so much money acting as a broker for energy trading.  Think of them as the stock market (or eBay) for energy.  The only problem was that their principal value lay in the fact that people trusted them, trusted their market, trusted their systems, and trusted their software.  Then one day  it was demonstrated that this company lied, cheated, and stole in almost every way you could imagine.  Enron’s stock dropped from $90 to just under $1 in a matter of weeks.  Basically, Enron’s major asset was trust, which it lost, and the company disintegrated overnight.

So how does a company protect itself from such quick devaluation?  The same way you and I protect ourselves from economic turbulence; a big savings account and as little debt as possible.   Microsoft, for example, is famous for “saving” close to a billion dollars a month… yes, a MONTH!  At the same time, Microsoft doesn’t borrow money.  I have been told, by people I put NO trust in to know this information, that they don’t even lease the copiers.  Competitors who want to beat Microsoft can certainly do so, but it will not be an easy fight.  That kind of financial position means that competitors must beat them dollar for dollar, customer for customer, year in and year out… for YEARS!

So who else do you know that doesn’t use debt?  Here are are couple names both in IT and outside of it.  Accenture, Activision Blizzard, Apple, Bed Bath & Beyond, Broadcom , Citrix Systems, eBay, Gap, Google, Infosys Technologies, Juniper Networks, Marvel Technology Group, Qualcomm, Research In Motion, Stryker, Texas Instruments, and Yahoo.  Want to see something more amazing?  Check out those companies 1, 3, and 5 year average returns compared to the market average!

I think it was Warren Buffett who said, “Leverage [i.e. debt] is a funny thing, people who don’t understand it shouldn’t use it; and those who do, don’t.”

A Thousand Furlongs of Sea

We must learn not to disassociate the airy flower from the earthy root, for the flower that is cut off from its root fades, and its seeds are barren, whereas the root, secure in mother earth, can produce flower after flower and bring their fruit to maturity.

Generally speaking I work behind a desk eight hours a day (OK, more like 12) but once in a great while I will get to go out with a field crew to do actual physical work.  While physical labor is generally pretty scary stuff; I love getting out-of-doors.  My most recent excursion was to the western side of Oklahoma on a GIS mapping project.

I have driven through the panhandle a couple time previously but really didn’t spend any time there.  It is absolutely BEAUTIFUL.  For someone who is used to the lush green of the Ozark mountains; the naked beauty of the gypsum hills and high plains was like landing on another planet.  This trip was actually months ago, but I forgot I had taken pictures until today. You can check out the photo gallery by clicking the link below.

Oklahoma Gypsum Hills and Eastern Panhandle

where there is no path and leave a trail.

Two roads diverged in a wood, and I–
I took the one less traveled by,
And that has made all the difference.

Robert Frost

Haven’t heard this song in a long while. It is an old Boy Scout hiking tune that seeps of longing and sadness. Makes me miss camping on cool fall mornings:

The Happy Wanderer

I love to go a-wandering,
Along the mountain track,
And as I go, I love to sing,
My knapsack on my back.

My knapsack on my back.

I love to wander by the stream
That dances in the sun,
So joyously it calls to me,
"Come! Join my happy song!"

I wave my hat to all I meet,
And they wave back to me,
And blackbirds call so loud and sweet
From ev'ry green wood tree.

High overhead, the skylarks wing,
They never rest at home
But just like me, they love to sing,
As o'er the world we roam.

Oh, may I go a-wandering
Until the day I die!
Oh, may I always laugh and sing,
Beneath God's clear blue sky!

Never Forget Today

Human pain does not let go of its grip at one point in time. Rather, it works its way out of our consciousness over time. There is a season of sadness. A season of anger. A season of tranquility. A season of hope.

–Robert Veninga

I was on my way to work when I heard about the first plane.  I remember thinking it was probably an accident, like the plane impact on the Empire State building.  I passed by Tinker Air Force Base on the way; it was guarded but nothing too crazy.  The second  plan crashed into the second building and I remember thinking that we would be going to war with someone.  I called my wife and told her not to leave home.  Being a state employee they told us to go home ourselves.  Passed by Tinker again… there was a tank, several 50mm Brownings, and lots of concrete barricades.  I almost enlisted right there but they wouldn’t let any non-military traffic into the base (my wife didn’t find out about that till a couple years later… she was not happy.)

I got home, hugged my wife and daughter, and cried…

Bookshelf Investing: A Drew Yates Re-post

Here is a repost of a Drew Yates article I found EXTREMELY useful. Unfortunately most of his old posts seem to be forever lost. It is an unfortunate fact that the great blog post I have read are hidden jems that must be dug for. I need to make a habit of copying them on occasion because, all to often, they disappear when their author looses interest and moves on. This is one of the useful top-10 lists I have read and I hope (that by saving it here) it will be useful for a long time to come.

On Books, Top 10 Rules For Investing In Bookshelves

Your bookshelf is like your knowledge portfolio. By investing in yourself, you can become a more interesting, intelligent, creative, and happier person while education improving your judgement and learning new skills. Here are my top ten points for managing your education by investing in your bookself.

1. Buy books for who you’d like to be, not who you are.

Why only buy books about what you already know? Don’t feel guilty about books you own that you haven’t read yet, don’t quite understand, or don’t quite fit your persona. Surround yourself with what you want to know. Achieve by osmosis.

2. You can’t know what you don’t know. Diversify!

Never underestimate the value of learning what you don’t know. Buy books in topics that have “no interest in.” Maybe you are wrong. Inject some randomness in your life.

Excercise: Minute Compass

Try this: stand in the center of the bookstore with your back to the door and check your watch. Turn and face the direction your minute hand points. Buy and read one book in that direction.

3. Understand your investment profile

A book you bought but didn’t read is $20 lost. A book you read but didn’t like or learn from is $20 and maybe a few hours lost. A book you read and learned from is priceless. So: a calculated risk of $20, or never learning anything new? You can’t even begin to understand what you’re missing when you don’t know what you don’t know.

It’s much easier to start reading a book you have than a book you don’t have.

Unless you have urgent expenses, invest generously. This is true for all investments.

4. Give your favorite books away.

Ideas are like currency. They only have value when shared.

Real power today lies at society’s “information hubs.” What better to demonstrate your informational worth than to give books? You can alway rebuy books if you need them. Don’t bother asking people to return your books. That’s tacky. Let them keep it as a token of your thoughtfulness, advice, and generosity. Maybe they will pass that book along to their friends with a shining review, too! That’s the ulitmate compliment.

Not: Used books are NOT GIFTS. Gifting something you are “done with” as is fantastically tacky and cheap. Besides, traditional gifts are more tokens of sacrifice and obligation than tokens of good-will and thoughtfulness. How else could you explain all those $10 gift certificates from your extended family and coworkers?

5. Buy books cheap, but don’t be cheap.

Investing in books are one of those rare opportunities where it pays to be a spontanious shopper. If you suddenly have the motivation to learn, don’t squander it to save five dollars! Naturally, don’t spend more than you have to. But like the morons who drive around town for the cheapest gas, it doesn’t pay to waste time to save a couple dollars. Well, actually it pays a couple dollars. Unless you’re 11, you probably could spend your time better.

Also, most good technical books can usually only be found new. Good technical books are kept as references, and people resell back books they don’t think they’ll use again. Also, most technical books have a shelf-life of only a few years. The only technical books at a value book store will probably be outdated and mediocre.

Cheap, readily available books, like classical literature, are usually at the library or internet for free, anyways.

6. Be Wary of Textbooks. Many Textbooks Suck.

Be suspecious of any book that marketed to undergraduates. If the publisher doesn’t take pride in their work and churns frivolous editions, why should you take pride in owning a copy? In my experience, most required engineering books are terrible. If you’re a computer science student, forget buying the textbook, just use the Internet.

Note: this varies per university. If you are savvy enough to judge books, you can often judge the quality of a university department by the quality of the required reading. Andrew in the comments also noted that many very specialized texts can only be found at universities.

7. Ask Bookstore Employees for Advice

Most bookstore employees like books. Unfortunately, they are usually stuck playing the Warehouse Index game for impatient customers. Make your bookstore employees happy. Ask for their advice. They will know which books are well-liked and which are trash, and they might know which publishers print the best quality books. Ask employees which books they like. And then buy what they like. You might even make some interesting friends this way.

Side note: never harass retail employees. Be nice. Really, whatever your problem is, it’s almost guarunteed not be the fault of anyone around you can talk to. Worse, have you ever known an employee to make exceptions for a jerk? Rarely. If you have a problem with a store, complain with your wallet (or your blog ;) ), never to employees.

8. Throw away bad books.

You probably own some books that were disappointing or technical books that are outdated. Throw them away. There’s nothing to be learned by hording trash knowledge. In fact, make trashing books symbolic of your intellectual health. You can’t fill a full cup.

9. Non-fiction is usually a better investment

Non-fiction has an obligation (you hope) to be true. Most fiction, like movies, only mean to be entertaining, not to make you think. If you want to read fiction, avoid books you would expect to find at your grocery store. Also, most science fiction and fantasy books are rarely good “investments.” Watch Star Wars, read Lord of the Rings, and be done with it.

10. If somebody recommends a book, STOP, note the title, and buy it immediately

Your investment will stagnate if you don’t do this. Make this a habit. Don’t try and rationalize this away. Shut up and do it. Somebody you respect has chosen to share very valuable knowledge with you and you have an obligation to due diligance. Even if you don’t like their recommendation, you have learned something important about the person who recommended it. To not do this, I think, is crude and insulting.

In fact, you should take notes whenever anyone is describing something they care about, whether it’s people they think you should know, books that they enjoy, or places they enjoy visiting. Not only is this flattering, but it’s honest and smart. What better way to prove your legitimate interest in somebody’s opinion than writing them down… and then backing your word with your wallet? Not even $20 in beer could be as well spent.

Note: don’t be obnoxious about taking notes. Just write down the author and title. People don’t want to feel like professors in casual conversation.

Albondigas Soup

Heather makes the best soups I have ever had.   My bragging has caused a number of people to ask for the recipes.  As I pull out the Heathers 900 year old hand written recipe cards, I will do my best to post my favorites.  Today’s soup selection in Albondigas Soup:

  • 1T Chop Fresh Cilantro
  • 1lb Ground Beef
  • 1/4 cup Rice
  • 1 Egg
  • 1t  Seasoned Salt
  • 1/4 cup Ice Water
  • 3 cans Chicken Broth
  • 1 can Diced Tomatoes
  • 1/4 cup Chopped Onion
  • 1 rib Celery Diced
  • 1 Carrot Diced
  • 1 Potato Diced
  • 1/4t Garlic Powder

In a medium bowl combine ground beef, rice, egg, cilantro, salt, an water; form into small meatballs.  In large saucepan, combine broth with vegetables and garlic powder.  Bring to boil; add meatballs.  Reduced heat; cover and simmer for 30 to 40 minutes, stirring occasionally.  Serves 6-8.

If this had been a REAL post

This has been posted with Deepest Sender.  Another Firefox add-on that I am testing.  Basically it creates a sidebar for posting to Livejournal/WordPress/Blogger.  It seems to work OK, but I really wish it didn’t re-login every time I closed/opened the sidebar.  It includes a full mini-GUI for editing/adding posts that is reachable via shortcut key (Ctrl+\).