Monday, October 6, 2025

Debian 13: How to save ai solution with mathematical formula into odt file

After you ask AI, and AI give you solution with mathematical formula. You can not directly to copy-paste the result into libreoffice writer nor microsoft word.

1. Ask your AI to show the result in latex format.

2. Copy paste the result into text file e.q. example.text.

3. Create empty odt file e.q. output.odt 

4. Use pandoc application to convert it into odt.

$ pandoc -f latex -t odt -o output.odt example.text

    if the input file is latin1 encoded, like my text files, the solution is (imo the best output):

$ iconv -f ISO-8859-1 example.text | pandoc -f latex -t odt -o tmp.odt

    WARNING: this command will replace any content in tmp.odt and output.odt. 

5. Now, you can open odt with mathematical formula. 

To install pandoc and iconv (part of libc-bin) 

# apt-get install pandoc libc-bin libreoffice-texmaths

 

Sunday, October 5, 2025

Debian 13: moving from iptables to nftables

Nftables has been introduced from debian 10. iptables still available until debian 12. since debian 13, nftables is the default firewall. there is iptables-nft layer if user still want to interact with nftables with iptables command with some limitation due to they have different way to manage firewall.

The nftables flow to create firewall rules:

  1. Create rule
  2. Create a table
  3. Create a chain
  4. Create a set (for IPv4 or IPv6)

