Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: November 2012

Brian Cunnie

A Quick & Dirty Anonymous FTP Server

Brian Cunnie
Monday, November 12, 2012

Hey, we need an FTP server. Yes, it has to be an FTP server. We’re going to tell our clients to upload files there. Oh, and we don’t want to bother creating userids for each individual clients—too much work, so it’s important that they can upload files but can’t see anybody else’s files. Except for us: we need to be able to see all the uploaded files.

FTP, although long since superseded by better & more efficient file transfer protocols (e.g. scp, HTTP, bittorrent), has managed to survive to this day, occasionally rearing its ugly head, reminding us that dinosaurs still walk the earth.

Here are the steps to go through to create a secure anonymous FTP server, one where the anonymous clients can upload files but cannot read them.

Create an Amazon EC2 Instance

Amazon AWS is an excellent service for hosting virtual machines on the Internet. Create an account and perform the following steps (caveat lector: Amazon may change the menus/procedures at its discretion):

  • Log into Amazon AWS (you have created an account, haven’t you?)
  • Click on EC2 Dashboard
  • Click Launch Instance
  • Select Classic Wizard
  • Select Ubuntu Server 12.04.1 LTS 64-bit
  • Select EC2; if you have an Availability Zone preference, select it here.
  • The Advanced Instance Options have a reasonable set of defaults
  • Similarly with the Storage Device Configuration
  • Add Tags
    • Name: anon FTP
  • Select Create a new Key Pair,
    • name it anonftp
    • click Create & Download
    • save to ~/.ssh/anonftp.pem
  • Select Create a new Security Group
    • group name anon FTP
    • group description allow all TCP
    • Create a new rule: All TCP
    • Click Add Rule
  • Click Launch
  • Click Close

  • Click on Elastic IPs

  • Click Allocate New Address (for example, 54.243.47.142, which we will use in the remainder of this document, but remember to substitute your allocated elastic IP address)
  • Click Associate Address
    • Instance: anon FTP

Configure Anon FTP

chmod 600 ~/.ssh/anonftp.pem
ssh -i ~/.ssh/anonftp.pem ubuntu@54.243.47.142
sudo apt-get install vsftpd
sudo vim /etc/vsftpd.conf

We made the following changes to our /etc/vsftpd.conf file:

local_enable=YES
write_enable=YES
anon_upload_enable=YES
chown_uploads=YES
chown_username=ftpmaster
chroot_local_user=YES

Now we need to create our ftpmaster user, who will be able to log in & see all files. We are going to assign him the password themasterseesall:

sudo restart vsftpd
sudo useradd -G ftp -d /srv/ftp ftpmaster
sudo passwd ftpmaster
sudo mkdir /srv/ftp/pub
sudo chown ftpmaster:ftp /srv/ftp/pub
sudo chmod 733 /srv/ftp/pub
sudo tee /srv/ftp/readme.txt <<-EOF
        Please upload all movies into the /pub directory.

        You may upload files into the pub directory, but you will not be
        able to read files in the pub directory, not even the ones
        you've uploaded.

        If you can't upload files into the /pub directory, it is possible
        that there is already a file of the same name already there; try
        uploading your file using a different name.
EOF

Test

From your workstation (not the Amazon EC2 instance), connect via anonymous FTP & upload a file. Also, try to get a directory listing:

ftp ftp@54.243.47.142
Connected to 54.243.47.142.
220 (vsFTPd 2.3.5)
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put /etc/hosts /pub/hosts.txt
local: /etc/hosts remote: /pub/hosts.txt
229 Entering Extended Passive Mode (|||64563|).
150 Ok to send data.
100% |*********************************************************************************************|   236        4.50 MiB/s    00:00 ETA
226 Transfer complete.
236 bytes sent in 00:00 (1.44 KiB/s)
ftp> ls /pub/
229 Entering Extended Passive Mode (|||29280|).
150 Here comes the directory listing.
226 Transfer done (but failed to open directory).
ftp> quit
221 Goodbye.

That was a successful FTP session:

  • we were able to connect & upload the file
  • we were unable to browse the contents of the upload directory

Now let’s make sure that the ftpmaster can log in & retrieve the uploaded files:

  • Browse ftp://ftpmaster:themasterseesall@54.243.47.142/pub
  • Click on the hosts.txt file to download

Configure DNS

  • Create a DNS A record for anonftp.yourcompany.com that points to 54.243.47.142

Security Concerns

