Hosting Your Own Ghostbin in 2019

I used a basic VM to get this going. You can likely do it with less. It has 2GBs of RAM, 80GBs of disk space and 2x 2.4GHz CPU cores. It was actually pretty easy to install, actually quite a bit easier then I remember.

Installing GhostBin
  1. Install your operating system. I used Ubuntu 18.04 Server.

  2. Install Go:

    cd /usr/local
    wget https://dl.google.com/go/go1.12.8.linux-amd64.tar.gz
    tar -C /usr/local -xzf go1.12.8.linux-amd64.tar.gz

    Add to the bottom of your /etc/profile file with:

    export PATH=$PATH:/usr/local/go/bin

    You can either also run that at your command prompt or logout and log back in.

  3. Install Mercurial and Python Pygments:

    apt install mercurial python-pygments
  4. Install ansi2html:

    apt install python-pip
    pip install ansi2html
  5. Install Git:

    cd /usr/local/src
    apt install autoconf libssl-dev zlib1g-dev libcurl4-openssl-dev tcl-dev gettext
    wget https://github.com/git/git/archive/v2.22.1.tar.gz
    tar zxvf v2.22.1.tar.gz
    cd git-2.22.1/
    make configure
    ./configure --prefix=/usr
    make -j2
    make install
  6. I recommend creating a new user to run your GhostBin code under:

    adduser ghostbin
  7. You should also set a password on the new user account using passwd ghostbin.

  8. Login as your new user account and add the following to your ~/.bashrc file:

    export GOPATH=$HOME/go
  9. Save and exit the file and run source ~/.bashrc.

  10. Next obtain the source code for GhostBin (login as your new user first):

    mkdir -p ~/go/src
    cd $HOME/go/src
    mkdir github.com
    cd github.com
    git clone https://github.com/DHowett/spectre.git
    cd spectre/
  11. At this point your full path should be something like - /home/ghostbin/go/src/github.com/ghostbin.

  12. Run go get.

  13. Run go build.

  14. Run which pygmentize. It should return /usr/bin/pygmentize. If not, no problem, just copy the path.

  15. You'll also want to run which ansi2html which should return /usr/local/bin/ansi2html. Again, if it doesn't no big deal, just copy the path.

  16. Now exit the languages.yml file and update the path for pygmentize which should be on line 6. Also update the path for ansi2html which should be on line 23. Save and exit. Here's my languages.yml up to line 25 to give you an example:

    formatters:
      default:
        name: default
        func: commandFormatter
        args:
        - /usr/bin/pygmentize
        - "-f"
        - html
        - "-l"
        - "%LANG%"
        - "-O"
        - "nowrap=True,encoding=utf-8"
      text:
        name: text
        func: plainText
      markdown:
        name: markdown
        func: markdown
      ansi:
        name: ansi
        func: commandFormatter
        args:
        - /usr/local/bin/ansi2html
        - "--naked"
      iphonesyslog:
  17. Next we'll need to build a CSS file which will give color to the pastes:

    pygmentize -f html -S $STYLE > public/css/theme-pygments.css

    You can choose from several styles/color themes:

    - monokai
    - manni
    - rrt
    - perldoc
    - borland
    - colorful
    - default
    - murphy
    - vs
    - trac
    - tango
    - fruity
    - autumn
    - bw
    - emacs
    - vim
    - pastie
    - friendly
    - native

    I used monokai:

    pygmentize -f html -S monokai > public/css/theme-pygments.css
  18. If all went well all that is left to do is to start the service:

    ./spectre
  19. Here's an screenshot of my install: GhostBin

  20. I would also recommend running the binary with the --help flag:

    $ ./spectre --help
    Usage of ./spectre:
      -addr string
            bind address and port (default "0.0.0.0:8080")
      -alsologtostderr
            log to standard error as well as files
      -log_backtrace_at value
            when logging hits line file:N, emit a stack trace
      -log_dir string
            If non-empty, write log files in this directory
      -logtostderr
            log to standard error instead of files
      -rebuild
            rebuild all templates for each request
      -root string
            path to generated file storage (default "./")
      -stderrthreshold value
            logs at or above this threshold go to stderr
      -v value
            log level for V logs
      -vmodule value
            comma-separated list of pattern=N settings for file-filtered logging

    This allows you to see flags you can run with the binary. I run mine as such:

    ./spectre -logtostderr

    This will just log the errors to the screen.

Setting Up GhostBin w/ Nginx
  1. Install Nginx:

    apt install nginx
  2. Create a Nginx configuration file for GhostBin:

    nano /etc/nginx/sites-available/ghostbin.conf
    # Upstream configuration
    upstream ghostbin_upstream {  
         server 0.0.0.0:8080;
         keepalive 64;
    }
    
    # Public
    server {  
        listen 80;
        server_name ghostbin.YOURDOMAIN.com; # domain of my site
    
        location / {
            proxy_http_version 1.1;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header   X-NginX-Proxy    true;
            proxy_set_header   Host             $http_host;
            proxy_set_header   Upgrade          $http_upgrade;
            proxy_redirect     off;
            proxy_pass         http://ghostbin_upstream;
        }
    }

    You'll obviously want to update the server_name bit. Save and exit the file.

  3. Next we need to make a symlink so Nginx knows to load the configuration:

    cd ../site-enabled
    ln -s ../sites-available/ghostbin.conf .
  4. Restart the Nginx service:

    systemctl restart nginx

    Your GhostBin site should now be available at http://ghostbin.YOURDOMAIN.com!

Other Notes
  • Whenever I start up the binary I see:

    E0815 21:19:58.915843   19895 main.go:773] Expirator Error: open expiry.gob: no such file or directory

    This doesn't appear to be an issue and I haven't had any issues with using GhostBin thus far. There seems to be some code in main.go referencing it. It looks related to the expiration of the paste, but I don't know GoLang so I can't be sure.

    pasteExpirator = gotimeout.NewExpirator(filepath.Join(arguments.root, "expiry.gob"), &ExpiringPasteStore{pasteStore})
  • It looks like the GhostBin repository has been renamed to 'spectre'. It looks like this was done to "de-brand" it for people who want to run it themselves and separate it from GhostBin.com where I believe the developer run their own copy. See this commit.

  • You should definitely set up your install with Let's Encrypt for SSL.