To kill a process, run
kill -9 PID
To kill a process by its name, run
pkill -9 -f '/x86_64\.uhavenobotsxd'

To kill a process, run
kill -9 PID
To kill a process by its name, run
pkill -9 -f '/x86_64\.uhavenobotsxd'

To find cpu temperature on Linux, run
cat /sys/class/thermal/thermal_zone*/temp
You can also use sensors command, to install, use
apt install lm-sensors -y
To find cpu frequency, run
lscpu | grep "MHz"
To monitor CPU frequency, run
watch -n1 "cat /proc/cpuinfo | grep 'MHz' | head -n16"

When connecting to an Ubuntu 24.04 server from CentOS 6 server, i got error “no hostkey alg”
root@server12:~# ssh root@144.24.105.110
no hostkey alg
root@server12:~#
To fix this error, edit /etc/ssh/sshd_config on Ubuntu server and add followng to end of the file
HostKeyAlgorithms +ssh-rsa,ssh-dss
PubkeyAcceptedKeyTypes +ssh-rsa,ssh-dss
Restart ssh service on Ubuntu
systemctl restart ssh
Now you should be able to connect to Ubuntu server from CentOS 6 using SSH. If you are using ssh key auth, use RSA key, newer keys like ed25519 won’t work and result in following error message
root@server12:~# ssh root@144.24.105.110
key_from_blob: remaining bytes in key blob 36
key_to_blob: unsupported key type 11
Permission denied (publickey).
root@server12:~#
Once the ile transfer is done, edit /etc/ssh/sshd_config on ubuntu server and remove the older (less secure) algorithms.
Back to ssh

Recently a customer send an ovpn file to connect to a server, which is on private netowrk.
When i connect to the VPN, all my internet traffic get routed via the VPN. I only want traffic the server get routed through the VPN.
The .ovpn file had following content
dev tun
persist-tun
persist-key
data-ciphers AES-256-CFB8:AES-128-GCM:AES-256-CBC
data-ciphers-fallback AES-256-CBC
auth SHA256
tls-client
client
resolv-retry infinite
remote 12.15.1.112 9411 udp4
nobind
verify-x509-name "colmed-oci" name
pkcs12 sok.p12
tls-auth sok-tls.key 1
remote-cert-tls server
explicit-exit-notify
To configure the OpenVPN client to route only specific traffic (e.g., 10.20.60.0/24) through the VPN while leaving the rest of the traffic to use your regular internet connection, edit .ovpn file and add the folowing to it.
route 10.20.60.0 255.255.255.0
pull-filter ignore "redirect-gateway"
First line tells the VPN client to route traffic destined for 10.20.60.0/24 through the VPN.
Second directive prevents OpenVPN from pushing a redirect-gateway command, which would send all traffic through the VPN.
To verify route, use the command
ip route
You will see entry like the following
boby@sok-01:~$ ip route | grep "10.20.60"
10.20.60.0/29 via 10.80.30.1 dev tun0
10.20.60.0/24 via 10.80.30.1 dev tun0
boby@sok-01:~$
Back to OpenVPN

When migrating a website, transferring files from the source server to the destination server is a key step. If you have SSH access, you can use commands like rsync, scp, or FTP to move the files efficiently.
However, without SSH access, the process becomes more tedious. You’d need to download the files to your local computer first and then upload them to the new server. This method not only consumes time but also uses up bandwidth, which can be a significant drawback, particularly for large files or slower internet connections.
This PHP script simplifies the process by allowing you to transfer files directly from the source server to the destination server without needing intermediate downloads. Using PHP’s cURL functions, you can download backups from the source server to the destination server, saving both time and bandwidth.
<?php
# Author: ServerOK
# Web: https://serverok.in/server-to-server-file-transfer-with-php-script
# URL of the file to be downloaded
$source_url = 'https://example.com/backup.zip';
$filename = basename(parse_url($source_url, PHP_URL_PATH));
$destination_path = __DIR__ . '/' . $filename;
set_time_limit(0);
function download($source, $destination) {
$ch = curl_init($source);
$fp = fopen($destination, 'w+');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 4096);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
$success = curl_exec($ch);
if ($success === false) {
echo 'cURL Error: ' . curl_error($ch);
return false;
}
curl_close($ch);
fclose($fp);
return true;
}
$success = download($source_url, $destination_path);
if ($success) {
echo '<p style="color: green; font-weight: bold; font-size: 16px;">File transferred successfully to ' . htmlspecialchars($destination_path) . '</p>';
} else {
echo '<p style="color: red; font-weight: bold; font-size: 16px;">File transfer failed</p>';
}
1) Create a Backup on the Source Server
Log in to your source server’s control panel and create a compressed archive (zip or tar.gz) of your website’s document root, usually “public_html” or “httpdocs”, depending on your server setup. Move this file to the document root so that it can be accessed via a URL, like:
https://example.com/backup.zip
2) Prepare the Destination Server
Log in to your destination server and create a file named download.php. Paste the PHP code above into the file. In the script, locate the line:
$source_url = 'https://example.com/backup.zip';
Replace the URL with the link to your backup file.
3) Run the PHP Script on the Destination Server
Run the script on your destination server to download the backup file and store it in the same folder as the script. Make sure you perform this step while the domain still points to the source server. If the domain is already pointed to the new server, the download link will no longer work.
To run the download.php script without changing the nameservers or DNS, you need to modify your computer’s hosts file and add an entry for the domain so your computer will see the site from the new server without DNS change.
NEW-SERVER-IP-HERE yourdomain.com www.yourdomain.com
After editing the hosts file, restart your browser to view the site from the new server. For more details, refer to Preview Website Before Nameserver Change.
Once the file is downloaded to the destination server, you can extract it using the hosting control panel or a PHP exec script. Move the extracted files to the correct directory to make the site work.
If your site uses a MySQL database, you’ll also need to download a database backup from the source server and restore it on the destination server. For large databases, phpMyAdmin may fail to restore properly. You can find a PHP script which help restore database backup using PHP script at How to Restore Large Database with PHP Script