Anonymous FTP can be a security concern (this author ran an anonymous FTP server in 2001 only to discover that a gentleman from Germany was using its diskspace & bandwidth to illegally distribute movies. Even worse, his taste in movies was universally mediocre). But this should not be a concern: given that anonymous FTP users cannot see or download the material they have uploaded, our German hacker would be thwarted in his attempt to use this FTP server as a distribution mechanism. Also, bittorrent has supplanted using pilfered anonymous FTP servers in the modern day.

There are also [somewhat lame] denial-of-service attacks: someone could, for example, fill the up the disk space, preventing others from uploading.

There is no encryption on the FTP uploads. If the content is sensitive, this may not be the appropriate solution.

Can the server be hacked? Can someone break in through one of the services and own the machine? I suspect the likelihood is low: there are only 2 services running: FTP & ssh.

  • The only user who can ssh in is the ubuntu user (for the sshd configuration requires ssh keys to log in, and ubuntu is the only user that has keys).
  • The FTP service is using an FTP server that has been built for security.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Rajan Agaskar

New Rails, Ruby patches. Download them.

Rajan Agaskar
Monday, November 12, 2012

Helps

Adding an “external” dependency

The heroku_san gem used to depend on the Heroku CLI gem, ‘heroku’ which has been sunsetted in favor of the Heroku Toolbelt. What’s a reliable way of including this dependency in the gem library?

Interestings

Smallest Federated Wiki

Ward Cunningham, inventor of the Wiki, has been working on a sequel called “Smallest Federated Wiki”. It’s packed with novel ideas about collaboration, markup, mobile emphasis, etc.

Best resources so far:
Presentation at RealTimeConf

videos:

http://wardcunningham.github.com/

New Rails and Ruby patches

patch 327 is avail. for Ruby: http://www.ruby-lang.org/en/news/2012/11/09/ruby19-hashdos-cve-2012-5371/

rails 3.2.9 is out this morning: https://github.com/rails/rails/tree/3-2-stable

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Matthew Kocher

Service Oriented Foreman

Matthew Kocher
Friday, November 9, 2012

I’m a big fan of David Dollar’s foreman for starting up everything you need to run an app. These days were seeing a number of projects that rely on multiple ruby apps with seperate gemfiles to have a usuable development environment.

On one project recently we had three external services which we did not want to depend on for development. We wrote a tiny rails app for each, which had json endpoints, models for fake data, and used Rails Admin almost exclusively for the UI. This was great, but starting each one by hand was a chore, and foreman didn’t want to respect the individual gemfiles.

The first thing that makes this dificult is bundler, which attempts to be helpful and make sure your gemset is still in effect when you shell out. How it does this is an ugly or beautiful hack, depending on your point of view.

    1.9.3p194 :001 > ENV['RUBYOPT']
    => nil
    1.9.3p194 :002 > require 'bundler'
    => true
    1.9.3p194 :003 > Bundler.require
    => [...]
    1.9.3p194 :004 > ENV['RUBYOPT']
    => "-I/Users/mkocher/.rvm/gems/ruby-1.9.3-p194@soloist/gems/bundler-1.2.0.rc.2/lib -rbundler/setup"

As you can see, Bundler has set RUBYOPT to load itself every time you shell out. We can prevent this from happening by using Bundler.with_clean_env.

    1.9.3p194 :005 > Bundler.with_clean_env { ENV['RUBYOPT'] }
    => nil

Better! But we’re not out of the woods yet.

RVM has recently started including rubygems-bundler in the global gemset. I with they hadn’t, but I also don’t want to tell people to uninstall it every time they get a new workstation.

To prevent rubygems-bundler from trying to keep you in your gemset, you’ll want to add a NOEXEC=skip to your environment.

With ruby, the cleanest way to do this is to include the env hash in your call to system:

  system({'NOEXEC'=>'skip'}, "rake -T")

Putting this all together, we made a script called run_app which looks like

    #!/usr/bin/env ruby
    require 'bundler'

    cmd = %Q{bash -lc "cd ../#{ARGV[0]} && source #{ENV['rvm_path']}/scripts/rvm && exec rackup config.ru -p #{ARGV[1]}"}

    Bundler.with_clean_env do
      system({'NOEXEC'=>'skip'}, cmd)
    end

We call this from our main project, and can pass it a directory and the port we want it to run on. foreman start now gives us an entire development environment nicely logging to one terminal.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mark Rushakoff

Dealing with issues in third-party libraries

Mark Rushakoff
Friday, November 9, 2012

Sometimes, despite your best efforts and despite following the documentation, the third-party library you chose for a task just won’t cooperate. Maybe it crashes, or maybe it produces the wrong output, or maybe you didn’t check the license up-front and you’re just now finding out you can’t use that library. What can you do?

