How to add bulk IP addresses to DigitalOcean firewall ?


Trying to add bulk IP’s in DigitalOcean firewall? You are in the right place.

DigitalOcean cloud control panel UI doesn’t allow you to paste in multiple IP Addresses at once. That’s a good idea for a UI improvement.

In the meantime you can definitely do it via the API

Use the following shell script.

It uses json for POST data, so update TOKEN, FIREWALL NAME, IP addresses, ports… and then run the script


# Author: Akhil Jalagam
# update TOKEN, FIREWALL NAME, IP addresses and then run the script

curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer $token" \
-d \
  "name": "'$FIREWALL_NAME'",
  "inbound_rules": [
      "protocol": "tcp",
      "ports": "all",
      "sources": {
        "addresses": [
      "protocol": "udp",
      "ports": "all",
      "sources": {
        "addresses": [

      "protocol": "icmp",
      "sources": {
        "addresses": [
  "outbound_rules": [
      "protocol": "icmp",
      "destinations": {
        "addresses": [
      "protocol": "tcp",
      "ports": "all",
      "destinations": {
        "addresses": [
      "protocol": "udp",
      "ports": "all",
      "destinations": {
        "addresses": [
}' ""

Hope it will save your time ! 😊

How to renew the SSL certificates for dovecot and postfix

Make a backup of the existing SSL key and certificate file

cd /etc/pki/dovecot
cp -a certs/dovecot.pem certs/dovecot.pem.old
cp -a private/dovecot.pem private/dovecot.pem.old

Create the new SSL certificate for two years:

openssl genrsa -out private/dovecot.pem 1024
openssl req -new -x509 -key private/dovecot.pem -out certs/dovecot.pem -days 730

Restart Dovecot and Postfix

sudo systemctl restart dovecot
sudo systemctl restart postfix

Check the start and end dates for the certificate:

openssl x509 -dates -in certs/dovecot.pem

How to display brightness level in i3status bar

How to display brightness level in i3status bar 1

I’ve been using Linux for a long time, but I was never entirely happy with the desktop environment options available. Until last year, Xfce was the closest to what I consider a good compromise between features and performance. Then I found i3, an amazing piece of software that changed my life.

i3 is a tiling window manager. The goal of a window manager is to control the appearance and placement of windows in a windowing system. Window managers are often used as part a full-featured desktop environment (such as GNOME or Xfce), but some can also be used as standalone applications.

i3status don’t have an option to display brightness level by default. But by tweaking some configuration we can easily achieve this.

Follow this method

  1. copy the script to /usr/local/bin


# Authors:
# - Moritz Warning <[email protected]> (2016)
# - Zhong Jianxin <[email protected]> (2014)
# - Akhil Jalagam <[email protected]> (2019)
# See file LICENSE at the project root directory for license information.
# i3status.conf should contain:
# general {
#   output_format = i3bar
# }
# i3 config looks like this:
# bar {
#   status_command exec /usr/share/doc/i3status/contrib/
# }
# Single interface:
# ifaces="eth0"
# Multiple interfaces:
# ifaces="eth0 wlan0"

# Auto detect interfaces
#ifaces=$(ls /sys/class/net | grep -E '^(eth|wlan|enp|wlp)')
ifaces="enp2s0 wlp3s0"


readable() {
  local bytes=$1
  local kib=$(( bytes >> 10 ))
  if [ $kib -lt 0 ]; then
    echo "? K"
  elif [ $kib -gt 1024 ]; then
    local mib_int=$(( kib >> 10 ))
    local mib_dec=$(( kib % 1024 * 976 / 10000 ))
    if [ "$mib_dec" -lt 10 ]; then
    echo "${mib_int}.${mib_dec} M"
    echo "${kib} K"

update_rate() {
  local time=$(date +%s)
  local rx=0 tx=0 tmp_rx tmp_tx

  for iface in $ifaces; do
    read tmp_rx < "/sys/class/net/${iface}/statistics/rx_bytes"
    read tmp_tx < "/sys/class/net/${iface}/statistics/tx_bytes"
    rx=$(( rx + tmp_rx ))
    tx=$(( tx + tmp_tx ))

  local interval=$(( $time - $last_time ))
  if [ $interval -gt 0 ]; then
    rate="$(readable $(( (rx - last_rx) / interval )))↓ $(readable $(( (tx - last_tx) / interval )))↑"
  # show brightness
  brightness=$(cat /sys/class/backlight/intel_backlight/brightness)


i3status | (read line && echo "$line" && read line && echo "$line" && read line && echo "$line" && update_rate && while :
  read line
  echo ",[{\"full_text\":\"${rate} | Sun: $(($brightness/75))% \" },${line#,\[}" || exit 1

In the above script you can change /sys/class/backlight/intel_backlight/brightness based on your backlight model.

2. update i3 config with the following

# control brightness
bindsym XF86MonBrightnessUp exec intelbacklight -inc 500 # increase screen brightness
bindsym XF86MonBrightnessDown exec intelbacklight -dec 500 # decrease screen brightness

# status bar
bar {
        status_command  /usr/local/bin/

Now reload the i3 config using Mod+Shift+r

Finally, you will see the net speed and brightness in status bar

If you don’t want to see net speed just remove {rate} from the echo command in above script

How to auto login in MySQL from a shell?

When you run MySQL commands MySQL, mysqlcheck, mysqdump and psql, psqldump, etc; they will pick username & password from this file if you do not provide them as argument (-u and -p). It can save you time.

Of course, if you specify username and password explicitly as part of the command’s arguments, they will be used.

.my.cnf ( for MySQL client )

[clienthost1]   # Note: client + host1

How to install PHP 7.1/7.2/7.3/7.4 in CentOS 7

Uncomment the required php version.

yum install -y
yum install -y yum-utils
# yum-config-manager --enable remi-php70
# yum-config-manager --enable remi-php71
# yum-config-manager --enable remi-php72
yum-config-manager --enable remi-php73
yum -y install php # php-mcrypt php-cli php-gd php-curl php-mysql php-ldap php-zip php-fileinfo 
php -v

How to auto login in Postgres from a shell?

When you run MySQL commands MySQL, mysqlcheck, mysqdump and psql, psqldump etc; they will pick username & password from this file if you do not provide them as argument (-u and -p). It can save you time.

Of course, if you specify username and password explicitly as part of the command’s arguments, they will be used.

.pgpass ( for psql client )

Custom fail2ban filters using regexp

fail2Ban is a very handy tool to prevent a lot of unwanted traffic from consuming bandwidth on your servers. It’s a very small and relatively simple IDS Type Tool that comes with some predefined Filters to automatically lockout potentially dangerous or bandwidth-consuming type attacks.

Creating a Custom Filter

badagents = 360Spider|ZmEu|Auto Spider 1.0|zgrab/[0-9]*\.[0-9a-zA-Z]*|Wget\(.*\)|MauiBot.*
failregex = ^.+?:\d+ <HOST> -.*"(GET|POST|HEAD).*HTTP.*(?:%(badagents)s)"$
ignoreregex =


fail2ban-regex /path-to-samples/sample.log /etc/fail2ban/filter.d/custom.conf

Jail example

enabled  = true
logpath  = /var/log/apache*/access.log
action   = iptables-ipset-proto4[name=Custom, port=1010, protocol=tcp]
findtime = 86400
bantime  = -1
maxretry = 1

Exploring the Logrotate Configuration

Logrotate is a system utility that manages the automatic rotation and compression of log files. If log files were not rotated, compressed, and periodically pruned, they could eventually consume all available disk space on a system.

Logrotate’s configuration information can generally be found in two places:

/etc/logrotate.conf: this file contains some default settings and sets up the rotation for a few logs that are not owned by any system packages. It also uses an include statement to pull in configuration from any file in the /etc/logrotate.d directory.

/etc/logrotate.d/: this is where any packages you install that need help with log rotation will place their Logrotate configuration. On a standard install, you should already have files here for basic system tools like apt, dpkg, rsyslog and so on.


/var/log/apt/history.log {
  rotate 12
  create 0640 www-data www-data
      systemctl reload example-app


  • rotate 12: keep twelve old log files.
  • monthly: rotate once a month.
  • compress: compress the rotated files. this uses gzip by default and results in files ending in .gz. The compression command can be changed using the compresscmd option.
  • missingok: don’t write an error message if the log file is missing.
  • notifempty: don’t rotate the log file if it is empty.
  • create 0640 www-data www-data: this creates a new empty log file after rotation, with the specified permissions (0640), owner (www-data), and group (also www-data).
  • sharedscripts: this flag means that any scripts added to the configuration are run only once per run, instead of for each file rotated. Since this configuration would match two log files in the example-app directory, the script specified in postrotate would run twice without this option.
  • postrotate to endscript: this block contains a script to run after the log file is rotated. In this case we’re reloading our example app. This is sometimes necessary to get your application to switch over to the newly created log file. Note that postrotate runs before logs are compressed. Compression could take a long time, and your software should switch to the new logfile immediately. For tasks that need to run after logs are compressed, use the lastaction block instead.

How to install, configure, create user and database with permissions – MySQL

MySQL is an open-source relational database management system. Its name is a combination of “My”, the name of co-founder Michael Widenius’s daughter, and “SQL”, the abbreviation for Structured Query Language.

Download and Install MySQL from the following link

rpm -ih mysql80-community-release-el7-3.noarch.rpm
yum update -y
yum install -y mysql-server


systemctl enable mysqld
systemctl start mysqld
# default password
grep -oP 'temporary password(.*): \K(\S+)' /var/log/mysqld.log

Create user and database with permissions

mysql -u root -p
# mysql > 
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypass';
GRANT ALL PRIVILEGES ON dbname.* TO 'myuser'@'%';

Starting with MySQL 8 you no longer can (implicitly) create a user using the GRANT command. Use CREATE USER instead, followed by the GRANT statement:

CREATE USER 'root'@'%' IDENTIFIED BY 'root';