# Install GogoCarto on Debian 10 Buster ## Server initial setup We are assuming the machine will be named **gogocarto**, and the related domain **gogocarto.fr**, your ip v4 **100.101.102.103** and ip v6 **acab:acab:acab:acab::2** DNS config : if you plan to use GogoCarto for multiples maps on subdomains as SAAS, don't forget to create a wildcard `*` A and AAAA entries so that every subdomains points to the right server Use Debian 10 Buster minimal iso for server install login as root and update system ```bash apt update && apt upgrade -y ``` Change hostname for gogocarto `hostnamectl set-hostname gogocarto` Edit /etc/hosts file and change hostname to gogocarto : `vi /etc/hosts` ```bash # nameserver config # IPv4 127.0.0.1 localhost.localdomain localhost 100.101.102.103 gogocarto gogocarto.fr # # IPv6 ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts acab:acab:acab:acab::2 gogocarto gogocarto.fr ``` ## Better security Create admin user in sudo group and add your public key in /home/admin.ssh/authorized_keys ```bash apt install sudo adduser admin usermod -aG sudo admin sudo -u admin vi /home/admin/.ssh/authorized_keys #add your key ``` Create gogocarto user (without special permissions) ```bash adduser gogocarto ``` SSH config we change port, allow only key and forbid root acces `vi /etc/ssh/sshd_config` ```bash Port 1999 # change port for something uncommon PermitRootLogin no # no login as root PermitEmptyPasswords no # empty password for ssh acces, bad idea.. AllowUsers admin gogocarto # only users admin and gogocarto shall pass MaxAuthTries 3 # only 3 tries ClientAliveInterval 60 #check activity every 60 seconds (1 minute) ClientAliveCountMax 5 # after 5 minutes without activity, kick out Protocol 2 # only more secure protocol IgnoreRhosts yes # ignore old unsecure ways to connect LogLevel INFO # log a lot of infos PasswordAuthentication no PubkeyAuthentication yes ChallengeResponseAuthentication no UsePAM no ``` Restart sshd `service sshd restart` TODO fail2ban firewall ## Install GogoCarto As admin user ```bash sudo apt-get update && sudo apt-get install -y --no-install-recommends \ bzip2 \ cron \ htop \ g++ \ gettext \ git \ gnupg \ imagemagick \ libfreetype6 \ libgd3 \ libmcrypt4 \ libmemcached11 \ libmemcachedutil2 \ libsodium23 \ libtidy5deb1 \ libxml2 \ libxslt1.1 \ libzip4 \ nano \ openssl \ unzip \ wget \ lftp \ libbz2-dev \ libc-client-dev \ libcurl4-openssl-dev \ libfreetype6-dev \ libgd-dev \ libicu-dev \ libkrb5-dev \ libmagickcore-dev \ libmagickwand-dev \ libonig-dev \ libmcrypt-dev \ libmemcached-dev \ libtidy-dev \ libxml2-dev \ libxslt-dev \ libz-dev \ libzip-dev \ python3-pip \ nginx \ php \ php-fpm \ php-common \ php-gmp \ php-curl \ php-intl \ php-mbstring \ php-xmlrpc \ php-gd \ php-pear \ php-bcmath \ php-imagick \ imagemagick \ php-soap \ php-ldap \ php-imap \ php-tidy \ php-bz2 \ php-dba \ php-exif \ php-gettext \ php-xml \ php-simplexml \ php-xsl \ php-cli \ php-zip \ php-dev \ dirmngr \ gnupg \ apt-transport-https \ software-properties-common \ ca-certificates \ curl \ build-essential \ ``` ## Mongodb ```bash curl -fsSL https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -` sudo add-apt-repository 'deb https://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main' sudo apt update sudo apt install mongodb-org -y sudo systemctl enable mongod --now pecl channel-update pecl.php.net pecl install mongodb ``` Add to `/etc/php/7.3/cli/php.ini` **AND** `/etc/php/7.3/fpm/php.ini` extension=mongodb.so Restart php service `service php7.3-fpm restart` ## Certbot (snap version) ``` sudo apt install snapd -y sudo snap install core; sudo snap refresh core sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/bin/certbot sudo snap set certbot trust-plugin-with-root=ok ``` ## acme.sh pour les certificats wildcard ```bash wget -O - https://get.acme.sh | sh -s email=contact@colibris-outilslibres.org export GANDI_LIVEDNS_KEY="fdmlfsdklmfdkmqsdfk" acme.sh --issue --dns dns_gandi_livedns -d gogocarto.fr -d *.gogocarto.fr ``` ## Composer ``` php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');" sudo mv composer.phar /usr/local/bin/composer ``` ## Node & Npm & Yarn ``` curl -sL https://deb.nodesource.com/setup_10.x | sudo bash - sudo apt-get install -y nodejs curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install yarn sudo npm install -g gulp ``` ## Cloning Repo ``` cd /var/www sudo mkdir gogocarto sudo chown gogocarto:gogocarto gogocarto/ sudo -u gogocarto git clone https://gitlab.adullact.net/pixelhumain/GoGoCarto.git gogocarto/ ``` ## Nginx Copier la conf dans `/etc/nginx/sites-avaible/gogocarto.fr` `ln -nsf /etc/nginx/sites-available/gogocarto.fr /etc/nginx/sites-enabled/gogocarto.fr` Edit `nginx.conf` -> user gogocarto `service nginx reload` Edit : `/etc/php/7.3/fpm/pool.d/www.conf` -> ``` user = gogocarto group = gogocarto listen.owner = gogocarto listen.group = gogocarto pm.max_children = 400 pm.start_servers = 100 pm.min_spare_servers = 100 pm.max_spare_servers = 300 ``` `service php7.3-fpm restart` ## Backups vi /root/backup.sh ```bash #!/bin/bash HOST=${HOST:-backup.host} USER=${USER:-user} PASSWORD=${PASSWORD:-pass} KEEPBACKUPDAYS=${KEEPBACKUPDAYS:-10} DIRECTORYMONGO=${DIRECTORYMONGO:-/var/backups/mongobackups} DIRECTORYFILES=${DIRECTORYFILES:-/var/backups/gogocarto-uploads} GOGOCARTODIRECTORY=${GOGOCARTODIRECTORY:-/var/www/gogocarto} if [ ! -d "$DIRECTORYMONGO" ]; then mkdir -p $DIRECTORYMONGO fi if [ ! -d "$DIRECTORYFILES" ]; then mkdir -p $DIRECTORYFILES fi # backup mongodb mongodump --out $DIRECTORYMONGO/`date +"%Y-%m-%d"` # backup gogocarto files cd $GOGOCARTODIRECTORY/web/uploads tar -zcvf $DIRECTORYFILES/`date +"%Y-%m-%d"`.tar.gz . # clean older backups find $DIRECTORYFILES/ -mtime +$KEEPBACKUPDAYS -exec rm -rf {} \; find $DIRECTORYMONGO/ -mtime +$KEEPBACKUPDAYS -exec rm -rf {} \; # compress and remplace existing on ftp cd $DIRECTORYFILES tar -zcvf /tmp/gogocarto-uploads.tar.gz . cd $DIRECTORYMONGO tar -zcvf /tmp/mongobackups.tar.gz . cd /tmp lftp -u $USER,$PASSWORD $HOST -e "rm -r gogocarto;mkdir -p gogocarto;cd gogocarto;put mongobackups.tar.gz; put gogocarto-uploads.tar.gz; exit" # remove local one rm mongobackups.tar.gz gogocarto-uploads.tar.gz ``` `chmod +x /root/backup.sh` ## Add crontab jobs `sudo crontab -e` ```bash * * * * * php /var/www/gogocarto/bin/console app:project:update #* * * * * sleep 30 && php /var/www/gogocarto/bin/console app:project:update @hourly php /var/www/gogocarto/bin/console --env=prod app:users:sendNewsletter */5 * * * * /var/www/gogocarto/bin/console --env=prod app:webhooks:post 30 3 * * * php /var/www/gogocarto/bin/console --env=prod app:projects:check-for-deleting 5 3 * * * /bin/bash /root/backup.sh #15 4 * * * /etc/init.d/mongodb restart 0 * * * * cd /var/www/gogocarto && bash bin/execute_custom_domain.sh ``` ## InfluxDB / Telegraf / Grafana For monitoring your server ### InfluxDB ```bash wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add - echo "deb https://repos.influxdata.com/debian buster stable" | sudo tee /etc/apt/sources.list.d/influxdb.list sudo apt update sudo apt install -y influxdb sudo systemctl enable --now influxdb ``` `sudo vim /etc/influxdb/influxdb.conf` ``` [http] auth-enabled = true ``` `curl -XPOST "http://localhost:8086/query" --data-urlencode "q=CREATE USER gogocarto WITH PASSWORD 'strongpassword' WITH ALL PRIVILEGES"` ### Telegraf `sudo apt -y install telegraf` `sudo vi /etc/telegraf/telegraf.conf` ``` # Global tags can be specified here in key="value" format. [global_tags] # dc = "us-east-1" # will tag all metrics with dc=us-east-1 # rack = "1a" ## Environment variables can be used as tags, and throughout the config file # user = "$USER" # Configuration for telegraf agent [agent] interval = "10s" round_interval = true metric_batch_size = 1000 metric_buffer_limit = 10000 collection_jitter = "0s" flush_interval = "10s" flush_jitter = "0s" precision = " " debug = false quiet = false hostname = " " omit_hostname = false ### OUTPUT # Configuration for influxdb server to send metrics to [[outputs.influxdb]] urls = ["http://localhost:8086"] database = "telegraf_metrics" ## Retention policy to write to. Empty string writes to the default rp. retention_policy = " " ## Write consistency (clusters only), can be: "any", "one", "quorum", "all" write_consistency = "any" ## Write timeout (for the InfluxDB client), formatted as a string. ## If not provided, will default to 5s. 0s means no timeout (not recommended). timeout = "5s" username = "gogocarto" password = "strongpassword" ## Set the user agent for HTTP POSTs (can be useful for log differentiation) # user_agent = "telegraf" ## Set UDP payload size, defaults to InfluxDB UDP Client default (512 bytes) # udp_payload = 512 # Read metrics about cpu usage [[inputs.cpu]] ## Whether to report per-cpu stats or not percpu = true ## Whether to report total system cpu stats or not totalcpu = true ## Comment this line if you want the raw CPU time metrics fielddrop = ["time_*"] # Read metrics about disk usage by mount point [[inputs.disk]] ## By default, telegraf gather stats for all mountpoints. ## Setting mountpoints will restrict the stats to the specified mountpoints. # mount_points = ["/"] ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually ## present on /run, /var/run, /dev/shm or /dev). ignore_fs = ["tmpfs", "devtmpfs"] # Read metrics about disk IO by device [[inputs.diskio]] ## By default, telegraf will gather stats for all devices including ## disk partitions. ## Setting devices will restrict the stats to the specified devices. # devices = ["sda", "sdb"] ## Uncomment the following line if you need disk serial numbers. # skip_serial_number = false # Get kernel statistics from /proc/stat [[inputs.kernel]] # no configuration # Read metrics about memory usage [[inputs.mem]] # no configuration # Get the number of processes and group them by status [[inputs.processes]] # no configuration # Read metrics about swap memory usage [[inputs.swap]] # no configuration # Read metrics about system load & uptime [[inputs.system]] # no configuration # Read metrics about network interface usage [[inputs.net]] # collect data only about specific interfaces # interfaces = ["eth0"] [[inputs.netstat]] # no configuration [[inputs.interrupts]] # no configuration [[inputs.linux_sysctl_fs]] # no configuration ``` ### Grafana cf. https://grafana.com/docs/grafana/latest/installation/debian/ Add nginx proxy for grafana `vi /etc/nginx/sites-availables` ``` server { listen 80; listen [::]:80; server_name monitor.fraternite-covid19.fr; access_log /var/log/nginx/gogocarto.fr.access.log; error_log /var/log/nginx/gogocarto.fr.error.log; location /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name monitor.gogocarto.fr; root /var/www/gogocarto/web; # For example with certbot (you need a certificate to run https) ssl_certificate /etc/letsencrypt/live/gogocarto.fr/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/gogocarto.fr/privkey.pem; # Security hardening (as of 11/02/2018) ssl_protocols TLSv1.2; # TLSv1.3, TLSv1.2 if nginx >= 1.13.0 ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; # ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0, not compatible with import-videos script ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; # Requires nginx >= 1.5.9 ssl_stapling on; # Requires nginx >= 1.3.7 ssl_stapling_verify on; # Requires nginx => 1.3.7 # Configure with your resolvers # resolver \$DNS-IP-1 \$DNS-IP-2 valid=300s; # resolver_timeout 5s; # Enable compression for JS/CSS/HTML bundle, for improved client load times. # It might be nice to compress JSON, but leaving that out to protect against potential # compression+encryption information leak attacks like BREACH. gzip on; gzip_types text/css application/javascript; gzip_vary on; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; access_log /var/log/nginx/gogocarto.fr.access.log; error_log /var/log/nginx/gogocarto.fr.error.log; location ^~ '/.well-known/acme-challenge' { default_type "text/plain"; root /var/www/certbot; } location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://localhost:3000; } } ``` Dans l'interface admin de grafana, roue crantée, ajouter la source influxdb avec host="http://localhost:8086" username = "gogocarto" password = "strongpassword" db="telegraf_metrics"