An ounce of prevention

Before you run into this problem of the failing library, one of the best ways to defend against unpredicted shortcomings in external libraries is to write your own abstraction layer around it. That way, if you do need to swap out the library, you can only make small changes to your wrapper instead of doing a search-and-replace across your whole application.

Is it always appropriate to wrap every third-party library? No. For example, if you need to calculate a particular type of checksum in only one spot in your application, you probably don’t need to abstract that library. Likewise, most web applications wouldn’t gain anything by abstracting jQuery or Zepto — it is assumed that those libraries are a hard dependency in the app, like Rails might be on a backend project.

The intuition of when wrapping a library is appropriate will come with time and experience; but as a rule of thumb, the more places you call that library in your application, the more appropriate it is to abstract away the library’s API.

Find an alternative, equivalent library

Most libraries out there have at least a couple alternative implementations from different parties. Try searching for jquery calendar plugin, for instance. The current top result on Google is a list of 30 different calendar implementations.

If you’re on a spike and figuring out which library to use for a particular piece of functionality, swapping out a library is usually easy and obvious. However, if much of your application already depends on a particular library, swapping out that library may potentially be very painful if you haven’t already written an abstraction layer. And if you don’t yet know which alternative library is most appropriate, then reimplementing the internals of the wrapper a couple times may very well be less painful than going through multiple iterations of search-and-replace throughout your entire application.

Implement the library’s functionality yourself

Reimplementing a library yourself can be very expensive, depending on the library. However, you gain the advantage of having a library that does exactly what you need. And if your client agrees to it, you can even consider releasing your implementation into the wild as another open-source solution.

The middle ground: find a lower-level library

If you do need to reimplement a library, you don’t necessarily need to rewrite the whole implementation from scratch. The trick here is finding an appropriate lower-level library.

Here are a couple examples of what I mean by utilizing a lower-level library:

  • You’re using a Javascript charting library that supports scatter plots and bar charts, but you need logarithmic scales and pie charts. D3.js gives you the tooling you need to draw practically any kind of chart.
  • You are using a framework that generates sprite sheets from separate images and appropriate CSS to use those sprite sheets, but it doesn’t update the CSS output, even when you force it to recompile. Drop down to a tool like sprite-factory where you precisely control the generated output as a function of sprite position and sprite sheet dimensions, etc.

It’s easy to look at those examples and say “Of course! I wouldn’t dream of implementing a way to generate sprite sheets without using an existing library.” However, it’s also very easy to end up writing large features from scratch without considering existing libraries that don’t completely solve your problem but only get you partway there.

Stay on your toes when it comes to integrating with other libraries. Working around an occasional shortcoming is well within “normal” usage of a third-party library, but if that library regularly gets in your way, hopefully you don’t find yourself completely locked in to that library.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Ash Hogan

DaisyBill is transforming the workers comp market and needs you!

Ash Hogan
Friday, November 9, 2012

At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring.

Daisybill, a current Pivotal Labs client, is making it their mission to transform the workers’ comp market so that injured workers’ receive the best medical treatment.

With the 1,000’s of state- specific regulations that constantly change, workers’ compensation medical billing is not an easy task. In fact, it’s so difficult to get paid that 75% of Texas physicians won’t treat injured workers citing billing complexities and 40% of workers’ comp bills submitted in California are never paid.

DaisyBill simplifies the workers’ comp billing process so that anyone can be a workers’ comp billing expert. DaisyBill’s e-billing solution for workers’ comp increases revenue and decreases A/R by making the process extraordinarily easy and efficient.

DaisyBill are hiring; here’s why you want to work there:


.

DaisyBill

Is a small team with solid financial backing, led by an entrepreneurial team with deep domain expertise.

Our development process is collaborative and emphasizes sustainable coding practices like domain-driven design, test-driven development, pair programming, continuous integration, and smart design decisions. We have state-of-the-art continuous integration and continuous deployment infrastructure.

Our product is relatively new (we started development in May 2012) which has allowed us to use new technology and we didn’t have build around a ‘legacy’ system.

Currently we are working out of Pivotal Labs NYC, but very soon we will be moving into our own loft around the corner from Union Square.

Our product is based on open-sourced platforms. We have done a substantial amount of open source work and are excited about future open source contributions.

You may be a good fit if you:

  • Have 3+ years experience with Ruby on Rails
  • Experience with test-driven development (”TDD”)
  • Interest in (or experience with) pair-programming
  • Have strong grounding in OOP and SOA principles
  • Git/Github.
  • Understand that hard work is a prerequisite for success
  • Ability to coach less experienced developers

