Category: Debian

  • Easy Files Encryption

    Don’t trust password managers? Well you can encrypt that txt file full of complicated passwords and give it a master password that hopefully only you will know about.

    Encrypting a File with Explicit Cipher:

    gpg --symmetric --cipher-algo AES256 file.txt

    In this example, AES256 is used as the cipher algorithm, providing strong encryption.

    To further enhance security, you can also add the --s2k-cipher-algo, --s2k-digest-algo, and --s2k-mode options for passphrase hashing. For example:

    Enhanced Security Example:

    gpg --symmetric --cipher-algo AES256 --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3 file.txt

    Here’s a breakdown of the options used:

    • --cipher-algo AES256: Specifies the symmetric encryption algorithm (AES256 in this case).
    • --s2k-cipher-algo AES256: Specifies the cipher algorithm for the passphrase-to-key conversion.
    • --s2k-digest-algo SHA512: Specifies the hash algorithm used for passphrase-to-key conversion.
    • --s2k-mode 3: Iterated and salted passphrase-to-key conversion.

    Remember, the goal is to balance security with usability. Stronger encryption and hashing algorithms may increase security but could also impact performance.

    When decrypting, GPG will automatically use the appropriate algorithms based on the information stored in the encrypted file.

    Feel free to adjust the options based on your security requirements, and always ensure that the recipients of the encrypted file can decrypt it with the chosen settings.

    2. CCRYPT COMMAND

    Another super easy method is to use ccrypt. It’s simple and fast and if you forget the password there is no way to decrypt or crack ope the file AFAIK.

    To encrypt:

    ccrypt -e my_file

    A file named my_files.cpt will be created

    To decrypt:

    ccrypt -d my_files.cpt

    And you get the original file back.

  • Connection metric management

    Here is how with some simple steps I changed the metric of an internet connection in order to give priority to a usb dongle so its set as the default interface for internet traffic in my personal laptop. The laptop’s integrated wifi interface does not support 5 Ghz connections so every time I boot up the system I had to manually disconnect the integrated interface and reconnect it so its metric changes to a higher value:

    First one needs to see the internet connections managed by the NetworkManager service in order to get the name of the internet connection we need to modify:

    nmcli connection show

    The list shows the 2 wifi connections I currently use. One is for General internet traffic and the other one to manage an openwrt device:

    NAME                    UUID                                  TYPE      DEVICE
    Connection_1            0711f8ae-049e-4e4f-8800-3cffc70b458f  wifi      wlp3s0
    Connection_2            b2c7835e-69ac-4520-b401-f7120a456d65  wifi      wlx3xvre3db545  

    To verify the current metric for both interfaces we use ip route:

    default via 192.168.1.1 dev wlp3s0 proto dhcp src 192.168.1.111 metric 600
    default via 192.168.5.1 dev wlx3xvre3db545 proto dhcp src 192.168.5.198 metric 601  

    As we can see the internet traffic has a default route through the slower wifi interface. We can change this by changing the metric:

    nmcli connection modify "Connection_2" ipv4.route-metric 100

    We restart the service:

    sudo systemctl restart NetworkManager

    Once the service is back up we verify the metric again:

    default via 192.168.5.1 dev wlx3xvre3db545 proto dhcp src 192.168.3.198 metric 100  
    default via 192.168.1.1 dev wlp3s0 proto dhcp src 192.168.1.111 metric 602

    This change will be persistent after a reboot.

  • Debian + Apache + mariadb + letsencrypt + wordpress

    Step 1: Update Your System

    First, make sure your system is up-to-date.

    sudo apt update
    sudo apt upgrade -y

    Step 2: Install Apache

    Install Apache web server.

    sudo apt install apache2 -y

    Enable and start the Apache service.

    sudo systemctl enable apache2
    sudo systemctl start apache2

    Step 3: Install MariaDB

    Install MariaDB server.

    sudo apt install mariadb-server mariadb-client -y

    Secure the MariaDB installation.

    sudo mysql_secure_installation

    Follow the prompts to:

    • Set a root password
    • Remove anonymous users
    • Disallow root login remotely
    • Remove test databases
    • Reload privilege tables

    Step 4: Create a Database for WordPress

    Log into MariaDB.

    sudo mysql -u root -p

    Run the following SQL commands to create a database and a user for WordPress.

    CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'strong_password';
    GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    Step 5: Install PHP

    Install PHP and necessary extensions.

    sudo apt install php libapache2-mod-php php-mysql php-mbstring php-xml php-zip php-gd php-curl -y

    Step 6: Configure PHP for Large File Uploads

    Edit the PHP configuration file.

    sudo nano /etc/php/*/apache2/php.ini

    Change the following settings:

    upload_max_filesize = 128M
    post_max_size = 128M
    max_execution_time = 300
    max_input_time = 300

    Step 7: Restart Apache

    After making changes to the PHP configuration, restart Apache.

    sudo systemctl restart apache2

    Step 8: Download and Install WordPress

    Navigate to the web directory /var/www/

    Download the latest version of WordPress.

    wget https://wordpress.org/latest.tar.gz
    tar -xzvf latest.tar.gz
    Or if it's a zip file
    unzip latest.zip
    rename the wordpress site with the domain of your wabsite
    mv wordpress mysite.com

    You might want to keep the wordpress compressed file untill next version comes up.

    From here you should be ready to go to the local ip address in your browser and finish the installation process of wordpress. If the wordpress installation opens and after putting the information to access to the database you just created for wordpress it does not connect, you will have to enter that information manually like is shown in the next step.

    Step 9: Configure WordPress

    Navigate to folder /var/www/mysite.com and create a WordPress configuration file from the sample file. Make a copy of the sample file and edit the new copy as shown below:

    cp wp-config-sample.php wp-config.php

    Edit the wp-config.php file.

    sudo nano wp-config.php

    Add your database details with the details you chose when you created the database in step 4:

    define('DB_NAME', 'wordpress_db');
    define('DB_USER', 'wordpress_user');
    define('DB_PASSWORD', 'strong_password');
    define('DB_HOST', 'localhost');

    Step 10: Set Permissions

    Set proper permissions for the WordPress files or better yet for this purpose to the www directory.

    sudo chown -R www-data:www-data /var/www/
    sudo find /var/www/ -type d -exec chmod 750 {} \;
    sudo find /var/www/ -type f -exec chmod 644 {} \;

    Step 11: Enable Apache Rewrite Module

    Enable the rewrite module.

    sudo a2enmod rewrite

    Step 11: Disable the default apache website

    sudo a2dissite 000-default.conf

    Step 12: Restart Apache Again

    Restart Apache to apply all changes.

    sudo systemctl restart apache2

    Step 13: Complete WordPress Installation

    Open a web browser and navigate to your server’s IP address. Follow the on-screen instructions to complete the WordPress installation.

    Step 14: Secure Your Server

    1. Install UFW (Uncomplicated Firewall)
    sudo apt install ufw -y
    sudo ufw allow 22
    sudo ufw allow 80sudo ufw allow 443sudo ufw enable
    1. Configure SSL with Let’s Encrypt

    If you have a domain name purchased or one for free, here is how to get the certificates from letsencrypt but first make sure to map your public ip address to the server running apache. Also you need to create at least a basic configuration file for mysite.com.

    Navigate to /etc/apache2/sites-available. Create and edit the configuration for mysite.com file by copying the following lines:

    nano mysite.com.conf

    <VirtualHost *:80>
           ServerName mysite.com
           Redirect permanent / https://mysite.com/
           RewriteEngine on
           RewriteCond %{SERVER_NAME} =mysite.com
           RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
    </VirtualHost>
    
    <VirtualHost *:443>
           ServerName mysite.com
    
           DocumentRoot /var/www/mysite.com
    
           <Directory /var/www/mysite.com>
               Options Indexes FollowSymLinks
               AllowOverride All
               Require all granted
           </Directory>
    
     #      SSLEngine on
     #          SSLCertificateFile /etc/letsencrypt/live/mysite.com/fullchain.pem
     #          SSLCertificateKeyFile /etc/letsencrypt/live/mysite.com/privkey.pem
     #          Include /etc/letsencrypt/options-ssl-apache.conf
    </VirtualHost>
    

    NOTE: I’ve left commented the lines corresponding to SSL because when you reload the apache service in the next step it will fail because the certificates are not yet present. Using the command certbot –apache will automatically add the necessary lines in the configuration file.

    Enable the site:

    sudo a2ensite mysite.com.conf

    Reload apache

    sudo systemctl reload apache2.service

    Install Certbot.

    sudo apt install certbot python3-certbot-apache -y

    Obtain an SSL certificate.

    sudo certbot --apache
    Or
    
    sudo certbot certonly --apache -d mywebsite.com

    Follow the prompts to set up HTTPS.

    1. Regular Updates and Backups

    Set up a cron job for automatic updates.

    sudo crontab -e

    Add the following line for daily updates:

    @daily apt update && apt upgrade -y

    Happy Blogging!

  • Configure partition table, format and auto mount disks. MBR – EXT4

    Connect the External HDD: Ensure that your external HDD is connected to your Debian system.

    Identify the Device: Use the lsblk or fdisk -l command to identify the device name of your external HDD. It will typically be something like /dev/sdX, where X is a letter assigned to the drive.

    lsblk

    Partition the Drive with MBR: Use the fdisk command to create an MBR partition on the external HDD.

    sudo fdisk /dev/sdX

    Once inside the fdisk program do the following:

    Create the ext4 Filesystem: After creating the partition, use the mkfs.ext4 command to create an ext4 filesystem.

    mkfs.ext4 /dev/sdX1

    Replace /dev/sdX1 with the actual partition identifier you created in the previous step.

    Label the Filesystem (Optional): You can optionally label the ext4 filesystem for easier identification. Replace NEW_LABEL with the desired label for your filesystem. That can for example be the model of the hard disk or it’s purpose.

    e2label /dev/sdX1 NEW_LABEL

    Mount the Filesystem: Create a directory where you want to mount the hard disk and mount the filesystem.

    sudo mkdir /media/LABEL sudo mount /dev/sdX1 /media/LABEL

    Adjust the mount point (/media/LABEL) according to your preference.

    Now, your external HDD should be formatted with MBR and have an ext4 filesystem. If you want the drive to be automatically mounted on boot, you may need to add an entry to the /etc/fstab file which is show below.

    Automounting disk with fstab

    Identify the UUID of the Partition: Use the blkid command to identify the UUID of the partition on your external HDD. The UUID uniquely identifies the partition, and using it in /etc/fstab helps avoid issues if the disk order changes.

    Replace /dev/sdX1 with the actual partition identifier.

    sudo blkid /dev/sdX1

    Take note of the PTUUID number without quotes. It should look something like this: “c381c2aa-044b-415a-b901-2a6a374b2591“.

    Edit the /etc/fstab file: Open the /etc/fstab file in a text editor using a command like sudo nano or sudo vim. Add a new line with the following information:

    UUID=your_partition_uuid /media/LABEL ext4 defaults 0 2

    Replace your_partition_uuid with the UUID you obtained in the first step, and adjust the mount point (/media/LABEL) if needed.Example using nano:

    sudo nano /etc/fstab

    Add the line to automount the disk with default values:

    UUID=c381c2aa-044b-415a-b901-2a6a374b2591 /media/LABEL ext4 defaults 0 2

    Or with more specific options:

    UUID=c381c2aa-044b-415a-b901-2a6a374b2591 /media/LABEL ext4 rw,relatime,nofail,errors=remount-ro 0 2
    1. rw:
      • Stands for “read-write.”
      • This option allows both read and write operations on the filesystem. It specifies that the filesystem should be mounted with read and write permissions.
    2. relatime:
      • This option stands for “relative atime.”
      • With relatime, the access time of files is updated only if the current access time is earlier than the modification time or the inode creation time. It’s an optimization over the traditional atime update mechanism, helping to reduce write operations to the filesystem.
    3. nofail:
      • This option indicates that if the filesystem cannot be mounted, the failure should not be considered fatal to the system boot process. If the device is not present or there are issues with the filesystem, the system will continue booting without the specified filesystem being mounted.
    4. errors=remount-ro:
      • Specifies the action to be taken in case of errors on the filesystem.
      • If errors are encountered, the filesystem will be remounted in read-only mode (ro). This is a safety measure to prevent further potential damage and data loss in case of filesystem errors.
    5. 0 2:
      • These are the dump and pass fields, respectively.
        • The dump field (0) indicates whether the filesystem should be backed up using the dump command. A value of 0 means no automatic backup.
        • The pass field (2) is used by the fsck command to determine the order in which filesystems are checked at boot time. A value of 2 typically means the filesystem will be checked after the root filesystem.

    In summary, the options in your /etc/fstab entry specify that the filesystem should be mounted with read-write permissions, use relative atime for optimization, not be considered critical for system boot (nofail), remount in read-only mode in case of errors, and be checked after the root filesystem during the boot process.

    Create the Mount Point (if not already created): If you haven’t created the mount point earlier, create it using:

    sudo mkdir /media/LABEL

    Mount All Filesystems in /etc/fstab: To mount all filesystems listed in /etc/fstab, you can use the following command:

    sudo mount -a

    To auto mount as a non root user

    To automount a disk with specific user permissions using /etc/fstab, you can utilize the user and noauto options along with the uid, gid, and umask options.

    1. Determine the UID and GID of the user you want to mount the disk as. You can find this information by running the following commands:
    id -u username
    id -g username
    1. Determine the UUID of the disk you want to mount. You can find this information using the blkid command:
    sudo blkid
    1. Edit the /etc/fstab file using a text editor:
    UUID=your_disk_uuid /mnt/mount_point filesystem defaults,user,noauto,uid=your_user_id,gid=your_group_id,umask=022 0 0
  • Easy WAN-LAN speed test over cli

    The following two debian tools makes it very easy to accurately measure your internet connection speed as well as in your LAN.

    Measuring internet connection speed

    sudo apt install speedtest-cli

    Run it by typing:

    speedtest-cli

    Measuring LAN connection speed

    sudo apt install iperf3

    Run the server in one device which will be listening for the client to establish a connection.

    iperf3 -s

    In your other network device install iperf3 and run the client against the server:

    iperf3 -c [server's ip address]

    Results should show up promptly

  • sshfs

    For an easy way to obtain temporary access to a directory in a remote location using the sshfs command just type in your terminal:

    sshfs remote_user@ip_address:/path_to_dir path_to_local_dir

    Make sure you have have already created the local directory to mount the remote directory, that you have the credentials of the remote user and all necessary permissions.

    For example:

    sshfs admin@192.168.1.130:/media/backup ~/nfs

    Now in your local file manager you will have access to the remote directory for the current session. Performance may be reduced with this method in contrast with other alternatives like a network file system setup but for managing small files it’s just perfect if you prefer to have a single secure connection to a remote location without having to use to much the terminal.

    NOTE: If you are a local non root user, you need to make sure to create the folder where you want to mount the remote disk somewhere in your home folder so you can have access to it either with CLI or a file explorer.

    To disconnect:

    fusermount -u /path/to/mount/point
  • Configure passwordless authentication

    Server Side

    1- In this scenario we are going to install an ssh server and configuring it so that it only accepts certificates to log in.

    sudo apt-get install openssh-server

    2- In the Remote Server: Ensure that password based ssh login is allowed in the ssh server configuration before copying your public key.. Edit the ssh configuration file after you have a working certificate based authentication. You should skip this step for now:

    sudo nano /etc/ssh/sshd_config

    Set the following options:

    PasswordAuthentication no
    ChallengeResponseAuthentication no
    UsePAM no
    KbdInteractiveAuthentication no

    Save and exit the file.

    sudo systemctl reload/restart sshd
    or
    sudo service ssh restart

    Client Side

    sudo apt-get install openssh-client

    Navigate to /home/.ssh

    3- Generate an SSH key pair (if you don\’t already have one. This command generates an RSA key pair with 4096 bits.

    ssh-keygen -t rsa -b 4096

    Or you can generate the more modern version with this command:

    ssh-keygen -t ed25519 -a 100 -f .ssh/testkey

    Give it a meaningful name and provide a password (optional)

    Add Your SSH Key to the SSH Agent: You need to add a new identity using your SSH private key to the SSH agent with the following command:

    ssh-add ~/.ssh/id_rsa (NOT the id_rsa.pub!)

    Ensure SSH Agent is Running: ssh-copy-id relies on an SSH agent to manage your keys. If you need to stop it, type eval \”$(ssh-agent -k)\”

    eval "$(ssh-agent -s)"
    Or
    eval $(ssh-agent -s)

    OPTIONAL: Make sure that ssh-agent is running and that will it start at system boot in your local session and adding a desired private key:

    nano ~/.bashrc

    4- Add the following line at the end of the file :

    eval "$(ssh-agent -s)"
    ssh-add PATH_TO_YOUR_PRIVATE_KEY

    To check if the SSH agent is running, you can use the ssh-add command with the -l option. If the ssh agent is running and has loaded any keys, you will see a list of the loaded key fingerprints. Open a terminal and run the following command:

    ssh-add -l

    Another way to check if the SSH agent is running, is to list the environment variables related to SSH.

    If the SSH agent is running, this command will print the path to the SSH agent socket. If it\’s not running, the command will produce no output. Run the following command:

    echo $SSH_AUTH_SOCK

    You can also see if ssh agent is running by showing it\’s PID.

    echo $SSH_AGENT_PID
    • There is another way to load the identities beside running the ssh agent and that is by creating a file named config inside the .ssh folder with the following information per server you want to connect to. The identities configured will be loaded at the time to try to connect via ssh.
    Host server
           Hostname server_ip_address
           User remote_user
           IdentityFile /home/local_user/.ssh/identity_file

    5- Make sure that ssh password authentication on your remote server is enabled. You\’ll need to copy your public key to the remote server using ssh-copy-id:

    ssh-copy-id -i /path/to/id_rsa.pub admin@remote_server_ip

    You are going to be prompted to type the password of your remote user to accept the public key.

    6- Once that\’s done, log in and if all goes well, you will connect to the remote machine without a password.

    ssh admin@remote_server_ip
  • Install Debian on RaspberryPi 3B+

    Go to https://raspi.debian.net/ and download the appropriate image file. I\’m going for this one: 20230612_raspi_3_bookworm.img.xz.

    Decompress the image:

    xz -d path/to/.img

    Copy image file to sdcard:

    sudo dd if=/path/to/.img of=/dev/sdx bs=4M status=progress conv=sync

    Insert the sdcard into your raspberrypi and start it up. First time run will get you prompted to user root without a password so you must give it a password right after login. Remote root login is disabled by default so in order to ssh into the raspberrypi create an admin account give it sudo privileges.\n\n\n\n

    Configure as root server-side

    Create a password for your root account

    passwd

    Update the system

    apt update && apt upgrade -y

    Create an admin account and provide a password

    adduser admin

    Install dependencies

    apt install sudo openssh-server

    Give sudo privileges to user admin by navigating to /etc/sudoers.d/ and either edit the README file or create a new file. Add the following line at the end of the file:\n\n\n\n

    admin ALL=(ALL:ALL) ALL

    Another way to setup sudo on a user is to add that user to the sudo group (you need to be root to do that).

    usermod -aG sudo admin

    Reboot the system and leave the raspberrypi without logging in locally with the root or admin accounts. From now on you should be able to log in remotely with your user admin and continue with further configurations.

    Take note of the ip address of your raspberrypi.

    ip a

    Configuration client-side

    Install open ssh client package.

    sudo apt install openssh-client

    Connect via ssh in your terminal.

    ssh admin@raspberrypi_ip_address

    Now you should be able to log in remotely with the admin account and continue with further configurations!

  • Automated folders backup

    This is a very simple way to back up folders in an incremental way and it can be tweaked slightly to make more or less copies while at the same time keeping a defined number of copies on disk, It starts by creating one copy of one or more folders and saves it in its unique folder named after the time and date of the day. The day after, it creates a second copy and the next day the same and so on. By the sixth day it will make a another copy but the script will also remove the oldest copy from disk. So you will always have a predefined number of copies on disk at all times (in this example it’s 5). If for any reason the admin executes the script manually this script won’t delete the oldest two folders but only the single oldest so keep that in mind. Another thing is that the websites_backup.service file has the last 2 lines commented. This is made on purpose due to that initially my idea was run the script once if the system reboots but this will accumulate unnecessary copies and probably make your disk run out of space if not paying attention.I kept the lines there just to remind myself of that.

    I’m using this script to keep copies of my websites. These are full folder copies.

    websites_backup.sh

    #!/bin/bash
    
    SOURCE_DIR="/var/www/*"
    BACKUP_DIR="/media/backup/websites_backups"
    LOG_FILE="/home/admin/CUSTOM_SERVER_SCRIPTS/backup.log"
    DATE=$(date +"%Y-%m-%d_%H-%M-%S")
    NUMBER_OF_BACKUPS="5"
    
            {
                    echo "Websites Backup Script execution started at: $(date)"
                    mkdir -p "$BACKUP_DIR/$DATE"
                    cp -ra $SOURCE_DIR "$BACKUP_DIR/$DATE"
                    echo "Copying all contents of /var/www/ folder to /media/backup/websites_backups"
                    echo "Websites Backups completed at: $(date)"
                    OLDEST_FOLDER=$(ls -t1 "$BACKUP_DIR" | tail -n +$((NUMBER_OF_BACKUPS+1)))
                    if [ -n "$OLDEST_FOLDER" ]; then
                            rm -rf "$BACKUP_DIR/$OLDEST_FOLDER"
                            echo "Deleted oldest backup folder, no more than 3 backups allowed."
                    fi
            } >> "$LOG_FILE" 2>&1  # Redirecting both stdout and stderr to the log file
    

    websites_backup.service

    To automate this process, a service file can be saved in /etc/systemd/system

    [Unit]
    Description=Backup process for websites in /var/www/ folder.
    After=network-online.target
    
    [Service]
    Type=simple
    ExecStart=/home/admin/CUSTOM_SERVER_SCRIPTS/websites_backup_script/websites_backup.sh
    Restart=on-failure
    StartLimitInterval=0
    
    # Running this script during system boot has been disabled.
    # Uncomment if you want it enabled. Keep in mind space storage management.
    #[Install]
    #WantedBy=multi-user.target

    Lets enable the service and to verify it’s running properly by typing:

    sudo systemctl enable websites_backup.service
    sudo systemctl status websites_backup.service

    websites_backup.timer

    [Unit]
    Description=websites_backup.service Timer
    
    [Timer]
    OnCalendar=*-*-* 7:00:00
    AccuracySec=1h
    RandomizedDelaySec=30m
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    

    Optional: Set OnCalendar=Mon 7:00:00 for weekly backup.

    This timer will trigger the execution of the websites_backup.service file that will run the websites_backup.sh script. This process will be repeated everyday at 7AM, it will also be triggered within 1 hour of the expected time of execution and an extra 30 mins max randomized execution time to avoid eventual processes spikes (if any). I believe it’s good practice to add randomized execution just in case you forget and decide to create a lot of services starting at the same time.

    In the near future I’d like to expand the functionality by also keeping 3 weekly copies at all times.

  • Install Nextcloud – Apache

    1. Prerequisites

    • Server: You need a server (VPS, dedicated server, or local server) running a Linux distribution (e.g., Ubuntu, CentOS, Debian).
    • Web Server: Apache should be installed and running.
    • PHP: Ensure PHP is installed (Nextcloud requires PHP 7.1 or higher) and php-gd, php-curl, php-xml, php-mbstring, php-zip.
    • Other optional but very useful packages, fail2ban and a front end firewall manager like ufw.
    sudo apt install certbot python3-certbot-apache wget

    Apache modules for enhanced security and for php integration

    sudo apt install libapache2-mod-php libapache2-mod-security2

    Certbot will provide the certificate for your website’s subdomain while python3-certbot-apache will facilitate the installation of the certificate in your system by integrating apache in the installation process. It will add the necessary lines where the certificates can be accessed into the nc.examle.conf file in folder sites-available and deploy the certificate, among other things

    2. Install Nextcloud Server Community edition

    https://download.nextcloud.com/server/releases/latest.zip

    Step 1: Unzip latest.zip to /var/www. I like to name those kind of folders as the name of the website they are holding in so you should rename it as example.com.

    Step 2: Set the correct permissions:

    sudo chown -R www-data:www-data /var/www/html/nc.example.com

    OPTIONAL INSTALL

    Alternatively, you can download the zip file and decompress the folder named nextcloud into your /var/www folder like so:

    Download the zip file to your home folder:

    wget https://download.nextcloud.com/server/releases/latest.zip

    Decompress:

    sudo unzip latest.zip -d /var/www/

    Rename folder according to the settings in your web server:

    mv /var/www/nextcloud /var/www/nc.example.com

    Set permissions to the www-data user

    Go to your ip address or domain setup for nextcloud after you had created an database user and the database itself.

    sudo chown -R www-data:www-data /var/www/nc.example.com

    3. Configure Apache for Nextcloud

    • Step 1: Enable necessary Apache modules:
    sudo a2enmod rewrite headers env dir mime ssl
    sudo systemctl restart apache2

    Step 2: Create a new Apache configuration file for Nextcloud:

    sudo nano /etc/apache2/sites-available/nc.example.com.conf

    Add the following configuration (modify paths if necessary):

    apache

    <VirtualHost *:80>
        ServerName nc.example.com
        Redirect permanent / https://nc.example.com/
    </VirtualHost>
    
    #########################################################
    
    <IfModule mod_ssl.c>
            <VirtualHost *:443>
                    ServerName nc.RootDomain
                    DocumentRoot /var/www/nc.example.com
    
    # NextCloud folder directives
                    <Directory /var/www/nc.example.com/>
                            Options +FollowSymlinks
                            AllowOverride All
                            Require all granted
                            Satisfy Any
                    </Directory>
    
    # Certificates
                    SSLEngine on
                    SSLCertificateFile /etc/letsencrypt/live/nc.example.com/cert.pem
                    SSLCertificateKeyFile /etc/letsencrypt/live/nc.example.com/privkey.pem
    
    # logging
                    ErrorLog ${APACHE_LOG_DIR}/nc.example.com_error.log
                    CustomLog ${APACHE_LOG_DIR}/nc.example.com_access.log combined
    
    # Reverse Proxy Directives. End edit appropriately before uncommenting.
    #               <Location />
    #                       ProxyPass http://localhost:50000/
    #                       ProxyPassReverse http://localhost:50000/
    #                       ProxyPreserveHost On
    #                       RequestHeader set X-Forwarded-Proto "https"
    #                       RequestHeader set X-Forwarded-Port "443"
    #               </Location>
    
            </VirtualHost>
    </IfModule>
    

    I’ve left some reverse proxy directives in the config file. Those are not going to be executed as long as they have the # at the beginning of the line. Remove them if you want.

    Once the config file is done and you are planing to have the nextcloud website in a subdomain, get the appropriate certificate with this command:

    sudo certbot certonly --webroot -w /var/www/example.com -d nc.example.com

    Step 3: Enable the Nextcloud site and restart Apache:

    sudo a2ensite nc.example.com
    sudo systemctl restart apache2

    4. If your plan is to use it for LAN only…

    <VirtualHost LAN_IP_ADDRESS:80>
        ServerAdmin admin@example.com
        ServerName nextcloud.example.com
    
        DocumentRoot /var/www/nextcloud
    
        <Directory /var/www/nextcloud>
            Options +FollowSymlinks
            AllowOverride All
    
            Require local
            # If you want to allow access from specific LAN IP ranges, use:
            # Require ip 192.168.1.0/24
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/nextcloud_error.log
        CustomLog ${APACHE_LOG_DIR}/nextcloud_access.log combined
    </VirtualHost>
    

    5. Using MySQL/MariaDB Command Line:

    The pre final step is to create a database for nextcloud. Download the appropriate packages if you dont have them already installed on your system. A secure installation of mariadb must have been already performed. I also prefer to name the database the same as the website from whic it receives the data.

    1. Access MySQL/MariaDB:bash

    mysql -u root -p

    Create a Database:

    CREATE DATABASE nc.example.com;

    Replace nc.example.com with the name you want for your Nextcloud database.

    Create a Database User:

    CREATE USER 'nextcloud_user'@'localhost' IDENTIFIED BY 'your_password';

    Replace nextcloud_user with the desired username and your_password with a strong password.

    Grant Permissions:

    GRANT ALL PRIVILEGES ON nc.example.com.* TO 'nextcloud_user'@'localhost';

    FLUSH PRIVILEGES;

    EXIT;

    Ensure to replace nc.example.com and nextcloud_user with your actual database name and username.

    6. Finalize Installation

    • Step 1: Open your web browser and navigate to http://nc.example.com/
    • Step 2: Follow the on-screen instructions to complete the Nextcloud setup.