Author: fjgraf

  • 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.

  • Editing image files

    So I decided to start adding images to this blog and I found two probably the best (prove me wrong) website for ai generated images and two (or three) pretty neat commands in my debian that are probably going to be the only ones I will ever use from now on when working with images.

    I’m no expert so I need easy to use tools just to get the job done quickly to upload images to this website and with minimum effort (I am shameless).

    https://zoo.replicate.dev

    Thanks to this website and the geniuses behind this open source project.

    So as a test, i will upload an image previously downloaded from their website. But before that, I will modify it to reduce its size to save space and make it more suitable as featured image.

    The first tool is exiftool that shows the metadata of the image.

    :~/server_images$ exiftool creepypplonajet.png

    ExifTool Version Number         : 12.16
    File Name                       : creepypiconajet.png
    Directory                       : .
    File Size                       : 879 KiB
    File Modification Date/Time     : 2023:11:04 04:49:15-04:00
    File Access Date/Time           : 2023:11:04 04:49:15-04:00
    File Inode Change Date/Time     : 2023:11:04 04:49:15-04:00
    File Permissions                : rw-r--r--
    File Type                       : PNG
    File Type Extension             : png
    MIME Type                       : image/png
    Image Width                     : 768
    Image Height                    : 768
    Bit Depth                       : 8
    Color Type                      : RGB
    Compression                     : Deflate/Inflate
    Filter                          : Adaptive
    Interlace                       : Noninterlaced
    Image Size                      : 768x768
    Megapixels                      : 0.590
    

    Then we have identify and convert… yep pretty simple named commands. Both identify and convert commands are part of the ImageMagick package and it’s supposed to be widely used and very popular.

    identify well.. identifies the images and convert well… converts them! I love the straightforwardness

    :~/server_images$ identify creepyppplonajet.png  
    creepyppplonajet.png PNG 768x768 768x768+0+0 8-bit sRGB 900046B 0.000u 0:00.000

    ls -lh

    -rw-r–r– 1 root root 879K Nov  4 04:49 creepypplonajet.png

    It’s a 768×768 image and 879 kilobytes. lets shrink it with convert by setting the pixel size.

    :~/server_images$ convert image.png -resize 200x200 image_small.png

    Your can also reduce (change) the size by choosing a percentage. In this case the image is reduced by 50%.

    :~/server_images$ convert image.png -resize 50% image_small.png
    After
    Before

    From 2.2 MB to 540 Kb

    Not bad at all and the possibilities are many in terms of efficiency managing large volumes of images and the capabilities of these tools.

    I’m juts going to make a brief pause to this post here and keep editing in the near feature to post more functionalities of the convert tool. In the meantime I’m publishing this post anyways!

    New edit: https://zoo.replicate.dev is not working as open as it was before. A good alternative is https://deepai.org.

  • 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.
  • Motion – Video recording and stream

    Ensure that your camera is being recognized by the system.

    Install video4linux utilities

    sudo apt install v4l-utils

    List devices (cameras)

    v4l2-ctl --list-devices

    The output should be something like this:

    HD Web Camera: HD Web Camera (usb-0000:00:14.0-4): /dev/video0 /dev/video1 /dev/media0

    For detailed information on a specific device:

    v4l2-ctl -d /dev/video0 --all

    To list the resolutions supported by your camera (2 ways):

    v4l2-ctl --list-formats-ext

    Or

    ffmpeg -f v4l2 -list_formats all -i /dev/video0

    Another way is to list the video devices available in /dev

    ls /dev/video*

    If you have only one camera, the device should show up as /dev/video0 in your system.

    Or with dmesg (it will print errors if any are found):

    dmesg | grep -i camera

    If there is necessary to update the camera’s firmware run:

    sudo apt install fwupd
    sudo fwupdmgr refresh
    sudo fwupdmgr get-updates
    sudo fwupdmgr update

    Install motion

    sudo apt-get install motion

    Test Mode should give a early hint if motion can handle your camera. Type the following command and if the output is suspended (active) then motion is getting video from the camera.

    sudo motion -s

    Configure Motion system files

    There is a chance that motion won’t create log and lib directories so verify if /var/log/motion and /var/bin/motion folders actually exist so you must create them and set change the directories and files ownership to the motion user:

    chown -R motion:motion /etc/motion
    chown -R motion:motion /var/log/motion
    chown -R motion:motion /var/lib/motion

    Configure /etc/motion/motion.conf

    Check the following github repo for the full motion.conf file if you wish all options. If not follow the next steps with the default config file.

    https://gist.github.com/richardhawthorn/72db3366d9824a3ed85de852bdb5ce0f

    sudo nano /etc/motion/motion.conf

    Depending on your system, the daemon mode should be off due to that motion would be running as a systemd service.

    daemon off 
    # Restrict to localhost
    webcontrol_localhost off
    # HTTP control interface (default on port 8080)
    webcontrol_port 8080
    # Start streaming server on port 8081
    stream_port 8081
    # Stream quality and settings
    stream_quality 100
    stream_motion on
    stream_maxrate 100
    stream_localhost off
    # IP camera configuration
    stream_localhost off
    stream_preview_scale 0.2
    stream_preview_new_name on
    video_device /dev/video0
    target_dir /tmp/motion
    output_pictures on
    
    # Other motion configuration options
    # See /usr/share/doc/motion/examples/motion-dist.conf.gz for additional options
    # Set the settings as needed for your camera and network environment.

    Restart motion service:

    sudo systemctl restart motion

    You should be able to see the live stream at http://ip_address:8080. It’s good practice to use ports above 50000 so lets change that in the config file for both webcontrol and the stream.

    If not, you can check via “systemctl status motion” for errors or in the log at /var/log/motion/motion.log. You can also check if motion is running and listening on 8080 and 8081 with ss:

    sudo ss -tunap | grep motion
    sudo ss -tunap | grep 51081

    If you find network problems, check your firewall configuration and open ports 8080 and 8081 if necessary.

    Setting up a password to the live stream

    Change the following options in /etc/motion/motion.conf. Type of configuration options to allow via the webcontrol (default port 8080). 2 is for advanced web configuration.

    webcontrol_parms 2

    The authentication method for the webcontrol. 1 is basic (user and password). Authentication string for the webcontrol. Syntax is username:password and you must remove the “;” (semicolon) to uncomment the line. Notice that the username is not a system user. Just make up a username to perform login inside the file.

    webcontrol_auth_method 1
    webcontrol_authentication someuser:pass

    Let’s do the same for webstream

    stream_auth_method 1
    stream_authentication someuser:pass
    sudo restart motion.service

    Your camera live feed should be available at your_local_ip:port and this time you will have to provide the user and password you have setup in the config file.

    Setup ssl-https with a self-signed certificate

    Install openssl if is not present on your system.

    sudo apt install openssl

    Create the key, csr, crt, and pem files. In the example below, the validity period is 2 years. Create a certs folder in /etc/motion. cd into the folder and type:

    sudo openssl genrsa -out /etc/motion/certs/motion.key 4096sudo openssl req -new -key /etc/motion/certs/motion.key -out /etc/motion/certs/motion.csr
    sudo openssl x509 -req -in /etc/motion/certs/motion.csr -signkey /etc/motion/certs/motion.key -out /etc/motion/certs/motion.crt -days 730
    sudo cat /etc/motion/certs/motion.crt /etc/motion/certs/motion.key > /etc/motion/certs/motion.pem

    Change ownership of the folder and all four created files to the motion user:

    sudo chown -R motion:motion /etc/motion/certs

    Configure motion.conf file again to add the paths to the crt and key files already created and don’t forget to remove the semicolons.

    # Use ssl / tls for the webcontrol
    webcontrol_tls on
    # Use ssl / tls for stream.
    stream_tls on
    
    # Full path and file name of the certificate file for tls
    webcontrol_cert /etc/ssl/motion/certs/motion.crt
    
    # Full path and file name of the key file for tls
    webcontrol_key /etc/motion/certs/motion.key
    
    # Use ssl / tls for stream.
    stream_tls on
    sudo systemctl restart motion

    Remember to configure port forward in your router and to open the ports in your system to successfully receive connections. Your camera should be availabe at your_public_ip:port

    Optional configuration for apache server

    If you wish to have the live stream available over the internet you will have to setup a virtual host in apache. In this example the live feed is available in a subdomain of my main site.

    The following extra modules for a proxy pass configuration need to be enabled.

    sudo a2enmod headers proxy proxy_http

    Create a new file in /etc/apache/sites-available/cam.yoursite.com.conf. Make sure you already have the required certificates from lets encrypt to your subdomain. Motion will not handle the certificates but rather apache. You must comment the lines with the path to other certificate and private key if you have been using them in motion.conf. The example here is using port 51081.

    <VirtualHost *:443>
        ServerName cam.yoursite.
    
        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/cam.yoursite.com/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/cam.yoursite.com/privkey.pem
    
        <Location />
            # Motion feed address
            ProxyPass http://localhost:51081/
            ProxyPassReverse http://localhost:51081/
            ProxyPreserveHost On
            RequestHeader set X-Forwarded-Proto "https"
            RequestHeader set X-Forwarded-Port "443"
        </Location>
    </VirtualHost>

    Enable the new site and restart apache.

    sudo a2ensite cam.yoursite.com.conf
    sudo service apache2 restart

    You should be able to view the live video stream with SSL by typing https://cam.yoursite.com and to access. I’ve left webcontrol only available over the LAN. Ports redirection will be handled automatically.

    Example of a simple motion.conf file.

    # Rename this distribution example file to motion.conf
    #
    # This config file was generated by motion 4.5.1
    # Documentation:  /usr/share/doc/motion/motion_guide.html
    #
    # This file contains only the basic configuration options to get a
    # system working.  There are many more options available.  Please
    # consult the documentation for the complete list of all options.
    #
    
    ############################################################
    # System control configuration parameters
    ############################################################
    
    # Start in daemon (background) mode and release terminal.
    daemon off
    
    # Start in Setup-Mode, daemon disabled.
    setup_mode off
    
    # File to store the process ID.
    ; pid_file value
    
    # File to write logs messages into.  If not defined stderr and syslog is used.
    log_file /var/log/motion/motion.log
    
    # Level of log messages [1..9] (EMG, ALR, CRT, ERR, WRN, NTC, INF, DBG, ALL).
    log_level 6
    
    # Target directory for pictures, snapshots and movies
    #target_dir /var/lib/motion 
    target_dir  /PATH/TO/YOUR/DESIRED/FOLDER
    
    # Video device (e.g. /dev/video0) to be used for capturing.
    video_device /dev/video0
    
    # Parameters to control video device.  See motion_guide.html
    ; video_params YUYV
    
    # The full URL of the network camera stream.
    ; netcam_url value
    
    # Name of mmal camera (e.g. vc.ril.camera for pi camera).
    ; mmalcam_name value
    
    # Camera control parameters (see raspivid/raspistill tool documentation)
    ; mmalcam_params value
    
    ############################################################
    # Image Processing configuration parameters
    ############################################################
    
    # Image width in pixels.
    width 800
    
    # Image height in pixels.
    height 600
    
    # Maximum number of frames to be captured per second.
    framerate 60
    
    # Rotate image this number of degrees. The rotation affects all saved images as
    # well as movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
    rotate 0
    
    # Text to be overlayed in the lower left corner of images
    text_left Camera_1
    
    # Text to be overlayed in the lower right corner of images.
    text_right %Y-%m-%d\n%T-%q
    
    # v4l2_palette allows one to choose preferable palette to be use by motion
    # to capture from those supported by your videodevice. (default: 17)
    # E.g. if your videodevice supports both V4L2_PIX_FMT_SBGGR8 and
    # V4L2_PIX_FMT_MJPEG then motion will by default use V4L2_PIX_FMT_MJPEG.
    # Setting v4l2_palette to 2 forces motion to use V4L2_PIX_FMT_SBGGR8
    # instead.
    #
    # Values :
    # V4l2 Option   FOURCC  v4l2_palette option
    # V4L2_PIX_FMT_SN9C10X  S910    0
    # V4L2_PIX_FMT_SBGGR16  BYR2    1
    # V4L2_PIX_FMT_SBGGR8   BA81    2
    # V4L2_PIX_FMT_SPCA561  S561    3
    # V4L2_PIX_FMT_SGBRG8   GBRG    4
    # V4L2_PIX_FMT_SGRBG8   GRBG    5
    # V4L2_PIX_FMT_PAC207   P207    6
    # V4L2_PIX_FMT_PJPG     PJPG    7
    # V4L2_PIX_FMT_MJPEG    MJPG    8
    # V4L2_PIX_FMT_JPEG     JPEG    9
    # V4L2_PIX_FMT_RGB24    RGB3    10
    # V4L2_PIX_FMT_SPCA501  S501    11
    # V4L2_PIX_FMT_SPCA505  S505    12
    # V4L2_PIX_FMT_SPCA508  S508    13
    # V4L2_PIX_FMT_UYVY     UYVY    14
    # V4L2_PIX_FMT_YUYV     YUYV    15
    # V4L2_PIX_FMT_YUV422P  422P    16
    # V4L2_PIX_FMT_YUV420   YU12    17
    # V4L2_PIX_FMT_Y10      Y10     18
    # V4L2_PIX_FMT_Y12      Y12     19
    # V4L2_PIX_FMT_GREY     GREY    20
    # v4l2_palette 17
    
    ############################################################
    # Motion detection configuration parameters
    ############################################################
    
    # Always save pictures and movies even if there was no motion.
    emulate_motion off
    
    # Threshold for number of changed pixels that triggers motion.
    threshold 1500
    
    # Noise threshold for the motion detection.
    ; noise_level 32
    
    # Despeckle the image using (E/e)rode or (D/d)ilate or (l)abel.
    despeckle_filter EedDl
    
    # Number of images that must contain motion to trigger an event.
    minimum_motion_frames 1
    
    # Gap in seconds of no motion detected that triggers the end of an event.
    event_gap 30
    
    # The number of pre-captured (buffered) pictures from before motion.
    pre_capture 3
    
    # Number of frames to capture after motion is no longer detected.
    post_capture 90
    
    ############################################################
    # Script execution configuration parameters
    ############################################################
    
    # Command to be executed when an event starts.
    ; on_event_start value
    
    # Command to be executed when an event ends.
    ; on_event_end value
    
    # Command to be executed when a movie file is closed.
    ; on_movie_end value
    
    ############################################################
    # Picture output configuration parameters
    ############################################################
    
    # Output pictures when motion is detected
    picture_output off
    
    # File name(without extension) for pictures relative to target directory
    picture_filename %Y%m%d%H%M%S-%q
    
    ############################################################
    # Movie output configuration parameters
    ############################################################
    
    # Create movies of motion events.
    movie_output on
    
    # Maximum length of movie in seconds.
    movie_max_time 60
    
    # The encoding quality of the movie. (0=use bitrate. 1=worst quality, 100=best)
    movie_quality 45
    
    # Container/Codec to used for the movie. See motion_guide.html
    movie_codec mkv
    
    # File name(without extension) for movies relative to target directory
    movie_filename %t-%v-%Y%m%d%H%M%S
    
    ############################################################
    # Webcontrol configuration parameters
    ############################################################
    
    # Port number used for the webcontrol.
    webcontrol_port 51080
    
    # Restrict webcontrol connections to the localhost.
    webcontrol_localhost off
    
    # Type of configuration options to allow via the webcontrol.
    webcontrol_parms 2
    
    # Set the authentication method (default: 0)
    # 0 = disabled
    # 1 = Basic authentication (username:password)
    # 2 = MD5 digest (the safer authentication)
    webcontrol_auth_method 1
    
    # Authentication for the http based control. Syntax username:password
    # Default: not defined (Disabled)
    webcontrol_authentication user:pass
    
    ############################################################
    # Live stream configuration parameters
    ############################################################
    
    # The port number for the live stream.
    stream_port 51081
    
    # Restrict stream connections to the localhost.
    stream_localhost off
    
    # Set the authentication method (default: 0)
    # 0 = disabled
    # 1 = Basic authentication
    # 2 = MD5 digest (the safer authentication)
    stream_auth_method 1
    
    # Authentication for the stream. Syntax username:password
    # Default: not defined (Disabled)
    stream_authentication user:pass
    
    ##############################################################
    # Camera config files - One for each camera.
    ##############################################################
    ; camera /usr/etc/motion/camera1.conf
    ; camera /usr/etc/motion/camera2.conf
    ; camera /usr/etc/motion/camera3.conf
    ; camera /usr/etc/motion/camera4.conf
    
    ##############################################################
    # Directory to read '.conf' files for cameras.
    ##############################################################
    ; camera_dir /usr/etc/motion/conf.d
    
  • Setup apache – wordpress (CLI only) for LAN

    Setup apache – wordpress (CLI only) for LAN

    sudo apt install apache2 mariadb-server php libapache2-mod-php php-mysql
    sudo apt-get install php php-mysql php-gd php-curl php-mbstring php-xml
    

    After installation, Apache should start automatically. To verify its status, use:

    sudo systemctl status apache2

    Secure MySQL/MariaDB: Run the security script to harden the database setup:

    sudo mysql_secure_installation

    And do not forget to save the root password for mariadb in a secure place!

    Create WordPress Database and User:

    Log in to the MySQL/MariaDB shell:

    sudo mysql -u root -p

    Create a new database, user, and grant privileges (replace placeholders with your preferred values):

    CREATE DATABASE wp_database;
    CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'password';
    GRANT ALL PRIVILEGES ON wp_database.* TO 'wp_user'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;

    Download and Extract WordPress: Navigate to Apache’s web root directory: cd /var/www/html and extract the “wordpress” folder.

    sudo wget https://wordpress.org/latest.tar.gz
    sudo tar -xzvf latest.tar.gz
    sudo mv wordpress/* .
    sudo rm -rf wordpress latest.tar.gz

    Configure WordPress:
    Make a copy of the sample config file in the root directory of wordpress and set it up by typing the details of wordPress database you previously configured.

    sudo cp wp-config-sample.php wp-config.php
    sudo nano wp-config.php

    Fill in the database details (DB_NAME, DB_USER, DB_PASSWORD), and save the file.

    Ensure proper file permissions for WordPress:

    sudo chown -R www-data:www-data /var/www/wordpress
    sudo chmod -R 755 /var/www/wordpress

    We can use the default apache file to manage incoming connections to port 80. Lets edit the contents to fit our purpose. You can create a new file if you wish to do so.

    sudo nano /etc/apache2/sites-available/000-default.conf
    <VirtualHost *:80>
    	ServerName LAN-WP
    
    	ServerAdmin webmaster@localhost
    	DocumentRoot /var/www/wordpress
    
    	ErrorLog ${APACHE_LOG_DIR}/error.log
    	CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>

    Ensure that the DocumentRoot directive points to the WordPress directory.

    Lets enable the site by typing:

    sudo a2ensite 000-default.conf

    Restart the apache server

    sudo systemctl reload apache2

    Open a web browser and navigate to your server’s IP address or domain.
    Follow the WordPress installation prompts to complete the setup (e.g., select language, set up admin user, etc.).

    Complete Installation:

    Log in to the WordPress admin dashboard and start configuring your site. That should get WordPress up and running on your Debian server with Apache and MariaDB. Adjust configurations as needed and follow WordPress best practices for security and optimization.

  • Send your public IP to your email – MSTP-MTA

    Send your public IP to your email – MSTP-MTA

    For those of us having a server at home with a basic home internet connection, the issue is how to easily bypass the problem of having port 25 blocked by our ISP. To quickly go around it you can setup an msmtp client to login to your personal email to send useful information from your running server. In this case is sending the public IP address just in case the IP address gets renewed so you can promptly update your DNS records for example if no automatic alternative is present. As far as I know wordpress DNS configuration does not have a way to be updated by an API so there you go…

    Manual Configuration

    For manual ip/dns public ip configuration and update, set up a msmtp client in your server and configure it using your external email provider credentials. This is in the scenario where you are unable to auto update your ip in your dns records. We’ll use msmtp-mta to setup an email event reminder so you can always be aware of any changes to act accordingly.

    sudo apt-get install msmtp-mta

    Create or edit the config file for msmtp. msmtp will look for a file named .msmtprc in your home folder by default (.file means it is an occult file and wont be displayed with ls unless specified). This file must contain the instructions and your personal credentials so that msmtp can use them to send your ip address to your own email securely with tls. This file creates an “account” readable by msmtp to be used to send email. In thiis example we will be storing the password in plain text inside the configuration file so it must be in a secure account only accessible to the owner of the external email service used to send emails. TLS will be enabled.

    nano /home/user/.msmtprc

    Edit with the following template:

    account admin
    host #EMAIL_DOMAIN E.g. google.com
    port 587 # verify port functionality. Port 25 is usually blocked by your ISP.
    auth on
    user admin@google.com #Try with username@yourmailserver.com first
    password TYPE_YOUR_EMAIL_PASSWORD_FOR_USER_ADMIN
    from admin@google.com
    tls on
    tls_starttls on
    tls_fingerprint #Get the SHA256 fingerprint from your email provider
    tls_trust_file /etc/ssl/certs/ca-certificates.crt #verify this location on your system.

    Be aware that if the information is not correctly typed, msmtp might give you misleading error codes which will make troubleshooting very hard. Check the correct details of our email provider before. An example of this is the real root server of your email provider might not be the .net or .com domain extension but rather a .us or pl or any other extemsion if they have the root email services in a foreign country. Next, create and configure a script to be used by msmtp in your home folder. Install curl if is not installed already.

    If problems arise with permissions, make sure to set permissions 600 for your user to the .msmtp file.

    sudo apt-get install curl
    sudo nano /home/user/.msmtprc_email_new_pub_ip.sh

    The following script will ask your public ip to ifconfig.me using the curl command and be stored in the variable IP_ADDRESS. This value will be in the subject of your email and passed to msmtp. msmtp will load the account details and send the email wherever you want to receive it. To make further comparisons the old ip address will be saved to a file to be compared the next time this script is executed.

    #!/bin/bash
    
    # Get current IP address
    IP_ADDRESS=$(curl -s ifconfig.me)
    
    # Define variables
    MSMTP_ACCOUNT=john
    RECIPIENT_EMAIL=john@gmail.com
    MSMTP_CONFIG_FILE=/home/john/.msmtprc
    IP_HISTORY_FILE=/home/john/.msmtprc_ip
    
    # Check if the IP history file exists; if not, create it
    if [[ ! -f $IP_HISTORY_FILE ]]; then
        echo "$IP_ADDRESS" > "$IP_HISTORY_FILE"
        exit 0  # Exit since there's no previous IP to compare
    fi
    
    # Read the historic IP address
    IP_HISTORIC=$(cat "$IP_HISTORY_FILE")
    
    # Compare the current IP address with the historic one
    if [[ "$IP_HISTORIC" != "$IP_ADDRESS" ]]; then
        # Send the email
        echo "Subject: UPDATE $IP_ADDRESS" | msmtp -a "$MSMTP_ACCOUNT" "$RECIPIENT_EMAIL"
        
        # Update the historic IP address
        echo "$IP_ADDRESS" > "$IP_HISTORY_FILE"
    else
        echo "IP address has not changed. No email sent."
    fi

    Save the file, make it executable and test if is working correctly.

    sudo chmod +x .msmtprc_email_new_pub_ip.sh
    sudo ./home/user/.msmtprc_email_new_pub_ip_update.sh

    Automate the task to send your public ip by email every 12 hours

    If all went well, continue creating a msmtprc_email_new_pub_ip.service and a msmtprc_email_new_pub_ip.timer files to run them as systemd services to automate sending emails right after system boot and every 12 hours.

    sudo nano /etc/systemd/system/msmtprc_email_new_pub_ip.service
    [Unit]
    Description=Runs a script to send public ip address via email.
    
    [Service]
    Type=simple
    User=admin
    WorkingDirectory=/home/admin/
    ExecStart=/home/user/.msmtprc_email_new_pub_ip.sh
    
    [Install]
    WantedBy=multi-user.target

    Save and exit.

    sudo nano /etc/systemd/system/msmtprc_email_new_pub_ip.timer
    [Unit]
    Description=Timer for msmtprc_email_new_pub.service file

    [Timer]
    OnCalendar=--* 5,18:00
    RandomizedDelaySec=12h
    Persistent=true

    [Install]
    WantedBy=timers.target

    Save file and exit.

    Reload the daemon

    sudo systemctl daemon-reload

    Enable both services

    sudo systemctl enable msmtprc_email_new_pub_ip.service msmtprc_email_new_pub_ip.timer

    Verify both services are running correctly with “sudo status name_of_service”

    Reboot your system and verify again.

    Check your email. If it’s successful, wait 12 hours for the next email.

    Another better option is using only one service file to manage the execution of the script and the timer. The timer here is going to trigger the execution of the script every hour and right after boot. I’m doing this now just because I can 🙂

    [Unit]
    Description=Sends public ip address to specified email address using msmtp.
    After=network-online.target
    
    [Service]
    Type=simple
    User=user
    WorkingDirectory=/home/user
    ExecStart=/home/user/.msmtprc_email_new_pub_ip.sh
    Restart=always
    RestartSec=3600
    StartLimitInterval=0
    
    [Install]
    WantedBy=multi-user.target
    

  • IP address autoupdate – Cloudflare

    IP address autoupdate – Cloudflare

    Create an API token in Cloudflare

    Log in to your cloudflare’s dashboard and enter the domain you want to manage.

    • Copy your “Zone ID”
    • Click to “Get your API token”
      • Create two permissions:
      • Zone | DNS | Read
      • Zone | DNS | Edit
    • Edit Zone resources
      • Include | Specific zone | YOUR_DOMAIN

    Save your API key token and save the number generated. Once you exit the page you won’t be able to get it again.


    apt install git

    Choose a good location to save the following git folder. It contains the script to update your ip.

    git clone https://github.com/K0p1-Git/cloudflare-ddns-updater.git

    Cd into folder, copy the template file, rename it and make a copy. Edit your new copy with your own details like so (I’m not using the global API):

    auth_email="YOUR_EMAIL"     # The email used to login 'https://dash.cloudflare.com'
    auth_method="token"         # Set to "global" for Global API Key or "token" for Scoped API Token
    auth_key="YOUR_API_TOKEN"   # Your API Token or Global API Key
    zone_identifier="YOUR_ZONE_ID"    # Can be found in the "Overview" tab of your domain
    record_name="YOUR_ROOT_DOMAIN"    # Which record you want to be synced
    ttl="3600"                        # Set the DNS TTL (seconds)
    proxy="false"                     # Set the proxy to true or false
    sitename="SITE_TITLE"          # Title of site "Example Site"
    slackchannel=""                                     # Slack Channel #example
    slackuri=""                                         # URI for Slack WebHook "https://hooks.slack.com/services/xxxxx"
    discorduri=""                                       # URI for Discord WebHook "https://discordapp.com/api/webhooks/xxxxx"
    sudo chmod +x [path_to_your_script]

    Schedule automatic verification and update of your public IP

    After that a cron job can be created to run the script periodically. Create it with sudo so it is run by root and not by your admin user. Reason if that if the system restarts and you are not around to log in, the cron job for your user won’t start until you log in. This is undesirable if your server is meant o run partially supervised.

    sudo crontab -e

    Example of adding a cron job to be executed every 15 mins everyday.

    */15 * * * * /home/user/cloudflare-ddns-updater/cloudflare-template.sh

    Save and exit.

    Update cron service.

    systemctl restart cron.service

    Using a systemd service file

    Instead of a cron job you can create a service file in /etc/systemd/system and save it with the following directives. This might be more advantageous because if the service stops for whatever reason you can be easily be notified to solve the problem. Here is an example of a service file where is defined the path to the script and the time interval (every 12 hours):

    [Unit]
    Description=Public IP address verification and update for cloudflare dns records.
    After=network-online.target
    
    [Service]
    Type=simple
    ExecStart=/home/user/cloudflare-ddns-updater/cloudflare-template.sh
    Restart=always
    RestartSec=43200
    StartLimitInterval=0
    
    [Install]
    WantedBy=multi-user.target
    

    sudo systemctl daemon-reload

    sudo systemctl restart [name_of_your_service_file]

    Credits to Jason K. and collaborators
    https://github.com/K0p1-Git/cloudflare-ddns-updater/tree/main