Decentralized Social Network - Mastodon

in #dapp7 years ago

What is Mastodon?

Mastodon is a free, open-source social network server based on open web protocols like ActivityPub and OStatus. The social focus of the project is a viable decentralized alternative to commercial social media silos that returns the control of the content distribution channels to the people.

It's a federated social network begun in October 2016 by Eugen Rochko, a 24-year old German software engineer, as an alternative to Twitter.

  • Open-source software package;
  • Anyone with an internet-connected computer to set up an “instance”;
  • Mastodon is less like Facebook and more like email – you can have your own address;
  • Mastodon has to support “federation” to share contents between instances.

mastodon-map-1024x675.png
Map of Mastodon instances from Mastodon Network Monitoring Project, August 17, 2017

Install and run Mastodon on Ubuntu Server 16.04

As it says above, you (anyone technically) can setup your own Mastodon instance and run. First step is install dependencies to make it work. (!!! You need to have a super user (root) privilege, you should know what you are doing!!!)

  • Install dependencies as a root user and libraries to run social media and database postgresql
$ sudo su
$ curl -sL https://deb.nodesource.com/setup_6.x | bash -
$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
$ apt update
$ apt -y install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev nginx redis-server redis-tools postgresql postgresql-contrib letsencrypt yarn libidn11-dev libicu-dev 
  • Install dependencies as a non-root user
$ adduser mastodon
$ sudo su - mastodon // log in as the mastodon user 
  • Ruby is required to run Mastodon
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  • Restart shell
$ exec bash
  • Check if rbenv is correctly installed
$ type rbenv

Your Ruby environment:
Screen Shot 2018-05-19 at 11.23.01 AM.jpg

  • Install ruby-build as rbenv plugin
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
  • Enable ruby
$ rbenv install 2.5.0
$ rbenv global 2.5.0
  • node.js And Ruby Dependencies
  1. Return to mastodon user's home directory
    $ cd ~
  2. Clone the Mastodon git repository into ~/live
    $ git clone https://github.com/tootsuite/mastodon.git live
  3. Change directory to ~/live
    $ cd ~/live
  4. Checkout to the latest stable branch
    $ git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)

Screen Shot 2018-05-19 at 11.59.22 AM.jpg

  • Install bundler
    ``$ gem install bundler```
  • Use bundler to install the rest of the Ruby dependencies
    $ bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test
  • Use yarn to install node.js dependencies
    $ yarn install --pure-lockfile

$ exit // -> back to root

PostgreSQL database setup for contents

Create a user for a PostgreSQL instance:

  1. Launch psql as the postgres user
    $ sudo -u postgres psql
  2. In the following prompt
CREATE USER mastodon CREATEDB;
\q

Screen Shot 2018-05-19 at 12.22.37 PM.jpg

  • nginx web server Configuration
  1. edit configuration file to fit your environment: ex. for domain isaif.space (it would be our Mastodon instance)
    $ cd /etc/nginx/sites-available
  2. create a file name isaif.space.conf
  3. add following configuration
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80;
  listen [::]:80;
  server_name isaif.space;
  root /home/mastodon/live/public;
  # Useful for Let's Encrypt
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name isaif.space;

  ssl_protocols TLSv1.2;
  ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  ssl_certificate     /etc/letsencrypt/live/isaif.space/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/isaif.space/privkey.pem;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 8m;

  root /home/mastodon/live/public;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  add_header Strict-Transport-Security "max-age=31536000";

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
    add_header Cache-Control "public, max-age=31536000, immutable";
    try_files $uri @proxy;
  }
  
  location /sw.js {
    add_header Cache-Control "public, max-age=0";
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";
    proxy_pass_header Server;

    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  location /api/v1/streaming {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";

    proxy_pass http://127.0.0.1:4000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  error_page 500 501 502 503 504 /500.html;
}
  • Activate the configuration
$ cd /etc/nginx/sites-enabled
$ ln -s ../sites-available/isaif.space.conf

Make it secure by SSL encryption

  • configure Let’s Encrypt (free SSL)
# systemctl stop nginx // stop nginx service first
# letsencrypt certonly --standalone -d isaif.space

Screen Shot 2018-05-19 at 1.13.46 PM.jpg

Screen Shot 2018-05-19 at 5.02.01 PM.jpg

  • restart nginx server
    # systemctl start nginx
  • The letsencrypt tool will ask if you want issue a new cert, please choose that option
    $ letsencrypt certonly --webroot -d isaif.space -w /home/mastodon/live/public/
    Screen Shot 2018-05-19 at 5.12.46 PM.jpg

Now you have working nginx web server, open isaif.space with a browser:
Screen Shot 2018-05-19 at 5.14.03 PM.jpg

Mastodon Application Configuration

Now, you need to activate Mastodon instance, setup as mastodon user:

$ sudo su - mastodon
$ cd ~/live
  • Run Mastodon setup wizard:

RAILS_ENV=production bundle exec rake mastodon:setup

Screen Shot 2018-05-19 at 5.23.25 PM.jpg
...
Screen Shot 2018-05-19 at 5.26.27 PM.jpg

It takes a while...

All done! You can now power on the Mastodon server 🐘

Do you want to create an admin user straight away? Yes
Default type scope order, limit and offset are ignored and will be nullified
Creating scope :cache_ids. Overwriting existing method Notification.cache_ids.
Username: admin
E-mail: [email protected]
You can login with the password: d18443179170cdc1243d61f303a0eaec
You can change your password once you login.

Finally, you can access your live Mastodon instance by opening https://isaif.space
Screen Shot 2018-05-19 at 9.22.06 PM.jpg

You can configure your instance more.

Problem of federation and possible solutions using blockchain

Users still need to be somewhat trustful of their instance administrator. These admins have the ability to delete content and accounts on the local server, and it’s also possible that the entire federation of instances will eventually centralize around a few key servers that make the system look more similar to how Twitter works today. The specific scenario where a user wants to move to another instance without losing all of their followers is where Bitcoin’s blockchain may be helpful.

By mapping Mastodon addresses to blockchain-based identity systems, a bit more power can be removed from instance administrators. Integration with Keybase or Onename may also remove some of the confusion users have had with Mastodon addresses in the first place.

Of course, it’s still unclear how necessary the use of a blockchain will turn out to be in these sorts of digital identity systems. It’s possible that a trusted third party, such as the Electronic Frontier Foundation, could provide this sort of service for free on a centralized server. There’s also early Bitcoin developer Martti Malmi’s Identifi, which stores public data on the IPFS network.

And there is a blockchain-powered social media networking startup called Hiveway platform to address above issues based on Mastodon. It looks like to have a promising but still doesn't prove it's possibility and idea yet.

References

https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md
http://www.ethanzuckerman.com/blog/2017/08/18/mastodon-is-big-in-japan-the-reason-why-is-uncomfortable/
https://medium.com/tootsuite/how-to-start-a-mastodon-server-dea0dec56028
https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/User-guide.md#decentralization-and-federation
https://cryptoinsider.21mil.com/blockchain-may-solve-key-issue-mastodon-new-federated-twitter-alternative/
https://medium.com/we-distribute/hiveway-io-shamelessly-rips-off-of-mastodon-and-slaps-a-blockchain-on-top-for-some-reason-57b7aba3e84f