Add rule(s) that match against that set, we’re using the inet family, the same output chain can handle both IPv4 and IPv6. These is /etc/nftables.conf for pc 

  1. any connection from localhost  to outside
  2. accept incoming connection for port http, https and ssh from outside
  3. block incoming access from ip 1.2.3.4 
  4. block incoming access from ip 1.2.3.5 for port ssh

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    # Define a set for allowed TCP ports
    set allowed_tcp_ports {
        type inet_service;
        elements = { 22, 80, 443 }
    }

    # Define a set for blocked IPv4 addresses (all traffic)
    set blocked_ips {
        type ipv4_addr;
        elements = { 1.2.3.4 }
    }

    # Define a set for IPs blocked only on SSH
    set ssh_blocked_ips {
        type ipv4_addr;
        elements = { 1.2.3.5 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        # Drop packets from blocked IPs (all traffic)
        ip saddr @blocked_ips drop

        # Drop SSH packets from ssh_blocked_ips
        tcp dport 22 ip saddr @ssh_blocked_ips drop

        # Allow loopback interface
        iif lo accept

        # Accept established and related connections
        ct state established,related accept

        # Allow ICMP (ping)
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # Allow TCP packets to ports in allowed_tcp_ports set
        tcp dport @allowed_tcp_ports accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

To add element in blocked_ips (temporary, need to save)

# nft add element inet filter blocked_ips { 5.6.7.8 }

To replace the whole element in blocked_ips (temporary, need to save)

# nft replace set inet filter blocked_ips { elements = { 1.2.3.4, 2.3.4.5 } }

To delete an element in blocked_ips (temporary, need to save)

# nft delete element inet filter blocked_ips { 203.0.113.5 }

To store/save nftables permanently  

# nft list ruleset > /etc/nftables.conf

This command will clean/remove all rules until nftables.conf reload

# nft flush ruleset

Back to iptables, in iptables the rules store and restore with following command:

# nft list ruleset > my_rules.nft
# nft -f my_rules.nft 

This is vulnerable to the system, there is a delay when system ready but not protected by firewall until system fully loading the the firewall rules. This weakness has been eliminate in nftables, nftables uses systemd to load the firewall. Firewall was loaded before system ready.

To enable nftables and start

# systemctl enable nftables
# systemctl start nftables

To export set blocked_ips in nftables

# nft list set inet filter blocked_ips > blocked_ips.conf
# nft -f blocked_ips.conf

These are more cleaner nftables.conf, set will be put on different file

/etc/nftables.conf:

#!/usr/sbin/nft -f

flush ruleset

include "/etc/nftables.d/sets-common.nft"
include "/etc/nftables.d/sets-ipv4.nft"
include "/etc/nftables.d/sets-ipv6.nft"

table inet filter {

    chain input {
        type filter hook input priority 0; policy drop;

        ip saddr @blocked_ips_v4 drop
        ip6 saddr @blocked_ips_v6 drop

        tcp dport 22 ip saddr @ssh_blocked_ips_v4 drop
        tcp dport 22 ip6 saddr @ssh_blocked_ips_v6 drop

        iif lo accept

        ct state established,related accept

        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        tcp dport @allowed_tcp_ports accept
        tcp dport @allowed_tcp_ports accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

/etc/nftables.d/sets-common.nft: 

table inet filter {
    set allowed_tcp_ports {
        type inet_service;
        elements = { 22, 80, 443 }
    }
}

/etc/nftables.d/sets-ipv4.nft: 

table inet filter {
    set blocked_ips_v4 {
        type ipv4_addr;
        elements = { 1.2.3.4 }
    }

    set ssh_blocked_ips_v4 {
        type ipv4_addr;
        elements = { 1.2.3.5 }
    }
}

/etc/nftables.d/sets-ipv6.nft:

table inet filter {
    set blocked_ips_v6 {
        type ipv6_addr;
        elements = { 2001:db8::dead:beef }
    }

    set ssh_blocked_ips_v6 {
        type ipv6_addr;
        elements = { 2001:db8::cafe:babe }
    }
}

 

Wednesday, October 1, 2025

Moving apace, mariadb and php project from a debian site to other debian site

I want to create a bash script to backup and restore the project (apache, mariadb and php) easily. I need to work at 2 debian machine with the same configuration in 2 different location. I ask to duck.ai to solve the problem. Here is the result.

Create a file myconfig.conf

# myconfig.conf
DB_NAME="your_database_name"
DB_USER="your_username"
DB_PASS="your_password"
PROJECT_ROOT="/path/to/your/php/project"  # Add this line

Create bash script mybackup.sh 

#!/bin/bash

# Load database configuration from myconfig.conf
source myconfig.conf

# Create a backup file name for the database
DB_BACKUP_FILE="${DB_NAME}_$(date +%Y-%m-%d).sql"
# Create a zip file name for the project
PROJECT_BACKUP_FILE="$(basename "$PROJECT_ROOT")_backup_$(date +%Y-%m-%d).zip"

# Function to backup the database
backup_database() {
    echo "Backing up database: $DB_NAME"
    mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" > "$DB_BACKUP_FILE"
    if [ $? -eq 0 ]; then
        echo "Database backup successful: $DB_BACKUP_FILE"
    else
        echo "Database backup failed!"
        return 1
    fi
}

# Function to zip the project files
zip_project() {
    echo "Zipping project files from: $PROJECT_ROOT"
    zip -r "$PROJECT_BACKUP_FILE" "$PROJECT_ROOT"
    if [ $? -eq 0 ]; then
        echo "Project backup successful: $PROJECT_BACKUP_FILE"
    else
        echo "Project backup failed!"
        return 1
    fi
}

# Function to restore the database
restore_database() {
    echo "Restoring database: $DB_NAME from $1"
    mysql -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" < "$1"
    if [ $? -eq 0 ]; then
        echo "Database restore successful!"
    else
        echo "Database restore failed!"
    fi
}

# Function to unzip the project files
unzip_project() {
    echo "Unzipping project files to: $PROJECT_ROOT"
    unzip -o "$1" -d "$PROJECT_ROOT"
    if [ $? -eq 0 ]; then
        echo "Project restore successful!"
    else
        echo "Project restore failed!"
    fi
}

# Check command line arguments
if [ "$1" == "backup" ]; then
    backup_database
    zip_project
elif [ "$1" == "restore" ]; then
    if [ -z "$2" ] || [ -z "$3" ]; then
        echo "Please provide the SQL backup file and the project zip file to restore from."
        exit 1
    fi
    SQL_BACKUP_FILE="$2"
    PROJECT_BACKUP_FILE="$3"
    restore_database "$SQL_BACKUP_FILE"
    unzip_project "$PROJECT_BACKUP_FILE"
else
    echo "Usage: $0 {backup|restore [sql_backup_file] [project_backup_file]}"
    exit 1
fi

To backup

./mybackup.sh backup

It will create 2 files

  1. zip for backup and restore web root project
  2. sql for backup and restore mariadb database 

To restore

./mybackup.sh restore your_database_backup.sql your_project_backup_file.zip

 

Tuesday, September 30, 2025

How to fix error HY000/1045 after upgrading phpmyadmin

I used Debian 13 repository to upgrade phpmyadmin. During upgrading from previous version, configuration can not be continue and must be ignore. After phpmyadmin installed error messages come to web:

  • mysqli::real_connect(): (HY000/1045): Access denied for user 'phpmyadmin'@'localhost' (using password: YES) 
  • Connection for controluser as defined in your configuration failed.

Create user pma (default) and password:

MariaDB [(none)]> CREATE USER 'pma'@'localhost' IDENTIFIED BY 'pmapass';
Query OK, 0 rows affected (0.003 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON phpmyadmin.* TO 'pma'@'localhost';
Query OK, 0 rows affected (0.003 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.002 sec)

Edit file /etc/phpmyadmin/config-db.php

...
$dbuser='pma';
$dbpass='pmapass';
...

Edit file /etc/phpmyadmin/config.inc.php

...
/* Configure according to dbconfig-common if enabled */
if (!empty($dbname)) {
    /* Authentication type */
    $cfg['Servers'][$i]['auth_type'] = 'cookie';
    /* Server parameters */
    if (empty($dbserver)) $dbserver = 'localhost';
    $cfg['Servers'][$i]['host'] = $dbserver;

    if (!empty($dbport) || $dbserver != 'localhost') {
        $cfg['Servers'][$i]['connect_type'] = 'tcp';
        $cfg['Servers'][$i]['port'] = $dbport;
    }
    //$cfg['Servers'][$i]['compress'] = false;
    /* Optional: User for advanced features */
    $cfg['Servers'][$i]['controluser'] = $dbuser;
    $cfg['Servers'][$i]['controlpass'] = $dbpass;
    /* Optional: Advanced phpMyAdmin features */
    $cfg['Servers'][$i]['pmadb'] = $dbname;
    $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
    $cfg['Servers'][$i]['relation'] = 'pma__relation';
    $cfg['Servers'][$i]['table_info'] = 'pma__table_info';
    $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
    $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
    $cfg['Servers'][$i]['column_info'] = 'pma__column_info';
    $cfg['Servers'][$i]['history'] = 'pma__history';
    $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
    $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
    $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
    $cfg['Servers'][$i]['recent'] = 'pma__recent';
    $cfg['Servers'][$i]['favorite'] = 'pma__favorite';
    $cfg['Servers'][$i]['users'] = 'pma__users';
    $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
    $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
    $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
    $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
    $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
    $cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';

    /* Uncomment the following to enable logging in to passwordless accounts,
     * after taking note of the associated security risks. */
    // $cfg['Servers'][$i]['AllowNoPassword'] = TRUE;

    /* Advance to next server for rest of config */
    $i++;
}

/* Authentication type */
//$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
//$cfg['Servers'][$i]['host'] = 'localhost';
//$cfg['Servers'][$i]['connect_type'] = 'tcp';
//$cfg['Servers'][$i]['compress'] = false;
/* Uncomment the following to enable logging in to passwordless accounts,
 * after taking note of the associated security risks. */
// $cfg['Servers'][$i]['AllowNoPassword'] = TRUE;

/**
 * phpMyAdmin configuration storage settings.
 */

/* User used to manipulate with storage */
$cfg['Servers'][$i]['controlhost'] = '';
$cfg['Servers'][$i]['controlport'] = '';
$cfg['Servers'][$i]['controluser'] = 'pma';
$cfg['Servers'][$i]['controlpass'] = 'pmapass';

/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
$cfg['Servers'][$i]['recent'] = 'pma__recent';
$cfg['Servers'][$i]['favorite'] = 'pma__favorite';
$cfg['Servers'][$i]['users'] = 'pma__users';
$cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
$cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
$cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
$cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
$cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';
...

 

Debian 13: how to limit cpu frequency to preserve power or keep cpu cooler

Since Debian 13, cpufreq is being replaced by cpupower. Don't mix using power-profiles-daemon and linux-cpupower. I prefer to use linux-cpupower.

Install 

# apt-get install linux-cpupower

Show available frequency

# cpupower frequency-info
analyzing CPU 1:
  driver: acpi-cpufreq
  CPUs which run at the same hardware frequency: 1
  CPUs which need to have their frequency coordinated by software: 1
  maximum transition latency: 4.0 us
  hardware limits: 1000 MHz - 2.20 GHz
  available frequency steps:  2.20 GHz, 2.00 GHz, 1.80 GHz, 1.60 GHz, 1.30 GHz, 1000 MHz
  available cpufreq governors: performance schedutil
  current policy: frequency should be within 1000 MHz and 2.20 GHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: 1.30 GHz (asserted by call to hardware)
  boost state support:
    Supported: yes
    Active: no
    Boost States: 2
    Total States: 8
    Pstate-Pb0: 2500MHz (boost state)
    Pstate-Pb1: 2400MHz (boost state)
    Pstate-P0:  2200MHz
    Pstate-P1:  2000MHz
    Pstate-P2:  1800MHz
    Pstate-P3:  1600MHz
    Pstate-P4:  1300MHz
    Pstate-P5:  1000MHz

Available frequency steps are:  2.20 GHz, 2.00 GHz, 1.80 GHz, 1.60 GHz, 1.30 GHz, 1000 MHz. Use frequency 1.8 GHz for all core:

# cpupower frequency-set -u 1.80 GHz
Setting cpu: 0
Setting cpu: 1
Setting cpu: 2
Setting cpu: 3

After applying maximum frequency

# cpupower frequency-info
analyzing CPU 2:
  driver: acpi-cpufreq
  CPUs which run at the same hardware frequency: 2
  CPUs which need to have their frequency coordinated by software: 2
  maximum transition latency: 4.0 us
  hardware limits: 1000 MHz - 2.20 GHz
  available frequency steps:  2.20 GHz, 2.00 GHz, 1.80 GHz, 1.60 GHz, 1.30 GHz, 1000 MHz
  available cpufreq governors: performance schedutil
  current policy: frequency should be within 1000 MHz and 1000 MHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: 1000 MHz (asserted by call to hardware)
  boost state support:
    Supported: yes
    Active: no
    Boost States: 2
    Total States: 8
    Pstate-Pb0: 2500MHz (boost state)
    Pstate-Pb1: 2400MHz (boost state)
    Pstate-P0:  2200MHz
    Pstate-P1:  2000MHz
    Pstate-P2:  1800MHz
    Pstate-P3:  1600MHz
    Pstate-P4:  1300MHz
    Pstate-P5:  1000MHz

To make it persistent, create or edit /etc/systemd/system/cpu-limit.service

[Unit]
Description=Set CPU power management settings
# latest state runlevel 3 in SysVinit, let CPU run maximum frequency during starting system services
After=multi-user.target
# run after network ready
#After=network.target
# network may not run
#After=sysinit.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cpupower frequency-set -u 2.00GHz
#ExecStart=/usr/bin/cpupower frequency-set --max 2.00GHz
#ExecStart=/usr/bin/cpupower frequency-set -g performance
# You can customize the cpupower command here.
# For example, to set to powersave:
# ExecStart=/usr/bin/cpupower frequency-set -g powersave
# Or to set a specific frequency:
# ExecStart=/usr/bin/cpupower frequency-set -f 2.5GHz

[Install]
WantedBy=multi-user.target

Note: you can copy paste and adjust frequency for your laptop/PC.

Change file permission

# chmod 644 /etc/systemd/system/cpu-limit.service

Reload system daemon

# systemctl daemon-reload
# systemctl enable cpu-limit.service
Created symlink '/etc/systemd/system/multi-user.target.wants/cpu-limit.service' → '/etc/systemd/system/cpu-limit.service'.

Everytime your restart this daemon will run time to set maximum frequency.