Its appointed time for everthing

If you are a command line junkie, you really need to check out @climagic on twitter.  Some days are better than others but I am constantly amazed at what is possible in bash/csh.  That said, here are a couple commands I have needed recently, many will be worthless to anyone else but oh well:

    • ar vx mypackage.deb – Unpackage a Debian binary install package. The result is actually three tar.gz files
    • dpkg -l  – List all installed Debian packges on a given system.
    • dpkg -c mypacakge.deb  –  List all files provided by the named Debian package.
    • hub pull-request -i 123 -b account/project:master -h account/project:branchtomerge  –  hub is a github utility that allows you to use some github functionality directly from the command line.  The preceding command will issue a pull request for branchtomerge into master and even tie the request to a given issue number (in this case issue #123.)
    • echo $(sha256sum $DEB | cut -f1 -d’ ‘) $(ls -l $DEB | cut -f5 -d’ ‘) $(basename $DEB)  –  This command creates the package hash structured named used INSIDE of Debian changes files.  Using the same command with (sha1sum|md5sum|sha256sum) will provided all three needed package id’s.  The reason this is useful is when you need to recreate a changes file without the original source package.  The rest of the file is fairly straight-forward but the signed package section has to absolutely precise. Also check out this link for more information.
    • asciiquarium  – OK, you might have to install this one first, but it is a full aquarium in ascii characters, including sharks that eat the fish.  Submarines, fishing hooks, and even the lock ness monster.
    • grc tail -f /var/log/maillog –  Note to self, I need to make an rpm for this package.  grc is a generic colorizer for other command line programs that don’t use color by default (like tail, traceroute, syslog, etc…)
    • isohybrid -h 64 -s 32 mycdimage.iso  –  Adds a simple filesystem layout to a standard iso image so it can be written to USB drive as well as an regular CD.  Really useful for building custom Linux CD/USB images.

Forms it never takes, places it can never be

So, after looking around for an answer today I finally found out where the Debian install CD stores its cd/usb boot menu configuration files.  While I have already had a great deal of experience editing grub.conf files by hand, this methodology simply doesn’t work on an “El Torito” Joliet CDROM image.  So Debian set-up their boot image (as part of the initial ram disk) inside of the /ISO/isolinux/ directory where ISO is the uncompressed version of the boot image.  Specifically you can configure things like:

    • The boot option timeout in /isolinux/isolinux.cfg
    • The background splash image in /isolinux./splash.png (640×480 on the default menu set-up)
    • Which sub-menu’s, options, boot methods, and GUI installs are available via the /isolinux/menu.cfg

Honestly, I may be the only person on the planet trying to figure this stuff out; but here it is for future reference or for anyone who wants to make their very own custom Debian install CD .

Building Debian For Fun and Profit

I needed to document the process I used to get a private Debian package repository with some custom applications.  Here is the process I went through.  You can find some reference links under my previous articles “Debian” heading.

Building

Basic steps to building setting up your personnel project to build Debian packages.

  1. Get most recent software version for your project (git pull, etc..)
  2. Rename project folder to include a default project number.  For example $mv myProject myProject-1.0
  3. In project directory run dh_make.  This will create a debian diectory with all the necessary files to build a deb package.
  4. Now would be a good time to edit your debian/control file and make any changes needed.
  5. If you project is a simple copy operation (say a php web application being installed onto an existing apache server) you will want to do the following:
    1. Create and edit a new file under debian/ named myProject.install (replace myProject with the name of your project.)
    2. Edit the file to specify the where you want the files copied to.  The format of the should be something like this (notice you can use wildcards:)

      myfolder/bin/* usr/bin
      src/etc/myproject.config etc/
      myfille usr/share/myfolder

    3. Make sure you debian/rules file looks something like this:

      #!/usr/bin/make -f

      %:
      dh $@

  6. Now, you should be able to build your package (and the changes & dsc files) by running dpkg-buildpackage.  The resulting packages will be in the directory one level up.

Hosting:

Hosting your own git repository can vary in complexity depending on which software you use to actually build the repository.  The easiest one I found to setup was mini-dinstall.  Start by installing mini-dinstall and apache2 via apt.  Apache is configured to start a basic server (all that we need) with the web page files hosted in /var/www.  Just clean out the www directory, add the mini-dinstall folders after the install:

rm -rf /var/www/*
mkdir -p /var/www/mini-dinstall/incoming

You will also need to create a configuration file for mini-dinstall to use when creating the package repository supporting files. Create/edit the file /etc/mini-dinstall.conf with something like the following:

[DEFAULT]
archivedir = /var/www
mail_to =
verify_sigs = false
architectures = amd64
archive_style = simple-subdir
generate_release = true
mail_on_success = false
release_codename = myreponame
release_description = My Repo Name  Hosting
release_label = myrepo
release_origin = myrepo

At this point mini-dinstall could be configured to run in server mode and watch for incoming packages, but using the utility below I have mine configured to run in batch mode every time I put new files on the hosted server.  This will cause mini-dinstall to create a debian package repository structure that can be accessed directly via apt.  Just add something like the following to your /etc/sources.list

deb http://yourserver.com unstable/abd64/

Deploying:

There is a really nice utility called dput that can be used for deploying software packages (and change files) to a hosting server.  The easiest way to get started is to install dput and then setup a configuration file.  Create a file in your home directory called .dput.cf (or globally in /etc/dput.cf) and add a deployment location like this:

[myservername]
fqdn                    = debian.myserverurl.com
method               = scp
incoming            = /var/www/mini-dinstall/incoming
login                    = root
post_upload_command = ssh root@debian.myserverurl.com mini-dinstall -b

That last line creates the repository using mini-dinstall mentioned above in section “hosting”.  This is particularly useful if you already share public keys with the remote system via ssh.  One you have set it up you can do deployment by typing:

dput -u myservername myproject.change

Where myproject.change is the file created above in “Building”.

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.

ssh-keygen
cat ~/.ssh/id_rsa.pub >> ~/.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 https://github.com/gitlabhq/gitlab-shell.git 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: “http://yourdomainforgitlab.com/”

Now run the gitlab-shell installer

./bin/install

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 https://github.com/gitlabhq/gitlabhq.git 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.

host: git.yourdomain.com
email_from: gitlab-noreply@git.yourdomain.com
support_email: you@yourdomain.com

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 ‘0.6.9.4’
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 user.name “GitLab”
git config –global user.email “gitlab-noreply@git.yourdomain.com”

A Date Which Will Live In Infamy

Date string conversion is fairly painless in JavaScript but sometimes the sheer number of options can be a little annoying to remember.  Below is a table of date display/conversion functions generated from

new Date(“2013-02-19T21:03:39.818Z”).

Hopefully this is helpful to someone else who doesn’t want to look up the output of each of these options.  One more note, these are outputs for US locals in the Central time-zone; other locals and other time-zones would very accordingly.

Date Function Output
 toString() Tue Feb 19 2013 15:03:39 GMT-0600 (CST)
toDateString()  Tue Feb 19 2013
toGMTString() Tue, 19 Feb 2013 21:03:39 GMT
toISOString() 2013-02-19T21:03:39.818Z
 toUTCString()  Tue, 19 Feb 2013 21:03:39 GMT
toTimeString() 15:03:39 GMT-0600 (CST)
 toLocaleString() Tue 19 Feb 2013 03:03:39 PM CST
 toLocaleDateString()  02/19/2013
 toLocaleTimeString()  03:03:39 PM
 toJSON()  2013-02-19T21:03:39.818Z
 valueOf()  1361307819818
toSource() (new Date(1361307819818))

A Beautiful mălum

GroundWarp has a new contract to do web based development for an Oklahoma City software firm called Phase2 Interactive.  One of the benefits of the job is a brand new Apple MacBook Air for use on the companies projects.  I have booted OSX just long enough to shrink the main system partition to almost nothing so I could Linux on it.  So far the entire process has been working pretty well and I am really excited about the quality of the Apple hardware.  Below are some of the system specific fixes I needed to make so overcome the non-standard Apple configuration is places.

  • Setup and install is fundamentally the same as a normal Linux install (at least for Fedora 18) on a 64 bit OS.  As the MacBook Air doesn’t have a built in CDROM you will need to burn the iso file to a USB stick for the install.  The only thing that might catch you is that some iso-to-usb tools (most notably unetbootin) actually copy the files to the USB drive then create their own custom boot menu.  The new secure EFI boot will not allow this without being signed (which Fedora is) so you will need to create your install USB with good old fashioned dd.  Make sure you use the 64 bit edition.

    dd if=../Fedora-18-x86-64-DVD.iso of=/dev/sdb

  • Apple obviously hates its users, and feels they should be punished for their insolence.  At least that is the only explanation I can come up with them flipping the default location of the Alt and Meta keys (key locations that pre-date the Apple by a dozen years… it would be like making the keyboard layout standard but swapping the location of the F and G keys.)  Thankfully this is an easy fix if you are using KDE.  Go to you System Settings, choose Input Devices, choose Keyboard, then choose the Advanced tab.  There is an expandable option titled Alt/Win key Behavior, click on the Left Alt is Swapped with Left Win. Select Apply.
  • By default Apple maps the F1 through F12 keys to their system function options (things like volume up/down and screen brightness.)  This is probably fine for most people but if you are a keyboard jokey or a programmer you almost certainly us the F keys constantly.  The quick fix for this is to run the following command as root:

    echo 2 > /sys/module/hid_apple/parameters/fnmode

  • I am not sure what the “right” way to set kernel module parameters on system boot now that Lennart Poettering bastardized evil systemd has infect the entire Linux world (remember when Linux was simple and intuitive) but once I find the official way to set that it I will update this post.
  • Got to go, but there is more to come.

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_COUNTRY=”US”
export KEY_PROVINCE=”OK”
export KEY_CITY=”Norman”
export KEY_ORG=”Rockerssoft”
export KEY_EMAIL=”name@emailaddress.com”
export KEY_EMAIL=name@emailaddress.com
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:)

tls-server
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
*nat
:PREROUTING ACCEPT [15:1166]
:INPUT ACCEPT [4:422]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [118860:18883888]
-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-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
COMMIT

  • 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.

But what’s my motivation?

Scripts in generally and bash in particular fill an enormous amount of my time.  The ability to create scripts that can handle a number of diverse inputs is directly related to how flexible and robust the code-base is.  The most common problem when handling files in Bash is the problem with spaces.  Linux is both case sensitive and handles spaces with less… grace… than some OSes.  Bash suffers from these same issues.  The easiest way to handle this is with the IFS system variable.  IFS is simply the field delimiter for Linux (i.e. white space) and, because it is a modifiable system variable, you set it to something that you will not run into.  For example:

#!/bin/bash
KEEPOLDVALUE=$IFS
IFS=$(echo -en “\n\b”)
for var in *
do
# Do something with each line of a file
echo “$var”
done
IFS=$KEEPOLDVALUE

That will solve the problem dealing with spaces when developing simple/basic scripts that are written for quick and dirty system management.  That said, when you are building scripts to use regularly you will need to do be a more comprehensive when testing your script.

A good place to start is by setting -u. Whenever testing new scripts, try running them without any arguments but WITH -u. If you fail to correctly initialize your variables running them with -u will warn you that there is a problem. For example:

$bash -u /tmp/mynewtestscript.sh
/tmp/mynewtestscript.sh: line 34: $DIRNAME: unbound variable

We can then verify that we have (at the very least) correctly initialized any variables that we will use and reduce the probability of side-effects.

A problem I ran into a lot with my early script creation was that I often needed standard output from one command to be sent to another command as command line input (as opposed to standard input.) The best way to solve this problem with using the bash built-in command execution form, for example:

echo $(ls)

But this isn’t always very elegant to implement directly, so another options is the wonderful xargs command.  xargs breaks the output of one command into individual arguments that it feeds to another command.  This allows you to use standard piping between otherwise un-pipeable commands.  For example:

ls | xargs echo

Sometime joining two vars can be complicated when those var names need characters between them.  To solve this you can you can use parameter substitution.  What this means, effectively, is that the var $tempvar and ${tempvar} are the same thing.  This allows you to combine variables with in-between characters without concern.

_a=”test”
_b=”/file”
newvar=${_a}folder${_b}

Another useful tip (found via this article from hacktux) is the mktemp executables for temporary file creation.  Needing a temp file to store intermediate data try the following:

tempfile=$(/bin/mktemp)
tempdir=$(/bin/mktemp -d)

Another common problem for bash scripts being used for administration is that they need to be run as root (or sudo root on Ubuntu systems.)  The way to solve this is to check the EUID environmental variable.  Root will always be 0 for EUID and you can put a simple check at the beginning of your script with the following:

if [[ $EUID -ne 0 ]]; then
echo “This script must be run as root” 1>&2
exit 1
fi

Need a random number of characters for your bash script?  Use dd and /dev/random to get a variable number of characters.  For example:

random=”$(dd if=/dev/urandom bs=3 count=1)”

Will give you three random characters (stored in $random) out of urandom current entropy pool.  Unfortunately the character  set is likely to be UTF-32 giving you a bunch of ?? symbols.  To convert those to base64 encoding just pipe the output through base64 (the conversion process may likely give you more than 3 characters to be sure to regexp to the number of characters you need):

random=”$(dd if=/dev/urandom bs=3 count=1 | base64)”

Starting Dropbox

My brother wanted a quick explanation on how to create an executable to start Dropbox. While I was helping him he was kind enough to mock my freakishly awesome IBM Model M Unicomp keyboard… the greatest keyboard in the world. This setup is designed to work the the local tar.gz install of Dropbox on Linux and NOT the rpm based install (that requires Gnome for the file manager.)

Create a new file in your ~/bin directory called startdropbox.sh with the following content

#!/bin/bash
~/.dropbox-dist/dropboxd &

After you have saved the file make the file executable by typeing

chmod 755 ~/bin/startdropbox.sh

Now you can start up dropbox by clicking on that icon at any time.

AND I LOVE MY CLICKY KEYBOARD BITCHES!!!