First, enable epel repo
dnf install epel-release
Enable rpmfusion repo
dnf install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
dnf install https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm
Install ffmpeg with
dnf install ffmpeg
Verify ffmpeg is working
[root@nc-ph-0997-24 ~]# ffmpeg -version
ffmpeg version 4.2.10 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 8 (GCC)
configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsrt --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-version3 --enable-vapoursynth --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg --enable-libzvbi --enable-avfilter --enable-avresample --enable-libmodplug --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[root@nc-ph-0997-24 ~]#
Back to ffmpeg

Restoring a large MySQL database can sometimes be a daunting task, especially when using phpMyAdmin, which may fail due to size limitations or timeouts. In such cases, utilizing SSH/Terminal is often the go-to solution. However, if you lack SSH access, you can still restore your database using a simple PHP script.
Create a new PHP file, for example, restore.php, and add the following code:
<?php
# Author: ServerOK
# Web: https://serverok.in
$mysqlDatabase = 'MYSQL_DB_NAME';
$mysqlUser = 'MYSQL_USER';
$mysqlPassword = 'MYSQL_PW';
$backupFile = 'BACKUP_FILE.sql';
// Increase execution time limits
ini_set('max_execution_time', 0);
set_time_limit(0);
ini_set('mysql.connect_timeout', 0);
ini_set('default_socket_timeout', 0);
$sqlCmd = "mysql -u $mysqlUser -p'$mysqlPassword' $mysqlDatabase < $backupFile";
exec($sqlCmd . " 2>&1", $output, $returnValue);
if ($returnValue == 0) {
echo "<h1 style='color:green'>Database restored successfully.</h1>";
} else {
echo "<h2 style='color:red'>ERROR: Database restore failed.</h2>";
echo "cd " . __DIR__ . "<br>";
echo "$sqlCmd<br>";
echo "<pre>";
print_r($output);
var_dump($returnValue);
}
In the script above, replace the following placeholders with your actual values:
MYSQL_DB_NAME: The name of the database you want to restore.
MYSQL_USER: Your MySQL username.
MYSQL_PW: Your MySQL password.
BACKUP_FILE.sql: The name of your backup file.
Upload your .sql backup file to your server’s document root folder. This is typically the same location where your restore.php script will reside. You can use FTP or File Manager to do it.
On cPanel server, the directory name is public_html, for Plesk, it is httpdocs. If you use another control panel, check with the control panel documentation.
Now, navigate to your script in a web browser by entering the following URL:
http://yourdomain.com/restore.php
After the restoration process, ensure you delete restore.php and the MySQL backup (.sql) file from your server to prevent any unauthorized access.
Back MySQL Restore

mdadm is used to manage software RAID. Install mdadm package with
apt install mdadm
To set up RAID 1 (mirror), you need 2 drives or partitions of the same size
Create a partition with the following commands on both the drives used for RAID 1.
parted /dev/sdX mklabel gpt
parted /dev/sdX mkpart primary ext4 0% 100%
parted /dev/sdX set 1 raid on
parted /dev/sdX print
Replace /dev/sdX with device name of the drive you will be using for the RAID.
To create a RAID 1 mirror, use the following command
IMPORTANT: Do not cut and paste without understanding what you are doing, you need to replace device names to avoid data loss.
mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1
In the above command, replace /dev/md0 with the device name of the RAID array you need. If your system already has a raid array with this name, use another name, for example: /dev/md1.
/dev/sdb1 and /dev/sdc1 = replace these with the device name of the drives you will be using for the RAID 1
To see the raid status, use the command
cat /proc/mdstat
To find details, use the command:
mdadm --detail /dev/md0
Once you created a RAID array, you need to format it with the command
mkfs.ext4 /dev/mdX
/dev/mdX = replace it with the actual device name used while creating the RAID array.
mkfs.ext4 will format the drive with EXT4 file system. To use other supported file systems replace mkfs.ext4 with other available file system types. For example mkfs.xfs
To mount the drive, use the following commands
mkdir /backup
mount /dev/md0 /backup
This will mount /dev/md0 as /backup. Change the mount point and device name as needed.
To ensure the array is reassembled automatically at boot, update the mdadm configuration file:
mdadm --detail --scan
Add entry for the RAID array in file /etc/mdadm/mdadm.conf
Update the initramfs:
update-initramfs -u
To automount the drive on boot, edit /etc/fstab
vi /etc/fstab
Add the following line
/dev/md0 /backup ext4 defaults 0 2
Verify it is mounting properly with the command
mount -a
Back to RAID
You can use dpkg-deb command to extract the contents of a .deb file in the Ubuntu or Debian system.
dpkg-deb -x file.deb folder
Example:
dpkg-deb -x anydesk_6.3.2-1_amd64.deb anydesk
Here we extract the content of the file anydesk_6.3.2-1_amd64.deb to the directory “anydesk’.
Back to dpkg

