Last active
August 4, 2023 14:37
-
-
Save midweste/2317e22e8ea2f95533eb2f62d594af2a to your computer and use it in GitHub Desktop.
Install sentry onpremise with nginx proxy, self-signed certificates and letsencrypt on fresh Ubuntu 20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Install sentry onpremise with nginx proxy, self-signed certificates and letsencrypt on Ubuntu 20 | |
# | |
# CHANGELOG | |
# 20200929 - Added mozilla ssl configuration https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1d&guideline=5.6 | |
# 20200929 - Added diffie-helman generation | |
# 20200928 - Initial version | |
# | |
# TODO | |
# move nginx.conf to home directory | |
# setup mail vars echo into .env | |
# setup cron certbot autorenew | |
# | |
# RESOURCES | |
# https://www.scaleway.com/en/docs/configure-sentry-server-on-scaleway/ | |
# https://rtfm.co.ua/en/sentry-running-self-hosted-errors-tracking-system-on-an-aws-ec2/ | |
# https://r.je/guide-lets-encrypt-certificate-for-local-development | |
# https://linuxize.com/post/secure-nginx-with-let-s-encrypt-on-ubuntu-18-04/ | |
if [ "$(id -u)" == "0" ]; then | |
echo "This script should not be run as root" 1>&2 | |
exit 1 | |
fi | |
echo "Install for sentry onpremise with nginx proxy, self-signed certificates and letsencrypt on Ubuntu 20" | |
echo "" | |
echo "Before starting installation:" | |
echo "-fresh install of Ubuntu 20" | |
echo "-hostname correctly set https://www.cyberciti.biz/faq/ubuntu-20-04-lts-change-hostname-permanently/" | |
echo "-at least 6GB of memory available in swap or otherwise" | |
echo "-timezone configured via sudo dpkg-reconfigure tzdata" | |
echo "-port forwarding for nginx:" | |
echo "-- sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT" | |
echo "-- sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT" | |
echo "-- sudo netfilter-persistent save" | |
echo "-if you want geoip support, put the GeoLite2-City database in ~/geoip/GeoLite2-City.mmdb" | |
echo "" | |
read -p "Ready to install? [n] " CONFIRMED | |
if [ "${CONFIRMED}" != 'y' ];then | |
echo "Exiting" | |
exit 2 | |
fi | |
read -p "Enter the server name or fqdn for this installation. " SERVERNAME | |
if [ -z "${SERVERNAME}" ];then | |
echo "Servername is required" | |
exit 2 | |
fi | |
# install vars | |
WORKINGDIR="${HOME}" | |
INSTALLDIR="sentry" | |
SENTRYDIR="${WORKINGDIR}/${INSTALLDIR}" | |
#SERVERNAME="sentry" | |
SENTRYVERSION="releases/20.9.0" | |
NOW=$(date '+%Y%m%d%H%M%S') | |
# some prereqs | |
sudo apt-get update | |
sudo apt-get install -y git dialog apt-utils nano cron iputils-ping net-tools | |
# set hosts to servername | |
sudo sed -i "s/127.0.1.1 /127.0.1.1 ${SERVERNAME} /g" /etc/hosts | |
#sudo sed -i "s/127.0.0.1 /127.0.0.1 ${SERVERNAME} /g" /etc/hosts | |
# docker-ce docker-compose install | |
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common | |
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - | |
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | |
sudo apt-get update | |
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose | |
# move docker folder to home directory | |
sudo service docker stop | |
[ -d "${HOME}/docker" ] && sudo mv "${HOME}/docker" "${HOME}/docker_${NOW}" | |
sudo mv /var/lib/docker "${HOME}/" | |
sudo ln -s "${HOME}/docker" /var/lib/docker | |
sudo service docker start | |
# sentry on premise install | |
cd "${WORKINGDIR}" | |
git clone https://github.com/getsentry/onpremise.git "${INSTALLDIR}" | |
cd "${INSTALLDIR}" | |
git checkout ${SENTRYVERSION} | |
if [ -f "${HOME}/geoip/GeoLite2-City.mmdb" ]; then | |
cp "${SENTRYDIR}/sentry/sentry.conf.example.py" "${SENTRYDIR}/sentry/sentry.conf.py" | |
echo "GEOIP_PATH_MMDB = '/geoip/GeoLite2-City.mmdb'" | tee -a "${SENTRYDIR}/sentry/sentry.conf.py" | |
cp "${SENTRYDIR}/docker-compose.yml" "${SENTRYDIR}/docker-compose.yml.${NOW}" | |
sed -i "s/ - '.\/sentry:\/etc\/sentry'/ - '.\/sentry:\/etc\/sentry'\n - '${HOME//\//\\/}\/geoip:\/geoip'/g" "${SENTRYDIR}/docker-compose.yml" | |
fi | |
cd "${SENTRYDIR}" | |
sed -i "s/MIN_RAM=2400/MIN_RAM=0/g" "./install.sh" | |
touch "./.env" | |
sudo bash "./install.sh" | |
# install nginx | |
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common nginx | |
# self signed certs and diffie-hellman | |
# https://gist.github.com/cecilemuller/9492b848eb8fe46d462abeb26656c4f8 | |
mkdir -p "${WORKINGDIR}/certs/selfsigned" | |
cd "${WORKINGDIR}/certs/selfsigned" | |
## strong diffie-hellman group | |
openssl dhparam -out dhparam.pem 2048 | |
## certificate authority | |
openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA" | |
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt | |
## domain name certificate | |
echo "authorityKeyIdentifier=keyid,issuer | |
basicConstraints=CA:FALSE | |
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment | |
subjectAltName = @alt_names | |
[alt_names] | |
DNS.1 = localhost | |
DNS.2 = ${SERVERNAME}" | tee "./settings.ext" | |
openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local" | |
openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile "./settings.ext" -out localhost.crt | |
sudo chown root:root -R "${WORKINGDIR}/certs" | |
# create server wide .well-known | |
mkdir -p "${WORKINGDIR}/nginx/.well-known/acme-challenge" | |
sudo chgrp www-data "${WORKINGDIR}/nginx" | |
sudo chmod g+s "${WORKINGDIR}/nginx" | |
echo "test" | tee "${WORKINGDIR}/nginx/.well-known/acme-challenge/test" | |
# install certbot https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04 | |
sudo ln -s "${WORKINGDIR}/certs" /etc/letsencrypt | |
sudo add-apt-repository -y ppa:certbot/certbot | |
sudo apt-get install -y certbot python3-certbot-nginx | |
# configure nginx to use new cert/response to .well-known requests | |
sudo cp /etc/nginx/sites-available/default "/etc/nginx/sites-available/default_${NOW}" | |
echo "# generated 2020-09-29, Mozilla Guideline v5.6, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration | |
# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1d&guideline=5.6 | |
server { | |
listen 80 default_server; | |
listen [::]:80 default_server; | |
return 301 https://\$host\$request_uri; | |
} | |
server { | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
server_name ${SERVERNAME}; | |
ssl_certificate ${WORKINGDIR}/certs/selfsigned/localhost.crt; | |
ssl_certificate_key ${WORKINGDIR}/certs/selfsigned/localhost.key; | |
# Stubs for Letsencrypt certificates | |
#ssl_certificate ${WORKINGDIR}/certs/live/${SERVERNAME}/fullchain.pem; | |
#ssl_certificate_key ${WORKINGDIR}/certs/live/${SERVERNAME}/privkey.pem; | |
# verify chain of trust of OCSP response using Root CA and Intermediate certs | |
#ssl_trusted_certificate ${WORKINGDIR}/certs/live/${SERVERNAME}/chain.pem; | |
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam | |
ssl_dhparam ${WORKINGDIR}/certs/selfsigned/dhparam.pem; | |
# intermediate configuration | |
ssl_protocols TLSv1.2 TLSv1.3; | |
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; | |
ssl_prefer_server_ciphers off; | |
# HSTS (ngx_http_headers_module is required) (63072000 seconds) | |
add_header Strict-Transport-Security \"max-age=63072000\" always; | |
# OCSP stapling | |
ssl_stapling on; | |
ssl_stapling_verify on; | |
# replace with the IP address of your resolver | |
resolver 8.8.8.8; | |
location /.well-known/acme-challenge/ { | |
allow all; | |
root ${WORKINGDIR}/nginx/; | |
default_type \"text/plain\"; | |
try_files \$uri =404; | |
} | |
location / { | |
proxy_pass http://localhost:9000; | |
add_header Strict-Transport-Security \"max-age=31536000\"; | |
} | |
}" | sudo tee /etc/nginx/sites-available/default | |
sudo nginx -t | |
sudo systemctl reload nginx | |
# setup sentry to use nginx proxy | |
sudo cp "${SENTRYDIR}/sentry/sentry.conf.py" "${SENTRYDIR}/sentry/sentry.conf.py.${NOW}.bak" | |
sudo sed -i "s/# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')/SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')/g" "${SENTRYDIR}/sentry/sentry.conf.py" | |
sudo sed -i "s/# SESSION_COOKIE_SECURE = True/SESSION_COOKIE_SECURE = True/g" "${SENTRYDIR}/sentry/sentry.conf.py" | |
sudo sed -i "s/# CSRF_COOKIE_SECURE = True/CSRF_COOKIE_SECURE = True/g" "${SENTRYDIR}/sentry/sentry.conf.py" | |
sudo sed -i "s/# SOCIAL_AUTH_REDIRECT_IS_HTTPS = True/SOCIAL_AUTH_REDIRECT_IS_HTTPS = True/g" "${SENTRYDIR}/sentry/sentry.conf.py" | |
echo "system.url-prefix: \"https://${SERVERNAME}\"" | sudo tee -a "${SENTRYDIR}/sentry/config.yml" | |
#sudo systemctl restart sentry | |
# set sentry to start as service | |
echo "[Unit] | |
Description=Sentry service | |
Requires=docker.service | |
After=docker.service | |
[Service] | |
Restart=always | |
WorkingDirectory=${SENTRYDIR} | |
# Compose up | |
# ExecStart= | |
ExecStart=/usr/bin/docker-compose -f docker-compose.yml up | |
# Compose down, remove containers and volumes | |
ExecStop=/usr/bin/docker-compose -f docker-compose.yml down -v | |
[Install] | |
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/sentry.service | |
sudo systemctl start sentry | |
sudo systemctl status sentry | |
sudo systemctl enable sentry | |
# wrapup/next steps | |
echo "" | |
echo "Installation complete" | |
echo "Browse to https://${SERVERNAME} or http://localhost:9000" | |
echo "Configure additional settings in:" | |
echo "${SENTRYDIR}/.env" | |
echo "${SENTRYDIR}/sentry/config.yml" | |
echo "${SENTRYDIR}/sentry/sentry.conf.py" | |
echo "See https://develop.sentry.dev/config/ for more details" | |
echo "" | |
echo "Test to see if your server is accessible to letsecrypt at: http://${SERVERNAME}/.well-known/acme-challenge/test" | |
echo "To request a real ssl certificate, use the following command and replace the self signed certificates in /etc/nginx/sites-available/default:" | |
echo "sudo certbot certonly --agree-tos --webroot -w ${WORKINGDIR}/nginx/ -d ${SERVERNAME}" | |
# todo: write into config | |
# SENTRY_EMAIL_HOST=smtp.mailtrap.io | |
# SENTRY_EMAIL_PORT=2525 | |
# SENTRY_EMAIL_PASSWORD=password | |
# SENTRY_EMAIL_USER=username | |
# SENTRY_EMAIL_USE_TLS="true" | |
# SENTRY_SERVER_EMAIL="no-reply@${SERVERNAME}" | |
# SENTRY_ENDPOINT="https://${SERVERNAME}" | |
# SENTRY_URL_PREFIX="https://${SERVERNAME}" | |
# https://certbot.eff.org/docs/using.html#nginx | |
#sudo certbot renew --dry-run | |
# sudo certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment