Installation - rodekruis/EspoCRM-knowledge-base GitHub Wiki
On this page, you can find documentation and step-by-step guide on how to install EspoCRM.
- Create a Virtual Machine in Azure
- Installation from script
- Installation with external MySQL database
- Security
- Cloning a VM in Azure
- Dump database from the MySQL container
This guide assumes that you are going to host EspoCRM on a Virtual Machine (VM) in Azure. There are other ways to host EspoCRM as well but these are not supported in these docs. These docs are inspired by this tutorial and this training of Azure
-
Resource Group: A resource group is a container that stores related resources for an Azure solution. In our case, one of our resources would be a virtual machine for EspoCRM. The resources in the resource group can be managed as a group. Generally, add resources that are part of the same project, share the same lifecycle to the same resource group so you can easily deploy, update, and delete them as a group
- Virtual Machine: A Virtual Machine is a compute resource that uses software instead of a physical computer to run programs and deploy apps. EspoCRM can be installed on local computer or laptop. However, we want to ensure that EspoCRM is running non stop. This means your computer would then need to ‘act’ like a server, meaning it should run all the time. This is sometimes not possible if your laptop is out of power, or has an issue. Therefore, it is recommended to install EspoCRM on a cloud based server.
- Go to the Azure Resource Group where you want to create the VM
- Find in the Azure Market Place and create a new resource called 'virtual machine' (you could check which VMs and regions Azure has in offer here)
- Give the following settings for the Basics page. If needed, adapt the settings to your own case.
- Subscription: your subscription
- Resource Group: your preferred RG under the selected subscription where the VM will be created within
- Give it a descriptive name. An example for DEH:
deh-espocrm-[country]-[environment]
- Region should be West Europe, unless there are specific data requirements. Warning: related resources to this VM configured with other regions could lead to conflicts.
- Availability options: Availability zone
- Availability zone: Zones 1
- Security Type: Trusted launch virtual machines
- Image: Ubuntu Server 20.04 LTS - x64 Gen2 or the latest version
- VM architecture: x64
- Size: Standard_DS1_v2 - 1 vcpu, 3.5 GiB memory (should be about 40 euros a month)
- Authentication type: Password
- Username: name your admin VM user name
- Password: generate a strong password and save it in a password manager like Bitwarden Make sure to share this password with colleagues in a Bitwarden collection.
- Public inbound ports: Allow selected ports
- Select inbound ports: SSH (22), HTTP (80), HTTPS (443)
- Following settings for the Disk page, or adjust them to your needs:
- OS disk size: Image default (30 GiB)
- OS disk type: Premium SSD (locally-redundant storage)
- Delete with VM: TRUE
- Settings for Networking page:
- Create a new virtual network or select an existing one (when would we want to create a new virtual network)
- Subnet: default
- Public IP: default
- NIC network security group: Basic
- Settings of the next pages Management, Monitoring, Advanced, Tags can be kept as default
- Go to Review + Create for final check of the settings and then choose Create to deploy the VM. Note: besides the VM, 5 other resources will also be created. Their names all start with the VM name. They support the VM functions such as disk, IP address, basic network security. In case the VM needs to be removed, those accompanied resources to the VM should be manually removed as well.
- Enable automated security updates
- Running Ubuntu Server VM with:
- user name
- password (or auth key)
- ip address
- Ports 22 open for jumpbox and 443 opened for any
- Domain with:
- Domain name with A-record pointing towards the IP of the VM
- Access the VM from a local machine (
ssh [USER NAME]@[IP ADDRESS]
) - There are three ways to install EspCRM. The preferred way is to install with SSL/TLS certificate but this requires that you have run the next step called 'Steps to 'connect' a public IP address to a URL:'. Run the following commands for using this preferred way:
- Do you need to install v8? (Likely, yes) Then follow these commands:
wget https://raw.githubusercontent.com/rodekruis/espocrm-installer/refs/heads/master/install.sh
chmod +x install.sh
sudo bash install.sh -y --ssl --letsencrypt --domain=[YOUR_ESPOCRM_DOMAIN] --email=[YOUR_EMAIL_ADDRESS] --version=8.4.2
- If you can install v9, then follow these commands:
wget https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
sudo bash install.sh -y --ssl --letsencrypt --domain=[YOUR_ESPOCRM_DOMAIN] --email=[YOUR_EMAIL_ADDRESS]
- In case you do not have a domain and need to use an IP address to access EspoCRM page, you can run the previous step without the flag
--ssl
. Note that this is not recommended due to security matters with HTTP.
- Do you need to install v8? (Likely, yes) Then follow these commands:
- When the installation is completed, it will list important details of the Espo instance. Note these down in a password manager (like in a Collection in Bitwarden):
- Public domain IP address/ URL of Espo instance
- Admin username, password of Espo instance
- Login to the newly created EspoCRM instance via the domain (or IP address) to ensure you have access.
If the public IP address/ URL of the Espo instance is not accessible, make sure the Inbound port rules set/created in VM's Network settings to allow any HTTPS and HTTP. For the latter, it is highly recommended to allow HTTP inbound from specific IP addresses such as (yours, office's) to restrict less secured access.
- Make sure you have access to the Domain Name System (DNS) of the National Society. These docs assume that there is an existing domain. If not, you can buy one via the DNS.
- Find the page within the DNS where you can add new rule
- Usually, there are three variables needed when adding an new rule:
- Record type: A (most used type)
- Name: the URL name including the NS domain (e.g. deh.demo.510.global)
- Content: the IP address from the VM (e.g. 172.205.203.9)
- Add this new rule and test it by going to the newly created URL and confirm it leads to the same page as the IP address leads to
- In a directory in the EspoCRM instance, e.g. ~/certs, create a Certificate Signing Request (CSR) and private key files:
You might need to fill in information when prompted, particularly when your expected url is a subdomain:
openssl req -new -newkey rsa:2048 -nodes -keyout <domain_ulr>.key -out <domain_ulr>.csr
- Country Name
- Org Name e.g. org-name
- Common Name (CN): . e.g. _.org-name.com_
- Subject Alternative Name (SAN): e.g. org-name.com
- Use the CSR file to request a SSL cert. When downloading the SSL cert, choose nginx as server platform.
- Reinstall EspoCRM with SSL settings with step 1-2 in this manual installation.
- Replace the command in step 3 of the manual installation with this command. Then continue the manual from step 4.
- Once finished the manual, add the SSL (.pem) and the generated private key (.key) with these steps
- You might need to add new inbound rule of the EspoCRM VM (in Azure portal) to allow all HTTPS inbound.
- The EspoCRM should be accessed via the URL in HTTPS. If so, remove all HTTP inbound rules to disabled insecure connection.
Installing EspoCRM with an external MySQL database server - instead of hosting the database on the VM itself - makes the system more robust and scalable in case of high volume and/or flow of data, and it is therefore recommended in those scenarios.
These instructions follow the manual installation steps, with some heavy customization.
- Create the VM, if not already done
- Download EspoCRM on the VM and unzip it
sudo apt install unzip
sudo mkdir /var/wwww
unzip EspoCRM-X.X.X.zip -d /var/www/espocrm
cd /var/www/espocrm/EspoCRM-X.X.X && sudo find data -type d -exec chmod 775 {} + && sudo chown -R 33:33 .;
- Install Nginx
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
- Install PHP and other PHP-related stuff
sudo apt install php8.3 -y
sudo apt install php8.3-fpm php-mbstring php8.3-zip php8.3-gd php8.3-mysql php8.3-curl php8.3-xml -y
- Edit
/etc/php/8.3/cli/php.ini
in the following lines
max_execution_time = 180
max_input_time = 180
memory_limit = 256M
post_max_size = 50M
upload_max_filesize = 50M
- Edit
/etc/nginx/sites-available/default
as follows
- Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
- Uncomment the
pass PHP scripts to FastCGI
block and change it as
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets):
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
# With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
}
- Uncomment the section to deny all access to Apache .htaccess files.
location ~ /\.ht {
deny all;
}
- Replace
/etc/nginx/nginx.conf
entirely with what follows (make sure to replace EspoCRM-X.X.X with your version)
worker_processes 1;
user www-data www-data;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost; # domain name
charset utf-8;
index index.html index.php;
client_max_body_size 50M;
keepalive_timeout 300;
types_hash_max_size 2048;
server_tokens off;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
gzip on;
gzip_types text/plain text/css text/javascript application/javascript application/json;
gzip_min_length 1000;
gzip_comp_level 9;
# root /path-to-espo/public; # path to public dir
root /var/www/espocrm/EspoCRM-X.X.X/public/;
access_log /var/logs/host.access.log;
error_log /var/logs/host.error.log info;
location /client {
# root /path-to-espo; # path to espocrm root dir
root /var/www/espocrm/EspoCRM-X.X.X/;
autoindex off;
location ~* ^.+\.(js|css|png|jpg|svg|svgz|jpeg|gif|ico|tpl)$ {
access_log off;
expires max;
}
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
#fastcgi_pass localhost:9000;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location /api/v1/ {
if (!-e $request_filename){
rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
}
}
location /portal/ {
try_files $uri $uri/ /portal/index.php?$query_string;
}
location /api/v1/portal-access {
if (!-e $request_filename){
rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
}
}
location ~ /(\.htaccess|\web.config|\.git) {
deny all;
}
}
include servers/*;
}
- Restart nginx and php8.3-fpm
sudo mkdir -m 777 /var/logs
sudo systemctl restart nginx php8.3-fpm
- If you navigate in your browser to the IP address of the VM you should now see the EspoCRM installation page
- Create an MySQL server and database:
Marketplace
>Azure Database for MySQL Flexible Server
- Configure MySQL server from Azure Portal
- Go to
Settings
>Databases
>+ Add
> create a new database calledespocrm
- Go to
Settings
>Server parameters
and selectrequire_secure_transport
:OFF
(only temporarily) - Go to
Settings
>Networking
and selectAllow public access from any Azure service within Azure to this server
- Go back to the EspoCRM installation page and proceed with installation
- Select
Platform
:MySQL / MariaDB
- Insert database server credentials
-
Host Name
:XXX.mysql.database.azure.com:3306
-
Database Name
:espocrm
-
- Ignore any warnings of failed requirements
- Secure connection to the database server
- From the Azure Portal > MySQL database resource, go to
Networking
>Download the SSL certificate
; it should be calledDigiCertGlobalRootCA.crt.pem
- Copy the certificate to the EspoCRM VM somewhere in its
data
(e.g.data/certs
) directory using the command below or use (S)FTP client software like WinSCP:
scp .\<certificatename>.pem <espo-username>@<espo-ip-address>:<your-home-dir>
sudo mv <certificatename>.pem /var/www/espocrm/EspoCRM-X.X.X/data/certs
- Edit the Espo data configuration file
config-internal.php
by adding file underdatabase
this line:
'sslCA' => 'data/certs/<certificatename>.pem'
- Go back to the Azure Portal > MySQL database resource >
Server parameters
and selectrequire_secure_transport
:ON
The following recommendations follow two dedicated EspoCRM penetration tests (see here and here) and a server hardening assessment, see those documents for the rationale and more details.
In Administration
> Authentication
select
- Auth Token Max Idle Time (hours): 4
- Enable 2-Factor Authentication: yes
- Force regular users to set up 2FA: yes
- Length of generated passwords: 10
- Minimum password length: 10
- Number of letters required in password: 2
- Password must contain letters of both upper and lower case: yes
- Number of digits required in password: 1
When setting up roles, make sure that users are not able to disable mandatory 2 factor authentication:
- Within the role
- Under
Field Level
- Go to entity
Users
- Set
Type
to Read -> no
Extra information: If this is not done, users can disable 2FA from their user page. If Force regular users to set up 2FA
is set to yes
(as above), when the user logs out and logs in again, (s)he is enforced to set up 2FA. Still, this means that in the meanwhile 2FA is disabled for that user.
sudo rm /var/www/espocrm/data/espocrm/application/Espo/Resources/metadata/dashlets/Iframe.json
sudo /var/www/espocrm/command.sh rebuild
Enable security headers in /var/www/espocrm/data/espocrm/data/config-internal.php
sudo nano /var/www/espocrm/data/espocrm/data/config-internal.php
Check if the following is already in this file and if not, add the appropriate lines:
'clientSecurityHeadersDisabled' => false,
'clientCspDisabled' => false,
'clientCspScriptSourceList' => [
0 => 'https://maps.googleapis.com'
],
'clientStrictTransportSecurityHeaderDisabled' => false,
'clientXFrameOptionsHeaderDisabled' => false,
Press ctrl+x
to exit. Then, press y
to save the changes
sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 600 /etc/at.deny
sudo chmod 600 /etc/crontab
sudo chmod 600 /var/log/*
sudo chmod 700 /etc/cron.daily
sudo chmod 700 /etc/cron.hourly
sudo chmod 700 /etc/cron.weekly
sudo chmod 700 /etc/cron.monthly
sudo chmod 750 /home/*
install auditd
sudo apt install -y auditd audispd-plugins
sudo systemctl --now enable auditd
If the above comments do not work. Run the following (to update apt-get), and then try again:
sudo apt-get update
edit /etc/default/grub
for automatic startup and to have enough space for logging
sudo nano /etc/default/grub
Changing the following (note for later: it seems that this is a duplicate but this was being recommended by security experts anyway)
GRUB_CMDLINE_LINUX="audit=1"
GRUB_CMDLINE_LINUX="audit_backlog_limit=8192"
Press ctrl+x
to exit. Then, press y
to save the change
update grub2 configuration
sudo update-grub
sudo apt-get install -y chkrootkit
Run the malware scan and review the result.
sudo chkrootkit
Edit /etc/ssh/sshd_config
as follows. Edited lines should also be uncommented (hash removed).
sudo nano /etc/ssh/sshd_config
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
X11Forwarding no
LogLevel VERBOSE
AllowTcpForwarding no
Compression no
MaxAuthTries 3
TPCKeepAlive no
AllowAgentForwarding no
LoginGraceTime 2m
MaxStartups 10:30:60
Press ctrl+x
to exit. Then, press y
to save the change
Edit /etc/login.defs
and edit the UMASK
and USERGROUPS_ENAB
lines
sudo nano /etc/login.defs
Search for UMASK or USERGROUPS_ENAB with ctrl + w
and edit it as follows:
UMASK 027
USERGROUPS_ENAB no
Press ctrl+x
to exit. Then, press y
to save the changes
Edit /etc/systemd/journald.conf
and add the following lines
sudo nano /etc/systemd/journald.conf
Storage=persistent
Press ctrl+x
to exit. Then, press y
to save the changes
A jumpbox for a Virtual Machine is a secure gateway server that provides controlled access to other VMs within a network, often used for administrative tasks and enhanced security.
Assumptions:
- you are using a Virtual Machine in Azure and have the correct permissions to change settings.
- you already have an existing jumpbox
To setup the Jumpbox for the specific VM:
- Go to the VM in Azure
- Go to the Networking tab
- Select the 'inbound port rule' with name 'SSH'
- Change the following settings:
- Source: IP Addresses
- Source IP addresses/CIDR ranges: JUMP_IP_ADDRESS
- Source port ranges: *
- Destination: Any
- Service: SSH
- Action: Allow
- Priority: 300
- Description (optional): Jumpbox
- You can check if the connection is now blocked by trying to login the VM via SSH with the VMs IP address. This should not be possible.
Access the VM via Jumpbox
- To access the VM with the jumpbox, go to your preferred SSH-client (PuTTY for example) and login with: <YOUR_USERNAME>@<JUMP_IP_ADDRESS> and port 22 (<YOUR_USERNAME> is usually your full email address)
- Go to https://microsoft.com/devicelogin and enter <YOUR_ONE_TIME_CODE> to authenticate. Follow the verification process and hit 'enter' in the SSH-client when ready.
- Now you can enter the VM of your choice by using the command
ssh <USER>@<VM_IP_ADDRESS>
(user is usuallyespoadmin
) and the relevant password.
- Create backup of the VM in Azure
- Click on restore the VM and in the "Restore type" select "Create new Virtual Machine".
- For the new VM, if the IP has not been created, create a new and then associate it with the VM interface
- If a Network Security Group has not been created, create it, associate it with the VM and open ports SSH (22) and HTTPS (443)
- Once cloned, the IP will rediret to the original VM. To solve that, you can re-run the installation script with:
bash install.sh -y --ssl --letsencrypt --domain=<NEW-URL> --email=<YOUR-EMAIL-ADDRESS>
N.B. if you will not use a custom domain - e.g. if the EspoCRM instance is for demo or training - simply do
bash install.sh -y
- Pay attention to the URL, it may happen that the new VM keeps redirecting to the original one. In that case go to the page
https://<NEW-URL>/#Admin/settings
and change the Site URL to the new URL. - Be sure that none of the test projets is using textit.
- Deactivate the workflows "Send messages" and "Get message status".
- Log-in through SSH and uninstall Apache2:
sudo apt remove apache2
- Reboot the docker containers:
sudo docker-compose -f /var/www/espocrm/docker-compose.yml restart
To get a dump of the database, you will need to get the MySQL root password first from the dockercompose file:
cat /var/www/espocrm/docker-compose.yml
Then copy the root mysql password to be found as MYSQL_ROOT_PASSWORD
Good practice is to create a dir to store the backups:
mkdir ~/backups
Next, go into the docker container of the mysql and execute bash replacing by the password and by the date:
sudo docker exec -ti espocrm-db /usr/bin/mariadb-dump -u root --password=<PASSWORD> espocrm > ~/backups/mysqldump_<DATE>.sql