Keeping your operating system up-to-date is crucial for maintaining security and stability. For Ubuntu/Debian users, the unattended-upgrades package offers a solution to automate this essential task
Unattended-upgrades is a package for Ubuntu and other Debian-based Linux distributions that automates the process of keeping your system up-to-date. Its primary purpose is to automatically install security updates without requiring manual intervention from the system administrator.
To install unattended-upgrades, run
sudo apt install unattended-upgrades
To configure, edit file
sudo vi /etc/apt/apt.conf.d/50unattended-upgrades
Uncomment the line
// "${distro_id}:${distro_codename}-updates";
To make it look like
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
"${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
Uncomment the following line, this helps if you need a quick reboot while an upgrade is running, good for desktops/workstations.
//Unattended-Upgrade::MinimalSteps "true";
Another configuration file is /etc/apt/apt.conf.d/20auto-upgrades, default values are fine for this.
sudo vi /etc/apt/apt.conf.d/20auto-upgrades
To debug unattended upgrade, run
sudo unattended-upgrade --dry-run --debug
Back to Ubuntu

DHCP, or Dynamic Host Configuration Protocol, is a network management protocol that automates the process of assigning IP addresses and other network configuration parameters to devices on a network. This crucial technology plays a vital role in modern network infrastructure, from small home networks to large enterprise environments.
In essence, DHCP eliminates the need for manual IP address configuration, making it easier for devices to join and communicate on a network. It dynamically assigns IP addresses, subnet masks, default gateways, and other network settings to client devices, streamlining network administration and reducing the potential for configuration errors.
On Ubuntu systems, dhclient works in conjunction with NetworkManager for easier network configuration management.
Configuration file located at /etc/dhcp/dhclient.conf
To view IP lease info, run “dhclient -v” command
root@sok-mysql-fix:~# dhclient -v
Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/eth0/00:16:3e:bf:97:d0
Sending on LPF/eth0/00:16:3e:bf:97:d0
Sending on Socket/fallback
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3 (xid=0xc266324)
DHCPOFFER of 10.18.211.81 from 10.18.211.1
DHCPREQUEST for 10.18.211.81 on eth0 to 255.255.255.255 port 67 (xid=0x2463260c)
DHCPACK of 10.18.211.81 from 10.18.211.1 (xid=0xc266324)
RTNETLINK answers: File exists
bound to 10.18.211.81 -- renewal in 1759 seconds.
root@sok-mysql-fix:~#
Or check the content of file /var/lib/dhcp/dhclient.leases
root@sok-mysql-fix:~# cat /var/lib/dhcp/dhclient.leases
lease {
interface "eth0";
fixed-address 10.18.211.81;
option subnet-mask 255.255.255.0;
option routers 10.18.211.1;
option dhcp-lease-time 3600;
option dhcp-message-type 5;
option domain-name-servers 10.18.211.1;
option dhcp-server-identifier 10.18.211.1;
option dhcp-renewal-time 1800;
option broadcast-address 10.18.211.255;
option dhcp-rebinding-time 3150;
option host-name "sok-mysql-fix";
option domain-name "lxd";
renew 0 2024/07/07 17:47:55;
rebind 0 2024/07/07 18:11:06;
expire 0 2024/07/07 18:18:36;
}
root@sok-mysql-fix:~#
To manually request a lease
dhclient <interface>
To release an IP address
dhclient -r <interface>

ThingsBoard is an open-source Internet of Things (IoT) platform designed for device management, data collection, processing, and visualization. It offers a scalable and secure infrastructure for building IoT solutions across various industries. ThingsBoard supports multiple communication protocols, allowing easy integration with diverse devices and sensors. The platform provides powerful data analytics tools, customizable dashboards, and rule-based automation capabilities. With its flexible architecture, ThingsBoard enables developers to create both cloud and on-premises IoT applications, making it suitable for businesses of all sizes seeking to implement IoT technologies.