mastodon

by bootsy
5 deployments · 5 still active · last rev. 12 days ago

-- THIS SCRIPT IS A WORK IN PROGRESS --
-- I CANNOT GUARANTEE FUNCTIONALITY --

This attempts to set up a Mastodon instance on your linode.
Note that this script requires user interaction, though it's been slightly optimized to keep it minimal.
You *MUST* log into the system using Lish and then do `screen -r stackScript` to interact with the script!

Compatible with: Ubuntu 18.04 LTS
						#!/bin/bash
#
# <UDF name="username" label="User Name">
# <UDF name="password" label="Password for user">
# <UDF name="pubkey" label="Public Key for User" example="ssh-rsa AA... user@host">
# <UDF name="host_name" label="Domain" example="example.com">
# <UDF name="email_addr" label="Email address" example="you@example.com">
# <UDF name="git_repo" label="Mastodon .git" default="https://github.com/tootsuite/mastodon.git" example="leave empty for vanilla masto">
# <UDF name="use_rc" label="Use latest release candidate instead of master branch" default="yes" oneOf="yes,no">
apt install screen
if [ -z "$STY" ]; then exec screen -dm -S stackScript /bin/bash "$0"; fi
source <ssinclude StackScriptID=1>  # Common bash functions

function log {
    echo "$(date '+%D %T') $1"
}
function as_user {
    su -l -c "$1" $USERNAME
}
function as_masto {
    su -l -c "$1" mastodon
}

cd /tmp

# Set up Hostname
if [ -z "${HOST_NAME}" ]; then
    HOST_NAME="$(get_rdns_primary_ip)"
fi
echo "$HOST_NAME" > /etc/hostname
hostname -F /etc/hostname

# Updating System, installing essentials
log "update system"
system_update
log "install essentials"
aptitude -y install \
    build-essential \
    zlib1g-dev \
    libssl-dev \
    libreadline5-dev \
    openssh-server \
    libyaml-dev \
    libcurl4-openssl-dev \
    libxslt-dev \
    libxml2-dev \
    python-software-properties \
    git-core \ 
    curl
goodstuff
log "essentials installed!"

# setup Postfix
log "set up postfix"
postfix_install_loopback_only


# Installing PostgreSQL 9.2 and nginx
log "Installing PostgreSQL 9.2 and nginx"
echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -sc`-pgdg main" > /etc/apt/sources.list.d/pgdg.list
wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
# nginx
wget -q -O - http://nginx.org/keys/nginx_signing.key | apt-key add -
cat <<EOT > /etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/ubuntu/ `lsb_release -sc` nginx
deb-src http://nginx.org/packages/ubuntu/ `lsb_release -sc` nginx
EOT

aptitude update
aptitude -y install postgresql-9.2 nginx
rm -v /etc/nginx/conf.d/*
ervice nginx start


# Creating User
log "Create User '${USERNAME}'"
echo "${USERNAME}:${PASSWORD}:1000:1000::/home/${USERNAME}:/bin/bash" | newusers
cp -a /etc/skel/.[a-z]* /home/$USERNAME
mkdir /home/${USERNAME}/.ssh
echo $PUBKEY >> /home/${USERNAME}/.ssh/authorized_keys
chown -R $USERNAME /home/$USERNAME
echo "${USERNAME} ALL=(ALL) ALL" >> /etc/sudoers


## MASTODON INSTALL STUFF START ## 
# Adding Fail2Ban
apt install -y fail2ban
if [ -n "$EMAIL_ADDR" ]; then
    echo "[DEFAULT]" >> /etc/fail2ban/jail.local 
    echo "destemail = $EMAIL_ADDR" >> /etc/fail2ban/jail.local 
    echo "sendername = Fail2Ban.$HOST_NAME" >> /etc/fail2ban/jail.local 
fi

cat >> /etc/fail2ban/jail.local << EOF
[sshd]
enabled = true
port = 22

[sshd-ddos]
enabled = true
port = 22
EOF
systemctl restart fail2ban

# iptables

apt install -y iptables-persistent

cat >> /etc/iptables/rules.v4 << EOF
*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

#  Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT
EOF
iptables-restore < /etc/iptables/rules.v4

# install node and stuff

curl -sL https://deb.nodesource.com/setup_8.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 install -y \
    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 libgdbm5 libgdbm-dev \
    nginx redis-server redis-tools postgresql postgresql-contrib \
    certbot python-certbot-nginx yarn libidn11-dev libicu-dev libjemalloc-dev

# add mastodon user
adduser --disabled-login mastodon 

# Installing rbenv
log "setting up rbenv"
as_masto "git clone git://github.com/sstephenson/rbenv.git ~/.rbenv"
as_masto "echo 'export PATH=\"\$HOME/.rbenv/bin:\$PATH\"' >> ~/.profile"
as_masto "echo 'eval \"\$(rbenv init -)\"' >> ~/.profile"
as_masto "git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build"
log "Installing Ruby 2.6.1"
as_masto "RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.1 && rbenv rehash && rbenv global 2.6.1"
as_masto "gem update --system"
as_masto "echo 'gem: --no-document' > ~/.gemrc && gem i bundler"


# Setting up Environment
cat >> /etc/environment << EOF
RAILS_ENV="production"
RACK_ENV="production"
EOF

# Setting up postgres
sudo -u postgres psql -c "CREATE USER mastodon CREATEDB;"

# Downloading mastodon
as_masto "git clone $GIT_REPO ~/live"

case "$USE_RC" in
    "yes")
       as_masto "cd ~/live && bash -c \"git checkout \$(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)\""
    ;;
    "no")
    ;;
esac

# install bundle and run setup
su -l mastodon <<EOSU
cd ~/live
bundle install \
  -j\$(getconf _NPROCESSORS_ONLN) \
  --deployment --without development test
yarn install --pure-lockfile
EOSU

## SETUP SCRIPT
# mastodon's install script is hot garbage
# it doesn't let you set defaults and tell it to prompt for everything else
# sad face

echo "Answers are usually the defaults, and you're not running in docker."
echo ""
as_masto "cd ~/live && RAILS_ENV=production bundle exec rake mastodon:setup"

# set up nginx
sed -i '/http {/,$d' /etc/nginx/nginx.conf
cat >> /etc/nginx/nginx.conf << EOF
http {
        ##
        # Basic Settings
        ##
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}
EOF
mkdir /etc/nginx/sites-enabled/
mkdir /etc/nginx/sites-available/

cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
sed -i "s/example.com/$HOST_NAME/g" /etc/nginx/sites-available/mastodon

# add ssl
systemctl stop nginx 
certbot certonly --standalone -d $HOST_NAME
sed -i "s/# ssl_certificate/ssl_certificate/g" /etc/nginx/sites-available/mastodon
systemctl restart nginx 

# enable systemd 
cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
systemctl start mastodon-web mastodon-sidekiq mastodon-streaming
systemctl enable mastodon-web mastodon-sidekiq mastodon-streaming

## MASTODON INSTALL STUFF END ## 
# Finishing
restartServices
log "StackScript Finished!"
echo "StackScript completed. I may need a reboot..." | wall