Hacking Your Tableau Linux Server

Cracking Tableau's master Postgres account.

Hacking Your Tableau Linux Server

    Let's say you're a Data Scientist. Well, maybe not a data scientist- I mean, those online data analysis courses were definitely worth it, and you'd made it this far without being quizzed on Bayesian linear regression. So maybe you're an analyst or something, but whatever:  you use Tableau, So you must be a Scientist™.

    I've admitted a few times in the past to have purchased a personal Tableau Server license in my more ignorant years (aka a few months ago). While BI tools are great for understanding preexisting data, they don't allow us to go much further. This is is entirely by design. Sure, you can clean and slice your data and put it into a cute iFrame dashboard, but Tableau explicitly makes one thing explicitly clear in their product design choices: your data is with them, and it's not going anywhere else. Today we're going to take a step towards changing that.

    Proprietary Product Design: Crimes Against Customers

    Tableau has explicit hierarchies for information, but let's start with workbooks. Workbooks are basically spreadsheets, or in other words, collections of SQL query outputs against a data source (or multiple data sources) via a clean UI. The resulting tabular data is referred to as views. An Excel user might equate these to "sheets", but a SQL user understands that these function more like a materialized view of sorts. One would think the tables we create (from our own data) inherently belongs to us, but it doesn't. Not until you get clever.

    I realize Tableau maybe be at the top of the market for its niche.... so the things I'm claiming may seem a little farfetched. Why am I so convinced that Tableau wants to lock your data? Stay with me here, and let me count the ways.

    Common Courtesy API Visibility

    Common knowledge suggest that visible APIs attracts development talent. The more intelligent people are exposed to your product, the more like they are to contribute. What happens if we check out the API response calls in our browser when viewing  Worksheet on Tableau Server?

    Let's just agree this is all useless.

    While this level of unnecessary paranoia on Tableau's part is distasteful, let's not forget that we're dealing with a product archaic enough to preview Windows server support over Linux. The narrative begins to make sense.

    Postgres Hide and Seek

    Tableau Server is running a Postgres database; really nothing magical happening here. Well, other than the database has been renamed, protected, and obfuscated in a way that even the server owner would struggle with. The default commands to interact with PostgreSQL are hidden from server admins altogether.

    $ psql postgres -u toddbirchard -p
    The program 'psql' is currently not installed. To run 'psql' please ask your administrator to install the package 'postgresql-client-common'
    
    -------------------
    
    $ sudo -u postgres psql postgres
    sudo: unknown user: postgres
    sudo: unable to initialize policy plugin
    
    -------------------
    
    $ sudo -u toddbirchard psql postgres
    sudo: psql: command not found
    
    -------------------
    
    $ psql
    psql: could not connect to server: No such file or directory
            Is the server running locally and accepting
            connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
    
    -------------------
    
    $ pgsql
    No command 'pgsql' found, did you mean:
     Command 'psql' from package 'postgresql-client-common' (main)
    pgsql: command not found
    

    What if we do a search?

    $ locate postgresql
    
    /etc/postgresql-common
    /etc/postgresql-common/user_clusters
    /opt/tableau-postgresql-odbc_9.5.3_amd64.deb
    /opt/tableau/tableau_driver/postgresql-odbc
    /opt/tableau/tableau_driver/postgresql-odbc/psqlodbcw.so
    /opt/tableau/tableau_server/packages/bin.20181.18.0510.1418/repo-jars/postgresql-9.4.1209.jar
    /opt/tableau/tableau_server/packages/clientfileservice.20181.18.0510.1418/postgresql-9.4.1208.jar
    /opt/tableau/tableau_server/packages/lib.20181.18.0510.1418/postgresql-9.4.1208.jar
    /opt/tableau/tableau_server/packages/lib.20181.18.0510.1418/postgresql-9.4.1209.jar
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/_int.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/adminpack.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/ascii_and_mic.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/auth_delay.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/auto_explain.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/autoinc.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/btree_gin.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/btree_gist.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/chkpass.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/citext.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/cube.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/cyrillic_and_mic.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/dblink.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/dict_int.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/dict_snowball.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/dict_xsyn.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/earthdistance.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/euc2004_sjis2004.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/euc_cn_and_mic.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/euc_jp_and_sjis.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/euc_kr_and_mic.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/euc_tw_and_big5.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/file_fdw.so
    /opt/tableau/tableau_server/packages/pgsql.20181.18.0510.1418/lib/postgresql/fuzzystrmatch.so
    

    ...And so forth. There are over a thousand results. Postgres is definitely up and running, Tableau just hates you. Unfortunately for Tableau, this drove me to hate them back.

    Enter TSM: The Linux Tableau CLI

    On Linux exclusively, TSM is intended to be your one tool to configure Tableau Server. It's a fine tool, but it just so happens to omit critical information and capabilities that somebody who owns their data might want to know. At first glance, it seems innocent and helpful:

    Command Explanation
    tsm configuration [parameters] -- Set customization for Tableau Server.
    tsm customize [parameters] -- Set customization for Tableau Server.
    tsm data-access [parameters] -- Category of commands related to data-access.
    tsm help | [category] -- Help for tsm commands
    .tsm initialize [parameters] -- Initialize Tableau Server
    tsm jobs [parameters] -- Category of commands related to async jobs.
    tsm licenses [parameters] -- Category of commands related to licensing.
    tsm login [parameters] -- Sign in to the TSM agent
    tsm logout -- Sign out from the TSM agent
    tsm maintenance [parameters] -- Category of commands related to maintenance.
    tsm pending-changes [parameters] -- Category of commands for pending changes.
    tsm register [parameters] -- Register the product
    tsm reset [parameters] -- Clears the initial admin user so you can enter a new one. Once reset is completed you will need to use the tabcmd initialuser command to create a new initial user before remote users can sign in again
    tsm restart [parameters] -- Restart Tableau Server
    tsm security [parameters] -- Category of commands related to security configuration
    tsm settings [parameters] -- Category of commands related to configuration and topology settings
    tsm sites [parameters] -- Category of commands related to site import and export
    tsm start [parameters] -- Start Tableau Server
    tsm status [parameters] -- View Tableau Server status
    tsm stop [parameters] -- Stop Tableau Server
    tsm topology [parameters] -- Category of commands related to server topology
    tsm user-identity-store [parameters] -- Category of commands related to user-identity-store
    tsm version -- Displays version information.

    The Red Herring

    Tableau owns Google results, period. Any search query containing the word "Tableau" is dominated with pages of content Tableau would prefer you abide by, and of these things is the creation of a readonly user to access the Postgres database. The catch here is that the readonly user can't read all tables at all: there are certain tables reserved specifically for a Postgres tableau "Superuser", which is utterly and entirely undocumented on Linux. For all I know, I my be the first to publish an article of this sort, but let's hope not.

    First, let's see which users exist on Postgres using TSM:

    $ tsm data-access repository-access list
    
    User       Access
    Tableau    true
    Readonly   true
    

    There's that Readonly user we talked about: feel free to play around with that user to create meaningless insights if you so please. On the other hand we have a Tableau user, which happens to be a Postgres superuser. If you don't feel comfortable accessing Superuser privileges, I suggest you leave now. This is Hackers And Slackers, and we don't fuck around; especially when software to the tune of 1 thousand dollars hides our data from us.

    Operation Shock and Awe

    There's a little command called tsm configuration which lets you set some cute variables for your server. The documentation is here, but there's just one piece missing, and it's the one we need.

    Tableau may be our Postgres Superuser, but what would its password possibly be? This isn't documented anywhere. Consider this my gift to you:

    $ tsm configuration get -k pgsql.adminpassword
    145v756270d3467bv3140af5f01v5c7e4976bcee
    

    Could it be? Did Tableau intentionally prevent users from access PostgreSQL directly from command line and hide an undocumented password? Yes, it does all of those things. It's time to fuck shit up.

    Claim Ownership

    We've made it this far. The bullet is in the chamber. Go ahead and take what is rightfully yours.

    tsm data-access repository-access enable --repository-username Tableau
    --repository-password 145v756270d3467bv3140af5f01v5c7e4976bcee
    

    Just make sure port 8060 is open on your VPC and you're in. Considering that there are zero search results for accomplishing this on Linux, it looks like it's just you and me now. One of us may likely go mad with power and turn on one another. That is the way of the Sith. Welcome.

    Unspeakable treasures lie within.

    Moving on Up

    Feel free to cruise the workgroup database for now and wreck havoc. As fun as this has been, I have another trick up my sleeve. You've spent a lot of time building Worksheets and views; what if you could programmatically sync to an external database and autogenerate a schema for these views, updated on a scheduler, to source data for products you're building?

    Thats sounds a lot like what a useful product would do. Stick around, and next time we'll be beating Tableau down for everything its worth.

    Todd Birchard's' avatar
    New York City Website
    Product manager turned engineer with an ongoing identity crisis. Breaks everything before learning best practices. Completely normal and emotionally stable.

    Product manager turned engineer with an ongoing identity crisis. Breaks everything before learning best practices. Completely normal and emotionally stable.