scripts/gitea-install-ubuntu2004.sh

501 lines
13 KiB
Bash
Raw Permalink Normal View History

#!/bin/bash
#############################################################
# Author: Taryel Hlontsi, 2023
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>
#############################################################
#############################################################
# SETUP SECTION, use "sudo" to run the script
#############################################################
# if set to true, ssh login only with ssh key which must(!) be configured upfront
NO_PASSWORD_SSH=true
# user for gitea, and DB password that should be entered on the initialization web page
HOST_USER='git' # better don't change it
DB_PASSWORD='PasswordGoesHere'
GITEA_URL='https://dl.gitea.com/gitea/1.19.3/gitea-1.19.3-linux-arm64'
# change the IP. If domain is used then set it here as the server name
OS_SERVER_NAME="gitea.local"
OS_IP="192.168.0.10"
OS_COUNTRY="PL"
# may be left as is
LOG_DIR="/home/${SUDO_USER}"
LOG="${LOG_DIR}/log.txt"
#############################################################
# HELPER FUNCTIONS
#############################################################
warn() {
PURPLE='\033[1;35m'
NC='\033[0m'
echo -e "${PURPLE}$1${NC}"
echo -e "WARN:\t$1" >> $LOG
}
info() {
GREEN='\033[1;32m'
NC='\033[0m'
echo -e "${GREEN}$1${NC}"
echo -e "INFO:\t$1" >> $LOG
}
trace() {
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}$1${NC}"
echo -e "TRACE:\t$1" >> $LOG
}
error() {
RED='\033[1;31m'
NC='\033[0m'
echo -e "${RED}$1${NC}"
echo -e "ERROR:\t$1" >> $LOG
}
not_set() {
count=$(grep -Pcx "$1" "$2")
code=$?
if [[ $code == 2 ]] && [[ -z "$count" ]]; then
echo "not_set() func or its caller contains a bug that has to be fixed! param1=${1} param2=${2} code=${code} count=${count}. Exiting!"
exit -1
fi
[[ $count == 0 ]] && [[ $code == 1 ]] && return 0
return 1
}
not_exist() {
if [[ ! -e "$2" ]]; then
warn "file does not exist: $2"
return 0
else
count=$(grep -Pc "$1" "$2")
code=$?
[[ $count == 0 ]] && [[ $code == 1 ]] && return 0
return 1
fi
}
configure() {
if not_exist "$1" "$3"; then
warn "setting \"$1\" is not in the file, thus won't be changed"
return 1
else
if not_set "$2" "$3"; then
sed -i "s~.*${1}.*~${2}~gi" "$3" &&
trace "\"$1\" set to \"$2\"" &&
return 0
else
warn "\"$2\" already set in \"$3\""
return 2
fi
fi
}
#############################################################
# 1 - ADD USER
#############################################################
add_user() {
info "STEP 1 Adding a user for container"
sudo adduser \
--system \
--shell /bin/bash \
--gecos 'Git Version Control' \
--group \
--disabled-password \
--home /home/git \
git
[[ $? -gt 0 ]] && { error 'Check git user setup, stopping now'; exit 1; }
info "STEP 1 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 2 - CHANGE SERVER NAME
#############################################################
change_servername() {
info "STEP 2 Changing server name to ${OS_SERVER_NAME}"
echo $OS_SERVER_NAME > /etc/hostname
hostentry="127.0.1.1\t${OS_SERVER_NAME}"
if not_set "$hostentry" "/etc/hosts"; then
echo -e "$hostentry" >> /etc/hosts
else
warn "\"$hostentry\" already set in \"/etc/hosts\""
fi
info "STEP 2 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 3 - INSTALL MARIADB
#############################################################
install_mariadb() {
info "STEP 3 Installing Maria DB"
apt-get -y install mariadb-server > /dev/null
systemctl --quiet is-active mariadb || systemctl start mariadb
systemctl --quiet is-enabled mariadb || systemctl enable mariadb
mysql -u root <<EOF
CREATE DATABASE IF NOT EXISTS gitea;
GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
ALTER USER 'root'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
FLUSH PRIVILEGES;
EOF
[[ $? -eq 0 ]] || { error 'Something went bananas while setting up a Maria DB, proceed?'; }
mysql -u root -p${DB_PASSWORD} -h localhost <<EOF
SHOW DATABASES;
SELECT User FROM mysql.user;
EOF
info "STEP 3 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 4 - INSTALL NGINX
#############################################################
install_nginx() {
info "STEP 4 Installing Nginx"
which nginx && { warn 'Nginx already installed. Since there might be other sites configured on the server, advised to proceed with manual configuration of Nginx:
- main config: /etc/nginx/nginx.conf
- sites: /etc/nginx/sites-available
- linked to: /etc/nginx/sites-enabled
- logs: /var/log/nginx'; return 1; }
KEY="/etc/ssl/private/gitea-snakeoil.key"
CRT="/etc/ssl/certs/gitea-snakeoil.crt"
trace "Generating a self signed sertificate (${KEY} and ${CRT})"
openssl req -x509 \
-nodes \
-days 2048 \
-newkey rsa:2048 \
-keyout $KEY \
-out $CRT \
-subj "/C=${OS_COUNTRY}/ST=${OS_COUNTRY}/L=${OS_COUNTRY}/O=E Corp/OU=IT/CN=${OS_SERVER_NAME}/emailAddress=info@example.com"
apt-get install -y nginx > /dev/null
systemctl --quiet is-active nginx || systemctl start nginx
ufw allow 'Nginx Full'
trace "Rewriting default /etc/nginx/nginx.conf"
cat <<EOF | tee /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 70;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
EOF
trace "Generating a new config /etc/nginx/sites-available/${OS_SERVER_NAME}.conf"
cat <<EOF | tee /etc/nginx/sites-available/${OS_SERVER_NAME}.conf
server {
listen 80;
server_name ${OS_SERVER_NAME};
return 301 https://${OS_SERVER_NAME}$request_uri;
access_log /var/log/nginx/${OS_SERVER_NAME}-access.log;
error_log /var/log/nginx/${OS_SERVER_NAME}-error.log;
}
server {
listen 443 ssl http2;
server_name ${OS_SERVER_NAME};
client_max_body_size 256m;
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 \$scheme;
ssl_certificate ${CRT};
ssl_certificate_key ${KEY};
location / {
proxy_redirect off;
proxy_pass http://localhost:3000/;
}
access_log /var/log/nginx/${OS_SERVER_NAME}-access.log;
error_log /var/log/nginx/${OS_SERVER_NAME}-error.log;
}
EOF
trace 'Making a link from sites-available to sites-enabled...'
ln -s /etc/nginx/sites-available/${OS_SERVER_NAME}.conf \
/etc/nginx/sites-enabled
nginx -t
info "STEP 4 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 5 - INSTALL GITEA
#############################################################
install_gitea() {
info "STEP 5 Installing Gitea as a binary"
trace "Downloading ${GITEA_URL}"
apt-get install -y git wget > /dev/null
wget --continue $GITEA_URL --output-document gitea
chmod +x gitea
chown git:git gitea
trace 'Creating nessesary directories with git owner'
mkdir -p /var/lib/gitea/{custom,data,log}
chown -Rv git:git /var/lib/gitea/
chmod -Rv 750 /var/lib/gitea/
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
cp --force gitea /usr/local/bin/gitea
cat <<EOF | tee /etc/systemd/system/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
DefaultDependencies=no
After=syslog.target
After=network.target
Wants=mariadb.service
After=mariadb.service
[Service]
Type=simple
User=git
Group=git
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Environment=GITEA_WORK_DIR=/var/lib/gitea/
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
trace 'Installing a systemd service'
systemctl daemon-reload
systemctl --quiet is-enabled gitea || systemctl enable gitea
systemctl restart gitea
gitea --version
info "STEP 5 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 6 - ADDITIONAL SECURITY FOR THE SERVER
#############################################################
secure_server() {
info "STEP 6 Securing the server"
trace "Installing openssh server..."
apt-get install -y openssh-server > /dev/null
systemctl --quiet is-active sshd || systemctl start sshd
systemctl --quiet is-enabled sshd || systemctl enable sshd
SSH_CFG="/etc/ssh/sshd_config"
SSH_CFG_BACK="${LOG_DIR}/sshd_config.backup"
trace "Going to rewrite ${SSH_CFG}"
trace "Backup will be here: ${SSH_CFG_BACK}"
if [[ -e "$SSH_CFG_BACK" ]]; then
warn "SSH config backup is already there!"
else
cp $SSH_CFG $SSH_CFG_BACK
cat <<EOF | tee ${SSH_CFG}
Include /etc/ssh/sshd_config.d/*.conf
PermitRootLogin no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
EOF
if $NO_PASSWORD_SSH; then
info "Disabling SSH with password completely!"
echo 'PasswordAuthentication no' >> $SSH_CFG
fi
fi
trace "Installing fail2ban..."
apt-get install -y fail2ban > /dev/null
systemctl --quiet is-active fail2ban || systemctl start fail2ban
systemctl --quiet is-enabled fail2ban || systemctl enable fail2ban
fail2ban-client status
F2B_CFG_ORIG="/etc/fail2ban/jail.conf"
F2B_CFG_COPY="/etc/fail2ban/jail.local"
if [[ -e "$F2B_CFG_COPY" ]]; then
warn "Fail2ban was already set up"
else
cp $F2B_CFG_ORIG $F2B_CFG_COPY
trace "Setting up ${F2B_CFG_COPY}"
configure 'bantime = 10m' 'bantime = 60m' $F2B_CFG_COPY
configure 'maxretry = 5' 'maxretry = 20' $F2B_CFG_COPY
fi
trace "Configuring ufw..."
ufw --force enable
ufw allow 'OpenSSH'
ufw status
info "STEP 6 done"
warn "Press enter to proceed with the next step"; read
}
#############################################################
# 7 - MAKE AN UPDATE HELPER (AS A SCRIPT)
#############################################################
create_updater() {
info 'Step 7 Create an updater for gitea (small helper utility)'
MY_HOME="/home/${SUDO_USER}"
SCRIPT='/usr/local/bin/gitea-update'
cat <<EOF | tee $SCRIPT
#!/bin/bash
user=\$(whoami)
if [[ \$user != root ]]; then
echo 'You are using a non-privileged account'
exit 1
fi
if [[ \$# -eq 0 ]]; then
echo 'Provide a web link to the bin file as an argument!'
echo "Example: gitea-update $GITEA_URL"
exit 1
else
echo "Link: \$1"
fi
mkdir -p "${MY_HOME}" > /dev/null
cd "${MY_HOME}"
gitea --version
wget --continue \$1 --output-document gitea
systemctl stop gitea
chmod +x gitea
chown git:git gitea
cp --force gitea /usr/local/bin/gitea
systemctl restart gitea
gitea --version
EOF
chmod +x $SCRIPT
trace "Updater has been created. call it 'sudo gitea-update url_to_new_version'"
info 'Step 7 done'
}
#############################################################
# RUN SECTION
#############################################################
user=$(whoami)
if [ $user != root ]; then
error "You are using a non-privileged account"
exit 1
fi
echo $(date +'%Y-%m-%d %H:%M') > $LOG
info "Hiya!"
sudo apt update
sudo apt upgrade -y
add_user
change_servername
install_mariadb
install_nginx
install_gitea
secure_server
create_updater
info "Don't forget to reboot"
info "Bye!"
info "PS. Log is here: ${LOG}"
warn "REBOOT NOW!!!"
exit 0
# restart is mandatory!!!
# if a real domain is available - a certificate can be obtained, for examle:
# sudo apt install certbot python3-certbot-nginx
# sudo certbot --nginx -d gittar.crabdance.com
# sudo certbot renew --dry-run
# gitea can be upgraded or downgraded by executing
# sudo gitea-update 'https://dl.gitea.com/gitea/1.19.3/gitea-1.19.3-linux-arm64'
# however before running it ensure there is no old gitea file in the home dir
# otherwise it will install the same version again (such 'safety' measure;))