What you will do

  • Develop new user facing features for our incredibly engaged customer base
  • Lead a team of developers
  • Work closely with the product owners to mold the future of the DaisyBill

What DaisyBill offers…

  • Startup culture
  • Flexible hours
  • Remote possibilities
  • Laid back environment
  • Casual dress
  • Competitive salary

How to apply

Email a copy of your resume, including the position you wish to apply for. Principals only please! Or apply on our site.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Justin Richard

[Standup][SF] 11/07/12: CSS tech talk at AirBnB tonight

Justin Richard
Wednesday, November 7, 2012

Events

  • Nicole Sullivan: OOCSS and Preprocessors in a tree, K-I-S-S-I-N-G

Hosted tech talk at AirBnB tonight

https://www.airbnb.com/meetups/q8daawbyx-tech-talk-nicole-sullivan

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Charlie Springer

Tracker Screencast: Release Markers

Charlie Springer
Tuesday, November 6, 2012

What’s a release? For us at Tracker it’s a marker in your backlog that represents the most important milestones. As you can see in the screencast, creating a release marker is just like making a story.

It’s that mysterious one on the end.

In a conversation with Joanne, she mentioned (in a delightful British accent), “The most key point of all is that the release marker should follow the stories planned for that milestone.” Here at Tracker we also use release markers, like bookmarks, to help organize the Icebox–for example: blocked or upcoming features.

Note: The Releases panel only shows scheduled releases – so no releases in the Icebox. To see all releases use this in the Search box type:Release.

Marlena thoroughly covered releases in the Agile Continuum, it would be hard to top her blogging prowess so here’s an excerpt:

While XP and Agile brought us out of the dark ages of big-bang releases in favor of smaller, more frequent releases, there are now varying flavors of frequent releases. In XP and Scrum, releases are typically associated with the end of an iteration, but they don’t necessarily have to be. On the Tracker team, we focus on flexibility within an iteration. This is part of the logic behind Tracker’s release markers. The release markers have a date, but that date does not have to coincide with the end of an iteration, neither is the marker tied to a certain set of stories. We have Epics for that. You can read more about both Epics and Releases here.

Learn more about releases here.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Reed Kennedy

Using Open Directory Authentication in Splunk

Reed Kennedy
Tuesday, November 6, 2012

Splunk is capable of authenticating users against LDAP, including Apple’s Open Directory.

To configure Splunk to authenticate against Apple’s Open Directory, start by logging into Splunk and creating a new LDAP strategy by navigating to the following:
Manager → Access controls → Authentication method

  • Check LDAP
  • Click Configure Splunk to use LDAP and map groups
  • Click New
  • Enter the below settings:

    LDAP strategy name: opendirectory

    Host: opendirectory.sf.pivotallabs.com
    Port: 389
    SSL: unchecked
    Bind DN: uid=diradmin,cn=users,dc=opendirectory,dc=sf,dc=pivotallabs,dc=com
    Bind DN Password: Open Directory diradmin password
    Confirm Password: Open Directory diradmin password

    User base DN: cn=users,dc=opendirectory,dc=sf,dc=pivotallabs,dc=com
    User base filter: blank
    User name attribute: uid
    Real name attribute: cn
    Group mapping attribute: uid

    Group base DN: cn=groups,dc=opendirectory,dc=sf,dc=pivotallabs,dc=com
    Static group search filter: blank
    Group name attribute: cn
    Static member attribute: memberuid
    Nested groups: unchecked

    Dynamic member attribute: blank
    Dynamic group search filter: blank

  • Click Save
  • Click Map groups
  • Select the group containing the people who should have access (in our case, “admin”)
  • Click add all >>
  • Click Save
  • Test by trying to log in as an LDAP / OD user from the admin group

Done!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Kyriacos Souroullas

[Standup][SF] 11/06/12: BART & Internet Don’t mix well

Kyriacos Souroullas
Tuesday, November 6, 2012

Helps

  • What’s the best mobile Internet service for BART commute to Walnut Creek?

Interestings

  • Git autocomplete for g

If you use g as a shorthand for git, you can have it tab complete commands and branches just like git by running:

complete -o default -o nospace -F _git g

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Kyriacos Souroullas

[Standup][SF] 11/05/12: A Lite Monday

Kyriacos Souroullas
Monday, November 5, 2012

Helps

  • Metrics for resque?

What are people using for monitoring their resque workers and/or jobs?

For example, knowing:

  • total # of jobs queued
  • min/max/mean/median time in queue
  • min/max/mean/median running time
  • etc…
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (780)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (20)
  • cucumber (20)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >